【OpenHarmony】存储管理服务模块架构
存储管理服务模块架构
1. 模块概述
源码:https://gitee.com/openharmony/filemanagement_storage_service
1.1 功能与目标
主要功能:
存储管理服务模块(Storage Service)是OpenHarmony系统中提供基础存储查询和管理能力的核心模块,为系统和应用提供统一的存储管理接口。该模块的主要功能包括:
- 外置存储卡管理:提供外置存储卡的挂载、卸载、格式化等管理功能
- 文件加解密:提供文件系统的加密和解密能力,支持用户数据保护
- 磁盘和卷管理:提供磁盘和卷的查询、创建、删除等管理功能
- 用户目录管理:提供多用户环境下的目录创建、删除、权限管理
- 存储空间统计:提供以应用或用户为维度的存储空间统计查询能力
- 文件共享:提供应用间文件共享和分布式文件共享功能
- MTP支持:提供MTP(Media Transfer Protocol)设备支持
- 配额管理:提供应用存储配额限制和管理功能
- 媒体FUSE:提供媒体文件的FUSE文件系统支持
- 云存储FUSE:提供云存储的FUSE文件系统支持
使用场景:
- 系统存储管理
- 应用存储空间管理
- 用户数据目录管理
- 外置存储设备管理
- 文件加密和安全保护
- 分布式文件共享
- 媒体文件管理
- 云存储集成
1.2 系统位置
系统架构位置:
存储管理服务模块位于OpenHarmony系统的foundation/filemanagement
子系统下,是文件管理框架的核心组件。
模块关系:
- 上层对接:为应用层和其他系统服务提供存储管理API
- 下层对接:对接底层文件系统、加密框架、硬件驱动等
- 横向协作:与多用户管理、包管理、媒体库服务、公共文件访问框架等模块协作
- 系统集成:集成到系统能力管理器中,提供系统级存储管理能力
核心模块地位:
该模块是文件管理子系统的核心模块,承担着统一存储管理接口的重要职责,是连接应用和底层存储系统的重要桥梁。
1.3 设计思路与模式
设计思路:
- 分层架构设计:采用storage_api、storage_manager、storage_daemon三层架构
- 服务分离:将常驻daemon服务和非常驻manager服务分离,提高系统效率
- 统一接口设计:通过统一的API接口屏蔽底层存储差异
- 安全优先:集成文件加密和权限控制机制,确保数据安全
- 多用户支持:支持多用户环境下的存储隔离和管理
- 异步处理机制:采用异步处理模式,提高系统响应性能
设计模式:
- 单例模式:VolumeManager、KeyManager等核心组件采用单例模式
- 代理模式:StorageManager作为代理,管理StorageDaemon连接和请求转发
- 观察者模式:存储状态变化通知机制
- 工厂模式:Volume和Disk对象的创建和管理
- 策略模式:不同存储类型的处理策略
1.4 系统框图
2. 模块结构
2.1 源文件与头文件
核心服务文件:
Storage Manager服务:
services/storage_manager/include/storage/storage_manager.h
- 存储管理器主类定义services/storage_manager/include/volume/volume_manager.h
- 卷管理器services/storage_manager/include/disk/disk_manager.h
- 磁盘管理器services/storage_manager/include/user/user_manager.h
- 用户管理器services/storage_manager/include/crypto/crypto_manager.h
- 加密管理器
Storage Daemon服务:
services/storage_daemon/include/volume/volume_manager.h
- 卷管理器services/storage_daemon/include/crypto/key_manager.h
- 密钥管理器services/storage_daemon/include/disk/disk_manager.h
- 磁盘管理器services/storage_daemon/include/user/user_manager.h
- 用户管理器services/storage_daemon/include/mtp/mtp_manager.h
- MTP管理器
接口定义文件:
interfaces/innerkits/storage_manager/native/volume_core.h
- 卷核心信息interfaces/innerkits/storage_manager/native/disk.h
- 磁盘信息interfaces/innerkits/storage_manager/native/storage_stats.h
- 存储统计interfaces/innerkits/storage_manager/native/bundle_stats.h
- 应用统计services/storage_daemon/IStorageDaemon.idl
- Daemon服务接口services/storage_manager/IStorageManager.idl
- Manager服务接口
JS API文件:
interfaces/kits/js/storage_manager/include/volumemanager_napi.h
- 卷管理JS接口interfaces/kits/js/storage_manager/include/storage_statistics_napi.h
- 存储统计JS接口interfaces/kits/js/storage_manager/include/keymanager_napi.h
- 密钥管理JS接口
工具和辅助文件:
services/common/include/storage_service_constant.h
- 服务常量定义services/common/include/storage_service_log.h
- 日志工具services/common/include/storage_rl_map.h
- 读写锁映射
2.2 类、结构体、函数与方法
核心类定义:
VolumeManager类(Daemon)
class VolumeManager final {
public:virtual ~VolumeManager() = default;static VolumeManager &Instance();// 卷管理std::string CreateVolume(const std::string diskId, dev_t device, bool isUserdata);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 MountUsbFuse(std::string volumeId, std::string &fsUuid, int &fuseFd);int32_t TryToFix(const std::string volId, uint32_t flags);int32_t Format(const std::string volId, const std::string fsType);int32_t SetVolumeDescription(const std::string volId, const std::string description);int32_t QueryUsbIsInUse(const std::string &diskPath, bool &isInUse);private:VolumeManager() = default;DISALLOW_COPY_AND_MOVE(VolumeManager);bool IsMtpDeviceInUse(const std::string &diskPath);StorageService::StorageRlMap<std::string, std::shared_ptr<VolumeInfo>> volumes_;std::shared_ptr<VolumeInfo> GetVolume(const std::string volId);int32_t CreateMountUsbFusePath(std::string fsUuid);int32_t ReadVolumeUuid(std::string volumeId, std::string &fsUuid);std::string mountUsbFusePath_;
};
KeyManager类
class KeyManager {
public:static KeyManager &GetInstance(void);// 全局密钥管理int InitGlobalDeviceKey(void);int InitGlobalUserKeys(void);// 用户密钥管理int GenerateUserKeys(unsigned int user, uint32_t flags);int DeleteUserKeys(unsigned int user);int UpdateUserAuth(unsigned int user, struct UserTokenSecret &userTokenSecret);int ActiveCeSceSeceUserKey(unsigned int user, KeyType type, const std::vector<uint8_t> &token,const std::vector<uint8_t> &secret);int InActiveUserKey(unsigned int user);// 应用密钥管理int GenerateAppkey(uint32_t user, uint32_t hashId, std::string &keyId, bool needReSet = false);int DeleteAppkey(uint32_t user, const std::string keyId);// 屏幕锁定管理int LockUserScreen(uint32_t user);int UnlockUserScreen(uint32_t user, const std::vector<uint8_t> &token,const std::vector<uint8_t> &secret);int GetLockScreenStatus(uint32_t user, bool &lockScreenStatus);// 文件加密状态int GetFileEncryptStatus(uint32_t userId, bool &isEncrypted, bool needCheckDirMount = false);// 恢复密钥管理int CreateRecoverKey(uint32_t userId, uint32_t userType, const std::vector<uint8_t> &token,const std::vector<uint8_t> &secret);int SetRecoverKey(const std::vector<uint8_t> &key);private:KeyManager();~KeyManager() {}DISALLOW_COPY_AND_MOVE(KeyManager);using KeyMap = std::map<KeyType, std::shared_ptr<BaseKey>>;std::map<unsigned int, KeyMap> userElKeys_;std::map<unsigned int, std::shared_ptr<DelayHandler>> userLockScreenTask_;std::shared_ptr<BaseKey> globalEl1Key_ { nullptr };std::mutex keyMutex_;bool hasGlobalDeviceKey_;
};
重要结构体:
VolumeCore结构体
class VolumeCore : public Parcelable {
public:VolumeCore();VolumeCore(std::string id, int32_t type, std::string diskId);VolumeCore(std::string id, int32_t type, std::string diskId, int32_t state);// 属性访问std::string GetId() const;int32_t GetType();std::string GetDiskId();int32_t GetState();void SetState(int32_t state);// 序列化支持bool Marshalling(Parcel &parcel) const override;static VolumeCore *Unmarshalling(Parcel &parcel);private:std::string id_; // 卷IDint32_t type_; // 卷类型(EMULATED/EXTERNAL)std::string diskId_; // 磁盘IDint32_t state_; // 卷状态bool errorFlag_; // 错误标志
};
Disk结构体
class Disk : public Parcelable {
public:Disk();Disk(std::string diskId, int64_t sizeBytes, std::string sysPath, std::string vendor, int32_t flag);// 属性访问std::string GetDiskId() const;int64_t GetSizeBytes();std::string GetSysPath();std::string GetVendor();int32_t GetFlag();void SetFlag(int32_t flag);// 序列化支持bool Marshalling(Parcel &parcel) const override;static Disk *Unmarshalling(Parcel &parcel);private:std::string diskId_; // 磁盘IDint64_t sizeBytes_; // 磁盘大小std::string sysPath_; // 系统路径std::string vendor_; // 厂商信息int32_t flag_; // 磁盘标志(SD_FLAG/USB_FLAG)
};
StorageStats结构体
class StorageStats final : public Parcelable {
public:StorageStats() {}StorageStats(int64_t total, int64_t audio, int64_t video, int64_t image, int64_t file, int64_t app): total_(total), audio_(audio), video_(video), image_(image), file_(file), app_(app) {}~StorageStats() {}// 存储统计信息int64_t total_ {0}; // 总大小int64_t audio_ {0}; // 音频大小int64_t video_ {0}; // 视频大小int64_t image_ {0}; // 图片大小int64_t file_ {0}; // 文件大小int64_t app_ {0}; // 应用大小// 序列化支持bool Marshalling(Parcel &parcel) const override;static StorageStats *Unmarshalling(Parcel &parcel);
};
2.3 继承与多态
继承关系:
VolumeCore
、Disk
、StorageStats
等结构体继承自Parcelable
,支持跨进程序列化VolumeManager
、KeyManager
等管理器类采用单例模式- 各种回调类继承自相应的接口基类
多态设计:
- 通过接口抽象实现不同存储类型的统一管理
- 回调机制支持多种事件类型的统一处理
- 策略模式实现不同存储策略的动态切换
- 工厂模式支持不同存储对象的创建
2.4 类图
2.5 模块内部依赖框图
3. 模块间交互
3.1 交互描述
与系统模块的交互:
- 多用户管理:通过os_account模块管理用户,调用storage_manager提供的能力管理相应用户的数据目录
- 包管理:通过bundle_framework模块提供包的管理功能,为storage_manager提供指定用户、指定包名对应的空间大小
- 媒体库服务:通过media_library模块提供媒体文件信息,为storage_manager提供指定用户的各类媒体文件的空间大小
- 公共文件访问框架:通过user_file_service模块提供对文件的管理功能,需要storage_manager提供的卷信息
- 加密框架:通过crypto_framework和huks模块提供加密和密钥管理能力
- 文件系统:通过底层文件系统提供存储操作能力
外部库依赖:
- 系统框架:SAMGR、SAFWK、AAFwk等系统框架
- 加密库:OpenSSL、Huks等加密相关库
- 文件系统工具:e2fsprogs、f2fs-tools、exfatprogs、ntfs-3g等文件系统工具
- USB和MTP:libusb、libmtp等USB和MTP相关库
- FUSE:libfuse提供用户空间文件系统支持
- 工具库:cJSON、c_utils、zlib等基础工具库
异步处理机制:
- 使用IPC机制进行跨进程通信
- 通过事件循环机制处理存储状态变化
- 支持多线程并发处理存储操作请求
- 采用观察者模式处理存储事件通知
3.2 事件驱动机制
事件类型:
- 磁盘创建/销毁事件
- 卷创建/销毁事件
- 卷挂载/卸载事件
- 用户创建/删除事件
- 文件加密状态变化事件
- MTP设备连接/断开事件
- 存储空间变化事件
事件处理流程:
- 注册事件监听器
- 接收系统或硬件事件通知
- 解析事件参数
- 更新内部状态
- 通知相关回调
- 执行相应的存储操作
3.3 外部依赖框图
4. 状态机转换图
4.1 状态机模型
存储管理服务模块的状态机包含以下主要状态:
服务状态:
SERVICE_NOT_START
- 服务未启动SERVICE_RUNNING
- 服务运行中SERVICE_STOPPING
- 服务停止中SERVICE_EXIT
- 服务已退出
卷状态:
VOLUME_UNMOUNTED
- 卷未挂载VOLUME_CHECKING
- 卷检查中VOLUME_MOUNTED
- 卷已挂载VOLUME_EJECTING
- 卷弹出中VOLUME_REMOVED
- 卷已移除VOLUME_BAD_REMOVAL
- 卷异常移除VOLUME_DAMAGED
- 卷损坏VOLUME_FUSE_REMOVED
- FUSE卷已移除
磁盘状态:
DISK_UNKNOWN
- 磁盘未知DISK_CONNECTED
- 磁盘已连接DISK_DISCONNECTED
- 磁盘已断开DISK_FORMATTING
- 磁盘格式化中DISK_FORMATTED
- 磁盘已格式化
用户状态:
USER_NOT_CREATED
- 用户未创建USER_CREATING
- 用户创建中USER_CREATED
- 用户已创建USER_STARTING
- 用户启动中USER_RUNNING
- 用户运行中USER_STOPPING
- 用户停止中USER_DELETED
- 用户已删除
加密状态:
ENCRYPTION_DISABLED
- 加密未启用ENCRYPTION_ENABLING
- 加密启用中ENCRYPTION_ENABLED
- 加密已启用ENCRYPTION_DISABLING
- 加密禁用中ENCRYPTION_ERROR
- 加密错误
4.2 状态切换规则
服务启动流程:
- 服务初始状态为
SERVICE_NOT_START
- 收到启动事件后,进入
SERVICE_RUNNING
状态 - 初始化各个子模块和事件监听器
- 注册到系统能力管理器
卷状态转换:
- 卷初始状态为
VOLUME_UNMOUNTED
- 收到挂载请求时,进入
VOLUME_CHECKING
状态 - 检查完成后,进入
VOLUME_MOUNTED
状态 - 收到卸载请求时,进入
VOLUME_EJECTING
状态 - 卸载完成后,回到
VOLUME_UNMOUNTED
状态 - 发生错误时,进入相应的错误状态
磁盘状态转换:
- 磁盘初始状态为
DISK_UNKNOWN
- 检测到磁盘连接时,进入
DISK_CONNECTED
状态 - 收到格式化请求时,进入
DISK_FORMATTING
状态 - 格式化完成后,进入
DISK_FORMATTED
状态 - 磁盘断开时,进入
DISK_DISCONNECTED
状态
用户状态转换:
- 用户初始状态为
USER_NOT_CREATED
- 收到创建请求时,进入
USER_CREATING
状态 - 创建完成后,进入
USER_CREATED
状态 - 收到启动请求时,进入
USER_STARTING
状态 - 启动完成后,进入
USER_RUNNING
状态 - 收到停止请求时,进入
USER_STOPPING
状态 - 停止完成后,回到
USER_CREATED
状态 - 收到删除请求时,进入
USER_DELETED
状态
加密状态转换:
- 加密初始状态为
ENCRYPTION_DISABLED
- 收到启用请求时,进入
ENCRYPTION_ENABLING
状态 - 启用完成后,进入
ENCRYPTION_ENABLED
状态 - 收到禁用请求时,进入
ENCRYPTION_DISABLING
状态 - 禁用完成后,回到
ENCRYPTION_DISABLED
状态 - 发生错误时,进入
ENCRYPTION_ERROR
状态
事件触发条件:
- 系统启动/停止事件
- 磁盘连接/断开事件
- 卷挂载/卸载事件
- 用户创建/删除事件
- 加密启用/禁用事件
- 硬件状态变化事件
4.3 状态机转换图
5. 接口设计
5.1 公共接口
存储管理接口:
获取卷信息
// IDL接口
void GetAllVolumes([out] VolumeExternal[] vecOfVol);
void GetVolumeByUuid([in] String fsUuid, [out] VolumeExternal vc);
void GetVolumeById([in] String volumeId, [out] VolumeExternal vc);
- 功能:获取系统中的卷信息
- 参数:
fsUuid
- 文件系统UUIDvolumeId
- 卷IDvecOfVol
- 输出参数,卷信息列表vc
- 输出参数,卷信息
- 返回值:操作结果码
- 异常处理:卷不存在时返回错误码
挂载/卸载卷
// IDL接口
void Mount([in] String volumeId);
void Unmount([in] String volumeId);
- 功能:挂载或卸载指定的卷
- 参数:
volumeId
- 卷ID - 返回值:操作结果码
- 权限要求:系统级权限
- 异常处理:卷不存在或权限不足时返回错误码
格式化卷
// IDL接口
void Format([in] String volumeId, [in] String fsType);
- 功能:格式化指定的卷
- 参数:
volumeId
- 卷IDfsType
- 文件系统类型
- 返回值:操作结果码
- 权限要求:系统级权限
- 异常处理:卷不存在或格式化失败时返回错误码
磁盘管理接口:
获取磁盘信息
// IDL接口
void GetAllDisks([out] Disk[] vecOfDisk);
void GetDiskById([in] String diskId, [out] Disk disk);
- 功能:获取系统中的磁盘信息
- 参数:
diskId
- 磁盘IDvecOfDisk
- 输出参数,磁盘信息列表disk
- 输出参数,磁盘信息
- 返回值:操作结果码
- 异常处理:磁盘不存在时返回错误码
分区磁盘
// IDL接口
void Partition([in] String diskId, [in] int type);
- 功能:对磁盘进行分区
- 参数:
diskId
- 磁盘IDtype
- 分区类型
- 返回值:操作结果码
- 权限要求:系统级权限
- 异常处理:磁盘不存在或分区失败时返回错误码
存储统计接口:
获取存储统计
// IDL接口
void GetUserStorageStats([out] StorageStats storageStats);
void GetUserStorageStats([in] int userId, [out] StorageStats storageStats);
void GetUserStorageStatsByType([in] int userId, [out] StorageStats storageStats, [in] String type);
- 功能:获取用户存储统计信息
- 参数:
userId
- 用户IDtype
- 统计类型storageStats
- 输出参数,存储统计信息
- 返回值:操作结果码
- 异常处理:用户不存在时返回错误码
获取应用统计
// IDL接口
void GetBundleStats([in] String pkgName, [out] BundleStats bundleStats, [in] int appIndex, [in] unsigned int statFlag);
void GetCurrentBundleStats([out] BundleStats bundleStats, [in] unsigned int statFlag);
- 功能:获取应用存储统计信息
- 参数:
pkgName
- 应用包名appIndex
- 应用索引statFlag
- 统计标志bundleStats
- 输出参数,应用统计信息
- 返回值:操作结果码
- 异常处理:应用不存在时返回错误码
用户管理接口:
用户生命周期管理
// IDL接口
void PrepareAddUser([in] int userId, [in] unsigned int flags);
void RemoveUser([in] int userId, [in] unsigned int flags);
void PrepareStartUser([in] int userId);
void StopUser([in] int userId);
void CompleteAddUser([in] int userId);
- 功能:管理用户的生命周期
- 参数:
userId
- 用户IDflags
- 操作标志
- 返回值:操作结果码
- 权限要求:系统级权限
- 异常处理:用户操作失败时返回错误码
加密管理接口:
用户密钥管理
// IDL接口
void DeleteUserKeys([in] unsigned int userId);
void UpdateUserAuth([in] unsigned int userId, [in] unsigned long secureUid,[in] List<unsigned char> token, [in] List<unsigned char> oldSecret,[in] List<unsigned char> newSecret);
void ActiveUserKey([in] unsigned int userId, [in] unsigned char[] token, [in] unsigned char[] secret);
void InactiveUserKey([in] unsigned int userId);
- 功能:管理用户的加密密钥
- 参数:
userId
- 用户IDsecureUid
- 安全用户IDtoken
- 认证令牌oldSecret
- 旧密钥newSecret
- 新密钥
- 返回值:操作结果码
- 权限要求:系统级权限
- 异常处理:密钥操作失败时返回错误码
屏幕锁定管理
// IDL接口
void LockUserScreen([in] unsigned int userId);
void UnlockUserScreen([in] unsigned int userId, [in] unsigned char[] token, [in] unsigned char[] secret);
void GetLockScreenStatus([in] unsigned int userId, [out] boolean lockScreenStatus);
- 功能:管理用户的屏幕锁定状态
- 参数:
userId
- 用户IDtoken
- 认证令牌secret
- 密钥lockScreenStatus
- 输出参数,锁定状态
- 返回值:操作结果码
- 异常处理:锁定操作失败时返回错误码
5.2 数据交换接口
IPC接口定义:
- 使用IDL定义跨进程接口
- 支持Parcelable对象序列化
- 提供异步回调机制
数据格式:
- VolumeCore、Disk、StorageStats等结构体支持序列化
- 使用MessageParcel进行数据传递
- 支持大数据量的传输
5.3 接口调用时序图
6. 总结
存储管理服务模块是OpenHarmony系统中文件管理框架的核心组件,通过分层架构设计为系统和应用提供统一的存储管理能力。该模块采用storage_api、storage_manager、storage_daemon三层架构,实现了常驻daemon服务和非常驻manager服务的分离,提高了系统效率。
主要特点:
- 分层架构设计,职责清晰
- 支持多用户环境下的存储隔离
- 完善的加密和安全保护机制
- 统一的存储管理接口
- 高效的异步处理能力
技术优势:
- 基于IPC的跨进程通信机制
- 完善的错误处理和异常管理
- 支持多种存储类型和设备
- 灵活的模块化架构设计
- 高效的存储空间统计能力
该模块为OpenHarmony系统的存储管理提供了坚实的基础,支持各种存储操作需求,是构建存储管理应用的重要基础设施。通过分层设计和多用户支持,为开发者提供了灵活、安全、高效的存储管理能力。