blob: 3b49b0da6c4a81bfddfe147d89aa1af035e17cc6 [file] [log] [blame]
Jeff Sharkeydeb24052015-03-02 21:01:40 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Sharkeydeb24052015-03-02 21:01:40 -080017#include "Utils.h"
18#include "VolumeBase.h"
Jeff Sharkey36801cc2015-03-13 16:09:20 -070019#include "VolumeManager.h"
20#include "ResponseCode.h"
Jeff Sharkeydeb24052015-03-02 21:01:40 -080021
Jeff Sharkey36801cc2015-03-13 16:09:20 -070022#include <base/stringprintf.h>
23#include <base/logging.h>
Jeff Sharkeydeb24052015-03-02 21:01:40 -080024
25#include <fcntl.h>
26#include <stdlib.h>
27#include <sys/mount.h>
28#include <sys/stat.h>
29#include <sys/types.h>
30
Jeff Sharkey36801cc2015-03-13 16:09:20 -070031using android::base::StringPrintf;
32
33#define DEBUG 1
34
Jeff Sharkeydeb24052015-03-02 21:01:40 -080035namespace android {
36namespace vold {
37
Jeff Sharkey36801cc2015-03-13 16:09:20 -070038VolumeBase::VolumeBase(Type type) :
Jeff Sharkeyce6a9132015-04-08 21:07:21 -070039 mType(type), mFlags(0), mUser(-1), mCreated(false), mState(
40 State::kUnmounted), mSilent(false) {
Jeff Sharkeydeb24052015-03-02 21:01:40 -080041}
42
43VolumeBase::~VolumeBase() {
Jeff Sharkey36801cc2015-03-13 16:09:20 -070044 CHECK(!mCreated);
Jeff Sharkeydeb24052015-03-02 21:01:40 -080045}
46
Jeff Sharkey36801cc2015-03-13 16:09:20 -070047void VolumeBase::setState(State state) {
Jeff Sharkeydeb24052015-03-02 21:01:40 -080048 mState = state;
Jeff Sharkeyce6a9132015-04-08 21:07:21 -070049 notifyEvent(ResponseCode::VolumeStateChanged, StringPrintf("%d", mState));
Jeff Sharkeydeb24052015-03-02 21:01:40 -080050}
51
Jeff Sharkey36801cc2015-03-13 16:09:20 -070052status_t VolumeBase::setFlags(int flags) {
53 if (mState != State::kUnmounted) {
54 LOG(WARNING) << getId() << " flags change requires state unmounted";
Jeff Sharkeydeb24052015-03-02 21:01:40 -080055 return -EBUSY;
56 }
57
Jeff Sharkey36801cc2015-03-13 16:09:20 -070058 mFlags = flags;
59 return OK;
60}
61
62status_t VolumeBase::setUser(userid_t user) {
63 if (mState != State::kUnmounted) {
64 LOG(WARNING) << getId() << " user change requires state unmounted";
65 return -EBUSY;
66 }
67
68 mUser = user;
69 return OK;
70}
71
Jeff Sharkeyce6a9132015-04-08 21:07:21 -070072status_t VolumeBase::setSilent(bool silent) {
73 if (mCreated) {
74 LOG(WARNING) << getId() << " silence change requires destroyed";
75 return -EBUSY;
76 }
77
78 mSilent = silent;
79 return OK;
80}
81
Jeff Sharkey36801cc2015-03-13 16:09:20 -070082status_t VolumeBase::setId(const std::string& id) {
83 if (mCreated) {
84 LOG(WARNING) << getId() << " id change requires not created";
85 return -EBUSY;
86 }
87
88 mId = id;
89 return OK;
90}
91
92status_t VolumeBase::setPath(const std::string& path) {
93 if (mState != State::kMounting) {
94 LOG(WARNING) << getId() << " path change requires state mounting";
95 return -EBUSY;
96 }
97
98 mPath = path;
Jeff Sharkeyce6a9132015-04-08 21:07:21 -070099 notifyEvent(ResponseCode::VolumePathChanged, mPath);
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700100 return OK;
101}
102
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700103void VolumeBase::notifyEvent(int event) {
104 if (mSilent) return;
105 VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
106 getId().c_str(), false);
107}
108
109void VolumeBase::notifyEvent(int event, const std::string& value) {
110 if (mSilent) return;
111 VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
112 StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
113}
114
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700115void VolumeBase::addVolume(const std::shared_ptr<VolumeBase>& volume) {
116 mVolumes.push_back(volume);
117}
118
119void VolumeBase::removeVolume(const std::shared_ptr<VolumeBase>& volume) {
120 mVolumes.remove(volume);
121}
122
123std::shared_ptr<VolumeBase> VolumeBase::findVolume(const std::string& id) {
124 for (auto vol : mVolumes) {
125 if (vol->getId() == id) {
126 return vol;
127 }
128 }
129 return nullptr;
130}
131
132status_t VolumeBase::create() {
133 CHECK(!mCreated);
Jeff Sharkey9c484982015-03-31 10:35:33 -0700134
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700135 mCreated = true;
Jeff Sharkey9c484982015-03-31 10:35:33 -0700136 status_t res = doCreate();
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700137 notifyEvent(ResponseCode::VolumeCreated, StringPrintf("%d", mType));
Jeff Sharkey3161fb32015-04-12 16:03:33 -0700138 setState(State::kUnmounted);
Jeff Sharkey9c484982015-03-31 10:35:33 -0700139 return res;
140}
141
142status_t VolumeBase::doCreate() {
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700143 return OK;
144}
145
146status_t VolumeBase::destroy() {
147 CHECK(mCreated);
148
149 if (mState == State::kMounted) {
150 unmount();
151 }
152
Jeff Sharkey3161fb32015-04-12 16:03:33 -0700153 setState(State::kRemoved);
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700154 notifyEvent(ResponseCode::VolumeDestroyed);
Jeff Sharkey9c484982015-03-31 10:35:33 -0700155 status_t res = doDestroy();
156 mCreated = false;
157 return res;
158}
159
160status_t VolumeBase::doDestroy() {
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700161 return OK;
162}
163
164status_t VolumeBase::mount() {
Jeff Sharkey0fd95352015-04-04 21:38:59 -0700165 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
166 LOG(WARNING) << getId() << " mount requires state unmounted or unmountable";
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700167 return -EBUSY;
168 }
169
170 setState(State::kMounting);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800171 status_t res = doMount();
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700172 if (res == OK) {
173 setState(State::kMounted);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800174 } else {
Jeff Sharkey0fd95352015-04-04 21:38:59 -0700175 setState(State::kUnmountable);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800176 }
177
178 return res;
179}
180
181status_t VolumeBase::unmount() {
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700182 if (mState != State::kMounted) {
183 LOG(WARNING) << getId() << " unmount requires state mounted";
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800184 return -EBUSY;
185 }
186
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700187 setState(State::kUnmounting);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800188
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700189 for (auto vol : mVolumes) {
Jeff Sharkey3161fb32015-04-12 16:03:33 -0700190 if (vol->destroy()) {
191 LOG(WARNING) << getId() << " failed to destroy " << vol->getId()
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700192 << " stacked above";
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800193 }
194 }
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700195 mVolumes.clear();
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800196
197 status_t res = doUnmount();
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700198 setState(State::kUnmounted);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800199 return res;
200}
201
202status_t VolumeBase::format() {
Jeff Sharkey0fd95352015-04-04 21:38:59 -0700203 if (mState == State::kMounted) {
204 unmount();
205 }
206
207 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
208 LOG(WARNING) << getId() << " format requires state unmounted or unmountable";
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800209 return -EBUSY;
210 }
211
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700212 setState(State::kFormatting);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800213 status_t res = doFormat();
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700214 setState(State::kUnmounted);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800215 return res;
216}
217
218status_t VolumeBase::doFormat() {
219 return -ENOTSUP;
220}
221
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800222} // namespace vold
223} // namespace android