1fb299fa2Sopenharmony_ci/*
2fb299fa2Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at
6fb299fa2Sopenharmony_ci *
7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8fb299fa2Sopenharmony_ci *
9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and
13fb299fa2Sopenharmony_ci * limitations under the License.
14fb299fa2Sopenharmony_ci */
15fb299fa2Sopenharmony_ci#include "fs_manager/partitions.h"
16fb299fa2Sopenharmony_ci#include <cstdlib>
17fb299fa2Sopenharmony_ci#include <string>
18fb299fa2Sopenharmony_ci#include <sys/stat.h>
19fb299fa2Sopenharmony_ci#include <sys/sysmacros.h>
20fb299fa2Sopenharmony_ci#include <unistd.h>
21fb299fa2Sopenharmony_ci#include "log/log.h"
22fb299fa2Sopenharmony_ci#include "partition_const.h"
23fb299fa2Sopenharmony_ci#include "scope_guard.h"
24fb299fa2Sopenharmony_ci#include "securec.h"
25fb299fa2Sopenharmony_ci
26fb299fa2Sopenharmony_cinamespace Updater {
27fb299fa2Sopenharmony_cistatic struct Disk *g_disks;
28fb299fa2Sopenharmony_cistatic int DeviceStat(const BlockDevice &dev, struct stat &devStat)
29fb299fa2Sopenharmony_ci{
30fb299fa2Sopenharmony_ci    int ret = 0;
31fb299fa2Sopenharmony_ci    if (!stat (dev.devPath.c_str(), &devStat)) {
32fb299fa2Sopenharmony_ci        ret = 1;
33fb299fa2Sopenharmony_ci    }
34fb299fa2Sopenharmony_ci    if (stat (dev.devPath.c_str(), &devStat) != EOK) {
35fb299fa2Sopenharmony_ci        LOG(ERROR) << "stat error: " << errno << std::endl;
36fb299fa2Sopenharmony_ci        ret = 0;
37fb299fa2Sopenharmony_ci    }
38fb299fa2Sopenharmony_ci    return ret;
39fb299fa2Sopenharmony_ci}
40fb299fa2Sopenharmony_ci
41fb299fa2Sopenharmony_cistatic int DeviceProbeType(BlockDevice &dev)
42fb299fa2Sopenharmony_ci{
43fb299fa2Sopenharmony_ci    struct stat devStat {};
44fb299fa2Sopenharmony_ci    int devMajor;
45fb299fa2Sopenharmony_ci    int devMinor;
46fb299fa2Sopenharmony_ci    BlockSpecific *specific = BLOCK_SPECIFIC(&dev);
47fb299fa2Sopenharmony_ci    if (DeviceStat(dev, devStat) == 0) {
48fb299fa2Sopenharmony_ci        return 0;
49fb299fa2Sopenharmony_ci    }
50fb299fa2Sopenharmony_ci
51fb299fa2Sopenharmony_ci    devMajor = static_cast<int>(major (devStat.st_rdev));
52fb299fa2Sopenharmony_ci    specific->major = devMajor;
53fb299fa2Sopenharmony_ci    devMinor = static_cast<int>(minor (devStat.st_rdev));
54fb299fa2Sopenharmony_ci    specific->minor = devMinor;
55fb299fa2Sopenharmony_ci    bool a1 = SCSI_BLK_MAJOR(devMajor) && (devMinor % 0x10 == 0);
56fb299fa2Sopenharmony_ci    bool a2 = devMajor == SDMMC_MAJOR && (devMinor % 0x08 == 0);
57fb299fa2Sopenharmony_ci    if (a1) {
58fb299fa2Sopenharmony_ci        dev.type = DEVICE_SCSI;
59fb299fa2Sopenharmony_ci    }
60fb299fa2Sopenharmony_ci    if (a2) {
61fb299fa2Sopenharmony_ci        dev.type = DEVICE_EMMC;
62fb299fa2Sopenharmony_ci    }
63fb299fa2Sopenharmony_ci    if (!a1 && !a2) {
64fb299fa2Sopenharmony_ci        dev.type = DEVICE_UNKNOWN;
65fb299fa2Sopenharmony_ci    }
66fb299fa2Sopenharmony_ci    return 1;
67fb299fa2Sopenharmony_ci}
68fb299fa2Sopenharmony_ci
69fb299fa2Sopenharmony_cistatic std::string LastComponent(const std::string &path)
70fb299fa2Sopenharmony_ci{
71fb299fa2Sopenharmony_ci    std::string tmp = "";
72fb299fa2Sopenharmony_ci    if (path == MMC_PATH) {
73fb299fa2Sopenharmony_ci        tmp = MMC_DEV;
74fb299fa2Sopenharmony_ci    }
75fb299fa2Sopenharmony_ci    if (path == SDA_PATH) {
76fb299fa2Sopenharmony_ci        tmp = SDA_DEV;
77fb299fa2Sopenharmony_ci    }
78fb299fa2Sopenharmony_ci    if (path == SDB_PATH) {
79fb299fa2Sopenharmony_ci        tmp = SDB_DEV;
80fb299fa2Sopenharmony_ci    }
81fb299fa2Sopenharmony_ci    return tmp;
82fb299fa2Sopenharmony_ci}
83fb299fa2Sopenharmony_ci
84fb299fa2Sopenharmony_cistatic bool ReadDeviceSysfsFile(BlockDevice &dev, const std::string &file, std::string &strl)
85fb299fa2Sopenharmony_ci{
86fb299fa2Sopenharmony_ci    FILE *f = nullptr;
87fb299fa2Sopenharmony_ci    char nameBuf[DEVPATH_SIZE];
88fb299fa2Sopenharmony_ci    char buf[BUFFER_SIZE];
89fb299fa2Sopenharmony_ci
90fb299fa2Sopenharmony_ci    if (snprintf_s(nameBuf, DEVPATH_SIZE, DEVPATH_SIZE - 1, "/sys/block/%s/device/%s",
91fb299fa2Sopenharmony_ci        LastComponent(dev.devPath).c_str(), file.c_str()) == -1) {
92fb299fa2Sopenharmony_ci        return false;
93fb299fa2Sopenharmony_ci    }
94fb299fa2Sopenharmony_ci    char realPath[PATH_MAX] = {0};
95fb299fa2Sopenharmony_ci    if (realpath(nameBuf, realPath) == nullptr) {
96fb299fa2Sopenharmony_ci        return false;
97fb299fa2Sopenharmony_ci    }
98fb299fa2Sopenharmony_ci    if ((f = fopen(realPath, "r")) == nullptr) {
99fb299fa2Sopenharmony_ci        return false;
100fb299fa2Sopenharmony_ci    }
101fb299fa2Sopenharmony_ci
102fb299fa2Sopenharmony_ci    if (fgets(buf, BUFFER_SIZE, f) == nullptr) {
103fb299fa2Sopenharmony_ci        fclose(f);
104fb299fa2Sopenharmony_ci        return false;
105fb299fa2Sopenharmony_ci    }
106fb299fa2Sopenharmony_ci    strl = buf;
107fb299fa2Sopenharmony_ci    fclose(f);
108fb299fa2Sopenharmony_ci    return true;
109fb299fa2Sopenharmony_ci}
110fb299fa2Sopenharmony_ci
111fb299fa2Sopenharmony_cistatic bool SdmmcGetProductInfo(BlockDevice &dev, std::string &type, std::string &name)
112fb299fa2Sopenharmony_ci{
113fb299fa2Sopenharmony_ci    std::string typeStr = "type";
114fb299fa2Sopenharmony_ci    std::string nameStr = "name";
115fb299fa2Sopenharmony_ci
116fb299fa2Sopenharmony_ci    bool ret = ReadDeviceSysfsFile(dev, typeStr, type);
117fb299fa2Sopenharmony_ci    bool red = ReadDeviceSysfsFile(dev, nameStr, name);
118fb299fa2Sopenharmony_ci    return (ret || red);
119fb299fa2Sopenharmony_ci}
120fb299fa2Sopenharmony_ci
121fb299fa2Sopenharmony_cibool SetBlockDeviceMode(BlockDevice &dev)
122fb299fa2Sopenharmony_ci{
123fb299fa2Sopenharmony_ci    BlockSpecific *specific = BLOCK_SPECIFIC(&dev);
124fb299fa2Sopenharmony_ci
125fb299fa2Sopenharmony_ci    specific->fd = open(dev.devPath.c_str(), RW_MODE);
126fb299fa2Sopenharmony_ci    if (specific->fd == -1) {
127fb299fa2Sopenharmony_ci        LOG(WARNING) << "Open " << dev.devPath << " with read-write failed, try read-only mode";
128fb299fa2Sopenharmony_ci        specific->fd = open(dev.devPath.c_str(), RD_MODE);
129fb299fa2Sopenharmony_ci        bool a1 = dev.readOnly;
130fb299fa2Sopenharmony_ci        dev.readOnly = 1;
131fb299fa2Sopenharmony_ci        if (specific->fd == -1) {
132fb299fa2Sopenharmony_ci            LOG(ERROR) << "Open " << dev.devPath << " with read-only mode failed: " << errno;
133fb299fa2Sopenharmony_ci            dev.readOnly = a1;
134fb299fa2Sopenharmony_ci            return false;
135fb299fa2Sopenharmony_ci        }
136fb299fa2Sopenharmony_ci    } else {
137fb299fa2Sopenharmony_ci        dev.readOnly = 0;
138fb299fa2Sopenharmony_ci    }
139fb299fa2Sopenharmony_ci    return true;
140fb299fa2Sopenharmony_ci}
141fb299fa2Sopenharmony_ci
142fb299fa2Sopenharmony_cistatic int BlockDeviceClose(const BlockDevice &dev)
143fb299fa2Sopenharmony_ci{
144fb299fa2Sopenharmony_ci    BlockSpecific* specific = BLOCK_SPECIFIC(&dev);
145fb299fa2Sopenharmony_ci    if (fsync(specific->fd) < 0 || close(specific->fd) < 0) {
146fb299fa2Sopenharmony_ci        return 0;
147fb299fa2Sopenharmony_ci    }
148fb299fa2Sopenharmony_ci    return 1;
149fb299fa2Sopenharmony_ci}
150fb299fa2Sopenharmony_ci
151fb299fa2Sopenharmony_cistatic std::string ReadPartitionFromSys(const std::string &devname, const std::string &partn,
152fb299fa2Sopenharmony_ci    const std::string &type, const std::string &table)
153fb299fa2Sopenharmony_ci{
154fb299fa2Sopenharmony_ci    FILE *f = nullptr;
155fb299fa2Sopenharmony_ci    char buf[BUFFER_SIZE] = {0};
156fb299fa2Sopenharmony_ci    std::string devPath;
157fb299fa2Sopenharmony_ci    std::string partString = "";
158fb299fa2Sopenharmony_ci    devPath = "/sys/block/" + devname + "/" + partn + "/" + type;
159fb299fa2Sopenharmony_ci    if (partn.empty()) {
160fb299fa2Sopenharmony_ci        devPath = "/sys/block/" + devname + "/" + type;
161fb299fa2Sopenharmony_ci    }
162fb299fa2Sopenharmony_ci
163fb299fa2Sopenharmony_ci    if (devPath.length() >= DEVPATH_SIZE) {
164fb299fa2Sopenharmony_ci        LOG(ERROR) << "devPath is invalid";
165fb299fa2Sopenharmony_ci        return partString;
166fb299fa2Sopenharmony_ci    }
167fb299fa2Sopenharmony_ci
168fb299fa2Sopenharmony_ci    if ((f = fopen(devPath.c_str(), "r")) == nullptr) {
169fb299fa2Sopenharmony_ci        return partString;
170fb299fa2Sopenharmony_ci    }
171fb299fa2Sopenharmony_ci
172fb299fa2Sopenharmony_ci    ON_SCOPE_EXIT(fclosef) {
173fb299fa2Sopenharmony_ci        fclose(f);
174fb299fa2Sopenharmony_ci    };
175fb299fa2Sopenharmony_ci
176fb299fa2Sopenharmony_ci    while (!feof(f)) {
177fb299fa2Sopenharmony_ci        if (fgets(buf, BUFFER_SIZE, f) == nullptr) {
178fb299fa2Sopenharmony_ci            return partString;
179fb299fa2Sopenharmony_ci        }
180fb299fa2Sopenharmony_ci        if (type == "uevent" && strstr(buf, table.c_str()) != nullptr) {
181fb299fa2Sopenharmony_ci            partString = std::string(buf + table.size(), sizeof(buf) - table.size());
182fb299fa2Sopenharmony_ci            if (!partString.empty()) {
183fb299fa2Sopenharmony_ci                partString.pop_back();
184fb299fa2Sopenharmony_ci            }
185fb299fa2Sopenharmony_ci            return partString;
186fb299fa2Sopenharmony_ci        } else if (type == "start" || type == "size") {
187fb299fa2Sopenharmony_ci            partString = std::string(buf, sizeof(buf) - 1);
188fb299fa2Sopenharmony_ci            LOG(INFO) << type << " partInf: " << std::string(buf, sizeof(buf) - 1);
189fb299fa2Sopenharmony_ci            return partString;
190fb299fa2Sopenharmony_ci        }
191fb299fa2Sopenharmony_ci        if (memset_s(buf, sizeof(buf), 0, sizeof(buf)) != EOK) {
192fb299fa2Sopenharmony_ci            return partString;
193fb299fa2Sopenharmony_ci        }
194fb299fa2Sopenharmony_ci    }
195fb299fa2Sopenharmony_ci
196fb299fa2Sopenharmony_ci    return partString;
197fb299fa2Sopenharmony_ci}
198fb299fa2Sopenharmony_ci
199fb299fa2Sopenharmony_cistatic int InitGeneric(BlockDevice &dev, const std::string modelName)
200fb299fa2Sopenharmony_ci{
201fb299fa2Sopenharmony_ci    struct stat devStat {};
202fb299fa2Sopenharmony_ci    if (DeviceStat(dev, devStat) == 0) {
203fb299fa2Sopenharmony_ci        LOG(ERROR) << "device stat error ";
204fb299fa2Sopenharmony_ci        return 0;
205fb299fa2Sopenharmony_ci    }
206fb299fa2Sopenharmony_ci    if (!SetBlockDeviceMode(dev)) {
207fb299fa2Sopenharmony_ci        LOG(ERROR) << "device authority error ";
208fb299fa2Sopenharmony_ci        return 0;
209fb299fa2Sopenharmony_ci    }
210fb299fa2Sopenharmony_ci
211fb299fa2Sopenharmony_ci    const std::string devName = LastComponent(dev.devPath);
212fb299fa2Sopenharmony_ci    std::string partSize = ReadPartitionFromSys(devName, "", "size", "");
213fb299fa2Sopenharmony_ci    if (partSize.empty()) {
214fb299fa2Sopenharmony_ci        return 0;
215fb299fa2Sopenharmony_ci    }
216fb299fa2Sopenharmony_ci    int devSize = atoi(partSize.c_str());
217fb299fa2Sopenharmony_ci    dev.length = devSize;
218fb299fa2Sopenharmony_ci    dev.sectorSize = SECTOR_SIZE_DEFAULT;
219fb299fa2Sopenharmony_ci    dev.physSectorSize = SECTOR_SIZE_DEFAULT;
220fb299fa2Sopenharmony_ci    dev.model = modelName;
221fb299fa2Sopenharmony_ci    BlockDeviceClose (dev);
222fb299fa2Sopenharmony_ci    dev.fd = -1;
223fb299fa2Sopenharmony_ci    return 1;
224fb299fa2Sopenharmony_ci}
225fb299fa2Sopenharmony_ci
226fb299fa2Sopenharmony_cistatic int InitSdmmc(BlockDevice &dev)
227fb299fa2Sopenharmony_ci{
228fb299fa2Sopenharmony_ci    std::string type = "";
229fb299fa2Sopenharmony_ci    std::string name = "";
230fb299fa2Sopenharmony_ci    std::string id = "";
231fb299fa2Sopenharmony_ci    bool a1 = SdmmcGetProductInfo(dev, type, name);
232fb299fa2Sopenharmony_ci    if (a1) {
233fb299fa2Sopenharmony_ci        id = type + name;
234fb299fa2Sopenharmony_ci    }
235fb299fa2Sopenharmony_ci    if (!a1) {
236fb299fa2Sopenharmony_ci        id = "Generic SD/MMC Storage Card";
237fb299fa2Sopenharmony_ci        return 0;
238fb299fa2Sopenharmony_ci    }
239fb299fa2Sopenharmony_ci    return InitGeneric(dev, id);
240fb299fa2Sopenharmony_ci}
241fb299fa2Sopenharmony_ci
242fb299fa2Sopenharmony_cistatic BlockDevice* NewBlockDevice(const std::string &path)
243fb299fa2Sopenharmony_ci{
244fb299fa2Sopenharmony_ci    BlockDevice *dev = nullptr;
245fb299fa2Sopenharmony_ci    BlockSpecific *specific = nullptr;
246fb299fa2Sopenharmony_ci
247fb299fa2Sopenharmony_ci    dev = static_cast<BlockDevice*>(calloc(1, sizeof (BlockDevice)));
248fb299fa2Sopenharmony_ci    if (dev == nullptr) {
249fb299fa2Sopenharmony_ci        LOG(ERROR) << "calloc errno " << errno;
250fb299fa2Sopenharmony_ci        return nullptr;
251fb299fa2Sopenharmony_ci    }
252fb299fa2Sopenharmony_ci
253fb299fa2Sopenharmony_ci    dev->devPath = path;
254fb299fa2Sopenharmony_ci    dev->specific = static_cast<BlockSpecific*>(calloc(1, sizeof (BlockSpecific)));
255fb299fa2Sopenharmony_ci    if (!dev->specific) {
256fb299fa2Sopenharmony_ci        LOG(ERROR) << "calloc errno " << errno;
257fb299fa2Sopenharmony_ci        free(dev);
258fb299fa2Sopenharmony_ci        return nullptr;
259fb299fa2Sopenharmony_ci    }
260fb299fa2Sopenharmony_ci
261fb299fa2Sopenharmony_ci    specific = BLOCK_SPECIFIC(dev);
262fb299fa2Sopenharmony_ci    dev->readOnly = 0;
263fb299fa2Sopenharmony_ci    dev->sectorSize = 0;
264fb299fa2Sopenharmony_ci    dev->physSectorSize = 0;
265fb299fa2Sopenharmony_ci
266fb299fa2Sopenharmony_ci    int ret = 0;
267fb299fa2Sopenharmony_ci    bool a1 = DeviceProbeType(*dev);
268fb299fa2Sopenharmony_ci    if (a1) {
269fb299fa2Sopenharmony_ci        if (dev->type == DEVICE_EMMC)  {
270fb299fa2Sopenharmony_ci            ret = InitSdmmc(*dev);
271fb299fa2Sopenharmony_ci            if (ret == 0) {
272fb299fa2Sopenharmony_ci                LOG(ERROR) << "Init sdmmc error";
273fb299fa2Sopenharmony_ci            }
274fb299fa2Sopenharmony_ci        }
275fb299fa2Sopenharmony_ci        if (dev->type != DEVICE_EMMC) {
276fb299fa2Sopenharmony_ci            LOG(WARNING) << "Unsupported device type";
277fb299fa2Sopenharmony_ci        }
278fb299fa2Sopenharmony_ci    }
279fb299fa2Sopenharmony_ci    if (!a1) {
280fb299fa2Sopenharmony_ci        LOG(ERROR) << "Device probe error";
281fb299fa2Sopenharmony_ci    }
282fb299fa2Sopenharmony_ci
283fb299fa2Sopenharmony_ci    if (ret == 0) {
284fb299fa2Sopenharmony_ci        free(dev->specific);
285fb299fa2Sopenharmony_ci        free(dev);
286fb299fa2Sopenharmony_ci        dev = nullptr;
287fb299fa2Sopenharmony_ci    }
288fb299fa2Sopenharmony_ci    return dev;
289fb299fa2Sopenharmony_ci}
290fb299fa2Sopenharmony_ci
291fb299fa2Sopenharmony_cistatic Disk* NewBlockDisk(const BlockDevice &dev, const DiskType diskType)
292fb299fa2Sopenharmony_ci{
293fb299fa2Sopenharmony_ci    Disk *disk = nullptr;
294fb299fa2Sopenharmony_ci
295fb299fa2Sopenharmony_ci    disk = static_cast<Disk*>(calloc (1, sizeof (Disk)));
296fb299fa2Sopenharmony_ci    if (disk == nullptr) {
297fb299fa2Sopenharmony_ci        LOG(ERROR) << "Allocate memory for disk failed: " << errno;
298fb299fa2Sopenharmony_ci        return nullptr;
299fb299fa2Sopenharmony_ci    }
300fb299fa2Sopenharmony_ci
301fb299fa2Sopenharmony_ci    disk->dev = (BlockDevice*)&dev;
302fb299fa2Sopenharmony_ci    disk->type = diskType;
303fb299fa2Sopenharmony_ci    disk->partsum = 0;
304fb299fa2Sopenharmony_ci    disk->partList.clear();
305fb299fa2Sopenharmony_ci    return disk;
306fb299fa2Sopenharmony_ci}
307fb299fa2Sopenharmony_ci
308fb299fa2Sopenharmony_ciint DiskAlloc(const std::string &path)
309fb299fa2Sopenharmony_ci{
310fb299fa2Sopenharmony_ci    struct Disk *disk = nullptr;
311fb299fa2Sopenharmony_ci    struct BlockDevice *dev = nullptr;
312fb299fa2Sopenharmony_ci    dev = NewBlockDevice(path);
313fb299fa2Sopenharmony_ci    if (dev == nullptr) {
314fb299fa2Sopenharmony_ci        LOG(ERROR) << "NewBlockDevice nullptr ";
315fb299fa2Sopenharmony_ci        return 0;
316fb299fa2Sopenharmony_ci    }
317fb299fa2Sopenharmony_ci
318fb299fa2Sopenharmony_ci    disk = NewBlockDisk(*dev, GPT);
319fb299fa2Sopenharmony_ci    if (disk == nullptr) {
320fb299fa2Sopenharmony_ci        LOG(ERROR) << "NewBlockDevice nullptr ";
321fb299fa2Sopenharmony_ci        return 0;
322fb299fa2Sopenharmony_ci    }
323fb299fa2Sopenharmony_ci    g_disks = disk;
324fb299fa2Sopenharmony_ci    return 1;
325fb299fa2Sopenharmony_ci}
326fb299fa2Sopenharmony_ci
327fb299fa2Sopenharmony_cistatic struct Partition* NewPartition(const BlockDevice &dev, int partn)
328fb299fa2Sopenharmony_ci{
329fb299fa2Sopenharmony_ci    Partition* part = (Partition*) calloc (1, sizeof (Partition));
330fb299fa2Sopenharmony_ci    if (part == nullptr) {
331fb299fa2Sopenharmony_ci        LOG(ERROR) << "Allocate memory for partition failed.";
332fb299fa2Sopenharmony_ci        return nullptr;
333fb299fa2Sopenharmony_ci    }
334fb299fa2Sopenharmony_ci    const std::string devName = LastComponent(dev.devPath);
335fb299fa2Sopenharmony_ci    char partName[64] = {0};
336fb299fa2Sopenharmony_ci    if (devName == MMC_DEV) {
337fb299fa2Sopenharmony_ci        if (snprintf_s(partName, sizeof(partName), sizeof(partName) - 1, "%sp%d", devName.c_str(), partn) == -1) {
338fb299fa2Sopenharmony_ci            free(part);
339fb299fa2Sopenharmony_ci            return nullptr;
340fb299fa2Sopenharmony_ci        }
341fb299fa2Sopenharmony_ci    }
342fb299fa2Sopenharmony_ci    if (devName != MMC_DEV && ((devName == SDA_DEV) || (devName == SDB_DEV)) &&
343fb299fa2Sopenharmony_ci        snprintf_s(partName, sizeof(partName), sizeof(partName) - 1, "%s%d", devName.c_str(), partn) == -1) {
344fb299fa2Sopenharmony_ci        free(part);
345fb299fa2Sopenharmony_ci        return nullptr;
346fb299fa2Sopenharmony_ci    }
347fb299fa2Sopenharmony_ci
348fb299fa2Sopenharmony_ci    std::string strstart = ReadPartitionFromSys(devName, partName, "start", "");
349fb299fa2Sopenharmony_ci    if (strstart.empty()) {
350fb299fa2Sopenharmony_ci        free(part);
351fb299fa2Sopenharmony_ci        return nullptr;
352fb299fa2Sopenharmony_ci    }
353fb299fa2Sopenharmony_ci    part->start = static_cast<size_t>(atoi(strstart.c_str()));
354fb299fa2Sopenharmony_ci
355fb299fa2Sopenharmony_ci    std::string strsize = ReadPartitionFromSys(devName, partName, "size", "");
356fb299fa2Sopenharmony_ci    if (strsize.empty()) {
357fb299fa2Sopenharmony_ci        free(part);
358fb299fa2Sopenharmony_ci        return nullptr;
359fb299fa2Sopenharmony_ci    }
360fb299fa2Sopenharmony_ci    part->length = static_cast<size_t>(atoi(strsize.c_str()));
361fb299fa2Sopenharmony_ci
362fb299fa2Sopenharmony_ci    std::string strdevname = ReadPartitionFromSys(devName, partName, "uevent", "DEVNAME=");
363fb299fa2Sopenharmony_ci    part->devName = partName;
364fb299fa2Sopenharmony_ci    if (!strdevname.empty()) {
365fb299fa2Sopenharmony_ci        part->devName = strdevname;
366fb299fa2Sopenharmony_ci    }
367fb299fa2Sopenharmony_ci    std::string strpartname = ReadPartitionFromSys(devName, partName, "uevent", "PARTNAME=");
368fb299fa2Sopenharmony_ci    part->partName = partName;
369fb299fa2Sopenharmony_ci    if (!strpartname.empty()) {
370fb299fa2Sopenharmony_ci        part->partName = strpartname;
371fb299fa2Sopenharmony_ci    }
372fb299fa2Sopenharmony_ci
373fb299fa2Sopenharmony_ci    part->partNum = partn;
374fb299fa2Sopenharmony_ci    part->type = NORMAL;
375fb299fa2Sopenharmony_ci    part->fsType = "";
376fb299fa2Sopenharmony_ci    part->changeType = NORMAL_CHANGE;
377fb299fa2Sopenharmony_ci    return part;
378fb299fa2Sopenharmony_ci}
379fb299fa2Sopenharmony_ci
380fb299fa2Sopenharmony_cistruct Partition* GetPartition(const Disk &disk, int partn)
381fb299fa2Sopenharmony_ci{
382fb299fa2Sopenharmony_ci    struct Partition *part = nullptr;
383fb299fa2Sopenharmony_ci    if (partn == 0) {
384fb299fa2Sopenharmony_ci        return nullptr;
385fb299fa2Sopenharmony_ci    }
386fb299fa2Sopenharmony_ci    if (disk.partList.empty()) {
387fb299fa2Sopenharmony_ci        return nullptr;
388fb299fa2Sopenharmony_ci    }
389fb299fa2Sopenharmony_ci    for (auto& p : disk.partList) {
390fb299fa2Sopenharmony_ci        if (p->partNum == partn) {
391fb299fa2Sopenharmony_ci            part = p;
392fb299fa2Sopenharmony_ci            break;
393fb299fa2Sopenharmony_ci        }
394fb299fa2Sopenharmony_ci    }
395fb299fa2Sopenharmony_ci    return part;
396fb299fa2Sopenharmony_ci}
397fb299fa2Sopenharmony_ci
398fb299fa2Sopenharmony_ciint ProbeAllPartitions()
399fb299fa2Sopenharmony_ci{
400fb299fa2Sopenharmony_ci    int i = 0;
401fb299fa2Sopenharmony_ci    struct Disk* disk = nullptr;
402fb299fa2Sopenharmony_ci    disk = g_disks;
403fb299fa2Sopenharmony_ci    if (disk == nullptr) {
404fb299fa2Sopenharmony_ci        return 0;
405fb299fa2Sopenharmony_ci    }
406fb299fa2Sopenharmony_ci    int partSum = DEFAULT_PARTSUM;
407fb299fa2Sopenharmony_ci    struct Partition* part = nullptr;
408fb299fa2Sopenharmony_ci    for (i = 1; i < partSum; i++) {
409fb299fa2Sopenharmony_ci        part = NewPartition(*(disk->dev), i);
410fb299fa2Sopenharmony_ci        if (!part) {
411fb299fa2Sopenharmony_ci            LOG(ERROR) << "Create new partition failed.";
412fb299fa2Sopenharmony_ci            break;
413fb299fa2Sopenharmony_ci        }
414fb299fa2Sopenharmony_ci        disk->partList.push_back(part);
415fb299fa2Sopenharmony_ci        disk->partsum++;
416fb299fa2Sopenharmony_ci    }
417fb299fa2Sopenharmony_ci    return disk->partsum;
418fb299fa2Sopenharmony_ci}
419fb299fa2Sopenharmony_ci
420fb299fa2Sopenharmony_ciDisk* GetRegisterBlockDisk(const std::string &path)
421fb299fa2Sopenharmony_ci{
422fb299fa2Sopenharmony_ci    if (g_disks == nullptr) {
423fb299fa2Sopenharmony_ci        return nullptr;
424fb299fa2Sopenharmony_ci    }
425fb299fa2Sopenharmony_ci    Disk *p = nullptr;
426fb299fa2Sopenharmony_ci    if (g_disks->dev->devPath == path) {
427fb299fa2Sopenharmony_ci        p = g_disks;
428fb299fa2Sopenharmony_ci    }
429fb299fa2Sopenharmony_ci    return p;
430fb299fa2Sopenharmony_ci}
431fb299fa2Sopenharmony_ci
432fb299fa2Sopenharmony_ciint GetPartitionNumByPartName(const std::string &partname, const PartitonList &plist)
433fb299fa2Sopenharmony_ci{
434fb299fa2Sopenharmony_ci    int ret = 0;
435fb299fa2Sopenharmony_ci    for (const auto &p : plist) {
436fb299fa2Sopenharmony_ci        if (p->partName == partname) {
437fb299fa2Sopenharmony_ci            ret = p->partNum;
438fb299fa2Sopenharmony_ci            break;
439fb299fa2Sopenharmony_ci        }
440fb299fa2Sopenharmony_ci    }
441fb299fa2Sopenharmony_ci    return ret;
442fb299fa2Sopenharmony_ci}
443fb299fa2Sopenharmony_ci} // namespace Updater
444