blob: cf3d54e3c7d58b69462d4712e60ef272f43556c1 [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"
Jeff Sharkeydeb24052015-03-02 21:01:40 -080020
Elliott Hughes7e128fb2015-12-04 15:50:53 -080021#include <android-base/stringprintf.h>
22#include <android-base/logging.h>
Jeff Sharkeydeb24052015-03-02 21:01:40 -080023
24#include <fcntl.h>
25#include <stdlib.h>
26#include <sys/mount.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29
Jeff Sharkey36801cc2015-03-13 16:09:20 -070030using android::base::StringPrintf;
31
Jeff Sharkeydeb24052015-03-02 21:01:40 -080032namespace android {
33namespace vold {
34
Jeff Sharkey36801cc2015-03-13 16:09:20 -070035VolumeBase::VolumeBase(Type type) :
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -070036 mType(type), mMountFlags(0), mMountUserId(-1), mCreated(false), mState(
Jeff Sharkeyce6a9132015-04-08 21:07:21 -070037 State::kUnmounted), mSilent(false) {
Jeff Sharkeydeb24052015-03-02 21:01:40 -080038}
39
40VolumeBase::~VolumeBase() {
Jeff Sharkey36801cc2015-03-13 16:09:20 -070041 CHECK(!mCreated);
Jeff Sharkeydeb24052015-03-02 21:01:40 -080042}
43
Jeff Sharkey36801cc2015-03-13 16:09:20 -070044void VolumeBase::setState(State state) {
Jeff Sharkeydeb24052015-03-02 21:01:40 -080045 mState = state;
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -060046
Jeff Sharkey814e9d32017-09-13 11:49:44 -060047 auto listener = getListener();
48 if (listener) listener->onVolumeStateChanged(getId(), static_cast<int32_t>(mState));
Jeff Sharkeydeb24052015-03-02 21:01:40 -080049}
50
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -070051status_t VolumeBase::setDiskId(const std::string& diskId) {
52 if (mCreated) {
53 LOG(WARNING) << getId() << " diskId change requires destroyed";
Jeff Sharkeydeb24052015-03-02 21:01:40 -080054 return -EBUSY;
55 }
56
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -070057 mDiskId = diskId;
Jeff Sharkey36801cc2015-03-13 16:09:20 -070058 return OK;
59}
60
Jeff Sharkeybc40cc82015-06-18 14:25:08 -070061status_t VolumeBase::setPartGuid(const std::string& partGuid) {
62 if (mCreated) {
63 LOG(WARNING) << getId() << " partGuid change requires destroyed";
64 return -EBUSY;
65 }
66
67 mPartGuid = partGuid;
68 return OK;
69}
70
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -070071status_t VolumeBase::setMountFlags(int mountFlags) {
72 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
73 LOG(WARNING) << getId() << " flags change requires state unmounted or unmountable";
Jeff Sharkey36801cc2015-03-13 16:09:20 -070074 return -EBUSY;
75 }
76
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -070077 mMountFlags = mountFlags;
78 return OK;
79}
80
81status_t VolumeBase::setMountUserId(userid_t mountUserId) {
82 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
83 LOG(WARNING) << getId() << " user change requires state unmounted or unmountable";
84 return -EBUSY;
85 }
86
87 mMountUserId = mountUserId;
Jeff Sharkey36801cc2015-03-13 16:09:20 -070088 return OK;
89}
90
Jeff Sharkeyce6a9132015-04-08 21:07:21 -070091status_t VolumeBase::setSilent(bool silent) {
92 if (mCreated) {
93 LOG(WARNING) << getId() << " silence change requires destroyed";
94 return -EBUSY;
95 }
96
97 mSilent = silent;
98 return OK;
99}
100
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700101status_t VolumeBase::setId(const std::string& id) {
102 if (mCreated) {
103 LOG(WARNING) << getId() << " id change requires not created";
104 return -EBUSY;
105 }
106
107 mId = id;
108 return OK;
109}
110
111status_t VolumeBase::setPath(const std::string& path) {
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -0700112 if (mState != State::kChecking) {
113 LOG(WARNING) << getId() << " path change requires state checking";
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700114 return -EBUSY;
115 }
116
117 mPath = path;
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -0600118
Jeff Sharkey814e9d32017-09-13 11:49:44 -0600119 auto listener = getListener();
120 if (listener) listener->onVolumePathChanged(getId(), mPath);
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -0600121
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700122 return OK;
123}
124
Jeff Sharkey1d6fbcc2015-04-24 16:00:03 -0700125status_t VolumeBase::setInternalPath(const std::string& internalPath) {
126 if (mState != State::kChecking) {
127 LOG(WARNING) << getId() << " internal path change requires state checking";
128 return -EBUSY;
129 }
130
131 mInternalPath = internalPath;
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -0600132
Jeff Sharkey814e9d32017-09-13 11:49:44 -0600133 auto listener = getListener();
134 if (listener) listener->onVolumeInternalPathChanged(getId(), mInternalPath);
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -0600135
Jeff Sharkey1d6fbcc2015-04-24 16:00:03 -0700136 return OK;
137}
138
Sudheer Shanka53947a32018-08-01 10:24:13 -0700139status_t VolumeBase::setLabel(const std::string& label) {
140 if (mState != State::kChecking) {
141 LOG(WARNING) << getId() << " label change requires state checking";
142 return -EBUSY;
143 }
144
145 mLabel = label;
146 return OK;
147}
148
Jeff Sharkey814e9d32017-09-13 11:49:44 -0600149android::sp<android::os::IVoldListener> VolumeBase::getListener() {
150 if (mSilent) {
151 return nullptr;
152 } else {
153 return VolumeManager::Instance()->getListener();
154 }
155}
156
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700157void VolumeBase::addVolume(const std::shared_ptr<VolumeBase>& volume) {
158 mVolumes.push_back(volume);
159}
160
161void VolumeBase::removeVolume(const std::shared_ptr<VolumeBase>& volume) {
162 mVolumes.remove(volume);
163}
164
165std::shared_ptr<VolumeBase> VolumeBase::findVolume(const std::string& id) {
166 for (auto vol : mVolumes) {
167 if (vol->getId() == id) {
168 return vol;
169 }
170 }
171 return nullptr;
172}
173
174status_t VolumeBase::create() {
175 CHECK(!mCreated);
Jeff Sharkey9c484982015-03-31 10:35:33 -0700176
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700177 mCreated = true;
Jeff Sharkey9c484982015-03-31 10:35:33 -0700178 status_t res = doCreate();
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -0600179
Jeff Sharkey814e9d32017-09-13 11:49:44 -0600180 auto listener = getListener();
181 if (listener) listener->onVolumeCreated(getId(),
182 static_cast<int32_t>(mType), mDiskId, mPartGuid);
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -0600183
Jeff Sharkey3161fb32015-04-12 16:03:33 -0700184 setState(State::kUnmounted);
Jeff Sharkey9c484982015-03-31 10:35:33 -0700185 return res;
186}
187
188status_t VolumeBase::doCreate() {
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700189 return OK;
190}
191
192status_t VolumeBase::destroy() {
193 CHECK(mCreated);
194
195 if (mState == State::kMounted) {
196 unmount();
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -0700197 setState(State::kBadRemoval);
198 } else {
199 setState(State::kRemoved);
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700200 }
201
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -0600202
Jeff Sharkey814e9d32017-09-13 11:49:44 -0600203 auto listener = getListener();
204 if (listener) listener->onVolumeDestroyed(getId());
Jeff Sharkeycbe69fc2017-09-15 16:50:28 -0600205
Jeff Sharkey9c484982015-03-31 10:35:33 -0700206 status_t res = doDestroy();
207 mCreated = false;
208 return res;
209}
210
211status_t VolumeBase::doDestroy() {
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700212 return OK;
213}
214
215status_t VolumeBase::mount() {
Jeff Sharkey0fd95352015-04-04 21:38:59 -0700216 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
217 LOG(WARNING) << getId() << " mount requires state unmounted or unmountable";
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700218 return -EBUSY;
219 }
220
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -0700221 setState(State::kChecking);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800222 status_t res = doMount();
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700223 if (res == OK) {
224 setState(State::kMounted);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800225 } else {
Jeff Sharkey0fd95352015-04-04 21:38:59 -0700226 setState(State::kUnmountable);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800227 }
228
229 return res;
230}
231
232status_t VolumeBase::unmount() {
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700233 if (mState != State::kMounted) {
234 LOG(WARNING) << getId() << " unmount requires state mounted";
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800235 return -EBUSY;
236 }
237
Jeff Sharkeyf1b996d2015-04-17 17:35:20 -0700238 setState(State::kEjecting);
Chih-Hung Hsieh11a2ce82016-07-27 14:11:02 -0700239 for (const auto& vol : mVolumes) {
Jeff Sharkey3161fb32015-04-12 16:03:33 -0700240 if (vol->destroy()) {
241 LOG(WARNING) << getId() << " failed to destroy " << vol->getId()
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700242 << " stacked above";
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800243 }
244 }
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700245 mVolumes.clear();
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800246
247 status_t res = doUnmount();
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700248 setState(State::kUnmounted);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800249 return res;
250}
251
Jeff Sharkeyd0640f62015-05-21 22:35:42 -0700252status_t VolumeBase::format(const std::string& fsType) {
Jeff Sharkey0fd95352015-04-04 21:38:59 -0700253 if (mState == State::kMounted) {
254 unmount();
255 }
256
257 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
258 LOG(WARNING) << getId() << " format requires state unmounted or unmountable";
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800259 return -EBUSY;
260 }
261
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700262 setState(State::kFormatting);
Jeff Sharkeyd0640f62015-05-21 22:35:42 -0700263 status_t res = doFormat(fsType);
Jeff Sharkey36801cc2015-03-13 16:09:20 -0700264 setState(State::kUnmounted);
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800265 return res;
266}
267
Jeff Sharkeyd0640f62015-05-21 22:35:42 -0700268status_t VolumeBase::doFormat(const std::string& fsType) {
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800269 return -ENOTSUP;
270}
271
Jeff Sharkeydeb24052015-03-02 21:01:40 -0800272} // namespace vold
273} // namespace android