mirror of
https://gitee.com/openharmony/filemanagement_storage_service
synced 2024-11-23 15:09:48 +00:00
volume: add volume manager
Signed-off-by: Xu Jia <xujia39@huawei.com> Change-Id: I1cd9cb05b5459868d689b539c4580f7edb092351
This commit is contained in:
parent
12be74d265
commit
f94b280862
@ -34,7 +34,8 @@
|
||||
"fsck_msdos",
|
||||
"gptfdisk",
|
||||
"newfs_msdos",
|
||||
"ntfs-3g"
|
||||
"ntfs-3g",
|
||||
"e2fsprogs"
|
||||
]
|
||||
},
|
||||
"build": {
|
||||
@ -51,7 +52,8 @@
|
||||
"//third_party/fsck_msdos:fsck_msdos",
|
||||
"//third_party/gptfdisk:sgdisk",
|
||||
"//third_party/newfs_msdos:newfs_msdos",
|
||||
"//third_party/ntfs-3g:ntfsprogs"
|
||||
"//third_party/ntfs-3g:ntfsprogs",
|
||||
"//third_party/e2fsprogs/misc:blkid"
|
||||
],
|
||||
"inner_kits": [
|
||||
{
|
||||
|
@ -54,6 +54,8 @@ ohos_executable("storage_daemon") {
|
||||
"disk/src/disk_config.cpp",
|
||||
"disk/src/disk_info.cpp",
|
||||
"disk/src/disk_manager.cpp",
|
||||
"volume/src/volume_info.cpp",
|
||||
"volume/src/volume_manager.cpp",
|
||||
"ipc/src/storage_daemon.cpp",
|
||||
"ipc/src/storage_daemon_stub.cpp",
|
||||
"ipc/src/storage_manager_client.cpp",
|
||||
|
@ -16,9 +16,60 @@
|
||||
#ifndef OHOS_STORAGE_DAEMON_VOLUME_INFO_H
|
||||
#define OHOS_STORAGE_DAEMON_VOLUME_INFO_H
|
||||
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
enum VolumeState {
|
||||
UNMOUNTED,
|
||||
CHECKING,
|
||||
MOUNTED,
|
||||
EJECTING,
|
||||
REMOVED,
|
||||
BADREMOVABLE,
|
||||
};
|
||||
|
||||
enum VolumeType {
|
||||
EXTERNAL,
|
||||
};
|
||||
|
||||
class VolumeInfo {
|
||||
public:
|
||||
VolumeInfo() = default;
|
||||
virtual ~VolumeInfo() = default;
|
||||
|
||||
int32_t Create(const std::string volId, const std::string diskId, dev_t device);
|
||||
int32_t Destroy();
|
||||
int32_t Mount(uint32_t flags);
|
||||
int32_t UMount(bool force = false);
|
||||
int32_t Check();
|
||||
int32_t Format(const std::string type);
|
||||
|
||||
std::string GetVolumeId();
|
||||
int32_t GetVolumeType();
|
||||
std::string GetDiskId();
|
||||
int32_t GetState();
|
||||
std::string GetMountPath();
|
||||
|
||||
protected:
|
||||
virtual int32_t DoCreate(dev_t dev) = 0;
|
||||
virtual int32_t DoDestroy() = 0;
|
||||
virtual int32_t DoMount(const std::string mountPath, uint32_t mountFlags) = 0;
|
||||
virtual int32_t DoUMount(const std::string mountPath, bool force) = 0;
|
||||
virtual int32_t DoCheck() = 0;
|
||||
virtual int32_t DoFormat(std::string type) = 0;
|
||||
|
||||
private:
|
||||
std::string id_;
|
||||
std::string diskId_;
|
||||
VolumeType type_;
|
||||
VolumeState mountState_;
|
||||
int32_t mountFlags_;
|
||||
int32_t userIdOwner_;
|
||||
std::string mountPath_;
|
||||
|
||||
const std::string mountPathDir_ = "/mnt/%s";
|
||||
};
|
||||
} // STORAGE_DAEMON
|
||||
} // OHOS
|
||||
|
@ -17,16 +17,35 @@
|
||||
#define OHOS_STORAGE_DAEMON_VOLUME_MANAGER_H
|
||||
|
||||
#include <nocopyable.h>
|
||||
#include <sys/types.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include "volume/volume_info.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
class VolumeManager final {
|
||||
public:
|
||||
virtual ~VolumeManager();
|
||||
virtual ~VolumeManager() = default;
|
||||
static VolumeManager* Instance();
|
||||
|
||||
std::string CreateVolume(const std::string diskId, dev_t device);
|
||||
int32_t DestroyVolume(const std::string volId);
|
||||
|
||||
int32_t Check(const std::string volId);
|
||||
int32_t Mount(const std::string volId, uint32_t flags);
|
||||
int32_t UMount(const std::string volId);
|
||||
int32_t Format(const std::string volId, const std::string fsType);
|
||||
|
||||
private:
|
||||
VolumeManager();
|
||||
VolumeManager() = default;
|
||||
DISALLOW_COPY_AND_MOVE(VolumeManager);
|
||||
|
||||
static VolumeManager* instance_;
|
||||
std::list<std::shared_ptr<VolumeInfo>> volumes_;
|
||||
|
||||
std::shared_ptr<VolumeInfo> GetVolume(const std::string volId);
|
||||
};
|
||||
} // STORAGE_DAEMON
|
||||
} // OHOS
|
||||
|
193
services/storage_daemon/volume/src/volume_info.cpp
Normal file
193
services/storage_daemon/volume/src/volume_info.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "volume/volume_info.h"
|
||||
#include <cstdlib>
|
||||
#include <sys/stat.h>
|
||||
#include "storage_service_log.h"
|
||||
#include "storage_service_errno.h"
|
||||
#include "utils/string_utils.h"
|
||||
|
||||
using namespace std;
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
int32_t VolumeInfo::Create(const std::string volId, const std::string diskId, dev_t device)
|
||||
{
|
||||
id_ = volId;
|
||||
diskId_ = diskId;
|
||||
type_ = EXTERNAL;
|
||||
mountState_ = UNMOUNTED;
|
||||
mountFlags_ = 0;
|
||||
userIdOwner_ = 0;
|
||||
mountPath_ = StringPrintf(mountPathDir_.c_str(), id_.c_str());
|
||||
|
||||
int32_t err = DoCreate(device);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
std::string VolumeInfo::GetVolumeId()
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
int32_t VolumeInfo::GetVolumeType()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
std::string VolumeInfo::GetDiskId()
|
||||
{
|
||||
return diskId_;
|
||||
}
|
||||
|
||||
int32_t VolumeInfo::GetState()
|
||||
{
|
||||
return mountState_;
|
||||
}
|
||||
|
||||
std::string VolumeInfo::GetMountPath()
|
||||
{
|
||||
return mountPath_;
|
||||
}
|
||||
|
||||
int32_t VolumeInfo::Destroy()
|
||||
{
|
||||
VolumeState state = REMOVED;
|
||||
if (mountState_ == REMOVED || mountState_ == BADREMOVABLE) {
|
||||
return E_OK;
|
||||
}
|
||||
if (mountState_ != UNMOUNTED) {
|
||||
// force umount
|
||||
UMount(true);
|
||||
state = BADREMOVABLE;
|
||||
}
|
||||
|
||||
int32_t err = DoDestroy();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
mountState_ = state;
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t VolumeInfo::Mount(uint32_t flags)
|
||||
{
|
||||
struct stat statbuf;
|
||||
int32_t err = 0;
|
||||
|
||||
if (mountState_ == MOUNTED) {
|
||||
return E_OK;
|
||||
}
|
||||
if (mountState_ != CHECKING) {
|
||||
LOGE("please check volume %{public}s first", GetVolumeId().c_str());
|
||||
return E_VOL_STATE;
|
||||
}
|
||||
|
||||
// check if dir exists
|
||||
err = lstat(mountPath_.c_str(), &statbuf);
|
||||
if (!err) {
|
||||
LOGE("volume mount path %{public}s exists, please remove first", GetMountPath().c_str());
|
||||
return E_MOUNT;
|
||||
}
|
||||
|
||||
err = mkdir(mountPath_.c_str(), S_IRWXU);
|
||||
if (err) {
|
||||
LOGE("the volume %{public}s create mount file %{public}s failed",
|
||||
GetVolumeId().c_str(), GetMountPath().c_str());
|
||||
return E_MOUNT;
|
||||
}
|
||||
|
||||
mountFlags_ = flags;
|
||||
err = DoMount(mountPath_, mountFlags_);
|
||||
if (err) {
|
||||
remove(mountPath_.c_str());
|
||||
return err;
|
||||
}
|
||||
|
||||
mountState_ = MOUNTED;
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t VolumeInfo::UMount(bool force)
|
||||
{
|
||||
int32_t err = 0;
|
||||
|
||||
if (mountState_ == REMOVED || mountState_ == BADREMOVABLE) {
|
||||
LOGE("the volume %{public}s is in REMOVED state", GetVolumeId().c_str());
|
||||
return E_VOL_STATE;
|
||||
}
|
||||
|
||||
if (mountState_ == UNMOUNTED) {
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
if (mountState_ == CHECKING) {
|
||||
mountState_ = UNMOUNTED;
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
if (mountState_ == EJECTING && !force) {
|
||||
return E_WAIT;
|
||||
}
|
||||
|
||||
mountState_ = EJECTING;
|
||||
|
||||
err = DoUMount(mountPath_, force);
|
||||
if (!force && err) {
|
||||
mountState_ = MOUNTED;
|
||||
return err;
|
||||
}
|
||||
|
||||
mountState_ = UNMOUNTED;
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t VolumeInfo::Check()
|
||||
{
|
||||
if (mountState_ != UNMOUNTED) {
|
||||
LOGE("the volume %{public}s is not in UNMOUNT state", GetVolumeId().c_str());
|
||||
return E_VOL_STATE;
|
||||
}
|
||||
|
||||
if (mountState_ == CHECKING) {
|
||||
mountState_ = UNMOUNTED;
|
||||
}
|
||||
|
||||
int32_t err = DoCheck();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
mountState_ = CHECKING;
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t VolumeInfo::Format(std::string type)
|
||||
{
|
||||
if (mountState_ != UNMOUNTED) {
|
||||
LOGE("Please unmount the volume %{public}s first", GetVolumeId().c_str());
|
||||
return E_VOL_STATE;
|
||||
}
|
||||
|
||||
int32_t err = DoFormat(type);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
return E_OK;
|
||||
}
|
||||
} // StorageDaemon
|
||||
} // OHOS
|
155
services/storage_daemon/volume/src/volume_manager.cpp
Normal file
155
services/storage_daemon/volume/src/volume_manager.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "volume/volume_manager.h"
|
||||
#include <cstdlib>
|
||||
#include <sys/sysmacros.h>
|
||||
#include "storage_service_log.h"
|
||||
#include "storage_service_errno.h"
|
||||
#include "utils/string_utils.h"
|
||||
#include "volume/external_volume_info.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
VolumeManager* VolumeManager::instance_ = nullptr;
|
||||
|
||||
VolumeManager* VolumeManager::Instance()
|
||||
{
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new VolumeManager();
|
||||
}
|
||||
|
||||
return instance_;
|
||||
}
|
||||
|
||||
std::shared_ptr<VolumeInfo> VolumeManager::GetVolume(const std::string volId)
|
||||
{
|
||||
for (std::list<std::shared_ptr<VolumeInfo>>::iterator it = volumes_.begin();
|
||||
it != volumes_.end(); ++it) {
|
||||
if ((*it)->GetVolumeId() == volId) {
|
||||
return (*it);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string VolumeManager::CreateVolume(const std::string diskId, dev_t device)
|
||||
{
|
||||
std::string volId = StringPrintf("vol-%u-%u", major(device), minor(device));
|
||||
|
||||
LOGI("create volume %{public}s.", volId.c_str());
|
||||
|
||||
std::shared_ptr<VolumeInfo> tmp = GetVolume(volId);
|
||||
if (tmp != nullptr) {
|
||||
LOGE("volume %{public}s exist.", volId.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
auto info = std::make_shared<ExternalVolumeInfo>();
|
||||
int32_t ret = info->Create(volId, diskId, device);
|
||||
if (ret) {
|
||||
return "";
|
||||
}
|
||||
|
||||
volumes_.push_back(info);
|
||||
return volId;
|
||||
}
|
||||
|
||||
int32_t VolumeManager::DestroyVolume(const std::string volId)
|
||||
{
|
||||
LOGI("destroy volume %{public}s.", volId.c_str());
|
||||
|
||||
std::shared_ptr<VolumeInfo> destroyNode = GetVolume(volId);
|
||||
|
||||
if (destroyNode == nullptr) {
|
||||
LOGE("the volume %{public}s does not exist", volId.c_str());
|
||||
return E_NON_EXIST;
|
||||
}
|
||||
|
||||
int32_t ret = destroyNode->Destroy();
|
||||
if (ret)
|
||||
return ret;
|
||||
volumes_.remove(destroyNode);
|
||||
destroyNode.reset();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t VolumeManager::Check(const std::string volId)
|
||||
{
|
||||
std::shared_ptr<VolumeInfo> info = GetVolume(volId);
|
||||
if (info == nullptr) {
|
||||
LOGE("the volume %{public}s does not exist.", volId.c_str());
|
||||
return E_NON_EXIST;
|
||||
}
|
||||
|
||||
int32_t err = info->Check();
|
||||
if (err != E_OK) {
|
||||
LOGE("the volume %{public}s check failed.", volId.c_str());
|
||||
return err;
|
||||
}
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t VolumeManager::Mount(const std::string volId, uint32_t flags)
|
||||
{
|
||||
std::shared_ptr<VolumeInfo> info = GetVolume(volId);
|
||||
if (info == nullptr) {
|
||||
LOGE("the volume %{public}s does not exist.", volId.c_str());
|
||||
return E_NON_EXIST;
|
||||
}
|
||||
|
||||
int32_t err = info->Mount(flags);
|
||||
if (err != E_OK) {
|
||||
LOGE("the volume %{public}s mount failed.", volId.c_str());
|
||||
return err;
|
||||
}
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t VolumeManager::UMount(const std::string volId)
|
||||
{
|
||||
std::shared_ptr<VolumeInfo> info = GetVolume(volId);
|
||||
if (info == nullptr) {
|
||||
LOGE("the volume %{public}s does not exist.", volId.c_str());
|
||||
return E_NON_EXIST;
|
||||
}
|
||||
|
||||
int32_t err = info->UMount();
|
||||
if (err != E_OK) {
|
||||
LOGE("the volume %{public}s mount failed.", volId.c_str());
|
||||
return err;
|
||||
}
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t VolumeManager::Format(const std::string volId, const std::string fsType)
|
||||
{
|
||||
std::shared_ptr<VolumeInfo> info = GetVolume(volId);
|
||||
if (info == nullptr) {
|
||||
LOGE("the volume %{public}s does not exist.", volId.c_str());
|
||||
return E_NON_EXIST;
|
||||
}
|
||||
|
||||
int32_t err = info->Format(fsType);
|
||||
if (err != E_OK) {
|
||||
LOGE("the volume %{public}s format failed.", volId.c_str());
|
||||
return err;
|
||||
}
|
||||
return E_OK;
|
||||
}
|
||||
} // StorageDaemon
|
||||
} // OHOS
|
@ -34,6 +34,9 @@ enum ErrNo {
|
||||
E_UMOUNT, // umount error
|
||||
E_SET_POLICY,
|
||||
E_USERID_RANGE, // id out or range
|
||||
E_VOL_STATE, // volume state check fail
|
||||
E_WAIT, // wait
|
||||
E_NOT_SUPPORT, // not support
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user