1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "volume/volume_info.h"
17 #include <cstdlib>
18 #include <sys/stat.h>
19 #include "storage_service_log.h"
20 #include "storage_service_errno.h"
21 #include "utils/string_utils.h"
22
23 using namespace std;
24 namespace OHOS {
25 namespace StorageDaemon {
Create(const std::string volId,const std::string diskId,dev_t device)26 int32_t VolumeInfo::Create(const std::string volId, const std::string diskId, dev_t device)
27 {
28 id_ = volId;
29 diskId_ = diskId;
30 type_ = EXTERNAL;
31 mountState_ = UNMOUNTED;
32 mountFlags_ = 0;
33 userIdOwner_ = 0;
34 mountPath_ = StringPrintf(mountPathDir_.c_str(), id_.c_str());
35
36 int32_t err = DoCreate(device);
37 if (err) {
38 return err;
39 }
40 return E_OK;
41 }
42
GetVolumeId()43 std::string VolumeInfo::GetVolumeId()
44 {
45 return id_;
46 }
47
GetVolumeType()48 int32_t VolumeInfo::GetVolumeType()
49 {
50 return type_;
51 }
52
GetDiskId()53 std::string VolumeInfo::GetDiskId()
54 {
55 return diskId_;
56 }
57
GetState()58 int32_t VolumeInfo::GetState()
59 {
60 return mountState_;
61 }
62
GetMountPath()63 std::string VolumeInfo::GetMountPath()
64 {
65 return mountPath_;
66 }
67
Destroy()68 int32_t VolumeInfo::Destroy()
69 {
70 VolumeState state = REMOVED;
71 if (mountState_ == REMOVED || mountState_ == BADREMOVABLE) {
72 return E_OK;
73 }
74 if (mountState_ != UNMOUNTED) {
75 // force umount
76 UMount(true);
77 state = BADREMOVABLE;
78 }
79
80 int32_t err = DoDestroy();
81 if (err) {
82 return err;
83 }
84 mountState_ = state;
85 return E_OK;
86 }
87
Mount(uint32_t flags)88 int32_t VolumeInfo::Mount(uint32_t flags)
89 {
90 struct stat statbuf;
91 int32_t err = 0;
92
93 if (mountState_ == MOUNTED) {
94 return E_OK;
95 }
96 if (mountState_ != CHECKING) {
97 LOGE("please check volume %{public}s first", GetVolumeId().c_str());
98 return E_VOL_STATE;
99 }
100
101 // check if dir exists
102 err = lstat(mountPath_.c_str(), &statbuf);
103 if (!err) {
104 LOGE("volume mount path %{public}s exists, please remove first", GetMountPath().c_str());
105 return E_MOUNT;
106 }
107
108 err = mkdir(mountPath_.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
109 if (err) {
110 LOGE("the volume %{public}s create mount file %{public}s failed",
111 GetVolumeId().c_str(), GetMountPath().c_str());
112 return E_MOUNT;
113 }
114
115 mountFlags_ = flags;
116 err = DoMount(mountPath_, mountFlags_);
117 if (err) {
118 remove(mountPath_.c_str());
119 return err;
120 }
121
122 mountState_ = MOUNTED;
123 return E_OK;
124 }
125
UMount(bool force)126 int32_t VolumeInfo::UMount(bool force)
127 {
128 int32_t err = 0;
129
130 if (mountState_ == REMOVED || mountState_ == BADREMOVABLE) {
131 LOGE("the volume %{public}s is in REMOVED state", GetVolumeId().c_str());
132 return E_VOL_STATE;
133 }
134
135 if (mountState_ == UNMOUNTED) {
136 return E_OK;
137 }
138
139 if (mountState_ == CHECKING) {
140 mountState_ = UNMOUNTED;
141 return E_OK;
142 }
143
144 if (mountState_ == EJECTING && !force) {
145 return E_WAIT;
146 }
147
148 mountState_ = EJECTING;
149
150 err = DoUMount(mountPath_, force);
151 if (!force && err) {
152 mountState_ = MOUNTED;
153 return err;
154 }
155
156 mountState_ = UNMOUNTED;
157 return E_OK;
158 }
159
Check()160 int32_t VolumeInfo::Check()
161 {
162 if (mountState_ != UNMOUNTED) {
163 LOGE("the volume %{public}s is not in UNMOUNT state", GetVolumeId().c_str());
164 return E_VOL_STATE;
165 }
166
167 if (mountState_ == CHECKING) {
168 mountState_ = UNMOUNTED;
169 }
170
171 int32_t err = DoCheck();
172 if (err) {
173 return err;
174 }
175 mountState_ = CHECKING;
176 return E_OK;
177 }
178
Format(std::string type)179 int32_t VolumeInfo::Format(std::string type)
180 {
181 if (mountState_ != UNMOUNTED) {
182 LOGE("Please unmount the volume %{public}s first", GetVolumeId().c_str());
183 return E_VOL_STATE;
184 }
185
186 int32_t err = DoFormat(type);
187 if (err) {
188 return err;
189 }
190 return E_OK;
191 }
192 } // StorageDaemon
193 } // OHOS
194