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 <cerrno>
16fb299fa2Sopenharmony_ci#include <cstring>
17fb299fa2Sopenharmony_ci#include <linux/blkpg.h>
18fb299fa2Sopenharmony_ci#include <linux/fs.h>
19fb299fa2Sopenharmony_ci#include <libgen.h>
20fb299fa2Sopenharmony_ci#include <string>
21fb299fa2Sopenharmony_ci#include <sys/ioctl.h>
22fb299fa2Sopenharmony_ci#include <sys/types.h>
23fb299fa2Sopenharmony_ci#include <unistd.h>
24fb299fa2Sopenharmony_ci#include "fs_manager/cmp_partition.h"
25fb299fa2Sopenharmony_ci#include "fs_manager/mount.h"
26fb299fa2Sopenharmony_ci#include "fs_manager/partitions.h"
27fb299fa2Sopenharmony_ci#include "log/log.h"
28fb299fa2Sopenharmony_ci#include "misc_info/misc_info.h"
29fb299fa2Sopenharmony_ci#include "partition_const.h"
30fb299fa2Sopenharmony_ci#include "scope_guard.h"
31fb299fa2Sopenharmony_ci#include "securec.h"
32fb299fa2Sopenharmony_ci
33fb299fa2Sopenharmony_cinamespace Updater {
34fb299fa2Sopenharmony_cinamespace {
35fb299fa2Sopenharmony_ciconstexpr const char *USERDATA_PARTNAME = "userdata";
36fb299fa2Sopenharmony_ciconstexpr const char *UPDATER_PARTNAME = "updater";
37fb299fa2Sopenharmony_ci}
38fb299fa2Sopenharmony_ci
39fb299fa2Sopenharmony_cistatic int BlkpgPartCommand(const Partition &part, struct blkpg_partition &pg, int op)
40fb299fa2Sopenharmony_ci{
41fb299fa2Sopenharmony_ci    struct blkpg_ioctl_arg args {};
42fb299fa2Sopenharmony_ci    args.op = op;
43fb299fa2Sopenharmony_ci    args.flags = 0;
44fb299fa2Sopenharmony_ci    args.datalen = static_cast<int>(sizeof(struct blkpg_partition));
45fb299fa2Sopenharmony_ci    args.data = static_cast<void *>(&pg);
46fb299fa2Sopenharmony_ci
47fb299fa2Sopenharmony_ci    int ret = 0;
48fb299fa2Sopenharmony_ci#ifndef UPDATER_UT
49fb299fa2Sopenharmony_ci    ret = ioctl(part.partfd, BLKPG, &args);
50fb299fa2Sopenharmony_ci#endif
51fb299fa2Sopenharmony_ci    if (ret < 0) {
52fb299fa2Sopenharmony_ci        LOG(ERROR) << "ioctl of partition " << part.partName << " with operation " << op << " failed";
53fb299fa2Sopenharmony_ci    }
54fb299fa2Sopenharmony_ci    return ret;
55fb299fa2Sopenharmony_ci}
56fb299fa2Sopenharmony_ci
57fb299fa2Sopenharmony_cistatic int DoUmountDiskPartition(const Partition &part)
58fb299fa2Sopenharmony_ci{
59fb299fa2Sopenharmony_ci    std::string partName = std::string("/") + part.partName;
60fb299fa2Sopenharmony_ci    int ret = UmountForPath(partName);
61fb299fa2Sopenharmony_ci    if (ret == -1) {
62fb299fa2Sopenharmony_ci        LOG(ERROR) << "Umount " << partName << " failed: " << errno;
63fb299fa2Sopenharmony_ci        return 0;
64fb299fa2Sopenharmony_ci    }
65fb299fa2Sopenharmony_ci    return 1;
66fb299fa2Sopenharmony_ci}
67fb299fa2Sopenharmony_ci
68fb299fa2Sopenharmony_cistatic void DoFsync(const BlockDevice &dev)
69fb299fa2Sopenharmony_ci{
70fb299fa2Sopenharmony_ci    BlockSpecific* bs = BLOCK_SPECIFIC(&dev);
71fb299fa2Sopenharmony_ci    int status;
72fb299fa2Sopenharmony_ci
73fb299fa2Sopenharmony_ci    while (true) {
74fb299fa2Sopenharmony_ci        status = fsync (bs->fd);
75fb299fa2Sopenharmony_ci        if (status >= 0) {
76fb299fa2Sopenharmony_ci            break;
77fb299fa2Sopenharmony_ci        }
78fb299fa2Sopenharmony_ci    }
79fb299fa2Sopenharmony_ci}
80fb299fa2Sopenharmony_ci
81fb299fa2Sopenharmony_cistatic int BlockSync(const Disk &disk)
82fb299fa2Sopenharmony_ci{
83fb299fa2Sopenharmony_ci    if (disk.dev->readOnly) {
84fb299fa2Sopenharmony_ci        return 0;
85fb299fa2Sopenharmony_ci    }
86fb299fa2Sopenharmony_ci    DoFsync(*(disk.dev));
87fb299fa2Sopenharmony_ci    return 1;
88fb299fa2Sopenharmony_ci}
89fb299fa2Sopenharmony_ci
90fb299fa2Sopenharmony_cistatic int BlkpgRemovePartition(const Partition &part)
91fb299fa2Sopenharmony_ci{
92fb299fa2Sopenharmony_ci    struct blkpg_partition blkPart {};
93fb299fa2Sopenharmony_ci    if (memset_s(&blkPart, sizeof(blkPart), 0, sizeof(blkPart)) != EOK) {
94fb299fa2Sopenharmony_ci        return -1;
95fb299fa2Sopenharmony_ci    }
96fb299fa2Sopenharmony_ci    blkPart.pno = part.partNum;
97fb299fa2Sopenharmony_ci    return BlkpgPartCommand(part, blkPart, BLKPG_DEL_PARTITION);
98fb299fa2Sopenharmony_ci}
99fb299fa2Sopenharmony_ci
100fb299fa2Sopenharmony_cistatic int BlockDiskOpen(Disk &disk)
101fb299fa2Sopenharmony_ci{
102fb299fa2Sopenharmony_ci    disk.dev->fd = open(disk.dev->devPath.c_str(), RW_MODE);
103fb299fa2Sopenharmony_ci    if (disk.dev->fd < 0) {
104fb299fa2Sopenharmony_ci        LOG(WARNING) << "open fail: " << disk.dev->devPath << errno;
105fb299fa2Sopenharmony_ci    }
106fb299fa2Sopenharmony_ci    return disk.dev->fd;
107fb299fa2Sopenharmony_ci}
108fb299fa2Sopenharmony_ci
109fb299fa2Sopenharmony_cistatic void BlockDiskClose(Disk &disk)
110fb299fa2Sopenharmony_ci{
111fb299fa2Sopenharmony_ci    if (disk.dev != nullptr) {
112fb299fa2Sopenharmony_ci        if (disk.dev->fd > 0) {
113fb299fa2Sopenharmony_ci            close(disk.dev->fd);
114fb299fa2Sopenharmony_ci            disk.dev->fd = -1;
115fb299fa2Sopenharmony_ci        }
116fb299fa2Sopenharmony_ci    }
117fb299fa2Sopenharmony_ci}
118fb299fa2Sopenharmony_ci
119fb299fa2Sopenharmony_cistatic bool DoRmPartition(const Disk &disk, int partn)
120fb299fa2Sopenharmony_ci{
121fb299fa2Sopenharmony_ci    Partition *part = nullptr;
122fb299fa2Sopenharmony_ci    part = GetPartition(disk, partn);
123fb299fa2Sopenharmony_ci    if (part == nullptr) {
124fb299fa2Sopenharmony_ci        LOG(ERROR) << "Cannot get partition info for partition number: " << partn;
125fb299fa2Sopenharmony_ci        return false;
126fb299fa2Sopenharmony_ci    }
127fb299fa2Sopenharmony_ci
128fb299fa2Sopenharmony_ci    if (disk.dev->fd < 0) {
129fb299fa2Sopenharmony_ci        return false;
130fb299fa2Sopenharmony_ci    }
131fb299fa2Sopenharmony_ci    part->partfd = disk.dev->fd;
132fb299fa2Sopenharmony_ci    int ret = BlkpgRemovePartition(*part);
133fb299fa2Sopenharmony_ci    part->partfd = -1;
134fb299fa2Sopenharmony_ci    if (ret < 0) {
135fb299fa2Sopenharmony_ci        LOG(ERROR) << "Delete part failed";
136fb299fa2Sopenharmony_ci        return false;
137fb299fa2Sopenharmony_ci    }
138fb299fa2Sopenharmony_ci    return true;
139fb299fa2Sopenharmony_ci}
140fb299fa2Sopenharmony_ci
141fb299fa2Sopenharmony_cistatic int BlkpgAddPartition(Partition &part)
142fb299fa2Sopenharmony_ci{
143fb299fa2Sopenharmony_ci    struct blkpg_partition blkPart {};
144fb299fa2Sopenharmony_ci    if (memset_s(&blkPart, sizeof(blkPart), 0, sizeof(blkPart)) != EOK) {
145fb299fa2Sopenharmony_ci        return 0;
146fb299fa2Sopenharmony_ci    }
147fb299fa2Sopenharmony_ci    blkPart.start = static_cast<long long>(part.start * SECTOR_SIZE_DEFAULT);
148fb299fa2Sopenharmony_ci    LOG(INFO) << "blkPart.start " << blkPart.start;
149fb299fa2Sopenharmony_ci    blkPart.length = static_cast<long long>(part.length * SECTOR_SIZE_DEFAULT);
150fb299fa2Sopenharmony_ci    LOG(INFO) << "blkPart.length " << blkPart.length;
151fb299fa2Sopenharmony_ci    blkPart.pno = part.partNum;
152fb299fa2Sopenharmony_ci    LOG(INFO) << "blkPart.pno " << blkPart.pno;
153fb299fa2Sopenharmony_ci    if (strncpy_s(blkPart.devname, BLKPG_DEVNAMELTH, part.devName.c_str(), part.devName.size()) != EOK) {
154fb299fa2Sopenharmony_ci        return 0;
155fb299fa2Sopenharmony_ci    }
156fb299fa2Sopenharmony_ci    LOG(INFO) << "blkPart.devname " << blkPart.devname;
157fb299fa2Sopenharmony_ci    if (strncpy_s(blkPart.volname, BLKPG_VOLNAMELTH, part.partName.c_str(), part.partName.size()) != EOK) {
158fb299fa2Sopenharmony_ci        return 0;
159fb299fa2Sopenharmony_ci    }
160fb299fa2Sopenharmony_ci    LOG(INFO) << "blkPart.volname " << blkPart.volname;
161fb299fa2Sopenharmony_ci    if (BlkpgPartCommand(part, blkPart, BLKPG_ADD_PARTITION) < 0) {
162fb299fa2Sopenharmony_ci        return 0;
163fb299fa2Sopenharmony_ci    }
164fb299fa2Sopenharmony_ci    return 1;
165fb299fa2Sopenharmony_ci}
166fb299fa2Sopenharmony_ci
167fb299fa2Sopenharmony_cistatic bool DoAddPartition(const Disk &disk, Partition &part)
168fb299fa2Sopenharmony_ci{
169fb299fa2Sopenharmony_ci    if (disk.dev->fd < 0) {
170fb299fa2Sopenharmony_ci        return false;
171fb299fa2Sopenharmony_ci    }
172fb299fa2Sopenharmony_ci
173fb299fa2Sopenharmony_ci    part.partfd = disk.dev->fd;
174fb299fa2Sopenharmony_ci    int ret = BlkpgAddPartition(part);
175fb299fa2Sopenharmony_ci    part.partfd = -1;
176fb299fa2Sopenharmony_ci    if (ret == 0) {
177fb299fa2Sopenharmony_ci        LOG(ERROR) << "Add partition failed";
178fb299fa2Sopenharmony_ci        return false;
179fb299fa2Sopenharmony_ci    }
180fb299fa2Sopenharmony_ci    return true;
181fb299fa2Sopenharmony_ci}
182fb299fa2Sopenharmony_ci
183fb299fa2Sopenharmony_cistatic void DestroyDiskPartitions(Disk &disk)
184fb299fa2Sopenharmony_ci{
185fb299fa2Sopenharmony_ci    if (!disk.partList.empty()) {
186fb299fa2Sopenharmony_ci        for (auto& p : disk.partList) {
187fb299fa2Sopenharmony_ci            if (p != nullptr) {
188fb299fa2Sopenharmony_ci                free(p);
189fb299fa2Sopenharmony_ci            }
190fb299fa2Sopenharmony_ci        }
191fb299fa2Sopenharmony_ci    }
192fb299fa2Sopenharmony_ci    disk.partList.clear();
193fb299fa2Sopenharmony_ci}
194fb299fa2Sopenharmony_ci
195fb299fa2Sopenharmony_cistatic void DestroyDiskDevices(const Disk &disk)
196fb299fa2Sopenharmony_ci{
197fb299fa2Sopenharmony_ci    if (disk.dev != nullptr) {
198fb299fa2Sopenharmony_ci        if (disk.dev->specific != nullptr) {
199fb299fa2Sopenharmony_ci            free(disk.dev->specific);
200fb299fa2Sopenharmony_ci        }
201fb299fa2Sopenharmony_ci        free(disk.dev);
202fb299fa2Sopenharmony_ci    }
203fb299fa2Sopenharmony_ci}
204fb299fa2Sopenharmony_ci
205fb299fa2Sopenharmony_cistatic bool WriteMiscMsgWithOffset(const std::string &msg, int32_t offset)
206fb299fa2Sopenharmony_ci{
207fb299fa2Sopenharmony_ci    const std::string miscDevPath = GetBlockDeviceByMountPoint("/misc");
208fb299fa2Sopenharmony_ci    char realPath[PATH_MAX] = {0};
209fb299fa2Sopenharmony_ci    if (realpath(miscDevPath.c_str(), realPath) == nullptr) {
210fb299fa2Sopenharmony_ci        LOG(ERROR) << "realPath is NULL";
211fb299fa2Sopenharmony_ci        return false;
212fb299fa2Sopenharmony_ci    }
213fb299fa2Sopenharmony_ci    FILE *fp = fopen(realPath, "rb+");
214fb299fa2Sopenharmony_ci    if (fp == nullptr) {
215fb299fa2Sopenharmony_ci        LOG(ERROR) << "fopen error " << errno;
216fb299fa2Sopenharmony_ci        return false;
217fb299fa2Sopenharmony_ci    }
218fb299fa2Sopenharmony_ci
219fb299fa2Sopenharmony_ci    ON_SCOPE_EXIT(flosefp) {
220fb299fa2Sopenharmony_ci        fclose(fp);
221fb299fa2Sopenharmony_ci    };
222fb299fa2Sopenharmony_ci
223fb299fa2Sopenharmony_ci    if (fseek(fp, offset, SEEK_SET) != 0) {
224fb299fa2Sopenharmony_ci        LOG(ERROR) << "fseek error";
225fb299fa2Sopenharmony_ci        return false;
226fb299fa2Sopenharmony_ci    }
227fb299fa2Sopenharmony_ci
228fb299fa2Sopenharmony_ci    if (fwrite(msg.c_str(), msg.length() + 1, 1, fp) < 0) {
229fb299fa2Sopenharmony_ci        LOG(ERROR) << "fwrite error " << errno;
230fb299fa2Sopenharmony_ci        return false;
231fb299fa2Sopenharmony_ci    }
232fb299fa2Sopenharmony_ci
233fb299fa2Sopenharmony_ci    int fd = fileno(fp);
234fb299fa2Sopenharmony_ci    fsync(fd);
235fb299fa2Sopenharmony_ci    return true;
236fb299fa2Sopenharmony_ci}
237fb299fa2Sopenharmony_ci
238fb299fa2Sopenharmony_cistatic bool WriteDiskPartitionToMisc(PartitonList &nlist)
239fb299fa2Sopenharmony_ci{
240fb299fa2Sopenharmony_ci    if (nlist.empty()) {
241fb299fa2Sopenharmony_ci        return false;
242fb299fa2Sopenharmony_ci    }
243fb299fa2Sopenharmony_ci    char blkdevparts[MISC_RECORD_UPDATE_PARTITIONS_SIZE] = "mmcblk0:";
244fb299fa2Sopenharmony_ci    std::sort(nlist.begin(), nlist.end(), [](const struct Partition *a, const struct Partition *b) {
245fb299fa2Sopenharmony_ci            return (a->start < b->start);
246fb299fa2Sopenharmony_ci    }); // Sort in ascending order
247fb299fa2Sopenharmony_ci    char tmp[SMALL_BUFFER_SIZE] = {0};
248fb299fa2Sopenharmony_ci    size_t size = 0;
249fb299fa2Sopenharmony_ci    for (auto& p : nlist) {
250fb299fa2Sopenharmony_ci        if (memset_s(tmp, sizeof(tmp), 0, sizeof(tmp)) != EOK) {
251fb299fa2Sopenharmony_ci            return false;
252fb299fa2Sopenharmony_ci        }
253fb299fa2Sopenharmony_ci        if (p->partName == "userdata") {
254fb299fa2Sopenharmony_ci            if (snprintf_s(tmp, sizeof(tmp), sizeof(tmp) - 1, "-(%s),",
255fb299fa2Sopenharmony_ci                p->partName.c_str()) == -1) {
256fb299fa2Sopenharmony_ci                    return false;
257fb299fa2Sopenharmony_ci                }
258fb299fa2Sopenharmony_ci        } else {
259fb299fa2Sopenharmony_ci            size = static_cast<size_t>(p->length * SECTOR_SIZE_DEFAULT / DEFAULT_SIZE_1MB);
260fb299fa2Sopenharmony_ci            if (snprintf_s(tmp, sizeof(tmp), sizeof(tmp) - 1, "%luM(%s),",
261fb299fa2Sopenharmony_ci                size, p->partName.c_str()) == -1) {
262fb299fa2Sopenharmony_ci                    return false;
263fb299fa2Sopenharmony_ci                }
264fb299fa2Sopenharmony_ci        }
265fb299fa2Sopenharmony_ci        if (strncat_s(blkdevparts, MISC_RECORD_UPDATE_PARTITIONS_SIZE - 1, tmp, strlen(tmp)) != EOK) {
266fb299fa2Sopenharmony_ci            LOG(ERROR) << "Block device name overflow";
267fb299fa2Sopenharmony_ci            return false;
268fb299fa2Sopenharmony_ci        }
269fb299fa2Sopenharmony_ci    }
270fb299fa2Sopenharmony_ci
271fb299fa2Sopenharmony_ci    blkdevparts[strlen(blkdevparts) - 1] = '\0';
272fb299fa2Sopenharmony_ci    LOG(INFO) << "blkdevparts is " << blkdevparts;
273fb299fa2Sopenharmony_ci
274fb299fa2Sopenharmony_ci    return WriteMiscMsgWithOffset(std::string(blkdevparts), MISC_RECORD_UPDATE_PARTITIONS_OFFSET);
275fb299fa2Sopenharmony_ci}
276fb299fa2Sopenharmony_ci
277fb299fa2Sopenharmony_cistatic bool AddPartitions(const Disk &disk, const PartitonList &ulist, int &partitionAddedCounter)
278fb299fa2Sopenharmony_ci{
279fb299fa2Sopenharmony_ci    if (!ulist.empty()) {
280fb299fa2Sopenharmony_ci        int userNum = GetPartitionNumByPartName(USERDATA_PARTNAME, disk.partList);
281fb299fa2Sopenharmony_ci        int step = 1;
282fb299fa2Sopenharmony_ci        char pdevname[DEVPATH_SIZE] = {0};
283fb299fa2Sopenharmony_ci        for (auto& p2 : ulist) {
284fb299fa2Sopenharmony_ci            if (p2->partName == USERDATA_PARTNAME) {
285fb299fa2Sopenharmony_ci                LOG(INFO) << "Change userdata image is not support.";
286fb299fa2Sopenharmony_ci                continue;
287fb299fa2Sopenharmony_ci            }
288fb299fa2Sopenharmony_ci            if (p2->partName == UPDATER_PARTNAME) {
289fb299fa2Sopenharmony_ci                LOG(ERROR) << "Change updater image is not supported.";
290fb299fa2Sopenharmony_ci                continue;
291fb299fa2Sopenharmony_ci            }
292fb299fa2Sopenharmony_ci            p2->partNum = userNum + step;
293fb299fa2Sopenharmony_ci            if (snprintf_s(pdevname, sizeof(pdevname), sizeof(pdevname) - 1, "%sp%d", MMC_DEV, p2->partNum) == -1) {
294fb299fa2Sopenharmony_ci                return false;
295fb299fa2Sopenharmony_ci            }
296fb299fa2Sopenharmony_ci            p2->devName.clear();
297fb299fa2Sopenharmony_ci            p2->devName = pdevname;
298fb299fa2Sopenharmony_ci            LOG(INFO) << "Adding partition " << p2->partName;
299fb299fa2Sopenharmony_ci            if (!DoAddPartition (disk, *p2)) {
300fb299fa2Sopenharmony_ci                LOG(ERROR) << "Add partition fail for " << p2->partName;
301fb299fa2Sopenharmony_ci                return false;
302fb299fa2Sopenharmony_ci            }
303fb299fa2Sopenharmony_ci            step++;
304fb299fa2Sopenharmony_ci            partitionAddedCounter++;
305fb299fa2Sopenharmony_ci        }
306fb299fa2Sopenharmony_ci    }
307fb299fa2Sopenharmony_ci    return true;
308fb299fa2Sopenharmony_ci}
309fb299fa2Sopenharmony_ci
310fb299fa2Sopenharmony_cistatic bool RemovePartitions(const Disk &disk, int &partitionRemovedCounter)
311fb299fa2Sopenharmony_ci{
312fb299fa2Sopenharmony_ci    PartitonList pList = disk.partList;
313fb299fa2Sopenharmony_ci    for (const auto &it : pList) {
314fb299fa2Sopenharmony_ci        if (it->changeType == NOT_CHANGE) {
315fb299fa2Sopenharmony_ci            continue;
316fb299fa2Sopenharmony_ci        }
317fb299fa2Sopenharmony_ci        if (it->partName == UPDATER_PARTNAME) {
318fb299fa2Sopenharmony_ci            LOG(ERROR) << "Cannot delete updater partition.";
319fb299fa2Sopenharmony_ci            continue;
320fb299fa2Sopenharmony_ci        }
321fb299fa2Sopenharmony_ci
322fb299fa2Sopenharmony_ci        if (it->partName == USERDATA_PARTNAME) {
323fb299fa2Sopenharmony_ci            LOG(INFO) << "Cannot delete userdata partition.";
324fb299fa2Sopenharmony_ci            continue;
325fb299fa2Sopenharmony_ci        }
326fb299fa2Sopenharmony_ci        if (DoUmountDiskPartition(*it) == 0) {
327fb299fa2Sopenharmony_ci            continue;
328fb299fa2Sopenharmony_ci        }
329fb299fa2Sopenharmony_ci        LOG(INFO) << "Removing partition " << it->partName;
330fb299fa2Sopenharmony_ci        if (!DoRmPartition (disk, it->partNum)) {
331fb299fa2Sopenharmony_ci            LOG(ERROR) << "Remove partition failed.";
332fb299fa2Sopenharmony_ci            return false;
333fb299fa2Sopenharmony_ci        }
334fb299fa2Sopenharmony_ci        partitionRemovedCounter++;
335fb299fa2Sopenharmony_ci    }
336fb299fa2Sopenharmony_ci    return true;
337fb299fa2Sopenharmony_ci}
338fb299fa2Sopenharmony_ci
339fb299fa2Sopenharmony_ciint CheckDevicePartitions(const std::string &path)
340fb299fa2Sopenharmony_ci{
341fb299fa2Sopenharmony_ci    if (DiskAlloc(path) == 0) {
342fb299fa2Sopenharmony_ci        LOG(ERROR) << "path not exist" << path;
343fb299fa2Sopenharmony_ci        return 0;
344fb299fa2Sopenharmony_ci    }
345fb299fa2Sopenharmony_ci    if (ProbeAllPartitions() == 0) {
346fb299fa2Sopenharmony_ci        LOG(ERROR) << "partition sum  is zero!";
347fb299fa2Sopenharmony_ci        return 0;
348fb299fa2Sopenharmony_ci    }
349fb299fa2Sopenharmony_ci    return 1;
350fb299fa2Sopenharmony_ci}
351fb299fa2Sopenharmony_ci
352fb299fa2Sopenharmony_ciint AdjustPartitions(Disk *disk, int &partitionChangedCounter)
353fb299fa2Sopenharmony_ci{
354fb299fa2Sopenharmony_ci    PartitonList ulist;
355fb299fa2Sopenharmony_ci    ulist.clear();
356fb299fa2Sopenharmony_ci
357fb299fa2Sopenharmony_ci    if (disk == nullptr || BlockDiskOpen(*disk) < 0) {
358fb299fa2Sopenharmony_ci        return 0;
359fb299fa2Sopenharmony_ci    }
360fb299fa2Sopenharmony_ci
361fb299fa2Sopenharmony_ci    if (GetRegisterUpdaterPartitionList(ulist) == 0) {
362fb299fa2Sopenharmony_ci        LOG(ERROR) << "get updater list fail!";
363fb299fa2Sopenharmony_ci        return 0;
364fb299fa2Sopenharmony_ci    }
365fb299fa2Sopenharmony_ci
366fb299fa2Sopenharmony_ci    if (!RemovePartitions(*disk, partitionChangedCounter)) {
367fb299fa2Sopenharmony_ci        return 0;
368fb299fa2Sopenharmony_ci    }
369fb299fa2Sopenharmony_ci
370fb299fa2Sopenharmony_ci    BlockSync(*disk);
371fb299fa2Sopenharmony_ci    if (!AddPartitions(*disk, ulist, partitionChangedCounter)) {
372fb299fa2Sopenharmony_ci        return 0;
373fb299fa2Sopenharmony_ci    }
374fb299fa2Sopenharmony_ci    BlockSync(*disk);
375fb299fa2Sopenharmony_ci    return 1;
376fb299fa2Sopenharmony_ci}
377fb299fa2Sopenharmony_ci
378fb299fa2Sopenharmony_ciint DoPartitions(PartitonList &nlist)
379fb299fa2Sopenharmony_ci{
380fb299fa2Sopenharmony_ci    LOG(INFO) << "do_partitions start";
381fb299fa2Sopenharmony_ci    if (nlist.empty()) {
382fb299fa2Sopenharmony_ci        LOG(ERROR) << "newpartitionlist is empty ";
383fb299fa2Sopenharmony_ci        return 0;
384fb299fa2Sopenharmony_ci    }
385fb299fa2Sopenharmony_ci
386fb299fa2Sopenharmony_ci    const std::string path = MMC_PATH;
387fb299fa2Sopenharmony_ci    if (CheckDevicePartitions(path) == 0) {
388fb299fa2Sopenharmony_ci        return 0;
389fb299fa2Sopenharmony_ci    }
390fb299fa2Sopenharmony_ci
391fb299fa2Sopenharmony_ci    Disk *disk = GetRegisterBlockDisk(path);
392fb299fa2Sopenharmony_ci    if (disk == nullptr) {
393fb299fa2Sopenharmony_ci        LOG(ERROR) << "getRegisterdisk fail! ";
394fb299fa2Sopenharmony_ci        return 0;
395fb299fa2Sopenharmony_ci    }
396fb299fa2Sopenharmony_ci    if (RegisterUpdaterPartitionList(nlist, disk->partList) == 0) {
397fb299fa2Sopenharmony_ci        LOG(ERROR) << "register updater list fail!";
398fb299fa2Sopenharmony_ci        free(disk);
399fb299fa2Sopenharmony_ci        return 0;
400fb299fa2Sopenharmony_ci    }
401fb299fa2Sopenharmony_ci
402fb299fa2Sopenharmony_ci    ON_SCOPE_EXIT(clearresource) {
403fb299fa2Sopenharmony_ci        BlockDiskClose(*disk);
404fb299fa2Sopenharmony_ci        DestroyDiskPartitions(*disk);
405fb299fa2Sopenharmony_ci        DestroyDiskDevices(*disk);
406fb299fa2Sopenharmony_ci        free(disk);
407fb299fa2Sopenharmony_ci    };
408fb299fa2Sopenharmony_ci
409fb299fa2Sopenharmony_ci    int partitionChangedCounter = 1;
410fb299fa2Sopenharmony_ci    if (AdjustPartitions(disk, partitionChangedCounter) == 0) {
411fb299fa2Sopenharmony_ci        return 0;
412fb299fa2Sopenharmony_ci    }
413fb299fa2Sopenharmony_ci
414fb299fa2Sopenharmony_ci    (void)WriteDiskPartitionToMisc(nlist);
415fb299fa2Sopenharmony_ci    return partitionChangedCounter;
416fb299fa2Sopenharmony_ci}
417fb299fa2Sopenharmony_ci} // Updater
418fb299fa2Sopenharmony_ci
419