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