blob: 307791d9de973592f4f6d8ebd7f5120351fe642e [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
17#define LOG_TAG "Vold"
18
19#include "Utils.h"
20#include "VolumeBase.h"
21
22#include <cutils/log.h>
23
24#include <fcntl.h>
25#include <stdlib.h>
26#include <sys/mount.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29
30namespace android {
31namespace vold {
32
33VolumeBase::VolumeBase(VolumeType type) :
34 mType(type), mState(VolumeState::kUnmounted) {
35}
36
37VolumeBase::~VolumeBase() {
38}
39
40void VolumeBase::setState(VolumeState state) {
41 mState = state;
42
43 // TODO: publish state up to framework
44}
45
46void VolumeBase::stackVolume(const std::shared_ptr<VolumeBase>& volume) {
47 mStacked.push_back(volume);
48}
49
50void VolumeBase::unstackVolume(const std::shared_ptr<VolumeBase>& volume) {
51 mStacked.remove(volume);
52}
53
54status_t VolumeBase::mount() {
55 if (getState() != VolumeState::kUnmounted) {
56 SLOGE("Must be unmounted to mount %s", getId().c_str());
57 return -EBUSY;
58 }
59
60 setState(VolumeState::kMounting);
61 status_t res = doMount();
62 if (!res) {
63 setState(VolumeState::kMounted);
64 } else {
65 setState(VolumeState::kCorrupt);
66 }
67
68 return res;
69}
70
71status_t VolumeBase::unmount() {
72 if (getState() != VolumeState::kMounted) {
73 SLOGE("Must be mounted to unmount %s", getId().c_str());
74 return -EBUSY;
75 }
76
77 setState(VolumeState::kUnmounting);
78
79 for (std::string target : mBindTargets) {
80 ForceUnmount(target);
81 }
82 mBindTargets.clear();
83
84 for (std::shared_ptr<VolumeBase> v : mStacked) {
85 if (v->unmount()) {
86 ALOGW("Failed to unmount %s stacked above %s", v->getId().c_str(),
87 getId().c_str());
88 }
89 }
90 mStacked.clear();
91
92 status_t res = doUnmount();
93 setState(VolumeState::kUnmounted);
94 return res;
95}
96
97status_t VolumeBase::format() {
98 if (getState() != VolumeState::kUnmounted
99 || getState() != VolumeState::kCorrupt) {
100 SLOGE("Must be unmounted or corrupt to format %s", getId().c_str());
101 return -EBUSY;
102 }
103
104 setState(VolumeState::kFormatting);
105 status_t res = doFormat();
106 setState(VolumeState::kUnmounted);
107 return res;
108}
109
110status_t VolumeBase::doFormat() {
111 return -ENOTSUP;
112}
113
114status_t VolumeBase::mountBind(const std::string& source, const std::string& target) {
115 if (::mount(source.c_str(), target.c_str(), "", MS_BIND, NULL)) {
116 SLOGE("Failed to bind mount %s to %s: %s", source.c_str(),
117 target.c_str(), strerror(errno));
118 return -errno;
119 }
120 mBindTargets.push_back(target);
121 return OK;
122}
123
124status_t VolumeBase::unmountBind(const std::string& target) {
125 ForceUnmount(target);
126 mBindTargets.remove(target);
127 return OK;
128}
129
130} // namespace vold
131} // namespace android