diff --git a/README.md b/README.md index 2eb9fc328bca6e5e531d71b971cace5aa5d33aa1..b1b425c2870031e71ac55f410cc1cedc2a7e4c43 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,83 @@ -# storage_distributed_file_manager +# 分布式文件管理 -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} +[TOC] -#### 软件架构 -软件架构说明 +## 简介 +分布式文件管理提供跨设备的、符合POSIX规范的文件访问能力。其在分布式软总线动态组网的基础上,为网络上各个设备结点提供一个统一的、逻辑的、树形的文件系统层次结构。 -#### 安装教程 +分布式文件管理的架构如下图所示: -1. xxxx -2. xxxx -3. xxxx +![架构图](https://images.gitee.com/uploads/images/2021/1102/094937_01125861_9249473.png "io.drawio.png") -#### 使用说明 +其包括如下几个核心模块: -1. xxxx -2. xxxx -3. xxxx +- distributedfiledaemon:分布式文件管理常驻用户态服务,负责接入设备组网、数据传输能力,并负责挂载hmdfs +- distributedfileservice:分布式文件管理服务进程,对应用提供分布式扩展能力 +- hmdfs(Harmony Distributed File System):分布式文件管理核心模块,是一种面向移动分布式场景的、高性能的、基于内核实现的、堆叠式文件系统。 -#### 参与贡献 +## 目录 -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +```raw +//foundation/storage/distributed_file_manager +├── frameworks // 接口实现 +│ └── native // c/c++ 接口实现 +├── interfaces // 接口声明 +│ └── innerkits // 对内接口声明 +├── services // 服务实现 +│ └── distributedfiledaemon // 常驻服务实现 +| └── include +| └── src + └── device // 设备上下线管理 + └── ipc // daemon进程拉起退出流程以及ipc接口实现 + └── mountpoint // hmdfs挂载管理 + └── network // 软总线和内核会话session交互相关 +| └── test +| └── BUILD.gn +| └── distributedfileservice // 三方应用调用流程服务实现 +└── utils // 公共组件 + ├── log // 日志组件 + └── system // 平台相关组件 +``` +## 约束 -#### 特技 +### 接口支持情况 -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +分布式文件管理当前不支持或有限支持如下 VFS 系统调用: + +- symlink:不支持 +- mmap:仅支持读 +- rename:仅支持同目录操作 + +### 目录项规格 + +- 最大目录层级 + + 与被堆叠文件系统,即data分区所用文件系统,如 ext4,f2fs等,保持一致 +- 最大文件名长度 + 取决于680字节与被堆叠文件支持长度的最小值。f2fs和ext4均为255字节。 +- 单文件最大大小 + 取决于2^64字节与被堆叠文件系统的最小值。ext4单文件最大为16TB, f2fs单文件最大为3.94T。 +- 单目录下最大目录项数 + 取决于被堆叠文件系统单文件大小。当堆叠f2fs时,假设平均目录长度放大系数为3,则为`3.94TB/4KB*85/3=29,966,344,738`个。 + +## 说明 + +### 使用说明 + +可以使用终端调试分布式文件管理能力。 + +在多台设备已经组网(同一局域网)的情况下, 并且在经过hichian模块可信认证的设备间,可以建立设备间分布式文件互相访问的能力。 +可以在应用内通过```Context.distributedFileDir()```接口获取本应用沙箱内的分布式路径,然后在此目录下可以进行创建、删除、读写文件和目录。 +在此目录下有```device_view```和```merge_view```两个目录。 + +device_view 的含义是分设备视图,其下的 local 对应被堆叠的本地文件系统,`79xxx0c8d` 对应相应设备上的本地文件系统。如果在 local 中进行文件系统操作,其影响也将体现在 hmdfs 的源目录,即 `/data/misc_ce/0/hmdfs/storage` 中。如果在 `79xxx0c8d` 中进行文件系统操作,其影响也将体现在对应设备的 hmdfs 的源目录中。 + +merge_view 的含义是融合视图,它由分设备视图中各目录融合而成。在其中进行文件系统操作,将影响所有设备 hmdfs 的源目录。特别地,当将会产生新文件/目录时,总会产生在本地 hmdfs 的源目录中。 + +## 相关 + +- [分布式软总线-SoftBus](https://gitee.com/openharmony/communication_dsoftbus) +- [分布式硬件-设备管理](https://gitee.com/openharmony/device_manager) +- [用户程序框架](https://gitee.com/openharmony/appexecfwk_standard) diff --git a/frameworks/native/service_proxy.cpp b/frameworks/native/service_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac73e3dfdc84666ddc941f203a3cca50a5764b56 --- /dev/null +++ b/frameworks/native/service_proxy.cpp @@ -0,0 +1,27 @@ +/* + * 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 "service_proxy.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +ServiceProxy::ServiceProxy(const sptr &impl) : IRemoteProxy(impl) {} +ServiceProxy::~ServiceProxy() {} + +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/service_proxy.h b/frameworks/native/service_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..5b510e969284c69899ecf6ee0c2deb48f9597236 --- /dev/null +++ b/frameworks/native/service_proxy.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef DISTRIBUTEDFILE_SERVICE_PROXY_H +#define DISTRIBUTEDFILE_SERVICE_PROXY_H + +#include +#include "i_distributedfile_service.h" +#include "message_parcel.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class ServiceProxy : public IRemoteProxy { +public: + /** + * ServiceProxy + * + * @param impl + */ + explicit ServiceProxy(const sptr &impl); + + virtual ~ServiceProxy(); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/frameworks/native/BUILD.gn b/interfaces/innerkits/native/BUILD.gn similarity index 64% rename from frameworks/native/BUILD.gn rename to interfaces/innerkits/native/BUILD.gn index 942bde711ee4e8e355ca60e38367ba4dbd8e1c42..009e52a7876977302eca673e133a038e0680ab73 100644 --- a/frameworks/native/BUILD.gn +++ b/interfaces/innerkits/native/BUILD.gn @@ -13,10 +13,34 @@ import("//build/ohos.gni") import("//foundation/storage/distributed_file_manager/distributedfile.gni") -ohos_shared_library("libdistributedfile_innerkits") { - include_dirs = [ "${innerkits_native_path}" ] +config("private_config") { + include_dirs = [ + "../../../frameworks/native", + ] + + configs = [ "//build/config/compiler:exceptions" ] +} +config("public_config") { + include_dirs = [ "." ] +} + +ohos_shared_library("libdistributedfile_innerkits") { sources = [ + "../../../frameworks/native/service_proxy.cpp" + ] + + configs = [ ":private_config" ] + + public_configs = [ ":public_config" ] + + external_deps = [ + "ipc:ipc_core", + "safwk:system_ability_fwk", + ] + + deps = [ + "${utils_path}:libdistributedfileutils", ] part_name = "storage_distributed_file_manager" diff --git a/interfaces/innerkits/native/i_distributedfile_service.h b/interfaces/innerkits/native/i_distributedfile_service.h new file mode 100644 index 0000000000000000000000000000000000000000..878461cbd84f9c3f3b76d53edc9f356dbc358fd2 --- /dev/null +++ b/interfaces/innerkits/native/i_distributedfile_service.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +#ifndef I_DISTRIBUTEDFILE_SERVICE_H +#define I_DISTRIBUTEDFILE_SERVICE_H + +#include "iremote_broker.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class IDistributedFileService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedFile.IDistributedFileService"); + // define the message code + // define the error code + enum { + DISTRIBUTEDFILE_SUCCESS = 0, + DISTRIBUTEDFILE_WRITE_DESCRIPTOR_TOKEN_FAIL, + ERR_FLATTEN_OBJECT, + DISTRIBUTEDFILE_NO_ERROR, + DISTRIBUTEDFILE_CONNECT_SYSTEM_ABILITY_STUB_FAIL, + REMOVE_DISTRIBUTEDFILE_DISTRIBUTEDDIRS_FAIL, + DISTRIBUTEDFILE_BAD_TYPE, + DISTRIBUTEDFILE_FAIL, + DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL, + DISTRIBUTEDFILE_WRITE_REPLY_FAIL, + DISTRIBUTEDFILE_DIR_NAME_IS_EMPTY, + DISTRIBUTEDFILE_NAME_NOT_FOUND, + DISTRIBUTEDFILE_PERMISSION_DENIED, + ROOT_UID, + SYSTEM_SERVICE_UID, + }; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // I_YANGHU_TESt_SERVICE_H \ No newline at end of file diff --git a/ohos.build b/ohos.build index 575dc9bbad43f2c715848719870e084f72014348..50e5a679c11f0ed00b3cda56658c43ac49a6f795 100755 --- a/ohos.build +++ b/ohos.build @@ -9,6 +9,17 @@ "module_list": [ "//foundation/storage/distributed_file_manager/services/:services_target" ], + "inner_kits":[ + { + "name": "//foundation/storage/distributed_file_manager/interfaces/innerkits/native:libdistributedfile_innerkits", + "header": { + "header_files": [ + "i_distributedfile_service.h" + ], + "header_base": "//foundation/storage/distributed_file_manager/interfaces/innerkits/native" + } + } + ], "test_list": [ "//foundation/storage/distributed_file_manager/services/distributedfiledaemon/test/unittest:unittest", "//foundation/storage/distributed_file_manager/test/moduletest:moduletest" diff --git a/services/4902.xml b/services/4902.xml new file mode 100644 index 0000000000000000000000000000000000000000..a7428c63c72d4854e6c4a5441cbc645bedc6aadb --- /dev/null +++ b/services/4902.xml @@ -0,0 +1,30 @@ + + + + distributedfileservice + + libdistributedfileservice.z.so + + + 4902 + libdistributedfileservice.z.so + + + true + false + 1 + + diff --git a/services/BUILD.gn b/services/BUILD.gn old mode 100755 new mode 100644 index 91e21af8e8e29264b6c9969328b6e40d2a018867..189a30a8640b84c267f2a7956b17a3919ddddc64 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -15,7 +15,9 @@ import("//build/ohos/sa_profile/sa_profile.gni") import("//foundation/storage/distributed_file_manager/distributedfile.gni") ohos_sa_profile("distributedfile_sa_profile") { - sources = [ "4901.xml" ] + sources = [ + "4901.xml", + "4902.xml"] part_name = "storage_distributed_file_manager" } @@ -31,5 +33,6 @@ group("services_target") { ":distributedfile_etc", ":distributedfile_sa_profile", "distributedfiledaemon:distributedfiledaemon_target", + "distributedfileservice:distributedfileservice_target", ] } diff --git a/services/distributedfile.cfg b/services/distributedfile.cfg index bc21a7068bfc146ffe0bcf56f39ffc6571df87d0..e2e31e54058eaf37067d3b9c864fba421a40c028 100644 --- a/services/distributedfile.cfg +++ b/services/distributedfile.cfg @@ -1,20 +1,27 @@ { - "jobs": [{ - "name": "boot", - "cmds": [ - "start distributedfiledaemon" - ] - },{ - "name" : "init", - "cmds" : [ - "mount tmpfs tmpfs /mnt" - ] - }], - "services": [{ - "name": "distributedfiledaemon", - "path": ["/system/bin/sa_main", "/system/profile/distributedfiledaemon.xml"], - "uid": "root", - "gid": ["root", "system", "shell", "readproc", "media_rw", "inet"], - "caps": ["SYS_PTRACE", "KILL"] - }] -} \ No newline at end of file + "jobs": [{ + "name": "boot", + "cmds": [ + "start distributedfiledaemon", + "start distributedfileservice" + ] + },{ + "name" : "init", + "cmds" : [ + "mount tmpfs tmpfs /mnt" + ] + }], + "services": [{ + "name": "distributedfileservice", + "path": ["/system/bin/sa_main", "/system/profile/distributedfileservice.xml"], + "uid": "system", + "gid": ["system"], + "caps": ["SYS_PTRACE", "KILL"] + },{ + "name": "distributedfiledaemon", + "path": ["/system/bin/sa_main", "/system/profile/distributedfiledaemon.xml"], + "uid": "root", + "gid": ["root"], + "caps": ["SYS_PTRACE", "KILL"] + }] +} diff --git a/services/distributedfiledaemon/BUILD.gn b/services/distributedfiledaemon/BUILD.gn index c18dc7558ba715de63637c0fb711cda2b2f4c43f..4eaaa6806f83231c3e3464460737ff50e936185f 100755 --- a/services/distributedfiledaemon/BUILD.gn +++ b/services/distributedfiledaemon/BUILD.gn @@ -17,6 +17,8 @@ ohos_shared_library("libdistributedfiledaemon") { include_dirs = [ "include", "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + "//base/security/deviceauth/interfaces/innerkits", + "//third_party/json/include" ] sources = [ @@ -37,6 +39,7 @@ ohos_shared_library("libdistributedfiledaemon") { deps = [ "${utils_path}:libdistributedfileutils", "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + "//base/security/deviceauth/services:deviceauth_sdk" ] external_deps = [ "dsoftbus_standard:softbus_client", diff --git a/services/distributedfiledaemon/include/device/device_info.h b/services/distributedfiledaemon/include/device/device_info.h index 2a340d56c2625cceae56c61f5bf0acaa384245fa..57ea917ddd298651a2e27cab886bc17bb3d2a25e 100644 --- a/services/distributedfiledaemon/include/device/device_info.h +++ b/services/distributedfiledaemon/include/device/device_info.h @@ -28,23 +28,15 @@ public: DeviceInfo() = default; ~DeviceInfo() = default; explicit DeviceInfo(const DistributedHardware::DmDeviceInfo &nodeInfo); - explicit DeviceInfo(const DeviceInfo &nodeInfo); + DeviceInfo(const DeviceInfo &nodeInfo); DeviceInfo &operator=(const DistributedHardware::DmDeviceInfo &nodeInfo); - /** - * @note Remove the concept iid later - */ - void SetIid(const uint64_t iid); void SetCid(const std::string &cid); - uint64_t GetIid() const; const std::string &GetCid() const; private: - std::atomic initIidFlag_{false}; std::atomic initCidFlag_{false}; - - uint64_t iid_{0}; std::string cid_; }; } // namespace DistributedFile diff --git a/services/distributedfiledaemon/include/device/device_manager_agent.h b/services/distributedfiledaemon/include/device/device_manager_agent.h index aa3948fb256c07591eccb650f20c362706868a1e..ad9ae0c36f77d3ea0fb7536b2bf49440ebdc54a9 100644 --- a/services/distributedfiledaemon/include/device/device_manager_agent.h +++ b/services/distributedfiledaemon/include/device/device_manager_agent.h @@ -18,24 +18,47 @@ #include #include #include +#include #include +#include "device_auth.h" #include "device_info.h" #include "device_manager.h" #include "mountpoint/mount_point.h" #include "network/network_agent_template.h" +#include "nlohmann/json.hpp" +#include "utils_actor.h" #include "utils_singleton.h" +#include "utils_startable.h" namespace OHOS { namespace Storage { namespace DistributedFile { +struct GroupInfo { + std::string groupName; + std::string groupId; + std::string groupOwner; + int32_t groupType; + GroupInfo() : groupType(0) {} + GroupInfo(std::string name, std::string id, std::string owner, int32_t type) + : groupName(name), groupId(id), groupOwner(owner), groupType(type) + { + } +}; + +void from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo); + class DeviceManagerAgent final : public DistributedHardware::DmInitCallback, public DistributedHardware::DeviceStateCallback, public std::enable_shared_from_this, + public Startable, + public Actor, public Utils::Singleton { DECLARE_SINGLETON(DeviceManagerAgent); public: + void Start() override; + void Stop() override; void JoinGroup(std::weak_ptr mp); void QuitGroup(std::weak_ptr mp); @@ -44,23 +67,32 @@ public: void OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo) override; void OnDeviceReady(const DistributedHardware::DmDeviceInfo &deviceInfo) override {} + void OfflineAllDevice(); + void ReconnectOnlineDevices(); + void AuthGroupOnlineProc(const DeviceInfo info); void OnRemoteDied() override; DeviceInfo &GetLocalDeviceInfo(); std::vector GetRemoteDevicesInfo(); private: - void InitLocalIid(); + void StartInstance() override; + void StopInstance() override; void InitLocalNodeInfo(); + void RegisterToExternalDm(); void UnregisterFromExternalDm(); - void Start() override; - void Stop() override; + void AuthGroupOfflineProc(const DeviceInfo &info); + void QueryRelatedGroups(const std::string &networkId, std::vector &groupList); + bool CheckIsAuthGroup(const GroupInfo &group); + void AllAuthGroupsOfflineProc(); // We use a mutex instead of a shared_mutex to serialize online/offline procedures std::mutex mpToNetworksMutex_; std::map> mpToNetworks_; DeviceInfo localDeviceInfo_; + std::unordered_map> authGroupMap_; + const DeviceGroupManager *hichainDeviceGroupManager_{nullptr}; }; } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfiledaemon/include/ipc/daemon.h b/services/distributedfiledaemon/include/ipc/daemon.h index 986cc7a3f35209ff6c188040df8eaac78b4e3cfe..32283511c3dc6dd3563da86d383cab362288819a 100644 --- a/services/distributedfiledaemon/include/ipc/daemon.h +++ b/services/distributedfiledaemon/include/ipc/daemon.h @@ -28,7 +28,7 @@ namespace Storage { namespace DistributedFile { enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; -class Daemon final: public SystemAbility, public DaemonStub, protected NoCopyable { +class Daemon final : public SystemAbility, public DaemonStub, protected NoCopyable { DECLARE_SYSTEM_ABILITY(Daemon); public: diff --git a/services/distributedfiledaemon/include/mountpoint/mount_manager.h b/services/distributedfiledaemon/include/mountpoint/mount_manager.h index 41b0156506961829fbcf7d8c8d38e7dda14d23ed..05a4abca6fa36e289716efc5180bf9fbeb6a1ec0 100644 --- a/services/distributedfiledaemon/include/mountpoint/mount_manager.h +++ b/services/distributedfiledaemon/include/mountpoint/mount_manager.h @@ -30,12 +30,12 @@ class MountManager final : public Utils::Singleton { public: void Mount(std::unique_ptr mp); void Umount(std::weak_ptr wmp); - + void Umount(const std::string &groupId); DECLARE_SINGLETON(MountManager); private: - void Start() override {} - void Stop() override {} + void StartInstance() override {} + void StopInstance() override {} std::mutex serializer_; std::vector> mountPoints_; diff --git a/services/distributedfiledaemon/include/mountpoint/mount_point.h b/services/distributedfiledaemon/include/mountpoint/mount_point.h index 59019a953f847abb4bda491f5cdd3dac9b46b2b0..e6a9a84a2921be6e33e2ed5e38501fc1960e2afe 100644 --- a/services/distributedfiledaemon/include/mountpoint/mount_point.h +++ b/services/distributedfiledaemon/include/mountpoint/mount_point.h @@ -35,6 +35,11 @@ public: return id_; }; + std::string GetAuthGroupId() const + { + return authGroupId_; + } + std::string ToString() const; Utils::MountArgument GetMountArgument() const; bool operator==(const MountPoint &rop) const; @@ -46,6 +51,7 @@ private: void Umount() const; static std::atomic idGen_; uint32_t id_{0}; + std::string authGroupId_{""}; }; } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfiledaemon/include/network/base_session.h b/services/distributedfiledaemon/include/network/base_session.h index db1f3aea37bb712243a39f3586862f4b53120363..1568d00899142abd9b103fbf5cc0ef105f002263 100644 --- a/services/distributedfiledaemon/include/network/base_session.h +++ b/services/distributedfiledaemon/include/network/base_session.h @@ -17,6 +17,7 @@ #define BASE_SESSION_H #include +#include namespace OHOS { namespace Storage { diff --git a/services/distributedfiledaemon/include/network/kernel_talker.h b/services/distributedfiledaemon/include/network/kernel_talker.h index c33a95ffa29c1a9eb7116e0534cd3c8c44542fa6..89f06f10aa72828e64ba8f05b621c08e6bc77ec1 100644 --- a/services/distributedfiledaemon/include/network/kernel_talker.h +++ b/services/distributedfiledaemon/include/network/kernel_talker.h @@ -36,7 +36,6 @@ constexpr int CID_MAX_LEN = 64; struct NotifyParam { int32_t notify; int32_t fd; - uint64_t remoteIid; uint16_t udpPort; uint8_t deviceType; int32_t flag; @@ -46,17 +45,17 @@ struct NotifyParam { class KernelTalker final : protected NoCopyable { public: - explicit KernelTalker(std::weak_ptr mountPoint, std::function callback) - : mountPoint_(mountPoint), GetSessionCallback_(callback) + explicit KernelTalker(std::weak_ptr mountPoint, + std::function getSessionCallback, + std::function closeSessionCallback) + : mountPoint_(mountPoint), GetSessionCallback_(getSessionCallback), CloseSessionCallback_(closeSessionCallback) { } KernelTalker() = default; ~KernelTalker() = default; void SinkSessionTokernel(std::shared_ptr session); - void SinkInitCmdToKernel(uint64_t iid); void SinkOfflineCmdToKernel(std::string cid); - std::unordered_set GetKernelSesions(); void CreatePollThread(); void WaitForPollThreadExited(); @@ -68,7 +67,7 @@ private: auto spt = mountPoint_.lock(); if (spt == nullptr) { LOGE("mountPoint is not exist! bad weak_ptr"); - return; // ! 抛异常 + return; } std::string ctrlPath = spt->GetMountArgument().GetCtrlPath(); LOGI("cmd path:%{public}s", ctrlPath.c_str()); @@ -95,6 +94,7 @@ private: std::atomic isRunning_{true}; std::unique_ptr pollThread_{nullptr}; std::function GetSessionCallback_{nullptr}; + std::function CloseSessionCallback_{nullptr}; }; } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfiledaemon/include/network/network_agent_template.h b/services/distributedfiledaemon/include/network/network_agent_template.h index 0f9485fae2007c28945b7f4df1854d5c985a1af7..d878472cb1aae8a6742d4db7561f454ebc074aeb 100644 --- a/services/distributedfiledaemon/include/network/network_agent_template.h +++ b/services/distributedfiledaemon/include/network/network_agent_template.h @@ -25,16 +25,22 @@ #include "mountpoint/mount_point.h" #include "network/kernel_talker.h" #include "network/session_pool.h" +#include "utils_actor.h" #include "utils_dfs_thread.h" +#include "utils_startable.h" namespace OHOS { namespace Storage { namespace DistributedFile { -class NetworkAgentTemplate { +class NetworkAgentTemplate : public Startable, public Actor { public: explicit NetworkAgentTemplate(std::weak_ptr mountPoint) - : mountPoint_(mountPoint), - kernerlTalker_(mountPoint, [&](NotifyParam ¶m) { GetSessionProcess(param); }), + : Actor(this), + mountPoint_(mountPoint), + kernerlTalker_( + mountPoint, + [&](NotifyParam ¶m) { GetSessionProcess(param); }, + [&](const std::string &cid) { CloseSessionForOneDevice(cid); }), sessionPool_(kernerlTalker_) { } @@ -42,8 +48,9 @@ public: void Start(); void Stop(); void ConnectOnlineDevices(); - void ConnectDeviceAsync(const DeviceInfo &info); - void DisconnectDevice(const DeviceInfo &info); + void DisconnectAllDevices(); + void ConnectDeviceAsync(const DeviceInfo info); + void DisconnectDevice(const DeviceInfo info); void AcceptSession(std::shared_ptr session); protected: @@ -51,7 +58,7 @@ protected: virtual void QuitDomain() = 0; virtual void StopTopHalf() = 0; virtual void StopBottomHalf() = 0; - virtual std::shared_ptr OpenSession(const DeviceInfo &info) = 0; + virtual void OpenSession(const DeviceInfo &info) = 0; virtual void CloseSession(std::shared_ptr session) = 0; std::weak_ptr mountPoint_; @@ -60,7 +67,10 @@ private: void HandleAllNotify(int fd); void NotifyHandler(NotifyParam ¶m); void GetSessionProcess(NotifyParam ¶m); - void GetSesion(const std::string &cid); + void GetSession(const std::string &cid); + void CloseSessionForOneDevice(const std::string &cid); + void AcceptSessionInner(std::shared_ptr session); + void GetSessionProcessInner(NotifyParam param); std::mutex taskMut_; std::list tasks_; diff --git a/services/distributedfiledaemon/include/network/session_pool.h b/services/distributedfiledaemon/include/network/session_pool.h index 52226b18624000c66512d5cb0971a572dac29859..b8ff96a83a68f0b7f8e4af5d4a539f1e3b4fcc76 100644 --- a/services/distributedfiledaemon/include/network/session_pool.h +++ b/services/distributedfiledaemon/include/network/session_pool.h @@ -32,7 +32,9 @@ public: explicit SessionPool(KernelTalker &talker) : talker_(talker) {} ~SessionPool() = default; void HoldSession(std::shared_ptr session); - void RefreshSessionPoolBasedOnKernel(); + void ReleaseSession(const int32_t fd); + void ReleaseSession(const std::string &cid); + void ReleaseAllSession(); private: std::recursive_mutex sessionPoolLock_; diff --git a/services/distributedfiledaemon/include/network/softbus/softbus_agent.h b/services/distributedfiledaemon/include/network/softbus/softbus_agent.h index c3065aff3e5ab76ea8af9e1b8a3b1eb50145313a..28d88c4b7f4415438e1c523d786b456cf1241f8d 100644 --- a/services/distributedfiledaemon/include/network/softbus/softbus_agent.h +++ b/services/distributedfiledaemon/include/network/softbus/softbus_agent.h @@ -34,10 +34,13 @@ protected: void QuitDomain() override; void StopTopHalf() override; void StopBottomHalf() override; - std::shared_ptr OpenSession(const DeviceInfo &info) override; + void OpenSession(const DeviceInfo &info) override; void CloseSession(std::shared_ptr session) override; private: + bool IsContinueRetry(const std::string &cid); + std::map OpenSessionRetriedTimesMap_; + std::string sessionName_; }; } // namespace DistributedFile diff --git a/services/distributedfiledaemon/include/network/softbus/softbus_session.h b/services/distributedfiledaemon/include/network/softbus/softbus_session.h index 0d6d30eef8d376b718267012fd2cf3593e343783..4816c3eaddac5d9a9cb69f65bd1705547b1867d9 100644 --- a/services/distributedfiledaemon/include/network/softbus/softbus_session.h +++ b/services/distributedfiledaemon/include/network/softbus/softbus_session.h @@ -21,9 +21,10 @@ namespace OHOS { namespace Storage { namespace DistributedFile { +constexpr int32_t INVALID_SOCKET_FD = -1; class SoftbusSession final : public BaseSession { public: - SoftbusSession(int sessionId) : sessionId_(sessionId) {} + explicit SoftbusSession(int sessionId); ~SoftbusSession() = default; bool IsFromServer() const override; std::string GetCid() const override; @@ -34,6 +35,10 @@ public: private: int sessionId_; + std::string cid_; + int32_t socketFd_{INVALID_SOCKET_FD}; + std::array key_; + bool IsServerSide_; }; } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfiledaemon/src/device/device_info.cpp b/services/distributedfiledaemon/src/device/device_info.cpp index 293ece7b72427cd142415b3b3c169a22743b2697..3a0c268ea8beb762c545b9705642570f11513eeb 100644 --- a/services/distributedfiledaemon/src/device/device_info.cpp +++ b/services/distributedfiledaemon/src/device/device_info.cpp @@ -14,6 +14,7 @@ */ #include "device/device_info.h" +#include "utils_exception.h" #include "utils_log.h" namespace OHOS { @@ -24,30 +25,21 @@ using namespace std; DeviceInfo::DeviceInfo(const DistributedHardware::DmDeviceInfo &nodeInfo) { cid_ = string(nodeInfo.deviceId); + initCidFlag_ = true; } DeviceInfo &DeviceInfo::operator=(const DistributedHardware::DmDeviceInfo &nodeInfo) { cid_ = string(nodeInfo.deviceId); + initCidFlag_ = true; return *this; } -DeviceInfo::DeviceInfo(const DeviceInfo &nodeInfo) : iid_(nodeInfo.iid_), cid_(nodeInfo.cid_) +DeviceInfo::DeviceInfo(const DeviceInfo &nodeInfo) : cid_(nodeInfo.cid_) { - initIidFlag_.store(nodeInfo.initIidFlag_.load()); initCidFlag_.store(nodeInfo.initCidFlag_.load()); } -void DeviceInfo::SetIid(const uint64_t iid) -{ - if (initIidFlag_ == false) { - iid_ = iid; - initIidFlag_ = true; - } else { - LOGI("Iid is already initializing"); - } -} - void DeviceInfo::SetCid(const string &cid) { if (initCidFlag_ == false) { @@ -58,20 +50,13 @@ void DeviceInfo::SetCid(const string &cid) } } -uint64_t DeviceInfo::GetIid() const -{ - if (initIidFlag_ == false) { - // TODO 抛异常 - } - return iid_; -} const string &DeviceInfo::GetCid() const { if (initCidFlag_ == false) { - // TODO 抛异常 + ThrowException(ERR_DEVICE_CID_UN_INIT, "cid uninitialized"); } return cid_; } } // namespace DistributedFile -} // namespace Storages +} // namespace Storage } // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/device/device_manager_agent.cpp b/services/distributedfiledaemon/src/device/device_manager_agent.cpp index 84e57a38e21e936bd0f698482c5b9ab6b87dd511..d5129fae105ac4d6ad2302e1b52ad261e0586dba 100644 --- a/services/distributedfiledaemon/src/device/device_manager_agent.cpp +++ b/services/distributedfiledaemon/src/device/device_manager_agent.cpp @@ -14,30 +14,50 @@ */ #include "device/device_manager_agent.h" -#include "network/softbus/softbus_agent.h" +#include #include #include +#include "device_auth.h" #include "ipc/i_daemon.h" +#include "mountpoint/mount_manager.h" +#include "network/softbus/softbus_agent.h" #include "softbus_bus_center.h" +#include "utils_exception.h" #include "utils_log.h" namespace OHOS { namespace Storage { namespace DistributedFile { +namespace { +constexpr int MAX_RETRY_COUNT = 7; +constexpr int IDENTICAL_ACCOUNT_GROUP = 1; +constexpr int PEER_TO_PEER_GROUP = 256; +constexpr int ACROSS_ACCOUNT_AUTHORIZE_GROUP = 1282; +} // namespace using namespace std; -DeviceManagerAgent::DeviceManagerAgent() {} +DeviceManagerAgent::DeviceManagerAgent() : Actor(this, std::numeric_limits::max()) {} DeviceManagerAgent::~DeviceManagerAgent() { StopInstance(); } +void DeviceManagerAgent::StartInstance() +{ + StartActor(); +} + +void DeviceManagerAgent::StopInstance() +{ + StopActor(); +} + void DeviceManagerAgent::Start() { - RegisterToExternalDm(); // TODO Catch? + RegisterToExternalDm(); InitLocalNodeInfo(); } @@ -51,20 +71,23 @@ void DeviceManagerAgent::JoinGroup(weak_ptr mp) auto smp = mp.lock(); if (!smp) { stringstream ss("Failed to join group: Received empty mountpoint"); - LOGE("%s", ss.str().c_str()); + LOGE("%{public}s", ss.str().c_str()); throw runtime_error(ss.str()); } - unique_lock lock(mpToNetworksMutex_); - auto agent = make_shared(mp); - auto [ignored, inserted] = mpToNetworks_.insert({smp->GetID(), agent}); - if (!inserted) { - stringstream ss; - ss << "Failed to join group: Mountpoint existed" << smp->ToString(); - throw runtime_error(ss.str()); + shared_ptr agent = nullptr; + { + unique_lock lock(mpToNetworksMutex_); + agent = make_shared(mp); + auto [ignored, inserted] = mpToNetworks_.insert({smp->GetID(), agent}); + if (!inserted) { + stringstream ss; + ss << "Failed to join group: Mountpoint existed" << smp->ToString(); + throw runtime_error(ss.str()); + } } - - agent->Start(); + LOGI("smp id %{public}d, groupId %{public}s", smp->GetID(), smp->GetAuthGroupId().c_str()); + agent->StartActor(); } void DeviceManagerAgent::QuitGroup(weak_ptr mp) @@ -72,7 +95,7 @@ void DeviceManagerAgent::QuitGroup(weak_ptr mp) auto smp = mp.lock(); if (!smp) { stringstream ss("Failed to quit group: Received empty mountpoint"); - LOGE("%s", ss.str().c_str()); + LOGE("%{public}s", ss.str().c_str()); throw runtime_error(ss.str()); } @@ -84,35 +107,166 @@ void DeviceManagerAgent::QuitGroup(weak_ptr mp) throw runtime_error(ss.str()); } - it->second->Stop(); + it->second->StopActor(); mpToNetworks_.erase(smp->GetID()); } +void DeviceManagerAgent::OfflineAllDevice() +{ + unique_lock lock(mpToNetworksMutex_); + for (auto &&networkAgent : mpToNetworks_) { + auto cmd = make_unique>(&NetworkAgentTemplate::DisconnectAllDevices); + cmd->UpdateOption({ + .tryTimes_ = 1, + }); + networkAgent.second->Recv(move(cmd)); + } +} + +void DeviceManagerAgent::ReconnectOnlineDevices() +{ + unique_lock lock(mpToNetworksMutex_); + for (auto &&networkAgent : mpToNetworks_) { + auto cmd = make_unique>(&NetworkAgentTemplate::ConnectOnlineDevices); + cmd->UpdateOption({ + .tryTimes_ = MAX_RETRY_COUNT, + }); + networkAgent.second->Recv(move(cmd)); + } +} + void DeviceManagerAgent::OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("OnDeviceOnline begin"); - auto dm = DeviceManagerAgent::GetInstance(); - unique_lock lock(dm->mpToNetworksMutex_); - for (auto &&networkAgent : dm->mpToNetworks_) { - DeviceInfo info(deviceInfo); - networkAgent.second->ConnectDeviceAsync(info); + DeviceInfo info(deviceInfo); + { + unique_lock lock(mpToNetworksMutex_); + for (auto &&networkAgent : mpToNetworks_) { + auto cmd = make_unique>( + &NetworkAgentTemplate::ConnectDeviceAsync, info); + cmd->UpdateOption({ + .tryTimes_ = MAX_RETRY_COUNT, + }); + networkAgent.second->Recv(move(cmd)); + } } + AuthGroupOnlineProc(info); + LOGI("OnDeviceOnline end"); } void DeviceManagerAgent::OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("OnDeviceOffline begin"); - auto dm = DeviceManagerAgent::GetInstance(); - - unique_lock lock(dm->mpToNetworksMutex_); - for (auto &&networkAgent : dm->mpToNetworks_) { - DeviceInfo info(deviceInfo); - networkAgent.second->DisconnectDevice(info); + DeviceInfo info(deviceInfo); + { + unique_lock lock(mpToNetworksMutex_); + for (auto &&networkAgent : mpToNetworks_) { + auto cmd = + make_unique>(&NetworkAgentTemplate::DisconnectDevice, info); + cmd->UpdateOption({ + .tryTimes_ = 1, + }); + networkAgent.second->Recv(move(cmd)); + } } + AuthGroupOfflineProc(info); LOGI("OnDeviceOffline end"); } +void from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo) +{ + if (jsonObject.find(FIELD_GROUP_NAME) != jsonObject.end()) { + groupInfo.groupName = jsonObject.at(FIELD_GROUP_NAME).get(); + } + + if (jsonObject.find(FIELD_GROUP_ID) != jsonObject.end()) { + groupInfo.groupId = jsonObject.at(FIELD_GROUP_ID).get(); + } + + if (jsonObject.find(FIELD_GROUP_OWNER) != jsonObject.end()) { + groupInfo.groupOwner = jsonObject.at(FIELD_GROUP_OWNER).get(); + } + + if (jsonObject.find(FIELD_GROUP_TYPE) != jsonObject.end()) { + groupInfo.groupType = jsonObject.at(FIELD_GROUP_TYPE).get(); + } +} + +void DeviceManagerAgent::QueryRelatedGroups(const std::string &networkId, std::vector &groupList) +{ + // piling test + GroupInfo g1("auth_group_test1", "groupId_12345", "wps_package", PEER_TO_PEER_GROUP); + groupList.emplace_back(g1); + GroupInfo g2("auth_group_test2", "groupId_987654", "qqMail_package", IDENTICAL_ACCOUNT_GROUP); + groupList.emplace_back(g2); +} + +void DeviceManagerAgent::AuthGroupOnlineProc(const DeviceInfo info) +{ + std::vector groupList; + QueryRelatedGroups(info.GetCid(), groupList); + for (const auto &group : groupList) { + if (!CheckIsAuthGroup(group)) { + continue; + } + if (authGroupMap_.find(group.groupId) == authGroupMap_.end()) { + LOGI("groupId %{public}s not exist, then mount", group.groupId.c_str()); + MountManager::GetInstance()->Mount(make_unique( + Utils::MountArgumentDescriptors::SetAuthGroupMountArgument(group.groupId, group.groupOwner, true))); + } + auto [iter, status] = authGroupMap_[group.groupId].insert(info.GetCid()); + if (status == false) { + LOGI("cid %{public}s has already inserted into groupId %{public}s", info.GetCid().c_str(), + group.groupId.c_str()); + continue; + } + } +} + +void DeviceManagerAgent::AuthGroupOfflineProc(const DeviceInfo &info) +{ + for (auto iter = authGroupMap_.begin(); iter != authGroupMap_.end();) { + auto set = iter->second; + auto groupId = iter->first; + if (set.find(info.GetCid()) == set.end()) { + continue; + } + + if (authGroupMap_.find(groupId) == authGroupMap_.end()) { + LOGI("can not find groupId %{public}s ", groupId.c_str()); + continue; + } + authGroupMap_[groupId].erase(info.GetCid()); + if (authGroupMap_[groupId].empty()) { + std::vector groupList; + if (groupList.size() == 0) { + MountManager::GetInstance()->Umount(groupId); + iter = authGroupMap_.erase(iter); + continue; + } + } + iter++; + } +} + +void DeviceManagerAgent::AllAuthGroupsOfflineProc() +{ + for (auto iter = authGroupMap_.begin(); iter != authGroupMap_.end();) { + auto groupId = iter->first; + MountManager::GetInstance()->Umount(groupId); + authGroupMap_.erase(iter++); + } +} + +bool DeviceManagerAgent::CheckIsAuthGroup(const GroupInfo &group) +{ + if (group.groupType == PEER_TO_PEER_GROUP || group.groupType == ACROSS_ACCOUNT_AUTHORIZE_GROUP) { + return true; + } + return false; +} + void DeviceManagerAgent::OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("OnDeviceInfoChanged"); @@ -123,24 +277,19 @@ void DeviceManagerAgent::InitLocalNodeInfo() NodeBasicInfo tmpNodeInfo; int errCode = GetLocalNodeDeviceInfo(IDaemon::SERVICE_NAME.c_str(), &tmpNodeInfo); if (errCode != 0) { - stringstream ss; - ss << "Failed to get local cid: error code reads " << errCode; - LOGW("%s", ss.str().c_str()); - throw runtime_error(ss.str()); + ThrowException(errCode, "Failed to get info of local devices"); } localDeviceInfo_.SetCid(string(tmpNodeInfo.networkId)); - InitLocalIid(); } void DeviceManagerAgent::OnRemoteDied() { LOGI("device manager service died"); - RegisterToExternalDm(); // ! TODO -} - -void DeviceManagerAgent::InitLocalIid() -{ - localDeviceInfo_.SetIid(0x12345678); // TODO 随机产生 + StopInstance(); + OfflineAllDevice(); // cannot commit a cmd to queue + AllAuthGroupsOfflineProc(); + StartInstance(); + ReconnectOnlineDevices(); } DeviceInfo &DeviceManagerAgent::GetLocalDeviceInfo() @@ -157,10 +306,7 @@ vector DeviceManagerAgent::GetRemoteDevicesInfo() auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); int errCode = deviceManager.GetTrustedDeviceList(pkgName, extra, deviceList); if (errCode) { - stringstream ss; - ss << "Failed to get info of remote devices: the error code reads " << errCode; - LOGE("%s", ss.str().c_str()); - throw runtime_error(ss.str()); + ThrowException(errCode, "Failed to get info of remote devices"); } vector res; @@ -176,19 +322,14 @@ void DeviceManagerAgent::RegisterToExternalDm() string pkgName = IDaemon::SERVICE_NAME; int errCode = deviceManager.InitDeviceManager(pkgName, shared_from_this()); if (errCode != 0) { - stringstream ss; - ss << "Failed to InitDeviceManager: the error code reads " << errCode; - LOGE("%s", ss.str().c_str()); - throw runtime_error(ss.str()); + ThrowException(errCode, "Failed to InitDeviceManager"); } string extra = ""; errCode = deviceManager.RegisterDevStateCallback(pkgName, extra, shared_from_this()); if (errCode != 0) { - stringstream ss; - ss << "Failed to RegisterDevStateCallback: the error code reads " << errCode; - LOGE("%s", ss.str().c_str()); - throw runtime_error(ss.str()); + ThrowException(errCode, "Failed to RegisterDevStateCallback"); } + LOGI("RegisterToExternalDm Succeed"); } void DeviceManagerAgent::UnregisterFromExternalDm() @@ -197,18 +338,13 @@ void DeviceManagerAgent::UnregisterFromExternalDm() string pkgName = IDaemon::SERVICE_NAME; int errCode = deviceManager.UnRegisterDevStateCallback(pkgName); if (errCode != 0) { - stringstream ss; - ss << "Failed to UnRegisterDevStateCallback: the error code reads " << errCode; - LOGE("%s", ss.str().c_str()); - throw runtime_error(ss.str()); + ThrowException(errCode, "Failed to UnRegisterDevStateCallback"); } errCode = deviceManager.UnInitDeviceManager(pkgName); if (errCode != 0) { - stringstream ss; - ss << "Failed to UnInitDeviceManager: the error code reads " << errCode; - LOGE("%s", ss.str().c_str()); - throw runtime_error(ss.str()); + ThrowException(errCode, "Failed to UnInitDeviceManager"); } + LOGI("UnregisterFromExternalDm Succeed"); } } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfiledaemon/src/mountpoint/mount_manager.cpp b/services/distributedfiledaemon/src/mountpoint/mount_manager.cpp index b0197e0688489e82933074fc268ba00c17174419..8e9792f5d6b2613596af9f5bcc0385b7e414ba2a 100644 --- a/services/distributedfiledaemon/src/mountpoint/mount_manager.cpp +++ b/services/distributedfiledaemon/src/mountpoint/mount_manager.cpp @@ -55,9 +55,14 @@ void MountManager::Mount(unique_ptr mp) LOGE("%{public}s", ss.str().c_str()); throw runtime_error(ss.str()); } - + try { + smp->Umount(); // try umount one time + } catch (const exception &e) { + LOGE("%{public}s", e.what()); + } smp->Mount(); - DeviceManagerAgent::GetInstance()->JoinGroup(smp); + auto dm = DeviceManagerAgent::GetInstance(); + dm->Recv(make_unique>>(&DeviceManagerAgent::JoinGroup, smp)); mountPoints_.push_back(smp); } @@ -74,10 +79,31 @@ void MountManager::Umount(weak_ptr wmp) LOGE("%{public}s", ss.str().c_str()); throw runtime_error(ss.str()); } - + LOGI("Umount begin"); smp->Umount(); - DeviceManagerAgent::GetInstance()->QuitGroup(smp); + auto dm = DeviceManagerAgent::GetInstance(); + dm->Recv(make_unique>>(&DeviceManagerAgent::QuitGroup, smp)); mountPoints_.erase(it); + LOGI("Umount end"); +} + +void MountManager::Umount(const std::string &groupId) +{ + if (groupId == "") { + LOGE("groupId is null, no auth group to unmount"); + return; + } + + decltype(mountPoints_.begin()) iter = + find_if(mountPoints_.begin(), mountPoints_.end(), + [groupId](const auto &cur_mp) { return cur_mp->authGroupId_ == groupId; }); + if (iter == mountPoints_.end()) { + stringstream ss; + ss << "Umount not find this auth group id" << groupId; + LOGE("Umount not find this auth group id %{public}s", groupId.c_str()); + throw runtime_error(ss.str()); + } + Umount(*iter); } } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfiledaemon/src/mountpoint/mount_point.cpp b/services/distributedfiledaemon/src/mountpoint/mount_point.cpp index b77e02ad56b2df77f8027b697e53818b6f0df53a..91755a469231294ce0d137ab8c91659783d63f29 100644 --- a/services/distributedfiledaemon/src/mountpoint/mount_point.cpp +++ b/services/distributedfiledaemon/src/mountpoint/mount_point.cpp @@ -31,6 +31,9 @@ atomic MountPoint::idGen_; MountPoint::MountPoint(const Utils::MountArgument &mountArg) : mountArg_(mountArg) { id_ = idGen_++; + if (mountArg.accountless_) { + authGroupId_ = mountArg.groupId_; + } } void MountPoint::Mount() const @@ -54,6 +57,12 @@ void MountPoint::Mount() const LOGE("Failed to mount: %{public}d %{public}s", cond.value(), cond.message().c_str()); throw system_error(errno, system_category()); } + LOGI("mount sucess: src %{public}s --> dst %{public}s", src.c_str(), dst.c_str()); + + if (mntArg.accountless_) { + Utils::ForceCreateDirectory(dst + "/device_view/local/data/" + mntArg.packageName_, + S_IRWXU | S_IRWXG | S_IXOTH); + } } void MountPoint::Umount() const diff --git a/services/distributedfiledaemon/src/network/kernel_talker.cpp b/services/distributedfiledaemon/src/network/kernel_talker.cpp index acb5e42f1a0436b2032564297d8473c9b7237b63..9666c01b3d29c24c03777a66266e8722ac38fdd0 100644 --- a/services/distributedfiledaemon/src/network/kernel_talker.cpp +++ b/services/distributedfiledaemon/src/network/kernel_talker.cpp @@ -24,22 +24,14 @@ namespace DistributedFile { using namespace std; constexpr int KEY_MAX_LEN = 32; -constexpr int HMDFS_ACCOUNT_HASH_MAX_LEN = 21; constexpr int POLL_TIMEOUT_MS = 200; constexpr int NONE_EVENT = -1; constexpr int READ_EVENT = 1; constexpr int TIME_OUT_EVENT = 0; -struct InitParam { - int32_t cmd; - uint64_t localIid; - uint8_t currentAccout[HMDFS_ACCOUNT_HASH_MAX_LEN]; -} __attribute__((packed)); - struct UpdateSocketParam { int32_t cmd; int32_t newfd; - uint64_t localIid; uint8_t status; uint8_t protocol; uint16_t udpPort; @@ -56,15 +48,11 @@ struct OfflineParam { } __attribute__((packed)); enum { - CMD_INIT = 0, - CMD_UPDATE_SOCKET, + CMD_UPDATE_SOCKET = 0, CMD_OFF_LINE, - CMD_SET_ACCOUNT, CMD_OFF_LINE_ALL, - CMD_UPDATE_CAPABILITY, - CMD_GET_P2P_SESSION_FAIL, CMD_DELETE_CONNECTION, - CMD_CNT + CMD_CNT, }; enum { @@ -80,12 +68,8 @@ enum { enum Notify { NOTIFY_HS_DONE = 0, NOTIFY_OFFLINE, - NOTIFY_OFFLINE_IID, NOTIFY_GET_SESSION, - NOTIFY_GOT_UDP_PORT, NOTIFY_NONE, - NOTIFY_DISCONNECT, - NOTIFY_D2DP_FAILED, NOTIFY_CNT, }; @@ -102,32 +86,21 @@ void KernelTalker::SinkSessionTokernel(shared_ptr session) UpdateSocketParam cmd = { .cmd = CMD_UPDATE_SOCKET, .newfd = socketFd, - .localIid = DeviceManagerAgent::GetInstance()->GetLocalDeviceInfo().GetIid(), .status = status, .protocol = TCP_TRANSPORT_PROTO, .linkType = 0, .binderFd = -1, }; if (memcpy_s(cmd.masterKey, KEY_MAX_LEN, masterkey.data(), KEY_MAX_LEN) != EOK) { - return; // !抛异常 + return; } if (memcpy_s(cmd.cid, CID_MAX_LEN, cid.c_str(), CID_MAX_LEN)) { - return; // !抛异常 + return; } SetCmd(cmd); } -void KernelTalker::SinkInitCmdToKernel(uint64_t iid) -{ - InitParam cmd = { - .cmd = CMD_INIT, - .localIid = iid, - }; - - SetCmd(cmd); -} - void KernelTalker::SinkOfflineCmdToKernel(string cid) { OfflineParam cmd = { @@ -135,20 +108,16 @@ void KernelTalker::SinkOfflineCmdToKernel(string cid) }; if (cid.length() < CID_MAX_LEN) { - return; // ! 抛异常 + LOGE("cid lengh err, cid:%{public}s, length:%{public}d", cid.c_str(), cid.length()); + return; } if (memcpy_s(cmd.remoteCid, CID_MAX_LEN, cid.c_str(), CID_MAX_LEN) != EOK) { - return; // ! 抛异常 + return; } SetCmd(cmd); } -unordered_set KernelTalker::GetKernelSesions() -{ - return {}; -} - void KernelTalker::CreatePollThread() { isRunning_ = true; @@ -185,13 +154,13 @@ void KernelTalker::PollRun() auto spt = mountPoint_.lock(); if (spt == nullptr) { LOGE("mountPoint is not exist! bad weak_ptr"); - return; // ! 抛异常 + return; } string ctrlPath = spt->GetMountArgument().GetCtrlPath(); cmdFd = open(ctrlPath.c_str(), O_RDWR); if (cmdFd < 0) { LOGE("Open node file error %{public}d", errno); - return; // ! 待审视,此处不能抛异常,用户态还没有通知到内核时,这个文件可能就不存在 + return; } LOGI("Open node file success"); @@ -243,9 +212,8 @@ void KernelTalker::NotifyHandler(NotifyParam ¶m) LOGI("NOTIFY_HS_DONE, remote cid %{public}s", cidStr.c_str()); break; case NOTIFY_OFFLINE: - case NOTIFY_OFFLINE_IID: - LOGI("%{public}s, remote cid %{public}s", (cmd == NOTIFY_OFFLINE) ? "NOTIFY_OFFLINE" : "NOTIFY_OFFLINE_IID", - cidStr.c_str()); + LOGI("NOTIFY_OFFLINE, remote cid %{public}s", cidStr.c_str()); + CloseSessionCallback_(cidStr); break; case NOTIFY_GET_SESSION: GetSessionCallback_(param); diff --git a/services/distributedfiledaemon/src/network/network_agent_template.cpp b/services/distributedfiledaemon/src/network/network_agent_template.cpp index 3a2ed16b40806d150d7344aac90f3262f291f185..507b28782ee646b3074866cb73ac36713aee0e41 100644 --- a/services/distributedfiledaemon/src/network/network_agent_template.cpp +++ b/services/distributedfiledaemon/src/network/network_agent_template.cpp @@ -15,6 +15,7 @@ #include "network/network_agent_template.h" #include "device/device_manager_agent.h" +#include "utils_exception.h" #include "utils_log.h" namespace OHOS { @@ -23,14 +24,14 @@ namespace DistributedFile { using namespace std; namespace { constexpr int MAX_RETRY_COUNT = 7; -constexpr int SLEEP_TIME = 1500; -} +constexpr int OPEN_SESSSION_DELAY_TIME = 100; +} // namespace void NetworkAgentTemplate::Start() { - JoinDomain(); // TODO 考虑下软总线是否有可能还没有起来 - ConnectOnlineDevices(); + JoinDomain(); kernerlTalker_.CreatePollThread(); + ConnectOnlineDevices(); } void NetworkAgentTemplate::Stop() @@ -40,71 +41,92 @@ void NetworkAgentTemplate::Stop() kernerlTalker_.WaitForPollThreadExited(); } -void NetworkAgentTemplate::ConnectDeviceAsync(const DeviceInfo &info) +void NetworkAgentTemplate::ConnectDeviceAsync(const DeviceInfo info) { - kernerlTalker_.SinkInitCmdToKernel(info.GetIid()); - - unique_lock taskLock(taskMut_); - tasks_.emplace_back(); - tasks_.back().RunLoopFlexible( - [info{DeviceInfo(info)}, this](uint64_t &sleepTime) { // ! 不能使用this,待解决 - auto session = OpenSession(info); - if (session == nullptr) { - LOGE("open session fail, retry, cid:%{public}s", info.GetCid().c_str()); - return false; - } - LOGI("open session success, cid:%{public}s", info.GetCid().c_str()); - return true; - }, - SLEEP_TIME, MAX_RETRY_COUNT); + std::this_thread::sleep_for(std::chrono::milliseconds( + OPEN_SESSSION_DELAY_TIME)); // Temporary workaround for time sequence issues(offline-onSessionOpened) + OpenSession(info); } void NetworkAgentTemplate::ConnectOnlineDevices() { - auto infos = DeviceManagerAgent::GetInstance()->GetRemoteDevicesInfo(); + auto dma = DeviceManagerAgent::GetInstance(); + auto infos = dma->GetRemoteDevicesInfo(); LOGI("Have %{public}d devices Online", infos.size()); for (const auto &info : infos) { - ConnectDeviceAsync(info); + auto cmd = + make_unique>(&NetworkAgentTemplate::ConnectDeviceAsync, info); + cmd->UpdateOption({ + .tryTimes_ = MAX_RETRY_COUNT, + }); + Recv(move(cmd)); + + dma->Recv( + make_unique>(&DeviceManagerAgent::AuthGroupOnlineProc, info)); } } -void NetworkAgentTemplate::DisconnectDevice(const DeviceInfo &info) +void NetworkAgentTemplate::DisconnectAllDevices() +{ + sessionPool_.ReleaseAllSession(); +} + +void NetworkAgentTemplate::DisconnectDevice(const DeviceInfo info) { LOGI("DeviceOffline, cid:%{public}s", info.GetCid().c_str()); - kernerlTalker_.SinkOfflineCmdToKernel(info.GetCid()); - sessionPool_.RefreshSessionPoolBasedOnKernel(); + sessionPool_.ReleaseSession(info.GetCid()); +} + +void NetworkAgentTemplate::CloseSessionForOneDevice(const string &cid) +{ + LOGI("session closed!"); } void NetworkAgentTemplate::AcceptSession(shared_ptr session) { - unique_lock taskLock(taskMut_); - tasks_.emplace_back(); - tasks_.back().Run([=] { - auto cid = session->GetCid(); - LOGI("AcceptSession thread run, cid:%{public}s", cid.c_str()); - sessionPool_.HoldSession(session); - return true; + auto cmd = make_unique>>( + &NetworkAgentTemplate::AcceptSessionInner, session); + cmd->UpdateOption({ + .tryTimes_ = 1, }); + Recv(move(cmd)); +} + +void NetworkAgentTemplate::AcceptSessionInner(shared_ptr session) +{ + auto cid = session->GetCid(); + LOGI("AcceptSesion, cid:%{public}s", cid.c_str()); + sessionPool_.HoldSession(session); } void NetworkAgentTemplate::GetSessionProcess(NotifyParam ¶m) +{ + auto cmd = + make_unique>(&NetworkAgentTemplate::GetSessionProcessInner, param); + cmd->UpdateOption({ + .tryTimes_ = 1, + }); + Recv(move(cmd)); +} + +void NetworkAgentTemplate::GetSessionProcessInner(NotifyParam param) { string cidStr(param.remoteCid, CID_MAX_LEN); - LOGI("NOTIFY_GET_SESSION, old fd %{public}d, remote cid %{public}s", param.fd, cidStr.c_str()); - sessionPool_.RefreshSessionPoolBasedOnKernel(); - GetSesion(cidStr); + int fd = param.fd; + LOGI("NOTIFY_GET_SESSION, old fd %{public}d, remote cid %{public}s", fd, cidStr.c_str()); + sessionPool_.ReleaseSession(fd); + GetSession(cidStr); } -void NetworkAgentTemplate::GetSesion(const string &cid) +void NetworkAgentTemplate::GetSession(const string &cid) { DeviceInfo deviceInfo; deviceInfo.SetCid(cid); - auto session = OpenSession(deviceInfo); - if (session == nullptr) { - LOGE("open session fail, retry, cid:%{public}s", cid.c_str()); - return; + try { + OpenSession(deviceInfo); + } catch (const Exception &e) { + LOGE("reget session failed, code: %{public}d", e.code()); } - LOGI("open session success, cid:%{public}s", cid.c_str()); } } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfiledaemon/src/network/session_pool.cpp b/services/distributedfiledaemon/src/network/session_pool.cpp index 6824636dd1541002c033516b1940f323647398ed..5add432afe50053ef551cfe3167facbe3bce25b9 100644 --- a/services/distributedfiledaemon/src/network/session_pool.cpp +++ b/services/distributedfiledaemon/src/network/session_pool.cpp @@ -25,23 +25,45 @@ void SessionPool::HoldSession(shared_ptr session) lock_guard lock(sessionPoolLock_); talker_.SinkSessionTokernel(session); AddSessionToPool(session); - RefreshSessionPoolBasedOnKernel(); } -void SessionPool::RefreshSessionPoolBasedOnKernel() +void SessionPool::ReleaseSession(const int32_t fd) { lock_guard lock(sessionPoolLock_); - auto kernelSessions = talker_.GetKernelSesions(); for (auto iter = usrSpaceSessionPool_.begin(); iter != usrSpaceSessionPool_.end();) { - if (kernelSessions.count((*iter)->GetHandle() == 0)) { - // (*iter)->Release(); - // iter = usrSpaceSessionPool_.erase(iter); // ! 待GetKernelSessions实现后放开 + if ((*iter)->GetHandle() == fd) { + (*iter)->Release(); + iter = usrSpaceSessionPool_.erase(iter); } else { ++iter; } } } +void SessionPool::ReleaseSession(const string &cid) +{ + talker_.SinkOfflineCmdToKernel(cid); + lock_guard lock(sessionPoolLock_); + for (auto iter = usrSpaceSessionPool_.begin(); iter != usrSpaceSessionPool_.end();) { + if ((*iter)->GetCid() == cid) { + (*iter)->Release(); + iter = usrSpaceSessionPool_.erase(iter); + } else { + ++iter; + } + } +} + +void SessionPool::ReleaseAllSession() +{ + lock_guard lock(sessionPoolLock_); + for (auto iter = usrSpaceSessionPool_.begin(); iter != usrSpaceSessionPool_.end();) { + talker_.SinkOfflineCmdToKernel((*iter)->GetCid()); + /* device offline, session release by softbus*/ + iter = usrSpaceSessionPool_.erase(iter); + } +} + void SessionPool::AddSessionToPool(shared_ptr session) { usrSpaceSessionPool_.push_back(session); diff --git a/services/distributedfiledaemon/src/network/softbus/softbus_agent.cpp b/services/distributedfiledaemon/src/network/softbus/softbus_agent.cpp index 59d988ac44be1f036b71c09045492b3c6b778354..ccb14e7c3962aa6fd42db47165e02311959d11bb 100644 --- a/services/distributedfiledaemon/src/network/softbus/softbus_agent.cpp +++ b/services/distributedfiledaemon/src/network/softbus/softbus_agent.cpp @@ -21,13 +21,16 @@ #include "network/softbus/softbus_session_dispatcher.h" #include "network/softbus/softbus_session_name.h" #include "session.h" +#include "utils_exception.h" #include "utils_log.h" namespace OHOS { namespace Storage { namespace DistributedFile { +namespace { +constexpr int MAX_RETRY_COUNT = 7; +} using namespace std; - SoftbusAgent::SoftbusAgent(weak_ptr mountPoint) : NetworkAgentTemplate(mountPoint) { auto spt = mountPoint.lock(); @@ -81,11 +84,10 @@ void SoftbusAgent::StopTopHalf() QuitDomain(); } void SoftbusAgent::StopBottomHalf() {} -shared_ptr SoftbusAgent::OpenSession(const DeviceInfo &info) +void SoftbusAgent::OpenSession(const DeviceInfo &info) { SessionAttribute attr; attr.dataType = TYPE_BYTES; - attr.unique = true; LOGD("Start to Open Session, cid:%{public}s", info.GetCid().c_str()); @@ -93,9 +95,10 @@ shared_ptr SoftbusAgent::OpenSession(const DeviceInfo &info) ::OpenSession(sessionName_.c_str(), sessionName_.c_str(), info.GetCid().c_str(), "hmdfs_wifiGroup", &attr); if (sessionId < 0) { LOGE("Failed to open session, cid:%{public}s, sessionId:%{public}d", info.GetCid().c_str(), sessionId); - return nullptr; + ThrowException(ERR_SOFTBUS_AGENT_ON_SESSION_OPENED_FAIL, "Open Session failed"); } - return make_shared(sessionId); + LOGD("Open Session SUCCESS, cid:%{public}s", info.GetCid().c_str()); + return; } void SoftbusAgent::CloseSession(shared_ptr session) @@ -107,17 +110,50 @@ void SoftbusAgent::CloseSession(shared_ptr session) session->Release(); } +bool SoftbusAgent::IsContinueRetry(const string &cid) +{ + auto retriedTimesMap = OpenSessionRetriedTimesMap_.find(cid); + if (retriedTimesMap != OpenSessionRetriedTimesMap_.end()) { + if (retriedTimesMap->second >= MAX_RETRY_COUNT) { + return false; + } + } else { + OpenSessionRetriedTimesMap_.insert({cid, 0}); + } + OpenSessionRetriedTimesMap_[cid]++; + return true; +} + int SoftbusAgent::OnSessionOpened(const int sessionId, const int result) { auto session = make_shared(sessionId); auto cid = session->GetCid(); - if (!session->IsFromServer()) { - if (result != 0) { - // !是否加OpenSession重试? - LOGE("open session failed, result:%{public}d", result); - return 0; + + DeviceInfo info; + info.SetCid(cid); + if (result != 0) { + LOGE("OnSessionOpened failed, Is %{public}s Side, result:%{public}d", + (session->IsFromServer() == true) ? "Server" : "Client", result); + if (!session->IsFromServer()) { // client retry + if (IsContinueRetry(cid)) { + auto cmd = make_unique>( + &NetworkAgentTemplate::ConnectDeviceAsync, info); + cmd->UpdateOption({ + .tryTimes_ = 1, + }); + Recv(move(cmd)); + } else { + LOGE("Exceeded the maximum number of retries, not retry"); + } } + return result; } + + auto retriedTimesMap = OpenSessionRetriedTimesMap_.find(cid); + if (retriedTimesMap != OpenSessionRetriedTimesMap_.end()) { + OpenSessionRetriedTimesMap_.erase(cid); + } + int socket_fd = session->GetHandle(); LOGI( "accept sesion, sessionid:%{public}d, Is %{public}s Side, fd %{public}d, from cid %{public}s, result " diff --git a/services/distributedfiledaemon/src/network/softbus/softbus_session.cpp b/services/distributedfiledaemon/src/network/softbus/softbus_session.cpp index 92264a0a7a7f283a5650a9a5ce9958d68c0f7601..6e4011b98ff8546f0efa0ec06c803b63bbe85afc 100644 --- a/services/distributedfiledaemon/src/network/softbus/softbus_session.cpp +++ b/services/distributedfiledaemon/src/network/softbus/softbus_session.cpp @@ -25,50 +25,65 @@ namespace DistributedFile { using namespace std; constexpr int32_t SOFTBUS_OK = 0; -constexpr int32_t INVALID_SOCKET_FD = -1; constexpr int32_t DEVICE_ID_SIZE_MAX = 65; +constexpr int32_t IS_SERVER = 0; -bool SoftbusSession::IsFromServer() const -{ - return (::GetSessionSide(sessionId_) == IS_SERVER) ? true : false; -} - -string SoftbusSession::GetCid() const +SoftbusSession::SoftbusSession(int sessionId) : sessionId_(sessionId) { char perDevId[DEVICE_ID_SIZE_MAX] = ""; int ret = ::GetPeerDeviceId(sessionId_, perDevId, sizeof(perDevId)); if (ret != SOFTBUS_OK) { LOGE("get my peer device id failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId_); - return {}; // ! 抛异常 + cid_ = ""; + } else { + cid_ = string(perDevId); } - return string(perDevId); -} -int32_t SoftbusSession::GetHandle() const -{ int32_t socket_fd; - int32_t ret = ::GetSessionHandle(sessionId_, &socket_fd); + ret = ::GetSessionHandle(sessionId_, &socket_fd); if (ret != SOFTBUS_OK) { LOGE("get session socket fd failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId_); - return INVALID_SOCKET_FD; + socketFd_ = INVALID_SOCKET_FD; + } else { + socketFd_ = socket_fd; } - return socket_fd; -} -array SoftbusSession::GetKey() const -{ array key; - int32_t ret = ::GetSessionKey(sessionId_, key.data(), key.size()); + ret = ::GetSessionKey(sessionId_, key.data(), key.size()); if (ret != SOFTBUS_OK) { LOGE("get session key failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId_); - return {}; // ! 抛异常 + key_ = {}; + } else { + key_ = key; } - return key; + + IsServerSide_ = (::GetSessionSide(sessionId_) == IS_SERVER) ? true : false; +} + +bool SoftbusSession::IsFromServer() const +{ + return IsServerSide_; +} + +string SoftbusSession::GetCid() const +{ + return cid_; +} + +int32_t SoftbusSession::GetHandle() const +{ + return socketFd_; +} + +array SoftbusSession::GetKey() const +{ + return key_; } void SoftbusSession::Release() const { ::CloseSession(sessionId_); + LOGI("session closed, sessionId:%{public}d", sessionId_); } void SoftbusSession::DisableSessionListener() const @@ -76,7 +91,7 @@ void SoftbusSession::DisableSessionListener() const int32_t ret = ::DisableSessionListener(sessionId_); if (ret != SOFTBUS_OK) { LOGE("disableSessionlistener failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId_); - return; // !抛异常 + return; } } } // namespace DistributedFile diff --git a/services/distributedfiledaemon/src/network/softbus/softbus_session_dispatcher.cpp b/services/distributedfiledaemon/src/network/softbus/softbus_session_dispatcher.cpp index d1c1faf42ab8135b1bb76ce309994b4f580cc5e4..e37a8ef4254dcdd74045844847d7d5b6ab86237b 100644 --- a/services/distributedfiledaemon/src/network/softbus/softbus_session_dispatcher.cpp +++ b/services/distributedfiledaemon/src/network/softbus/softbus_session_dispatcher.cpp @@ -31,8 +31,7 @@ constexpr int32_t SESSION_NAME_SIZE_MAX = 256; mutex SoftbusSessionDispatcher::softbusAgentMutex_; map> SoftbusSessionDispatcher::busNameToAgent_; -void SoftbusSessionDispatcher::RegisterSessionListener(const string busName, - weak_ptr softbusAgent) +void SoftbusSessionDispatcher::RegisterSessionListener(const string busName, weak_ptr softbusAgent) { if (busName == "") { stringstream ss; @@ -70,9 +69,9 @@ weak_ptr SoftbusSessionDispatcher::GetAgent(int sessionId) { char peeSessionName[SESSION_NAME_SIZE_MAX]; int ret = GetPeerSessionName(sessionId, peeSessionName, sizeof(peeSessionName)); - if (ret != 0) { // ! TODO 魔术字 + if (ret != 0) { LOGE("Get my peer session name failed, session id is %{public}d.", sessionId); - return {}; // ! TODO + return {}; } auto agent = busNameToAgent_.find(string(peeSessionName)); if (agent != busNameToAgent_.end()) { @@ -80,7 +79,7 @@ weak_ptr SoftbusSessionDispatcher::GetAgent(int sessionId) return agent->second; } LOGE("Get Session Agent fail, not exist! sessionId:%{public}d, busName:%{public}s", sessionId, peeSessionName); - return {}; // ! TODO + return {}; } int SoftbusSessionDispatcher::OnSessionOpened(int sessionId, int result) { @@ -102,5 +101,5 @@ void SoftbusSessionDispatcher::OnSessionClosed(int sessionId) } } } // namespace DistributedFile -} // namespace Storages +} // namespace Storage } // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/test/unittest/BUILD.gn b/services/distributedfiledaemon/test/unittest/BUILD.gn index e6df95ed913af946079648553cc028bb96c24f9d..a76085157069b518dedd4cd963aa2dc135cd8b71 100644 --- a/services/distributedfiledaemon/test/unittest/BUILD.gn +++ b/services/distributedfiledaemon/test/unittest/BUILD.gn @@ -21,6 +21,8 @@ config("module_private_config") { include_dirs = [ "${services_path}/distributedfiledaemon/include", "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + "//base/security/deviceauth/interfaces/innerkits", + "//third_party/json/include", ] } @@ -41,6 +43,7 @@ ohos_unittest("DeviceManagerAgentTest") { "//third_party/googletest:gtest_main", "${utils_path}:libdistributedfileutils", "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + "//base/security/deviceauth/services:deviceauth_sdk", ] defines = [ diff --git a/services/distributedfiledaemon/test/unittest/device/device_manager_agent_test.cpp b/services/distributedfiledaemon/test/unittest/device/device_manager_agent_test.cpp index 20613477f87d553a17242b8a61354d580ca57520..c029960ebcccff7a8bcd290e236d90cafa6c3ecc 100644 --- a/services/distributedfiledaemon/test/unittest/device/device_manager_agent_test.cpp +++ b/services/distributedfiledaemon/test/unittest/device/device_manager_agent_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 XXXX Device Co., Ltd. + * 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 diff --git a/services/distributedfileservice/BUILD.gn b/services/distributedfileservice/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..d54c88a0c924d16e5b9ce50697efc3881f5f776b --- /dev/null +++ b/services/distributedfileservice/BUILD.gn @@ -0,0 +1,48 @@ +# 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. +import("//build/ohos.gni") +import("//foundation/storage/distributed_file_manager/distributedfile.gni") + +ohos_shared_library("libdistributedfileservice") { + include_dirs = [ + "include/ipc", + ] + + sources = [ + "src/ipc/distributedfile_service_stub.cpp", + "src/ipc/distributedfile_service.cpp", + ] + + configs = [ "${utils_path}:compiler_configs" ] + + external_deps = [ + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:appexecfwk_core", + ] + + deps = [ + "${utils_path}:libdistributedfileutils", + "../../interfaces/innerkits/native:libdistributedfile_innerkits", + ] + + part_name = "storage_distributed_file_manager" + subsystem_name = "storage" +} + +group("distributedfileservice_target") { + deps = [ ":libdistributedfileservice" ] +} \ No newline at end of file diff --git a/services/distributedfileservice/include/ipc/distributedfile_service.h b/services/distributedfileservice/include/ipc/distributedfile_service.h new file mode 100644 index 0000000000000000000000000000000000000000..2ed0ef60ff154e574d10101d6b3359936594a2e7 --- /dev/null +++ b/services/distributedfileservice/include/ipc/distributedfile_service.h @@ -0,0 +1,43 @@ +/* + * 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. + */ + +#ifndef DISTRIBUTEDFILE_SERVICE_H +#define DISTRIBUTEDFILE_SERVICE_H + +#include "distributedfile_service_stub.h" +#include "iremote_stub.h" +#include "singleton.h" +#include "system_ability.h" + +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DistributedFileService : public SystemAbility, + public DistributedFileServiceStub, + public std::enable_shared_from_this { + DECLARE_DELAYED_SINGLETON(DistributedFileService) + DECLARE_SYSTEM_ABILITY(DistributedFileService) +public: + void OnDump() override; + void OnStart() override; + void OnStop() override; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // DISTRIBUTEDFILE_SERVICE_H diff --git a/services/distributedfileservice/include/ipc/distributedfile_service_stub.h b/services/distributedfileservice/include/ipc/distributedfile_service_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..419f6782b9aa8d185260cad988e7a144b5599953 --- /dev/null +++ b/services/distributedfileservice/include/ipc/distributedfile_service_stub.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef DISTRIBUTEDFILE_SERVICE_STUB_H +#define DISTRIBUTEDFILE_SERVICE_STUB_H + +#include +#include + +#include "i_distributedfile_service.h" +#include "message_parcel.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DistributedFileServiceStub : public IRemoteStub { +public: + DistributedFileServiceStub(); + ~DistributedFileServiceStub(); + virtual int + OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using DistributedFileServiceFunc = int32_t (DistributedFileServiceStub::*)(MessageParcel &data, + MessageParcel &reply); + std::map memberFuncMap_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // DISTRIBUTEDFILE_SERVICE_STUB_H \ No newline at end of file diff --git a/test/moduletest/src/distributedfiledeamon_service_test.cpp b/services/distributedfileservice/src/ipc/distributedfile_service.cpp similarity index 32% rename from test/moduletest/src/distributedfiledeamon_service_test.cpp rename to services/distributedfileservice/src/ipc/distributedfile_service.cpp index 7329e67d835d1415c250bab87b5c547a85509a42..e09d7636ea0fd31c90892a19e5c1f38d8af8963a 100644 --- a/test/moduletest/src/distributedfiledeamon_service_test.cpp +++ b/services/distributedfileservice/src/ipc/distributedfile_service.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 XXXX Device Co., Ltd. + * 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 @@ -12,74 +12,47 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "distributedfile_service.h" -#include -#include -#include -#include +#include +#include -#include "device/device_manager_agent.h" -#include "mountpoint/mount_point.h" +#include "bundle_mgr_interface.h" +#include "bundle_mgr_proxy.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "message_parcel.h" +#include "parcel.h" #include "utils_directory.h" #include "utils_log.h" + namespace OHOS { namespace Storage { namespace DistributedFile { -namespace Test { -using namespace testing::ext; using namespace std; -class DistributedFileDaemonServiceTest : public testing::Test { -public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); -}; - -void DistributedFileDaemonServiceTest::SetUpTestCase(void) -{ - // input testsuit setup step,setup invoked before all testcases -} +DistributedFileService::DistributedFileService() : SystemAbility(STORAGE_DISTRIBUTED_FILE_SERVICE_SA_ID, false) {} -void DistributedFileDaemonServiceTest::TearDownTestCase(void) -{ - // input testsuit teardown step,teardown invoked after all testcases -} +DistributedFileService::~DistributedFileService() {} -void DistributedFileDaemonServiceTest::SetUp(void) +void DistributedFileService::OnDump() { - // input testcase setup step,setup invoked before each testcases + LOGI("OnDump"); } -void DistributedFileDaemonServiceTest::TearDown(void) +void DistributedFileService::OnStart() { - // input testcase teardown step,teardown invoked after each testcases + bool ret = SystemAbility::Publish(DelayedSingleton::GetInstance().get()); + if (!ret) { + LOGE("Leave, publishing DistributedFileService failed!"); + return; + } } -/** - * @tc.name: mount_test_001 - * @tc.desc: Verify the mount/umount function. - * @tc.type: FUNC - * @tc.require: Issue Number - */ -HWTEST_F(DistributedFileDaemonServiceTest, mount_umount_test_001, TestSize.Level1) +void DistributedFileService::OnStop() { - auto mp = make_unique(OHOS::DistributedFile::Utils::MountArgumentDescriptors::Alpha(9527)); - - shared_ptr smp = move(mp); - - try { - smp->Mount(); - smp->Umount(); - LOGE("testcase run OK"); - } catch (const exception &e) { - LOGE("%{public}s", e.what()); - EXPECT_EQ(0, 1); - } - EXPECT_EQ(0, 0); + LOGI("DistributedFileService::OnStop start"); } -} // namespace Test } // namespace DistributedFile } // namespace Storage -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/services/distributedfileservice/src/ipc/distributedfile_service_stub.cpp b/services/distributedfileservice/src/ipc/distributedfile_service_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..08c7f202fd044b261d4caf14b0a59920a99fb4a7 --- /dev/null +++ b/services/distributedfileservice/src/ipc/distributedfile_service_stub.cpp @@ -0,0 +1,58 @@ +/* + * 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 "distributedfile_service_stub.h" + +#include +#include + +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +DistributedFileServiceStub::DistributedFileServiceStub() +{ +} + +DistributedFileServiceStub::~DistributedFileServiceStub() +{ + memberFuncMap_.clear(); +} + +int DistributedFileServiceStub::OnRemoteRequest(uint32_t code, + MessageParcel &data, + MessageParcel &reply, + MessageOption &option) +{ + std::u16string myDescriptor = DistributedFileServiceStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (myDescriptor != remoteDescriptor) { + return DISTRIBUTEDFILE_BAD_TYPE; + } + + auto itFunc = memberFuncMap_.find(code); + if (itFunc != memberFuncMap_.end()) { + auto memberFunc = itFunc->second; + if (memberFunc != nullptr) { + return (this->*memberFunc)(data, reply); + } + } + + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn index 26350e2a5bf6db2a28c18858149842b4e44ff6a6..d7ff046b90d1959ae2c56f085e058a210905c4b8 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -21,6 +21,11 @@ config("module_private_config") { include_dirs = [ "${services_path}/distributedfiledaemon/include", "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/communication/dsoftbus/interfaces/kits/bus_center", + "//foundation/communication/dsoftbus/interfaces/kits/common", + "//base/security/deviceauth/interfaces/innerkits", + "//third_party/json/include", ] } @@ -28,7 +33,18 @@ ohos_moduletest("DistributedFileDaemonServiceTest") { module_out_path = module_output_path sources = [ - "${services_path}/distributedfiledaemon/src/mountpoint/mount_point.cpp" + "${services_path}/distributedfiledaemon/src/mountpoint/mount_point.cpp", + "${services_path}/distributedfiledaemon/src/mountpoint/mount_manager.cpp", + "${services_path}/distributedfiledaemon/src/device/device_manager_agent.cpp", + "${services_path}/distributedfiledaemon/src/device/device_info.cpp", + "${services_path}/distributedfiledaemon/src/ipc/daemon_stub.cpp", + "${services_path}/distributedfiledaemon/src/ipc/daemon.cpp", + "${services_path}/distributedfiledaemon/src/network/network_agent_template.cpp", + "${services_path}/distributedfiledaemon/src/network/kernel_talker.cpp", + "${services_path}/distributedfiledaemon/src/network/session_pool.cpp", + "${services_path}/distributedfiledaemon/src/network/softbus/softbus_agent.cpp", + "${services_path}/distributedfiledaemon/src/network/softbus/softbus_session_dispatcher.cpp", + "${services_path}/distributedfiledaemon/src/network/softbus/softbus_session.cpp", ] sources += [ "src/distributedfiledaemon_service_test.cpp" ] @@ -47,6 +63,14 @@ ohos_moduletest("DistributedFileDaemonServiceTest") { "//third_party/googletest:gmock", "${utils_path}:libdistributedfileutils", "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + "//foundation/storage/distributed_file_manager/services/distributedfiledaemon:libdistributedfiledaemon", + "//base/security/deviceauth/services:deviceauth_sdk", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "ipc:ipc_core", + "safwk:system_ability_fwk", ] } diff --git a/test/moduletest/src/distributedfiledaemon_service_test.cpp b/test/moduletest/src/distributedfiledaemon_service_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9f29c2907338c95b60cb4820a6a0032920c40733 --- /dev/null +++ b/test/moduletest/src/distributedfiledaemon_service_test.cpp @@ -0,0 +1,684 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "device/device_info.h" +#include "device/device_manager_agent.h" +#include "mountpoint/mount_point.h" +#include "network/kernel_talker.h" +#include "network/session_pool.h" +#include "network/softbus/softbus_session.h" +#include "securec.h" +#include "utils_directory.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Test { +using namespace testing::ext; +using namespace std; + +static const string srcHead = "/data/misc_ce/"; +static const string dstHead = "/mnt/hmdfs/"; +static const string cacheHead = "/data/misc_ce/"; +std::mutex cmdMutex_; + +const int KEY_MAX_LEN = 32; +const int CID_MAX_LEN = 64; +struct UpdateSocketParam { + int32_t cmd; + int32_t newfd; + uint8_t status; + uint8_t protocol; + uint16_t udpPort; + uint8_t deviceType; + uint8_t masterKey[KEY_MAX_LEN]; + char cid[CID_MAX_LEN]; + int32_t linkType; + int32_t binderFd; +} __attribute__((packed)); + +class DistributedFileDaemonServiceTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DistributedFileDaemonServiceTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void DistributedFileDaemonServiceTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void DistributedFileDaemonServiceTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void DistributedFileDaemonServiceTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: mount_test_001 + * @tc.desc: Verify the mount/umount function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, mount_umount_test_001, TestSize.Level1) +{ + auto mp = make_unique( + OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(9527)); + + shared_ptr smp = move(mp); + + try { + smp->Mount(); + smp->Umount(); + LOGE("testcase run OK"); + } catch (const exception &e) { + LOGE("%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} + +/** + * @tc.name: distributedFileDaemon_service_test_001_mount + * @tc.desc: Verify the mount/umount function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, distributedFileDaemon_service_test_001_mount, TestSize.Level1) +{ + const int userId = 3333; + + auto mountArgument = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId); + auto mp = make_unique(mountArgument); + + shared_ptr smp = move(mp); + + try { + smp->Mount(); + + const string src = mountArgument.GetFullSrc(); + const char *srcPath = src.data(); + int ret = access(srcPath, F_OK); + EXPECT_EQ(0, ret); + + const string dst = mountArgument.GetFullDst(); + const char *dstPath = dst.data(); + ret = access(dstPath, F_OK); + EXPECT_EQ(0, ret); + + const string cache = mountArgument.GetCachePath(); + const char *cachePath = cache.data(); + ret = access(cachePath, F_OK); + EXPECT_EQ(0, ret); + + stringstream srcTest; + srcTest << src << "/test"; + Utils::ForceCreateDirectory(srcTest.str(), S_IRWXU | S_IRWXG | S_IXOTH); + + stringstream dstTest; + dstTest << dst << "/device_view/local" + << "/test"; + const string pathStr = dstTest.str(); + const char *dstPathTest = pathStr.data(); + ret = access(dstPathTest, F_OK); + EXPECT_EQ(0, ret); + + Utils::ForceRemoveDirectory(dstPathTest); + + const string strTestStr = srcTest.str(); + ret = access(strTestStr.data(), F_OK); + EXPECT_EQ(-1, ret); + + smp->Umount(); + + stringstream srcStream; + srcStream << srcHead << userId; + Utils::ForceRemoveDirectory(srcStream.str()); + + ret = access(srcStream.str().data(), F_OK); + EXPECT_EQ(-1, ret); + + LOGE("testcase distributedFileDaemon_service_test_001_mount run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} + +/** + * @tc.name: distributedFileDaemon_service_test_002_multiple_mount + * @tc.desc: Verify the mount/umount function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, distributedFileDaemon_service_test_002_multiple_mount, TestSize.Level1) +{ + const int userId[2] = {3335, 3336}; + Utils::MountArgument mountArgument[2]; + shared_ptr smpArr[2]; + + const int len = sizeof(userId) / sizeof(userId[0]); + for (int i = 0; i < len; i++) { + mountArgument[i] = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId[i]); + auto mp = make_unique(mountArgument[i]); + smpArr[i] = move(mp); + } + + try { + for (int j = 0; j < len; j++) { + smpArr[j]->Mount(); + } + + for (int k = 0; k < len; k++) { + const string src = mountArgument[k].GetFullSrc(); + const char *srcPath = src.data(); + int ret = access(srcPath, F_OK); + EXPECT_EQ(0, ret); + + const string dst = mountArgument[k].GetFullDst(); + const char *dstPath = dst.data(); + ret = access(dstPath, F_OK); + EXPECT_EQ(0, ret); + + const string cache = mountArgument[k].GetCachePath(); + const char *cachePath = cache.data(); + ret = access(cachePath, F_OK); + EXPECT_EQ(0, ret); + + stringstream srcTest; + srcTest << src << "/test"; + Utils::ForceCreateDirectory(srcTest.str(), S_IRWXU | S_IRWXG | S_IXOTH); + + stringstream dstTest; + dstTest << dst << "/device_view/local" + << "/test"; + const string pathStr = dstTest.str(); + const char *dstPathTest = pathStr.data(); + ret = access(dstPathTest, F_OK); + EXPECT_EQ(0, ret); + + Utils::ForceRemoveDirectory(dstPathTest); + + const string strTestStr = srcTest.str(); + ret = access(strTestStr.data(), F_OK); + EXPECT_EQ(-1, ret); + + smpArr[k]->Umount(); + + stringstream srcStream; + srcStream << srcHead << userId[k]; + Utils::ForceRemoveDirectory(srcStream.str()); + + ret = access(srcStream.str().data(), F_OK); + EXPECT_EQ(-1, ret); + } + + LOGE("testcase distributedFileDaemon_service_test_002_mount run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} + +/** + * @tc.name: distributedFileDaemon_service_test_003_unmount + * @tc.desc: Verify the mount/umount function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, distributedFileDaemon_service_test_003_unmount, TestSize.Level1) +{ + const int userId = 3337; + + auto mountArgument = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId); + auto mp = make_unique(mountArgument); + + shared_ptr smp = move(mp); + + try { + smp->Mount(); + + const string dst = mountArgument.GetFullDst(); + const char *dstPath = dst.data(); + stringstream dstTest1, dstTest2; + dstTest1 << dst << "/device_view/local" + << "/test1"; + dstTest2 << dst << "/device_view/local" + << "/test2"; + Utils::ForceCreateDirectory(dstTest1.str(), S_IRWXU | S_IRWXG | S_IXOTH); + Utils::ForceCreateDirectory(dstTest2.str(), S_IRWXU | S_IRWXG | S_IXOTH); + + const string src = mountArgument.GetFullSrc(); + const string srcTest1 = src + "/test1"; + int ret = access(srcTest1.data(), F_OK); + EXPECT_EQ(0, ret); + + Utils::ForceRemoveDirectory(srcTest1); + + ret = access(dstTest1.str().data(), F_OK); + EXPECT_EQ(-1, ret); + + smp->Umount(); + + ret = access(dstPath, F_OK); + EXPECT_EQ(-1, ret); + + const string srcTest2 = src + "/test2"; + const char *srcPathTest2 = srcTest2.data(); + ret = access(srcTest2.data(), F_OK); + EXPECT_EQ(0, ret); + + Utils::ForceRemoveDirectory(srcPathTest2); + + stringstream srcStream; + srcStream << srcHead << userId; + Utils::ForceRemoveDirectory(srcStream.str()); + + ret = access(srcStream.str().data(), F_OK); + EXPECT_EQ(-1, ret); + + LOGE("testcase distributedFileDaemon_service_test_003_unmount run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} + +/** + * @tc.name: distributedFileDaemon_service_test_004_repeats_mount + * @tc.desc: Verify the mount/umount function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, distributedFileDaemon_service_test_004_repeats_mount, TestSize.Level1) +{ + const int userId = 3338; + + auto mountArgument = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId); + auto mp = make_unique(mountArgument); + + shared_ptr smp = move(mp); + + try { + smp->Mount(); + smp->Mount(); + + const string src = mountArgument.GetFullSrc(); + const char *srcPath = src.data(); + int ret = access(srcPath, F_OK); + EXPECT_EQ(0, ret); + + const string dst = mountArgument.GetFullDst(); + const char *dstPath = dst.data(); + ret = access(dstPath, F_OK); + EXPECT_EQ(0, ret); + + const string cache = mountArgument.GetCachePath(); + const char *cachePath = cache.data(); + ret = access(cachePath, F_OK); + EXPECT_EQ(0, ret); + + stringstream srcTest; + srcTest << src << "/test"; + Utils::ForceCreateDirectory(srcTest.str(), S_IRWXU | S_IRWXG | S_IXOTH); + + stringstream dstTest; + dstTest << dst << "/device_view/local" + << "/test"; + const string pathStr = dstTest.str(); + const char *dstPathTest = pathStr.data(); + ret = access(dstPathTest, F_OK); + EXPECT_EQ(0, ret); + + Utils::ForceRemoveDirectory(dstPathTest); + + const string strTestStr = srcTest.str(); + ret = access(strTestStr.data(), F_OK); + EXPECT_EQ(-1, ret); + + smp->Umount(); + + stringstream srcStream; + srcStream << srcHead << userId; + Utils::ForceRemoveDirectory(srcStream.str()); + + ret = access(srcStream.str().data(), F_OK); + EXPECT_EQ(-1, ret); + + LOGE("testcase distributedFileDaemon_service_test_004_repeats_mount run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} + +/** + * @tc.name: distributedFileDaemon_service_test_005_repeats_unmount + * @tc.desc: Verify the mount/umount function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, distributedFileDaemon_service_test_005_repeats_unmount, TestSize.Level1) +{ + const int userId = 3339; + + auto mountArgument = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId); + auto mp = make_unique(mountArgument); + + shared_ptr smp = move(mp); + + try { + smp->Mount(); + + const string dst = mountArgument.GetFullDst(); + const char *dstPath = dst.data(); + stringstream dstTest1, dstTest2; + dstTest1 << dst << "/device_view/local" + << "/test1"; + dstTest2 << dst << "/device_view/local" + << "/test2"; + Utils::ForceCreateDirectory(dstTest1.str(), S_IRWXU | S_IRWXG | S_IXOTH); + Utils::ForceCreateDirectory(dstTest2.str(), S_IRWXU | S_IRWXG | S_IXOTH); + + const string src = mountArgument.GetFullSrc(); + const string srcTest1 = src + "/test1"; + const char *srcPathTest1 = srcTest1.data(); + int ret = access(srcPathTest1, F_OK); + EXPECT_EQ(0, ret); + + Utils::ForceRemoveDirectory(srcPathTest1); + + ret = access(dstTest1.str().data(), F_OK); + EXPECT_EQ(-1, ret); + + smp->Umount(); + try { + smp->Umount(); + } catch (const exception &e) { + string err = e.what(); + string out = "No such file or directory"; + + if (err.find(out) == string::npos) { + LOGE("005-Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + } + + ret = access(dstPath, F_OK); + EXPECT_EQ(-1, ret); + + const string srcTest2 = src + "/test2"; + const char *srcPathTest2 = srcTest2.data(); + printf("005ck--7--info:%s\n", srcPathTest2); + ret = access(srcPathTest2, F_OK); + EXPECT_EQ(0, ret); + + Utils::ForceRemoveDirectory(srcPathTest2); + + stringstream srcStream; + srcStream << srcHead << userId; + Utils::ForceRemoveDirectory(srcStream.str()); + + ret = access(srcStream.str().data(), F_OK); + EXPECT_EQ(-1, ret); + + LOGE("testcase distributedFileDaemon_service_test_005_unmount run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} + +/** + * @tc.name: distributedFileDaemon_service_test_006_repeats_init_register + * @tc.desc: Verify the Start/Stop function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, + distributedFileDaemon_service_test_006_repeats_init_register, + TestSize.Level1) +{ + auto dm = DeviceManagerAgent::GetInstance(); + shared_ptr sdm = move(dm); + + try { + sdm->Start(); + sdm->Stop(); + LOGE("testcase distributedFileDaemon_service_test_006_repeats_init_register run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} +/** + * @tc.name: distributedFileDaemon_service_test_007_repeats_create_net_instance + * @tc.desc: Verify the JoinGroup/QuitGroup function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, + distributedFileDaemon_service_test_007_repeats_create_net_instance, + TestSize.Level1) +{ + const int userId = 4200; + auto mountArgument = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId); + auto mp = make_unique(mountArgument); + shared_ptr smp = move(mp); + + try { + auto sdm = DeviceManagerAgent::GetInstance(); + + smp->Mount(); + sdm->Start(); + sdm->JoinGroup(smp); + smp->Umount(); + sdm->QuitGroup(smp); + sdm->Stop(); + LOGE("testcase distributedFileDaemon_service_test_007_repeats_create_net_instance run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} +/** + * @tc.name: distributedFileDaemon_service_test_008_repeats_repeat_create_net_instance + * @tc.desc: Verify the JoinGroup/QuitGroup function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, + distributedFileDaemon_service_test_008_repeats_repeat_create_net_instance, + TestSize.Level1) +{ + const int userId = 4201; + auto mountArgument = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId); + auto mp = make_unique(mountArgument); + shared_ptr smp = move(mp); + + try { + auto sdm = DeviceManagerAgent::GetInstance(); + + smp->Mount(); + sdm->Start(); + sdm->JoinGroup(smp); + try { + sdm->JoinGroup(smp); + } catch (const exception &e) { + string err = e.what(); + string out = "Mountpoint existed"; + + if (err.find(out) == string::npos) { + LOGE("008-Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + } + smp->Umount(); + sdm->QuitGroup(smp); + sdm->Stop(); + LOGE("testcase distributedFileDaemon_service_test_008_repeats_repeat_create_net_instance run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} +/** + * @tc.name: distributedFileDaemon_service_test_009_repeats_create_multipe_net_instance + * @tc.desc: Verify the JoinGroup/QuitGroup function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, + distributedFileDaemon_service_test_009_repeats_create_multipe_net_instance, + TestSize.Level1) +{ + const int userId1 = 4202; + const int userId2 = 4203; + auto mountArgument1 = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId1); + auto mountArgument2 = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId2); + auto mp1 = make_unique(mountArgument1); + auto mp2 = make_unique(mountArgument2); + shared_ptr smp1 = move(mp1); + shared_ptr smp2 = move(mp2); + + try { + auto sdm = DeviceManagerAgent::GetInstance(); + + smp1->Mount(); + smp2->Mount(); + sdm->Start(); + sdm->JoinGroup(smp1); + sdm->JoinGroup(smp2); + smp1->Umount(); + smp2->Umount(); + sdm->QuitGroup(smp1); + sdm->QuitGroup(smp2); + sdm->Stop(); + LOGE("testcase distributedFileDaemon_service_test_009_repeats_create_multipe_net_instance run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} +/** + * @tc.name: distributedFileDaemon_service_test_010_repeats_repeat_del_net_instance + * @tc.desc: Verify the JoinGroup/QuitGroup function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, + distributedFileDaemon_service_test_010_repeats_repeat_del_net_instance, + TestSize.Level1) +{ + const int userId = 4204; + auto mountArgument = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId); + auto mp = make_unique(mountArgument); + shared_ptr smp = move(mp); + + try { + auto sdm = DeviceManagerAgent::GetInstance(); + + smp->Mount(); + sdm->Start(); + sdm->JoinGroup(smp); + smp->Umount(); + sdm->QuitGroup(smp); + try { + sdm->QuitGroup(smp); + } catch (const exception &e) { + string err = e.what(); + string out = "Mountpoint didn't exist"; + + if (err.find(out) == string::npos) { + LOGE("010-Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + } + sdm->Stop(); + LOGE("testcase distributedFileDaemon_service_test_010_repeats_repeat_del_net_instance run end"); + } catch (const exception &e) { + LOGE("Error:%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} + +/** + * @tc.name: distributedFileDaemon_service_test_015_kernel_notify_deal + * @tc.desc: Verify the JoinGroup/QuitGroup function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, distributedFileDaemon_service_test_015_kernel_notify_deal, TestSize.Level1) +{ + const int userId = 4500; + auto mountArgument = OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(userId); + auto mp = make_unique(mountArgument); + shared_ptr smp = move(mp); + + KernelTalker kt( + smp, + [&](NotifyParam ¶m) { + EXPECT_EQ(param.notify, 2); + }, + [&](const std::string &cid) { + string str = "remoteCid-1"; + EXPECT_TRUE(strcmp(cid.data(), str.data()) == 0); + }); + + for (int i = 0; i < 7; i++) { + std::string str = "remoteCid-" + to_string(i); + NotifyParam param = {i, 72, 16, 8, 336, 326}; + strcpy_s(param.remoteCid, CID_MAX_LEN, str.data()); + kt.NotifyHandler(param); + } + + EXPECT_EQ(0, 0); +} + +} // namespace Test +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/utils/system/include/utils_actor.h b/utils/system/include/utils_actor.h new file mode 100644 index 0000000000000000000000000000000000000000..18b27291d75261fe7975b53ae3153e628ae9750c --- /dev/null +++ b/utils/system/include/utils_actor.h @@ -0,0 +1,170 @@ +/* + * 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. + */ + +#ifndef UTILS_ACTOR_H +#define UTILS_ACTOR_H + +#include +#include +#include +#include +#include +#include + +#include "utils_cmd.h" +#include "utils_thread_safe_queue.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +constexpr int RETRY_SLEEP_TIME = 1500; +/** + * @brief The Actor Model + * + * @tparam Ctx Context for Commands + */ +template +class Actor { +public: + explicit Actor(Ctx *ctx, int startCmdTryTimes = 1) : ctx_(ctx), retryTimes_(startCmdTryTimes) {} + virtual ~Actor() {} + + void StartActor() + { + // Always insert cmds b4 starting an actor + StartCtx(); + loop_ = std::thread(&Actor::Main, this); + } + + void StopActor() + { + // Always insert cmds b4 starting an actor + StopCtx(); + pendingCmds_.Halt(); + + loop_.join(); + } + + void Recv(std::unique_ptr> pcmd) + { + pendingCmds_.Push(std::move(pcmd)); + } + +protected: + ThreadSafeQueue> pendingCmds_; + + Ctx *ctx_{nullptr}; + uint32_t retryTimes_{1}; + std::thread loop_; + + std::list> retryTasks; + +private: + void DelayRetry(std::unique_ptr> cmd) + { + using namespace std::literals::chrono_literals; + std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_SLEEP_TIME)); + pendingCmds_.Push(std::move(cmd)); + } + + void Retry(std::unique_ptr> cmd) + { + pendingCmds_.PushFront(std::move(cmd)); + using namespace std::literals::chrono_literals; + std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_SLEEP_TIME)); + } + + void StartCtx() + { + auto startCmd = std::make_unique>(&Ctx::Start); + startCmd->UpdateOption({ + .importance_ = CmdImportance::SUBVITAL, + .tryTimes_ = retryTimes_, + }); + pendingCmds_.Push(std::move(startCmd)); + } + + void StopCtx() + { + auto cmd = std::make_unique>(&Ctx::Stop); + cmd->UpdateOption({ + .importance_ = CmdImportance::VITAL, + .tryTimes_ = 1, + }); + pendingCmds_.Push(std::move(cmd)); + } + + bool IsExistStopTask() + { + bool result = false; + pendingCmds_.ForEach([&result](const std::unique_ptr> &item) { + if (item->option_.importance_ == CmdImportance::VITAL) { + result = true; + } + }); + return result; + } + + void Main() + { + while (true) { + std::unique_ptr> currentCmd; + try { + while (true) { + currentCmd = pendingCmds_.WaitAndPop(); + (*currentCmd)(ctx_); + currentCmd.release(); + } + } catch (const Exception &e) { + if (e.code() == ERR_UTILS_ACTOR_QUEUE_STOP) { + break; + } + + const CmdOptions &op = currentCmd->option_; + + if (IsExistStopTask() && (op.tryTimes_ > 0)) { + break; // exist stop Task, stop retry + } + + if (op.importance_ == CmdImportance::TRIVIAL) { + if (op.tryTimes_) { + retryTasks.emplace_back( + std::async(std::launch::async, &Actor::DelayRetry, this, std::move(currentCmd))); + continue; + } + } else { + if (op.tryTimes_) { + Retry(std::move(currentCmd)); + continue; + } + if (op.importance_ == CmdImportance::VITAL) { + break; + } + if (op.importance_ == CmdImportance::NORMAL) { + StopCtx(); + StartCtx(); + continue; + } + } + } catch (const std::exception &e) { + LOGE("Unexpected Low Level exception"); + } + } + } +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_ACTOR_H diff --git a/utils/system/include/utils_cmd.h b/utils/system/include/utils_cmd.h new file mode 100644 index 0000000000000000000000000000000000000000..fc41bfc7e6f4aa03cab1d21facd597110c2c8cd9 --- /dev/null +++ b/utils/system/include/utils_cmd.h @@ -0,0 +1,90 @@ +/* + * 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. + */ + +#ifndef UTILS_CMD_H +#define UTILS_CMD_H + +#include +#include + +#include "utils_exception.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +enum class CmdImportance { + // If it fails(even has tried multiple times), shutdown the actor. + VITAL, + + SUBVITAL, + // If it fails(even has tried multiple times), reboot the actor. + NORMAL, + + // If it fails(may also try multiple times), just do nothing. + TRIVIAL, +}; + +struct CmdOptions { + CmdImportance importance_{CmdImportance::TRIVIAL}; + uint32_t tryTimes_{1}; +}; + +template +class Actor; + +template +class VirtualCmd { + friend class Actor; + +public: + VirtualCmd() = default; + virtual ~VirtualCmd() = default; + virtual void operator()(Ctx *ctx) = 0; + + void UpdateOption(CmdOptions op) + { + option_ = op; + } + +protected: + CmdOptions option_; +}; + +template +class Cmd : public VirtualCmd { + friend class Actor; + +public: + Cmd(void (Ctx::*f)(Args...), Args... args) : f_(f), args_(args...) {} + ~Cmd() override = default; + +private: + void (Ctx::*f_)(Args...); + std::tuple args_; + + void operator()(Ctx *ctx) override + { + if (!VirtualCmd::option_.tryTimes_) { + ThrowException(ERR_UTILS_ACTOR_INVALID_CMD, "Cannot execute a command that has 0 try times"); + } + + VirtualCmd::option_.tryTimes_--; + std::apply(f_, std::tuple_cat(std::make_tuple(ctx), args_)); + } +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_CMD_H \ No newline at end of file diff --git a/utils/system/include/utils_exception.h b/utils/system/include/utils_exception.h new file mode 100644 index 0000000000000000000000000000000000000000..6afd215aa2f29131fe328e6932bf2ab195d75a66 --- /dev/null +++ b/utils/system/include/utils_exception.h @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#ifndef UTILS_EXCEPTION_H +#define UTILS_EXCEPTION_H + +#include +#include +#include + +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +enum { + ERR_DEFAULT, + ERR_UTILS_ACTOR_QUEUE_STOP, + ERR_UTILS_ACTOR_INVALID_CMD, + ERR_NETWORK_AGENT_TEMPLATE_OPEN_SESSION_FAIL, + ERR_SOFTBUS_AGENT_ON_SESSION_OPENED_FAIL, + ERR_DEVICE_CID_UN_INIT, +}; + +class Exception : public std::exception { +public: + Exception(int code, const std::string &msg) : code_(code), msg_(msg){}; + + uint32_t code() const noexcept + { + return code_; + } + + virtual const char *what() const noexcept + { + return msg_.c_str(); + } + +private: + int code_{ERR_DEFAULT}; + std::string msg_; +}; + +#define ThrowException(code, msg) \ + do { \ + std::stringstream __ss; \ + __ss << '[' << code << ']' << msg << std::endl; \ + LOGE("%{public}s", __ss.str().c_str()); \ + throw Exception(code, __ss.str()); \ + } while (0) + +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_EXCEPTION_H \ No newline at end of file diff --git a/utils/system/include/utils_mount_argument.h b/utils/system/include/utils_mount_argument.h index a57a077388e8640722eda95b237eff5bdbc53616..f68fbc18ded1d6e484a6e70ed9712e1dcb5198cd 100644 --- a/utils/system/include/utils_mount_argument.h +++ b/utils/system/include/utils_mount_argument.h @@ -24,8 +24,8 @@ namespace DistributedFile { namespace Utils { struct MountArgument final { int userId_{0}; - - std::string account_; + bool accountless_{false}; + std::string groupId_; bool needInitDir_{false}; bool useCache_{false}; bool caseSensitive_{true}; @@ -33,6 +33,7 @@ struct MountArgument final { bool enableFixupOwnerShip_{false}; bool enableOfflineStash_{true}; bool externalFS_{false}; + std::string packageName_; std::string GetFullSrc() const; std::string GetFullDst() const; @@ -45,6 +46,8 @@ struct MountArgument final { class MountArgumentDescriptors final { public: static MountArgument Alpha(int userId = 0); + static MountArgument + SetAuthGroupMountArgument(const std::string &groupId, const std::string &packageName, bool accountless); }; } // namespace Utils } // namespace DistributedFile diff --git a/utils/system/include/utils_singleton.h b/utils/system/include/utils_singleton.h index 5704975564fd1b6653c6206997a00ae6e34ffee0..14c9dd03e268f28af83973d6245d83a06407a09a 100644 --- a/utils/system/include/utils_singleton.h +++ b/utils/system/include/utils_singleton.h @@ -37,18 +37,17 @@ template class Singleton : public NoCopyable { public: static std::shared_ptr GetInstance(); - static void StopInstance(); protected: /** * @note We depend on the IPC manager to serialize the start and the stop procedure */ - virtual void Start() = 0; + virtual void StartInstance() = 0; /** * @note Be very careful when freeing memory! Threads may call stop and other member functions simultaneously */ - virtual void Stop() = 0; + virtual void StopInstance() = 0; }; /** @@ -67,20 +66,10 @@ std::shared_ptr Singleton::GetInstance() static std::once_flag once; std::call_once(once, []() mutable { dummy = new std::shared_ptr(new T()); - (*dummy)->Start(); + (*dummy)->StartInstance(); }); return *dummy; } - -template -void Singleton::StopInstance() -{ - static std::once_flag once; - std::call_once(once, []() { - auto instance = GetInstance(); - instance->Stop(); - }); -} } // namespace Utils } // namespace DistributedFile } // namespace Storage diff --git a/interfaces/innerkits/native/daemon_proxy.h b/utils/system/include/utils_startable.h similarity index 68% rename from interfaces/innerkits/native/daemon_proxy.h rename to utils/system/include/utils_startable.h index 013803ef38a758e8f9c68248a3d4bbb6db06f251..e00127c2ae47306ba8f9b1a2b1865620ce3c7c9d 100644 --- a/interfaces/innerkits/native/daemon_proxy.h +++ b/utils/system/include/utils_startable.h @@ -12,25 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef DAEMON_PROXY_H -#define DAEMON_PROXY_H -#include - -#include "i_daemon.h" +#ifndef UTILS_STARTABLE_H +#define UTILS_STARTABLE_H namespace OHOS { namespace Storage { namespace DistributedFile { -class DaemonProxy : public IRemoteProxy { +class Startable { public: - explicit DaemonProxy(const sptr &impl) : IRemoteProxy(impl) {} - ~DaemonProxy() {} - -private: - static inline BrokerDelegator delegator_; + virtual void Start() = 0; + virtual void Stop() = 0; }; } // namespace DistributedFile } // namespace Storage } // namespace OHOS -#endif // DAEMON_PROXY_H \ No newline at end of file +#endif // UTILS_STARTABLE_H \ No newline at end of file diff --git a/utils/system/include/utils_thread_safe_queue.h b/utils/system/include/utils_thread_safe_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..fb6139dcc0845e461f5729e5b7283f3070313154 --- /dev/null +++ b/utils/system/include/utils_thread_safe_queue.h @@ -0,0 +1,102 @@ +/* + * 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. + */ + +#ifndef UTILS_THREAD_SAFE_QUEUE_H +#define UTILS_THREAD_SAFE_QUEUE_H + +#include +#include +#include +#include +#include + +#include "utils_exception.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { + +/** + * @brief A Thread-safe Queue. + * + * Design choices: + * 1) unlimited capacity + * 2) throw exception to indicate failues + * 3) blocking pop interface + * 3) hatlable + * + * @tparam T Any type. Aggregate data type is prefered + * + */ + +template +class ThreadSafeQueue { +public: + void Push(std::unique_ptr pt) + { + if (!pt) { + ThrowException(ERR_UTILS_ACTOR_INVALID_CMD, "Push an empty cmd"); + } + std::unique_lock lock(mutex_); + queue_.emplace_back(std::move(pt)); + cv_.notify_one(); + } + + void PushFront(std::unique_ptr pt) + { + if (!pt) { + ThrowException(ERR_UTILS_ACTOR_INVALID_CMD, "Push an empty cmd"); + } + std::unique_lock lock(mutex_); + queue_.emplace_front(std::move(pt)); + cv_.notify_one(); + } + + std::unique_ptr WaitAndPop() + { + std::unique_lock lock(mutex_); + cv_.wait(lock, [&] { return !queue_.empty() || halted; }); + if (halted && queue_.empty()) { + ThrowException(ERR_UTILS_ACTOR_QUEUE_STOP, "Queue was halted"); + } + + auto res = std::move(queue_.front()); + queue_.pop_front(); + return std::move(res); + } + + void ForEach(std::function &)> executor) + { + std::unique_lock lock(mutex_); + std::for_each(queue_.begin(), queue_.end(), executor); + } + + void Halt() + { + halted = true; + cv_.notify_all(); + } + +private: + std::deque> queue_; + std::mutex mutex_; + std::condition_variable cv_; + + bool halted{false}; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_THREAD_SAFE_QUEUE_H \ No newline at end of file diff --git a/utils/system/include/utils_uid.h b/utils/system/include/utils_uid.h deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/utils/system/src/utils_mount_argument.cpp b/utils/system/src/utils_mount_argument.cpp index abde578d53f7793678d43bdb0143148ed2a70715..01a4f8ab01f6f80815997c8292809688d39e11c9 100644 --- a/utils/system/src/utils_mount_argument.cpp +++ b/utils/system/src/utils_mount_argument.cpp @@ -23,25 +23,43 @@ namespace Storage { namespace DistributedFile { namespace Utils { using namespace std; +namespace { +static const std::string DATA_POINT = "/data/service/el2/"; +static const std::string BASE_MOUNT_POINT = "/mnt/hmdfs/"; +static const std::string AUTH_GROUP_MOUNT_POINT = "/mnt/hmdfs/auth_groups/"; +static const std::string SYSFS_HMDFS_PATH = "sys/fs/hmdfs/"; +} // namespace string MountArgument::GetFullSrc() const { stringstream ss; - ss << "/data/misc_ce/" << userId_ << "/hmdfs/storage"; + if (!accountless_) { + ss << DATA_POINT << userId_ << "/hmdfs/storage"; + } else { + ss << DATA_POINT << userId_ << "/hmdfs/auth_groups/" << groupId_; + } return ss.str(); } string MountArgument::GetFullDst() const { stringstream ss; - ss << "/mnt/hmdfs/" << userId_ << "/"; + if (!accountless_) { + ss << BASE_MOUNT_POINT << userId_ << "/"; + } else { + ss << AUTH_GROUP_MOUNT_POINT << groupId_ << "/"; + } return ss.str(); } string MountArgument::GetCachePath() const { stringstream ss; - ss << "/data/misc_ce/" << userId_ << "/hmdfs/cache/"; + if (!accountless_) { + ss << DATA_POINT << userId_ << "/hmdfs/cache/"; + } else { + ss << DATA_POINT << userId_ << "/hmdfs/auth_groups/" << groupId_ << "/cache/"; + } return ss.str(); } @@ -61,7 +79,7 @@ string MountArgument::GetCtrlPath() const auto dst = GetFullDst(); auto res = MocklispHash(dst); stringstream ss; - ss << "/sys/fs/hmdfs/" << res << "/cmd"; + ss << SYSFS_HMDFS_PATH << res << "/cmd"; return ss.str(); } @@ -98,7 +116,7 @@ unsigned long MountArgument::GetFlags() const MountArgument MountArgumentDescriptors::Alpha(int userId) { MountArgument mountArgument = { - .account_ = "default", + .groupId_ = "default", .needInitDir_ = true, .useCache_ = true, .enableMergeView_ = true, @@ -109,6 +127,24 @@ MountArgument MountArgumentDescriptors::Alpha(int userId) mountArgument.userId_ = userId; return mountArgument; } + +MountArgument MountArgumentDescriptors::SetAuthGroupMountArgument(const std::string &groupId, + const std::string &packageName, + bool accountless) +{ + MountArgument mountArgument = { + .accountless_ = accountless, + .groupId_ = groupId, + .needInitDir_ = true, + .useCache_ = true, + .enableMergeView_ = true, + .enableFixupOwnerShip_ = true, + .enableOfflineStash_ = true, + .externalFS_ = false, + .packageName_ = packageName, + }; + return mountArgument; +} } // namespace Utils } // namespace DistributedFile } // namespace Storage diff --git a/utils/system/src/utils_uid.cpp b/utils/system/src/utils_uid.cpp deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000