存储管理服务指引

项目定位

本仓库对应 OpenHarmony foundation/filemanagement/storage_service。优先按这些目录定位问题:

  • services/storage_daemon/:底层守护进程,负责设备热插拔、分区/挂载/格式化、fscrypt 密钥管理、用户目录创建/销毁、配额管理。
  • services/storage_manager/:系统 SA(ID 5003),负责卷/磁盘状态维护、用户生命周期、空间统计与监控、IPC 桥接到 Daemon(ID 5004)。
  • interfaces/innerkits/interfaces/kits/:Native 内部 API 和 JS/ETS 对外 API。
  • services/common/:共享常量、日志宏、错误码定义。
  • test/test/fuzztest/:单元测试和 fuzz 目标。

构建和验证

构建命令从 OpenHarmony 源码根目录执行,不在本子目录执行。

./build.sh --product-name rk3568 --build-target storage_daemon --ccache
./build.sh --product-name rk3568 --build-target storage_manager --ccache
prebuilts/build-tools/linux-x86/bin/ninja -C out/rk3568 StorageDaemonProviderTest

涉及真实磁盘、加密、多用户或配额的行为,需要补充板侧证据。提交使用 git commit -s,并保留 Co-Authored-By: Agent。变更需通过单元测试和 fuzz 测试。

错误码与代码规范

命名规则

类型 规则 注意
类名 大驼峰 KeyManagerVolumeInfo
函数名 大驼峰 GenerateUserKeysActiveUserKey
变量名 小驼峰 userIdvolumeId
成员变量 下划线结尾或小驼峰 源码中两种并存,修改时保持同文件一致
常量 extern const MAX_USER_ID 类型是 int 不是 int32_tEL1 类型是 std::string 不是 const char*
枚举 大驼峰类型 + 大写值 VolumeStateenum 不是 enum classDiskInfo::Tableenum class

错误码选用

禁止使用 E_ERR(太笼统),必须使用对应类别的具体错误码:

场景 必须使用 禁止使用
userId 范围无效 E_USERID_RANGE E_ERR
volumeId/diskId 不存在 E_NON_EXIST E_ERR
volume 状态不允许 E_VOL_STATE E_ERR
目录创建失败 E_CREATE_DIR_RECURSIVE_FAILED E_ERR
目录销毁失败 E_DESTROY_DIR E_ERR
密钥存储失败 E_ELX_KEY_STORE_ERROR E_ERR
密钥激活失败 E_ELX_KEY_ACTIVE_ERROR E_ERR
权限不足 E_PERMISSION_DENIED E_ERR
参数无效 E_PARAMS_INVALID E_ERR

错误码范围

基础值 STORAGE_SERVICE_SYS_CAP_TAG = 13600000(定义于 interfaces/innerkits/storage_manager/native/storage_service_errno.h):

范围 类别 示例
0 成功(E_OK
13600001-13600025 通用错误 E_PERMISSION_DENIEDE_NON_EXISTE_PARAMS_INVALID
13600201-13600245 密钥管理 E_USERID_RANGEE_ELX_KEY_STORE_ERRORE_ELX_KEY_ACTIVE_ERROR
13600350-13600353 密钥完整性 E_DIR_INTEGRITY_ERRE_KEY_SIZE_ERROR
13601201 BundleManager E_BUNDLEMGR_ERROR
13601701-13601719 卷状态 E_VOL_STATEE_TIMEOUT_MOUNT

日志必打节点

流程 必打节点 级别
用户管理(Prepare/Start/Complete/Stop/Remove) 开始、成功、失败 LOGI/LOGE
密钥管理(Generate/Active/Inactive/Lock/Unlock/Update) 成功、失败 LOGI/LOGE
卷操作(Mount/Unmount/Format/TryToFix) 开始、成功、失败 LOGI/LOGE
磁盘事件(添加/移除) 设备信息、正常/异常移除 LOGI/LOGW
IPC 连接 连接成功/失败、断开 LOGI/LOGE/LOGW

敏感信息禁止打印:不可在日志中出现密码、密钥数据、token 内容。只打印长度或状态。

编码约束

约束项 限制
单个函数 ≤ 50 行,超过则拆分
单个文件 ≤ 2000 行,超过则按职责拆分

知识索引

稳定背景知识放在 docs/knowledge/。改动前按场景读取对应文件:

场景 先读
用户创建/删除、PrepareAddUser/StartUser/CompleteAddUser、EL 目录、多用户隔离、回滚 docs/knowledge/user-directory-lifecycle.md
卷 Mount/Unmount、EJECTING、磁盘热插拔、SD/USB/光驱/MTP 差异、挂载超时 docs/knowledge/disk-volume-lifecycle.md
密钥生成/激活、锁屏/解锁 EL2、V1/V2 兼容、App 密钥 docs/knowledge/crypto-key-management.md
Manager-Daemon 职责、懒连接、崩溃恢复、IPC 新增流程 docs/knowledge/ipc-interface-guide.md
配额设置/查询、存储监控阈值、共享文件 ACL docs/knowledge/storage-quota-monitoring.md
VolumeState 跳转、DiskType/KeyType 作用域、位掩码 docs/knowledge/enums-and-state-machine.md
代码放置位置、Instance/GetInstance 差异、头文件路径 docs/knowledge/architecture.md
实现必做步骤、各场景操作必做项 docs/knowledge/implementation-templates.md
测试覆盖要求、Mock 选择、Fuzz docs/knowledge/testing-guide.md
时序跳步、状态跳转、锁屏访问、跨用户、IPC 死锁 docs/knowledge/constraints-and-traps.md
日志查看、SA 状态检查、问题定位 docs/knowledge/debugging-guide.md
编译宏差异、HUKS/OsAccount 不可用 docs/knowledge/external-dependencies.md

项目约束

  • 用户时序不可跳步:PrepareAddUser → StartUser → CompleteAddUser,缺步会导致 EL2-EL4 密钥未激活。
  • 卷状态不可跳转:MOUNTED → EJECTING → REMOVED,必须经过 EJECTING,不可直接置 REMOVED。
  • EL2 密钥锁屏移除、解锁安装:锁屏时不可访问 EL2 加密数据,必须在解锁后才操作。
  • 用户隔离:不可用 userId=100 的密钥操作 userId=105 的目录,密钥和目录必须匹配。
  • IPC 死锁预防:不要在持有 Manager 锁时调用 Daemon IPC,先释放锁再发起 IPC。
  • 高危删除约束:对路径执行不可逆删除(递归删除、RmDirRecurse/ForceRemoveDirectoryunlinkrmdir 等)前,必须确认目标真实后端即预期对象——挂载类间接层(设备挂载/绑定挂载/重复或多层挂载等)会使挂载点目录的真实后端≠表面,对残留挂载层的挂载点递归删会穿透到源数据导致数据丢失。删挂载点目录前必须逐层彻底卸载、确认无残留挂载层,否则禁止执行、需人工确认。
  • ELX 密钥删除约束:删除 EL1~EL5 任一等级密钥是不可逆操作——ClearKey 会擦除密钥材料并递归删除密钥目录与备份目录(ForceRemoveDirectory),密钥一旦删除则对应等级加密数据永久无法解密;且低等级(如 EL1)删除会令 EL2~EL5 链式依赖断裂、高等级数据一并无法激活。删除前必须确认已无回滚/恢复需要:存在 need_restore 标志或半成品/待恢复态时禁止销毁密钥材料(须先恢复或重建),并在用户/设备销毁流程确认完成后再执行,否则禁止删除、需人工确认。