diff --git a/README.md b/README.md index 2eb9fc328bca6e5e531d71b971cace5aa5d33aa1..5c911bb93e74fa2801298a1777cf591b115fa711 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,85 @@ -# 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 +- distributedfiledeamon:分布式文件管理常驻用户态服务,负责接入设备组网、数据传输能力,并负责挂载hmdfs +- distributedfileservice:分布式文件管理按需启动用户态服务,负责为应用在hmdfs中创建专属跨设备文件目录 +- hmdfs(HarMony Didstributed File System):分布式文件管理核心模块,是一种面向移动分布式场景的、高性能的、基于内核实现的、堆叠式文件系统。 -#### 参与贡献 +## 目录 -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +```raw +//foundation/storage/distributed_file_manager +├── frameworks // 接口实现 +│ └── native // c/c++ 接口实现 +├── interfaces // 接口声明 +│ └── innerkits // 对内接口声明 +├── services // 服务实现 +│ └── distributedfiledeamon // 常驻服务实现 +| └── 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`个。 + +### 时延 + +多数操作的默认超时时间均为4秒种,以下操作除外: + +- TODO + +## 说明 + +### 使用说明 + +可以使用终端调试分布式文件管理能力。 + +在两台设备已经组网的情况下,通过 hdc 进入 `/mnt/hmdfs/0/` 目录,即可看见形如下方所述的目录结构: + +``` +/mnt/hmdfs/0/device_view/local +/mnt/hmdfs/0/device_view/7914943294a41be79c2c4f1f3cb4773c46674c86305cc05b0245dc74f99e0c8d +/mnt/hmdfs/0/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..0cbb1c08e85bf2233ef450d76885112dbd7568ba --- /dev/null +++ b/frameworks/native/service_proxy.cpp @@ -0,0 +1,77 @@ +/* + * 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() {} + +int32_t ServiceProxy::GetBundleDistributedDir(const std::string &dirName) +{ + int32_t error = GET_DISTRIBUTEDFILE_DISTRIBUTED_DIR_FAIL; + + MessageOption option; + MessageParcel dataParcel; + MessageParcel replyParcel; + if (!dataParcel.WriteInterfaceToken(ServiceProxy::GetDescriptor())) { + LOGE("write descriptor failed"); + return DISTRIBUTEDFILE_WRITE_DESCRIPTOR_TOKEN_FAIL; + } + dataParcel.WriteString(dirName); + if (Remote() == nullptr) { + LOGE("Remote object address is null"); + return DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL; + } + error = Remote()->SendRequest(GET_BUNDLE_DISTRIBUTED_DIR, dataParcel, replyParcel, option); + if (error != DISTRIBUTEDFILE_NO_ERROR) { + LOGE("Function GetBundleDistributedDir! errCode:%{public}d", error); + return DISTRIBUTEDFILE_CONNECT_SYSTEM_ABILITY_STUB_FAIL; + } + + return replyParcel.ReadInt32(); +} + +int32_t ServiceProxy::RemoveBundleDistributedDirs(const std::string &dirName) +{ + int32_t error = REMOVE_DISTRIBUTEDFILE_DISTRIBUTEDDIRS_FAIL; + MessageOption option; + MessageParcel dataParcel; + MessageParcel replyParcel; + if (!dataParcel.WriteInterfaceToken(ServiceProxy::GetDescriptor())) { + LOGE("write descriptor failed"); + return DISTRIBUTEDFILE_WRITE_DESCRIPTOR_TOKEN_FAIL; + } + + dataParcel.WriteString(dirName); + if (Remote() == nullptr) { + LOGE("Remote object address is null"); + return DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL; + } + + error = Remote()->SendRequest(REMOVE_BUNDLE_DISTRIBUTED_DIRS, dataParcel, replyParcel, option); + if (error != DISTRIBUTEDFILE_NO_ERROR) { + LOGE("Function RemoveBundleDistributedDirs! errCode:%{public}d", error); + return DISTRIBUTEDFILE_CONNECT_SYSTEM_ABILITY_STUB_FAIL; + } + + return replyParcel.ReadInt32(); +} +} // 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..46c6044bbe1cccaca4ee5795a9cde6972112f35f --- /dev/null +++ b/frameworks/native/service_proxy.h @@ -0,0 +1,47 @@ +/* + * 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(); + + int32_t GetBundleDistributedDir(const std::string &dirName) override; + int32_t RemoveBundleDistributedDirs(const std::string &dirName) override; + +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..0b283ff54c3bfa87b5d6c2ac8afd703cd726b63a --- /dev/null +++ b/interfaces/innerkits/native/i_distributedfile_service.h @@ -0,0 +1,60 @@ +/* + * 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 + enum DistributedFileSurfaceCode { + INTERFACE1 = 0, + GET_BUNDLE_DISTRIBUTED_DIR, + REMOVE_BUNDLE_DISTRIBUTED_DIRS, + }; + // define the error code + enum { + DISTRIBUTEDFILE_SUCCESS = 0, + GET_DISTRIBUTEDFILE_DISTRIBUTED_DIR_FAIL = 1, + 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, + }; + // define business functions + virtual int32_t GetBundleDistributedDir(const std::string &dirName) = 0; + virtual int32_t RemoveBundleDistributedDirs(const std::string &dirName) = 0; +}; +} // 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..6b8b2cf566673541d824b8d627ed9aab075fd647 --- /dev/null +++ b/services/4902.xml @@ -0,0 +1,30 @@ + + + + distributedfile + + 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..44e648c2e2c12b71a5c22eb5faa51ac822ca0175 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 distributedfile" + ] + },{ + "name" : "init", + "cmds" : [ + "mount tmpfs tmpfs /mnt" + ] + }], + "services": [{ + "name": "distributedfile", + "path": ["/system/bin/sa_main", "/system/profile/distributedfile.xml"], + "uid": "root", + "gid": ["root", "system", "shell", "readproc", "media_rw", "inet"], + "caps": ["SYS_PTRACE", "KILL"] + },{ + "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"] + }] +} 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..76052c4929896aa97d15a744f18ca78c3899796f 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..002e7063c1379ed4637697d9b0ea7478e73c8b19 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..917ea77b043efcb4eaa1166162b96a14eb936adc 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()); } - + LOGE("Umount begin"); smp->Umount(); - DeviceManagerAgent::GetInstance()->QuitGroup(smp); + auto dm = DeviceManagerAgent::GetInstance(); + dm->Recv(make_unique>>(&DeviceManagerAgent::QuitGroup, smp)); mountPoints_.erase(it); + LOGE("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..ec7e4549800b11d75b0a53f7f89d8bd9bada5c17 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.account_; + } } 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()); } + LOGE("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/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..7c6449e47fd9f82e1567885bf2a98b412ef92e29 --- /dev/null +++ b/services/distributedfileservice/include/ipc/distributedfile_service.h @@ -0,0 +1,46 @@ +/* + * 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; + + int32_t GetBundleDistributedDir(const std::string &dirName) override; + int32_t RemoveBundleDistributedDirs(const std::string &dirName) 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..0b5218b58384a5e1e5d4b145f3fe367d148e84f8 --- /dev/null +++ b/services/distributedfileservice/include/ipc/distributedfile_service_stub.h @@ -0,0 +1,47 @@ +/* + * 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_; + + int32_t GetBundleDistributedDirInner(MessageParcel &data, MessageParcel &reply); + int32_t RemoveBundleDistributedDirsInner(MessageParcel &data, MessageParcel &reply); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // DISTRIBUTEDFILE_SERVICE_STUB_H \ No newline at end of file diff --git a/services/distributedfileservice/src/ipc/distributedfile_service.cpp b/services/distributedfileservice/src/ipc/distributedfile_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2840d1e42c97f76f8b872b8670eb82e999a26cc --- /dev/null +++ b/services/distributedfileservice/src/ipc/distributedfile_service.cpp @@ -0,0 +1,135 @@ +/* + * 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.h" + +#include +#include + +#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 { +using namespace std; +const bool g_registerResult = + SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); + +DistributedFileService::DistributedFileService() : SystemAbility(STORAGE_DISTRIBUTED_FILE_SERVICE_SA_ID, false) {} + +DistributedFileService::~DistributedFileService() {} + +void DistributedFileService::OnDump() +{ + LOGI("OnDump"); +} + +void DistributedFileService::OnStart() +{ + bool ret = SystemAbility::Publish(DelayedSingleton::GetInstance().get()); + if (!ret) { + LOGE("Leave, publishing DistributedFileService failed!"); + return; + } +} + +void DistributedFileService::OnStop() +{ + LOGI("DistributedFileService::OnStop start"); +} + +int32_t DistributedFileService::GetBundleDistributedDir(const std::string &dirName) +{ + std::string path = dirName; + if (path.empty()) { + LOGE("DistributedFileService-%{public}s: Failed to get app dir, error: invalid app name", __func__); + return DISTRIBUTEDFILE_DIR_NAME_IS_EMPTY; + } + + sptr systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityMgr == nullptr) { + LOGE("BundleService Get ISystemAbilityManager failed ... \n"); + return DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL; + } + + sptr remote = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (remote == nullptr) { + LOGE("BundleService Get IRemoteObject failed ... \n"); + return DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL; + } + + int callingUid = IPCSkeleton::GetCallingUid(); + auto BundleMgrService = std::make_unique(remote); + if (BundleMgrService.get() == nullptr) { + LOGE("remote iface_cast BundleMgrService failed ... %{public}s\n", strerror(errno)); + return DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL; + } + + int32_t uid = BundleMgrService->GetUidByBundleName(path, callingUid); + if (uid < 0) { + LOGE("DistributedFileService-%{public}s: Failed to get uid", __func__); + return DISTRIBUTEDFILE_NAME_NOT_FOUND; + } + + if (callingUid != 0) { + if (uid != callingUid) { + LOGE("DistributedFileService-%{public}s: Bundle failed to create dir", __func__); + return DISTRIBUTEDFILE_PERMISSION_DENIED; + } + } + + LOGI("DistributedFileService::GetBundleDistributedDir path : %{public}s", path.c_str()); + Utils::ForceCreateDirectory(path); + return DISTRIBUTEDFILE_SUCCESS; +} + +int32_t DistributedFileService::RemoveBundleDistributedDirs(const std::string &dirName) +{ + std::string path = dirName; + if (path.empty()) { + LOGE("DistributedFileService-%{public}s: Failed to get app dir, error: invalid app name", __func__); + return DISTRIBUTEDFILE_DIR_NAME_IS_EMPTY; + } + + sptr systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityMgr == nullptr) { + LOGE("BundleService Get ISystemAbilityManager failed ... \n"); + return DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL; + } + + sptr remote = systemAbilityMgr->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (remote == nullptr) { + LOGE("BundleService Get IRemoteObject failed ... \n"); + return DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL; + } + + auto BundleMgrService = std::make_unique(remote); + if (BundleMgrService.get() == nullptr) { + LOGE("remote iface_cast BundleMgrService failed ... \n"); + return DISTRIBUTEDFILE_REMOTE_ADDRESS_IS_NULL; + } + + Utils::ForceRemoveDirectory(path); + return DISTRIBUTEDFILE_SUCCESS; +} +} // namespace DistributedFile +} // namespace Storage +} // 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..b0ad8d0d91c8295043f55a7301dd3ae170576f39 --- /dev/null +++ b/services/distributedfileservice/src/ipc/distributedfile_service_stub.cpp @@ -0,0 +1,95 @@ +/* + * 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() +{ + memberFuncMap_[GET_BUNDLE_DISTRIBUTED_DIR] = &DistributedFileServiceStub::GetBundleDistributedDirInner; + memberFuncMap_[REMOVE_BUNDLE_DISTRIBUTED_DIRS] = &DistributedFileServiceStub::RemoveBundleDistributedDirsInner; +} + +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); +} + +int32_t DistributedFileServiceStub::GetBundleDistributedDirInner(MessageParcel &data, MessageParcel &reply) +{ + std::string dirName = data.ReadString(); + if (dirName.empty()) { + LOGE("DistributedFileService-%{public}s: Failed to get app dir, error: invalid app name", __func__); + return DISTRIBUTEDFILE_DIR_NAME_IS_EMPTY; + } + + int32_t result = GetBundleDistributedDir(dirName); + LOGD("DistributedFileServiceStub : GetBundleDistributedDir result = %{public}d", result); + if (!reply.WriteInt32(result)) { + LOGE("fail to write parcel"); + return DISTRIBUTEDFILE_WRITE_REPLY_FAIL; + } + + return result; +} + +int32_t DistributedFileServiceStub::RemoveBundleDistributedDirsInner(MessageParcel &data, MessageParcel &reply) +{ + std::string dirName = data.ReadString(); + if (dirName.empty()) { + LOGE("DistributedFileServiceStub : Failed to get app dir, error: invalid dir name"); + return DISTRIBUTEDFILE_DIR_NAME_IS_EMPTY; + } + + int32_t result = RemoveBundleDistributedDirs(dirName); + if (!reply.WriteInt32(result)) { + LOGE("fail to write parcel"); + return DISTRIBUTEDFILE_WRITE_REPLY_FAIL; + } + + return result; +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/test/moduletest/src/distributedfiledeamon_service_test.cpp b/test/moduletest/src/distributedfiledaemon_service_test.cpp similarity index 88% rename from test/moduletest/src/distributedfiledeamon_service_test.cpp rename to test/moduletest/src/distributedfiledaemon_service_test.cpp index 7329e67d835d1415c250bab87b5c547a85509a42..14bf160c6dd825f16908d29217604fa4996ea04c 100644 --- a/test/moduletest/src/distributedfiledeamon_service_test.cpp +++ b/test/moduletest/src/distributedfiledaemon_service_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 @@ -65,9 +65,10 @@ void DistributedFileDaemonServiceTest::TearDown(void) */ HWTEST_F(DistributedFileDaemonServiceTest, mount_umount_test_001, TestSize.Level1) { - auto mp = make_unique(OHOS::DistributedFile::Utils::MountArgumentDescriptors::Alpha(9527)); + auto mp = make_unique( + OHOS::Storage::DistributedFile::Utils::MountArgumentDescriptors::Alpha(9527)); - shared_ptr smp = move(mp); + shared_ptr smp = move(mp); try { smp->Mount(); 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..6b36132e35d1d8b19d026918f6d5265a16bafed5 100644 --- a/utils/system/include/utils_mount_argument.h +++ b/utils/system/include/utils_mount_argument.h @@ -24,7 +24,7 @@ namespace DistributedFile { namespace Utils { struct MountArgument final { int userId_{0}; - + bool accountless_{false}; std::string account_; bool needInitDir_{false}; bool useCache_{false}; @@ -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..cc29e3fabf7a965942851cbaaf672554c8ba59ad 100644 --- a/utils/system/src/utils_mount_argument.cpp +++ b/utils/system/src/utils_mount_argument.cpp @@ -27,21 +27,33 @@ using namespace std; string MountArgument::GetFullSrc() const { stringstream ss; - ss << "/data/misc_ce/" << userId_ << "/hmdfs/storage"; + if (!accountless_) { + ss << "/data/misc_ce/" << userId_ << "/hmdfs/storage"; + } else { + ss << "/data/misc_ce/" << userId_ << "/hmdfs/auth_groups/" << account_; + } return ss.str(); } string MountArgument::GetFullDst() const { stringstream ss; - ss << "/mnt/hmdfs/" << userId_ << "/"; + if (!accountless_) { + ss << "/mnt/hmdfs/" << userId_ << "/"; + } else { + ss << "/mnt/hmdfs/auth_groups/" << account_ << "/"; + } return ss.str(); } string MountArgument::GetCachePath() const { stringstream ss; - ss << "/data/misc_ce/" << userId_ << "/hmdfs/cache/"; + if (!accountless_) { + ss << "/data/misc_ce/" << userId_ << "/hmdfs/cache/"; + } else { + ss << "/data/misc_ce/" << userId_ << "/hmdfs/auth_groups/" << account_ << "/cache/"; + } return ss.str(); } @@ -109,6 +121,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, + .account_ = 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