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