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