/* * Copyright (c) 2021-2024 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 KERNEL_TALKER_H #define KERNEL_TALKER_H #include <atomic> #include <fcntl.h> #include <functional> #include <memory> #include <mutex> #include <poll.h> #include <thread> #include <unistd.h> #include <unordered_set> #include "mountpoint/mount_point.h" #include "network/base_session.h" #include "utils_log.h" namespace OHOS { namespace Storage { namespace DistributedFile { constexpr int CID_MAX_LEN = 64; struct NotifyParam { int32_t notify; int32_t fd; char remoteCid[CID_MAX_LEN]; } __attribute__((packed)); class KernelTalker final : protected NoCopyable, public std::enable_shared_from_this<KernelTalker> { public: explicit KernelTalker(std::weak_ptr<MountPoint> mountPoint, std::function<void(NotifyParam &)> getSessionCallback, std::function<void(const std::string &)> closeSessionCallback) : mountPoint_(mountPoint), GetSessionCallback_(getSessionCallback), CloseSessionCallback_(closeSessionCallback) { } KernelTalker() = default; ~KernelTalker() = default; void SinkSessionTokernel(std::shared_ptr<BaseSession> session, const std::string backStage); void SinkDevslTokernel(const std::string &cid, uint32_t devsl); void SinkOfflineCmdToKernel(std::string cid); void CreatePollThread(); void WaitForPollThreadExited(); private: template<typename T> void SetCmd(T &cmd) { auto spt = mountPoint_.lock(); if (spt == nullptr) { LOGE("mountPoint is not exist! bad weak_ptr"); return; } std::string ctrlPath = spt->GetMountArgument().GetCtrlPath(); LOGI("cmd path:%{public}s", GetAnonyString(ctrlPath).c_str()); std::lock_guard<std::mutex> lock(cmdMutex_); char resolvedPath[PATH_MAX] = {'\0'}; char *realPath = realpath(ctrlPath.c_str(), resolvedPath); if (realPath == nullptr) { return; } int file = open(realPath, O_RDWR); if (file < 0) { LOGE("Open node file error. %{public}d", errno); return; } int err = write(file, &cmd, sizeof(T)); if (err < 0) { LOGE("write return err. %{public}d", errno); } close(file); } void PollRun(); void HandleAllNotify(int fd); void NotifyHandler(NotifyParam ¶m); std::weak_ptr<MountPoint> mountPoint_; std::mutex cmdMutex_; std::atomic<bool> isRunning_ {true}; std::unique_ptr<std::thread> pollThread_ {nullptr}; std::function<void(NotifyParam &)> GetSessionCallback_ {nullptr}; std::function<void(const std::string &cid)> CloseSessionCallback_ {nullptr}; }; } // namespace DistributedFile } // namespace Storage } // namespace OHOS #endif // KERNEL_TALKER_H