• 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 <thread>
19 
20 #include <sys/sysmacros.h>
21 
22 #include "storage_service_errno.h"
23 #include "storage_service_log.h"
24 #include "utils/string_utils.h"
25 #include "utils/file_utils.h"
26 #include "utils/disk_utils.h"
27 #include "ipc/storage_manager_client.h"
28 
29 namespace OHOS {
30 namespace StorageDaemon {
31 DiskManager* DiskManager::instance_ = nullptr;
32 
Instance()33 DiskManager* DiskManager::Instance()
34 {
35     if (instance_ == nullptr) {
36         instance_ = new DiskManager();
37     }
38 
39     return instance_;
40 }
41 
~DiskManager()42 DiskManager::~DiskManager()
43 {
44     LOGI("Destroy DiskManager");
45 }
46 
HandleDiskEvent(NetlinkData * data)47 void DiskManager::HandleDiskEvent(NetlinkData *data)
48 {
49     std::lock_guard<std::mutex> lock(lock_);
50     std::string devType = data->GetParam("DEVTYPE");
51     if (devType != "disk") {
52         return;
53     }
54 
55     unsigned int major = (unsigned int) std::stoi(data->GetParam("MAJOR"));
56     unsigned int minor = (unsigned int) std::stoi(data->GetParam("MINOR"));
57     dev_t device = makedev(major, minor);
58 
59     switch (data->GetAction()) {
60         case NetlinkData::Actions::ADD: {
61             auto diskInfo = MatchConfig(data);
62             if (diskInfo == nullptr) {
63                 LOGE("Can't match config");
64             } else {
65                 CreateDisk(diskInfo);
66                 LOGI("Handle Disk Add Event");
67             }
68             break;
69         }
70         case NetlinkData::Actions::CHANGE: {
71             ChangeDisk(device);
72             LOGI("Handle Disk Change Event");
73             break;
74         }
75         case NetlinkData::Actions::REMOVE: {
76             DestroyDisk(device);
77             LOGI("Handle Disk Remove Event");
78             break;
79         }
80         default: {
81             LOGW("Cannot handle unexpected disk event %{public}d", data->GetAction());
82             break;
83         }
84     }
85 }
86 
MatchConfig(NetlinkData * data)87 std::shared_ptr<DiskInfo> DiskManager::MatchConfig(NetlinkData *data)
88 {
89     std::string sysPath = data->GetSyspath();
90     std::string devPath = data->GetDevpath();
91     unsigned int major = (unsigned int) std::stoi(data->GetParam("MAJOR"));
92     unsigned int minor = (unsigned int) std::stoi(data->GetParam("MINOR"));
93     dev_t device = makedev(major, minor);
94 
95     for (auto config : diskConfig_) {
96         if (config->IsMatch(devPath)) {
97             int flag = config->GetFlag();
98             if (major == DISK_MMC_MAJOR) {
99             flag |= DiskInfo::DeviceFlag::SD_FLAG;
100             } else {
101             flag |= DiskInfo::DeviceFlag::USB_FLAG;
102             }
103             auto diskInfo =  std::make_shared<DiskInfo>(sysPath, devPath, device, flag);
104             return diskInfo;
105         }
106     }
107 
108     return nullptr;
109 }
110 
CreateDisk(std::shared_ptr<DiskInfo> & diskInfo)111 void DiskManager::CreateDisk(std::shared_ptr<DiskInfo> &diskInfo)
112 {
113     int ret;
114 
115     ret = diskInfo->Create();
116     if (ret != E_OK) {
117         LOGE("Create DiskInfo failed");
118         return;
119     }
120 
121     disk_.push_back(diskInfo);
122 }
123 
ChangeDisk(dev_t device)124 void DiskManager::ChangeDisk(dev_t device)
125 {
126     for (auto &diskInfo : disk_) {
127         if (diskInfo->GetDevice() == device) {
128             diskInfo->ReadMetadata();
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