1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef KERNEL_TALKER_H
16 #define KERNEL_TALKER_H
17 
18 #include <atomic>
19 #include <fcntl.h>
20 #include <functional>
21 #include <memory>
22 #include <mutex>
23 #include <poll.h>
24 #include <thread>
25 #include <unistd.h>
26 #include <unordered_set>
27 
28 #include "mountpoint/mount_point.h"
29 #include "network/base_session.h"
30 #include "utils_log.h"
31 
32 namespace OHOS {
33 namespace Storage {
34 namespace DistributedFile {
35 constexpr int CID_MAX_LEN = 64;
36 struct NotifyParam {
37     int32_t notify;
38     int32_t fd;
39     char remoteCid[CID_MAX_LEN];
40 } __attribute__((packed));
41 
42 class KernelTalker final : protected NoCopyable, public std::enable_shared_from_this<KernelTalker> {
43 public:
KernelTalker(std::weak_ptr<MountPoint> mountPoint,std::function<void (NotifyParam &)> getSessionCallback,std::function<void (const std::string &)> closeSessionCallback)44     explicit KernelTalker(std::weak_ptr<MountPoint> mountPoint,
45                           std::function<void(NotifyParam &)> getSessionCallback,
46                           std::function<void(const std::string &)> closeSessionCallback)
47         : mountPoint_(mountPoint), GetSessionCallback_(getSessionCallback), CloseSessionCallback_(closeSessionCallback)
48     {
49     }
50     KernelTalker() = default;
51     ~KernelTalker() = default;
52 
53     void SinkSessionTokernel(std::shared_ptr<BaseSession> session, const std::string backStage);
54     void SinkDevslTokernel(const std::string &cid, uint32_t devsl);
55     void SinkOfflineCmdToKernel(std::string cid);
56 
57     void CreatePollThread();
58     void WaitForPollThreadExited();
59 
60 private:
61     template<typename T>
SetCmd(T & cmd)62     void SetCmd(T &cmd)
63     {
64         auto spt = mountPoint_.lock();
65         if (spt == nullptr) {
66             LOGE("mountPoint is not exist! bad weak_ptr");
67             return;
68         }
69         std::string ctrlPath = spt->GetMountArgument().GetCtrlPath();
70         LOGI("cmd path:%{public}s", GetAnonyString(ctrlPath).c_str());
71         std::lock_guard<std::mutex> lock(cmdMutex_);
72         char resolvedPath[PATH_MAX] = {'\0'};
73         char *realPath = realpath(ctrlPath.c_str(), resolvedPath);
74         if (realPath == nullptr) {
75             return;
76         }
77 
78         int file = open(realPath, O_RDWR);
79         if (file < 0) {
80             LOGE("Open node file error. %{public}d", errno);
81             return;
82         }
83         int err = write(file, &cmd, sizeof(T));
84         if (err < 0) {
85             LOGE("write return err. %{public}d", errno);
86         }
87         close(file);
88     }
89 
90     void PollRun();
91     void HandleAllNotify(int fd);
92     void NotifyHandler(NotifyParam &param);
93 
94     std::weak_ptr<MountPoint> mountPoint_;
95     std::mutex cmdMutex_;
96     std::atomic<bool> isRunning_ {true};
97     std::unique_ptr<std::thread> pollThread_ {nullptr};
98     std::function<void(NotifyParam &)> GetSessionCallback_ {nullptr};
99     std::function<void(const std::string &cid)> CloseSessionCallback_ {nullptr};
100 };
101 } // namespace DistributedFile
102 } // namespace Storage
103 } // namespace OHOS
104 #endif // KERNEL_TALKER_H