• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #include "disk/disk_manager.h"
17 
18 #include <sys/sysmacros.h>
19 #include <thread>
20 
21 #include "ipc/storage_manager_client.h"
22 #include "storage_service_errno.h"
23 #include "storage_service_log.h"
24 #include "utils/disk_utils.h"
25 #include "utils/file_utils.h"
26 #include "utils/string_utils.h"
27 
28 namespace OHOS {
29 namespace StorageDaemon {
30 DiskManager* DiskManager::instance_ = nullptr;
31 
Instance()32 DiskManager* DiskManager::Instance()
33 {
34     if (instance_ == nullptr) {
35         instance_ = new DiskManager();
36     }
37 
38     return instance_;
39 }
40 
~DiskManager()41 DiskManager::~DiskManager()
42 {
43     LOGI("Destroy DiskManager");
44 }
45 
HandleDiskEvent(NetlinkData * data)46 void DiskManager::HandleDiskEvent(NetlinkData *data)
47 {
48     std::lock_guard<std::mutex> lock(lock_);
49     std::string devType = data->GetParam("DEVTYPE");
50     if (devType != "disk") {
51         return;
52     }
53 
54     unsigned int major = (unsigned int) std::stoi(data->GetParam("MAJOR"));
55     unsigned int minor = (unsigned int) std::stoi(data->GetParam("MINOR"));
56     dev_t device = makedev(major, minor);
57 
58     switch (data->GetAction()) {
59         case NetlinkData::Actions::ADD: {
60             auto diskInfo = MatchConfig(data);
61             if (diskInfo == nullptr) {
62                 LOGE("Can't match config");
63             } else {
64                 CreateDisk(diskInfo);
65                 LOGI("Handle Disk Add Event");
66             }
67             break;
68         }
69         case NetlinkData::Actions::CHANGE: {
70             ChangeDisk(device);
71             LOGI("Handle Disk Change Event");
72             break;
73         }
74         case NetlinkData::Actions::REMOVE: {
75             DestroyDisk(device);
76             LOGI("Handle Disk Remove Event");
77             break;
78         }
79         default: {
80             LOGW("Cannot handle unexpected disk event %{public}d", data->GetAction());
81             break;
82         }
83     }
84 }
85 
MatchConfig(NetlinkData * data)86 std::shared_ptr<DiskInfo> DiskManager::MatchConfig(NetlinkData *data)
87 {
88     std::string sysPath = data->GetSyspath();
89     std::string devPath = data->GetDevpath();
90     unsigned int major = (unsigned int) std::stoi(data->GetParam("MAJOR"));
91     unsigned int minor = (unsigned int) std::stoi(data->GetParam("MINOR"));
92     dev_t device = makedev(major, minor);
93 
94     for (auto config : diskConfig_) {
95         if (config->IsMatch(devPath)) {
96             uint32_t flag = static_cast<uint32_t>(config->GetFlag());
97             if (major == DISK_MMC_MAJOR) {
98                 flag |= DiskInfo::DeviceFlag::SD_FLAG;
99             } else {
100                 flag |= DiskInfo::DeviceFlag::USB_FLAG;
101             }
102             auto diskInfo =  std::make_shared<DiskInfo>(sysPath, devPath, device, static_cast<int>(flag));
103             return diskInfo;
104         }
105     }
106 
107     return nullptr;
108 }
109 
CreateDisk(std::shared_ptr<DiskInfo> & diskInfo)110 void DiskManager::CreateDisk(std::shared_ptr<DiskInfo> &diskInfo)
111 {
112     int ret;
113 
114     ret = diskInfo->Create();
115     if (ret != E_OK) {
116         LOGE("Create DiskInfo failed");
117         return;
118     }
119 
120     disk_.push_back(diskInfo);
121 }
122 
ChangeDisk(dev_t device)123 void DiskManager::ChangeDisk(dev_t device)
124 {
125     for (auto &diskInfo : disk_) {
126         if (diskInfo->GetDevice() == device) {
127             diskInfo->ReadMetadata();
128             diskInfo->ReadPartition();
129         }
130     }
131 }
132 
DestroyDisk(dev_t device)133 void DiskManager::DestroyDisk(dev_t device)
134 {
135     int ret;
136 
137     for (auto i = disk_.begin(); i != disk_.end();) {
138         if ((*i)->GetDevice() == device) {
139             ret = (*i)->Destroy();
140             if (ret != E_OK) {
141                 LOGE("Destroy DiskInfo failed");
142                 return;
143             }
144 
145             StorageManagerClient client;
146             ret = client.NotifyDiskDestroyed((*i)->GetId());
147             if (ret != E_OK) {
148                 LOGI("Notify Disk Destroyed failed");
149             }
150             i = disk_.erase(i);
151         } else {
152             i++;
153         }
154     }
155 }
156 
GetDisk(dev_t device)157 std::shared_ptr<DiskInfo> DiskManager::GetDisk(dev_t device)
158 {
159     for (auto &diskInfo : disk_) {
160         if (diskInfo->GetDevice() == device) {
161             return diskInfo;
162         }
163     }
164     return nullptr;
165 }
166 
AddDiskConfig(std::shared_ptr<DiskConfig> & diskConfig)167 void DiskManager::AddDiskConfig(std::shared_ptr<DiskConfig> &diskConfig)
168 {
169     std::lock_guard<std::mutex> lock(lock_);
170     diskConfig_.push_back(diskConfig);
171 }
172 
ReplayUevent()173 void DiskManager::ReplayUevent()
174 {
175     TraverseDirUevent(sysBlockPath_, true);
176 }
177 
HandlePartition(std::string diskId)178 int32_t DiskManager::HandlePartition(std::string diskId)
179 {
180     int32_t ret = E_NON_EXIST;
181 
182     for (auto i = disk_.begin(); i != disk_.end(); i++) {
183         if ((*i)->GetId() == diskId) {
184             ret = (*i)->Partition();
185             break;
186         }
187     }
188 
189     return ret;
190 }
191 } // namespace STORAGE_DAEMON
192 } // namespace OHOS
193