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 <errno.h> 17#include <stdlib.h> 18#include <string.h> 19#include <stdbool.h> 20#include <sys/mount.h> 21#include <sys/stat.h> 22#include <sys/wait.h> 23#include <unistd.h> 24#include <linux/limits.h> 25#include "beget_ext.h" 26#include "fs_manager/fs_manager.h" 27#include "init_utils.h" 28#include "param/init_param.h" 29#include "securec.h" 30#include "switch_root.h" 31#ifdef SUPPORT_HVB 32#include "fs_dm.h" 33#include "dm_verity.h" 34#endif 35#include "init_filesystems.h" 36#ifdef EROFS_OVERLAY 37#include "erofs_mount_overlay.h" 38#endif 39#ifdef __cplusplus 40#if __cplusplus 41extern "C" { 42#endif 43#endif 44 45#define FS_MANAGER_BUFFER_SIZE 512 46#define BLOCK_SIZE_BUFFER (64) 47#define RESIZE_BUFFER_SIZE 1024 48const off_t PARTITION_ACTIVE_SLOT_OFFSET = 1024; 49const off_t PARTITION_ACTIVE_SLOT_SIZE = 4; 50 51__attribute__((weak)) void InitPostMount(const char *mountPoint, int rc) 52{ 53} 54 55__attribute__((weak)) void InitTimerControl(bool isSuspend) 56{ 57} 58 59__attribute__((weak)) bool NeedDoAllResize(void) 60{ 61 return true; 62} 63 64static const SUPPORTED_FILE_SYSTEM supportedFileSystems[] = { 65 { "ext4", 0 }, 66 { "f2fs", 1 }, 67 { "overlay", 0 }, 68 { NULL, 0 } 69}; 70 71static void **extendedFileSystems_ = NULL; 72 73void InitSetExtendedFileSystems(const SUPPORTED_FILE_SYSTEM *extendedFileSystems[]) 74{ 75 extendedFileSystems_ = (void **)extendedFileSystems; 76} 77 78static const SUPPORTED_FILE_SYSTEM *GetSupportedFileSystemInfo(const char *fsType) 79{ 80 return (const SUPPORTED_FILE_SYSTEM *)OH_ExtendableStrDictGet((void **)supportedFileSystems, 81 sizeof(SUPPORTED_FILE_SYSTEM), fsType, 0, extendedFileSystems_); 82} 83 84static bool IsSupportedDataType(const char *fsType) 85{ 86 const SUPPORTED_FILE_SYSTEM *item = GetSupportedFileSystemInfo(fsType); 87 if (item == NULL) { 88 return false; 89 } 90 if (item->for_userdata) { 91 return true; 92 } 93 return false; 94} 95 96bool IsSupportedFilesystem(const char *fsType) 97{ 98 const SUPPORTED_FILE_SYSTEM *item = GetSupportedFileSystemInfo(fsType); 99 if (item == NULL) { 100 return false; 101 } 102 return true; 103} 104 105/* 1024(stdout buffer size) - 256(log tag max size approximately) */ 106#define LOG_LINE_SZ 768 107#define PIPE_FDS 2 108 109static void LogToKmsg(int fd) 110{ 111 char buffer[LOG_LINE_SZ] = {0}; 112 int lineMaxSize = LOG_LINE_SZ - 1; 113 int pos = 0; 114 115 do { 116 ssize_t lineSize = read(fd, buffer, lineMaxSize); 117 if (lineSize < 0) { 118 BEGET_LOGE("Failed to read, errno: %d", errno); 119 break; 120 } 121 if (!lineSize) { 122 /* No more lines, just break */ 123 break; 124 } 125 if (lineSize > lineMaxSize) { 126 BEGET_LOGE("Invalid read size, ret: %d is larger than buffer size: %d", lineSize, lineMaxSize); 127 lineSize = lineMaxSize; 128 } 129 /* Make sure that each line terminates with '\0' */ 130 buffer[lineSize] = '\0'; 131 int posStart = 0; 132 for (pos = posStart; pos < lineSize; pos++) { 133 if (buffer[pos] == '\n') { 134 buffer[pos] = '\0'; 135 BEGET_LOGI("%s", &buffer[posStart]); 136 posStart = pos + 1; 137 } 138 } 139 if (posStart < pos) { 140 BEGET_LOGI("%s", &buffer[posStart]); 141 } 142 } while (1); 143 (void)close(fd); 144} 145 146static void RedirectToStdFd(int fd) 147{ 148 if (dup2(fd, STDOUT_FILENO) < 0) { 149 BEGET_LOGE("Failed to dup2 stdout, errno: %d, just continue", errno); 150 } 151 if (dup2(fd, STDERR_FILENO) < 0) { 152 BEGET_LOGE("Failed to dup2 stderr, errno: %d, just continue", errno); 153 } 154 (void)close(fd); 155} 156 157static int ExecCommand(int argc, char **argv) 158{ 159 BEGET_CHECK(!(argc == 0 || argv == NULL || argv[0] == NULL), return -1); 160 161 bool logToKmsg = false; 162 int pipeFds[PIPE_FDS]; 163 if (pipe2(pipeFds, O_CLOEXEC) < 0) { 164 BEGET_LOGE("Failed to create pipe, errno: %d, just continue", errno); 165 } else { 166 logToKmsg = true; 167 } 168 169 BEGET_LOGI("Execute %s begin", argv[0]); 170 pid_t pid = fork(); 171 BEGET_ERROR_CHECK(pid >= 0, return -1, "Fork new process to format failed: %d", errno); 172 if (pid == 0) { 173 if (logToKmsg) { 174 (void)close(pipeFds[0]); 175 RedirectToStdFd(pipeFds[1]); 176 } 177 execv(argv[0], argv); 178 BEGET_LOGE("Failed to execv, errno: %d", errno); 179 exit(-1); 180 } 181 if (logToKmsg) { 182 (void)close(pipeFds[1]); 183 LogToKmsg(pipeFds[0]); 184 } 185 int status = 0; 186 waitpid(pid, &status, 0); 187 if (WIFEXITED(status)) { 188 BEGET_LOGI("Execute success, status: %d, command: %s", WEXITSTATUS(status), argv[0]); 189 return WEXITSTATUS(status); 190 } 191 BEGET_LOGE("Failed to execute %s", argv[0]); 192 return -1; 193} 194 195int DoFormat(const char *devPath, const char *fsType) 196{ 197 if (devPath == NULL || fsType == NULL) { 198 return -1; 199 } 200 201 if (!IsSupportedFilesystem(fsType)) { 202 BEGET_LOGE("Do not support filesystem \" %s \"", fsType); 203 return -1; 204 } 205 int ret = 0; 206 if (strcmp(fsType, "ext4") == 0) { 207 char blockSizeBuffer[BLOCK_SIZE_BUFFER] = {0}; 208 const unsigned int blockSize = 4096; 209 ret = snprintf_s(blockSizeBuffer, BLOCK_SIZE_BUFFER, BLOCK_SIZE_BUFFER - 1, "%u", blockSize); 210 BEGET_ERROR_CHECK(ret != -1, return -1, "Failed to build block size buffer"); 211 212 char *formatCmds[] = { 213 "/bin/mke2fs", "-F", "-t", (char *)fsType, "-b", blockSizeBuffer, (char *)devPath, NULL 214 }; 215 int argc = ARRAY_LENGTH(formatCmds); 216 char **argv = (char **)formatCmds; 217 ret = ExecCommand(argc, argv); 218 } else if (IsSupportedDataType(fsType)) { 219#ifdef __MUSL__ 220 char *formatCmds[] = { 221 "/bin/mkfs.f2fs", "-d1", "-O", "encrypt", "-O", "quota", "-O", "verity", "-O", "project_quota,extra_attr", 222 "-O", "sb_checksum", (char *)devPath, NULL 223 }; 224#else 225 char *formatCmds[] = { 226 "/bin/make_f2fs", "-d1", "-O", "encrypt", "-O", "quota", "-O", "verity", "-O", "project_quota,extra_attr", 227 "-O", "sb_checksum", (char *)devPath, NULL 228 }; 229#endif 230 int argc = ARRAY_LENGTH(formatCmds); 231 char **argv = (char **)formatCmds; 232 ret = ExecCommand(argc, argv); 233 } 234 return ret; 235} 236 237MountStatus GetMountStatusForMountPoint(const char *mp) 238{ 239 if (mp == NULL) { 240 return MOUNT_ERROR; 241 } 242 char buffer[FS_MANAGER_BUFFER_SIZE] = {0}; 243 const int expectedItems = 6; 244 int count = 0; 245 char **mountItems = NULL; 246 MountStatus status = MOUNT_ERROR; 247 bool found = false; 248 249 FILE *fp = fopen("/proc/mounts", "r"); 250 BEGET_CHECK(fp != NULL, return status); 251 252 while (fgets(buffer, sizeof(buffer) - 1, fp) != NULL) { 253 size_t n = strlen(buffer); 254 if (buffer[n - 1] == '\n') { 255 buffer[n - 1] = '\0'; 256 } 257 mountItems = SplitStringExt(buffer, " ", &count, expectedItems); 258 if (mountItems != NULL && count == expectedItems) { 259 // Second item in /proc/mounts is mount point 260 if (strcmp(mountItems[1], mp) == 0) { 261 FreeStringVector(mountItems, count); 262 found = true; 263 break; 264 } 265 FreeStringVector(mountItems, count); 266 } 267 } 268 if (found) { 269 status = MOUNT_MOUNTED; 270 } else if (feof(fp) > 0) { 271 status = MOUNT_UMOUNTED; 272 } 273 (void)fclose(fp); 274 fp = NULL; 275 return status; 276} 277 278#define MAX_RESIZE_PARAM_NUM 20 279static int DoResizeF2fs(const char* device, const unsigned long long size, const unsigned int fsManagerFlags) 280{ 281 char *file = "/system/bin/resize.f2fs"; 282 char sizeStr[RESIZE_BUFFER_SIZE] = {0}; 283 char *argv[MAX_RESIZE_PARAM_NUM] = {NULL}; 284 int argc = 0; 285 286 BEGET_ERROR_CHECK(NeedDoAllResize(), return -1, "no need do resize, bucause kdump has done"); 287 BEGET_ERROR_CHECK(access(file, F_OK) == 0, return -1, "resize.f2fs is not exists."); 288 289 argv[argc++] = file; 290 if (fsManagerFlags & FS_MANAGER_PROJQUOTA) { 291 argv[argc++] = "-O"; 292 argv[argc++] = "extra_attr,project_quota"; 293 } 294 if (fsManagerFlags & FS_MANAGER_CASEFOLD) { 295 argv[argc++] = "-O"; 296 argv[argc++] = "casefold"; 297 argv[argc++] = "-C"; 298 argv[argc++] = "utf8"; 299 } 300 if (fsManagerFlags & FS_MANAGER_COMPRESSION) { 301 argv[argc++] = "-O"; 302 argv[argc++] = "extra_attr,compression"; 303 } 304 if (fsManagerFlags & FS_MANAGER_DEDUP) { 305 argv[argc++] = "-O"; 306 argv[argc++] = "extra_attr,dedup"; 307 } 308 309 if (size != 0) { 310 unsigned long long realSize = size * 311 ((unsigned long long)RESIZE_BUFFER_SIZE * RESIZE_BUFFER_SIZE / FS_MANAGER_BUFFER_SIZE); 312 int len = sprintf_s(sizeStr, RESIZE_BUFFER_SIZE, "%llu", realSize); 313 if (len <= 0) { 314 BEGET_LOGE("Write buffer size failed."); 315 } 316 argv[argc++] = "-t"; 317 argv[argc++] = sizeStr; 318 } 319 320 argv[argc++] = (char*)device; 321 BEGET_ERROR_CHECK(argc <= MAX_RESIZE_PARAM_NUM, return -1, "argc: %d is too big.", argc); 322 return ExecCommand(argc, argv); 323} 324 325static int DoFsckF2fs(const char* device) 326{ 327 char *file = "/system/bin/fsck.f2fs"; 328 BEGET_ERROR_CHECK(access(file, F_OK) == 0, return -1, "fsck.f2fs is not exists."); 329 330 char *cmd[] = { 331 file, "-p1", (char *)device, NULL 332 }; 333 334 int argc = ARRAY_LENGTH(cmd); 335 char **argv = (char **)cmd; 336 InitTimerControl(true); 337 int ret = ExecCommand(argc, argv); 338 InitTimerControl(false); 339 return ret; 340} 341 342static int DoResizeExt(const char* device, const unsigned long long size) 343{ 344 char *file = "/system/bin/resize2fs"; 345 BEGET_ERROR_CHECK(access(file, F_OK) == 0, return -1, "resize2fs is not exists."); 346 347 int ret = 0; 348 if (size == 0) { 349 char *cmd[] = { 350 file, "-f", (char *)device, NULL 351 }; 352 int argc = ARRAY_LENGTH(cmd); 353 char **argv = (char **)cmd; 354 ret = ExecCommand(argc, argv); 355 } else { 356 char sizeStr[RESIZE_BUFFER_SIZE] = {0}; 357 int len = sprintf_s(sizeStr, RESIZE_BUFFER_SIZE, "%lluM", size); 358 if (len <= 0) { 359 BEGET_LOGE("Write buffer size failed."); 360 } 361 char *cmd[] = { 362 file, "-f", (char *)device, sizeStr, NULL 363 }; 364 int argc = ARRAY_LENGTH(cmd); 365 char **argv = (char **)cmd; 366 ret = ExecCommand(argc, argv); 367 } 368 return ret; 369} 370 371static int DoFsckExt(const char* device) 372{ 373 char *file = "/system/bin/e2fsck"; 374 BEGET_ERROR_CHECK(access(file, F_OK) == 0, return -1, "e2fsck is not exists."); 375 376 char *cmd[] = { 377 file, "-y", (char *)device, NULL 378 }; 379 int argc = ARRAY_LENGTH(cmd); 380 char **argv = (char **)cmd; 381 return ExecCommand(argc, argv); 382} 383 384static int Mount(const char *source, const char *target, const char *fsType, 385 unsigned long flags, const char *data) 386{ 387 struct stat st = {}; 388 int rc = -1; 389 390 bool isTrue = source == NULL || target == NULL || fsType == NULL; 391 BEGET_ERROR_CHECK(!isTrue, return -1, "Invalid argument for mount."); 392 393 isTrue = stat(target, &st) != 0 && errno != ENOENT; 394 BEGET_ERROR_CHECK(!isTrue, return -1, "Cannot get stat of \" %s \", err = %d", target, errno); 395 396 BEGET_CHECK((st.st_mode & S_IFMT) != S_IFLNK, unlink(target)); // link, delete it. 397 398 if (mkdir(target, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) { 399 BEGET_ERROR_CHECK(errno == EEXIST, return -1, "Failed to create dir \" %s \", err = %d", target, errno); 400 } 401 errno = 0; 402 if ((rc = mount(source, target, fsType, flags, data)) != 0) { 403 BEGET_WARNING_CHECK(errno != EBUSY, rc = 0, "Mount %s to %s busy, ignore", source, target); 404 } 405 return rc; 406} 407 408static int GetSlotInfoFromCmdLine(const char *slotInfoName) 409{ 410 char value[MAX_BUFFER_LEN] = {0}; 411 BEGET_INFO_CHECK(GetParameterFromCmdLine(slotInfoName, value, MAX_BUFFER_LEN) == 0, 412 return -1, "Failed to get %s value from cmdline", slotInfoName); 413 return atoi(value); 414} 415 416static int GetSlotInfoFromBootctrl(off_t offset, off_t size) 417{ 418 char bootctrlDev[MAX_BUFFER_LEN] = {0}; 419 BEGET_ERROR_CHECK(GetBlockDevicePath("/bootctrl", bootctrlDev, MAX_BUFFER_LEN) == 0, 420 return -1, "Failed to get bootctrl device"); 421 char *realPath = GetRealPath(bootctrlDev); 422 BEGET_ERROR_CHECK(realPath != NULL, return -1, "Failed to get bootctrl device real path"); 423 int fd = open(realPath, O_RDWR | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 424 free(realPath); 425 BEGET_ERROR_CHECK(fd >= 0, return -1, "Failed to open bootctrl device, errno %d", errno); 426 BEGET_ERROR_CHECK(lseek(fd, offset, SEEK_SET) >= 0, close(fd); return -1, 427 "Failed to lseek bootctrl device fd, errno %d", errno); 428 int slotInfo = 0; 429 BEGET_INFO_CHECK(read(fd, &slotInfo, sizeof(slotInfo)) == size, close(fd); return -1, 430 "Failed to read current slot from bootctrl, errno %d", errno); 431 close(fd); 432 return slotInfo; 433} 434 435int GetBootSlots(void) 436{ 437 return GetSlotInfoFromCmdLine("bootslots"); 438} 439 440int GetCurrentSlot(void) 441{ 442 // get current slot from cmdline 443 int currentSlot = GetSlotInfoFromCmdLine("currentslot"); 444 BEGET_CHECK_RETURN_VALUE(currentSlot <= 0, currentSlot); 445 BEGET_LOGI("No valid slot value found from cmdline, try to get it from bootctrl"); 446 447 // get current slot from bootctrl 448 return GetSlotInfoFromBootctrl(PARTITION_ACTIVE_SLOT_OFFSET, PARTITION_ACTIVE_SLOT_SIZE); 449} 450 451static int DoMountOneItem(FstabItem *item) 452{ 453 BEGET_LOGI("Mount device %s to %s", item->deviceName, item->mountPoint); 454 unsigned long mountFlags; 455 char fsSpecificData[FS_MANAGER_BUFFER_SIZE] = {0}; 456 457 mountFlags = GetMountFlags(item->mountOptions, fsSpecificData, sizeof(fsSpecificData), 458 item->mountPoint); 459 460 int retryCount = 3; 461 int rc = 0; 462 while (retryCount-- > 0) { 463 rc = Mount(item->deviceName, item->mountPoint, item->fsType, mountFlags, fsSpecificData); 464 if (rc == 0) { 465 return rc; 466 } 467 468 if (FM_MANAGER_FORMATTABLE_ENABLED(item->fsManagerFlags)) { 469 BEGET_LOGI("Device is formattable"); 470 int ret = DoFormat(item->deviceName, item->fsType); 471 BEGET_LOGI("End format image ret %d", ret); 472 if (ret != 0) { 473 continue; 474 } 475 rc = Mount(item->deviceName, item->mountPoint, item->fsType, mountFlags, fsSpecificData); 476 if (rc == 0) { 477 return rc; 478 } 479 } 480 BEGET_LOGE("Mount device %s to %s failed, err = %d, retry", item->deviceName, item->mountPoint, errno); 481 } 482 return rc; 483} 484 485#ifdef EROFS_OVERLAY 486static int MountItemByFsType(FstabItem *item) 487{ 488 if (CheckIsErofs(item->deviceName)) { 489 if (strcmp(item->fsType, "erofs") == 0) { 490 if (IsOverlayEnable()) { 491 return DoMountOverlayDevice(item); 492 } 493 int rc = DoMountOneItem(item); 494 if (rc == 0 && strcmp(item->mountPoint, "/usr") == 0) { 495 SwitchRoot("/usr"); 496 } 497 return rc; 498 } else { 499 BEGET_LOGI("fsType not erofs system, device [%s] skip erofs mount process", item->deviceName); 500 return 0; 501 } 502 } 503 504 if (strcmp(item->fsType, "erofs") != 0) { 505 int rc = DoMountOneItem(item); 506 if (rc == 0 && strcmp(item->mountPoint, "/usr") == 0) { 507 SwitchRoot("/usr"); 508 } 509 return rc; 510 } 511 512 BEGET_LOGI("fsType is erofs system, device [%s] skip ext4 or hms mount process", item->deviceName); 513 return 0; 514} 515#endif 516 517int MountOneItem(FstabItem *item) 518{ 519 if (item == NULL) { 520 return -1; 521 } 522 523 if (FM_MANAGER_WAIT_ENABLED(item->fsManagerFlags)) { 524 WaitForFile(item->deviceName, WAIT_MAX_SECOND); 525 } 526 527 if (strcmp(item->mountPoint, "/data") == 0 && IsSupportedDataType(item->fsType)) { 528 int ret = DoResizeF2fs(item->deviceName, 0, item->fsManagerFlags); 529 if (ret != 0) { 530 BEGET_LOGE("Failed to resize.f2fs dir %s , ret = %d", item->deviceName, ret); 531 } 532 533 ret = DoFsckF2fs(item->deviceName); 534 if (ret != 0) { 535 BEGET_LOGE("Failed to fsck.f2fs dir %s , ret = %d", item->deviceName, ret); 536 } 537 } else if (strcmp(item->fsType, "ext4") == 0 && strcmp(item->mountPoint, "/data") == 0) { 538 int ret = DoResizeExt(item->deviceName, 0); 539 if (ret != 0) { 540 BEGET_LOGE("Failed to resize2fs dir %s , ret = %d", item->deviceName, ret); 541 } 542 ret = DoFsckExt(item->deviceName); 543 if (ret != 0) { 544 BEGET_LOGE("Failed to e2fsck dir %s , ret = %d", item->deviceName, ret); 545 } 546 } 547 548 int rc = 0; 549#ifdef EROFS_OVERLAY 550 rc = MountItemByFsType(item); 551#else 552 rc = DoMountOneItem(item); 553 if (rc == 0 && (strcmp(item->mountPoint, "/usr") == 0)) { 554 SwitchRoot("/usr"); 555 } 556#endif 557 InitPostMount(item->mountPoint, rc); 558 if (rc != 0) { 559 if (FM_MANAGER_NOFAIL_ENABLED(item->fsManagerFlags)) { 560 BEGET_LOGE("Mount no fail device %s to %s failed, err = %d", item->deviceName, item->mountPoint, errno); 561 } else { 562 BEGET_LOGW("Mount %s to %s failed, err = %d. Ignore failure", item->deviceName, item->mountPoint, errno); 563 rc = 0; 564 } 565 } else { 566 BEGET_LOGI("Mount %s to %s successful", item->deviceName, item->mountPoint); 567 } 568 return rc; 569} 570 571#if defined EROFS_OVERLAY && defined SUPPORT_HVB 572static bool NeedDmVerity(FstabItem *item) 573{ 574 if (CheckIsErofs(item->deviceName)) { 575 if (strcmp(item->fsType, "erofs") == 0) { 576 return true; 577 } 578 } else { 579 if (strcmp(item->fsType, "erofs") != 0) { 580 return true; 581 } 582 } 583 return false; 584} 585#endif 586 587static void AdjustPartitionNameByPartitionSlot(FstabItem *item) 588{ 589 BEGET_CHECK_ONLY_RETURN(strstr(item->deviceName, "/system") != NULL || 590 strstr(item->deviceName, "/vendor") != NULL); 591 char buffer[MAX_BUFFER_LEN] = {0}; 592 int slot = GetCurrentSlot(); 593 BEGET_ERROR_CHECK(slot > 0 && slot <= MAX_SLOT, slot = 1, "slot value %d is invalid, set default value", slot); 594 BEGET_ERROR_CHECK(sprintf_s(buffer, sizeof(buffer), "%s_%c", item->deviceName, 'a' + slot - 1) > 0, 595 return, "Failed to format partition name suffix, use default partition name"); 596 free(item->deviceName); 597 item->deviceName = strdup(buffer); 598 if (item->deviceName == NULL) { 599 BEGET_LOGE("failed dup devicename"); 600 return; 601 } 602 BEGET_LOGI("partition name with slot suffix: %s", item->deviceName); 603} 604 605static int CheckRequiredAndMount(FstabItem *item, bool required) 606{ 607 int rc = 0; 608 if (item == NULL) { 609 return -1; 610 } 611 612 // Mount partition during second startup. 613 if (!required) { 614 if (!FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) { 615 rc = MountOneItem(item); 616 } 617 return rc; 618 } 619 620 // Mount partition during one startup. 621 if (FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) { 622 int bootSlots = GetBootSlots(); 623 BEGET_INFO_CHECK(bootSlots <= 1, AdjustPartitionNameByPartitionSlot(item), 624 "boot slots is %d, now adjust partition name according to current slot", bootSlots); 625#ifdef SUPPORT_HVB 626#ifdef EROFS_OVERLAY 627 if (!NeedDmVerity(item)) { 628 BEGET_LOGI("not need dm verity, do mount item %s", item->deviceName); 629 return MountOneItem(item); 630 } 631#endif 632 rc = HvbDmVeritySetUp(item); 633 if (rc != 0) { 634 BEGET_LOGE("set dm_verity err, ret = 0x%x", rc); 635 if (!FM_MANAGER_NOFAIL_ENABLED(item->fsManagerFlags)) { 636 rc = 0; 637 BEGET_LOGW("DmVeritySetUp fail for %s, ignore error and do not mount", item->deviceName); 638 } else { 639 BEGET_LOGE("DmVeritySetUp fail for no fail devices %s, error!", item->deviceName); 640 } 641 return rc; 642 } 643#endif 644 rc = MountOneItem(item); 645 } 646 return rc; 647} 648 649int MountAllWithFstab(const Fstab *fstab, bool required) 650{ 651 BEGET_CHECK(fstab != NULL, return -1); 652 653 FstabItem *item = NULL; 654 int rc = -1; 655 656#ifdef SUPPORT_HVB 657 if (required) { 658 rc = HvbDmVerityinit(fstab); 659 if (rc != 0) { 660 BEGET_LOGE("set dm_verity init, ret = 0x%x", rc); 661 return rc; 662 } 663 } 664#endif 665 666 for (item = fstab->head; item != NULL; item = item->next) { 667 rc = CheckRequiredAndMount(item, required); 668 if (required && (rc < 0)) { // Init fail to mount in the first stage and exit directly. 669 break; 670 } 671 } 672 673#ifdef SUPPORT_HVB 674 if (required) 675 HvbDmVerityFinal(); 676#endif 677 678 return rc; 679} 680 681int MountAllWithFstabFile(const char *fstabFile, bool required) 682{ 683 bool isFile = fstabFile == NULL || *fstabFile == '\0'; 684 BEGET_CHECK(!isFile, return -1); 685 686 Fstab *fstab = NULL; 687 if ((fstab = ReadFstabFromFile(fstabFile, false)) == NULL) { 688 BEGET_LOGE("[fs_manager][error] Read fstab file \" %s \" failed\n", fstabFile); 689 return -1; 690 } 691 692 int rc = MountAllWithFstab(fstab, required); 693 if (rc != 0) { 694 BEGET_LOGE("[startup_failed]MountAllWithFstab failed %s %d %d %d", fstabFile, FSTAB_MOUNT_FAILED, required, rc); 695 } 696 ReleaseFstab(fstab); 697 fstab = NULL; 698 return rc; 699} 700 701int UmountAllWithFstabFile(const char *fstabFile) 702{ 703 bool isFile = fstabFile == NULL || *fstabFile == '\0'; 704 BEGET_CHECK(!isFile, return -1); 705 706 Fstab *fstab = NULL; 707 fstab = ReadFstabFromFile(fstabFile, false); 708 BEGET_ERROR_CHECK(fstab != NULL, return -1, "Read fstab file \" %s \" failed.", fstabFile); 709 710 FstabItem *item = NULL; 711 int rc = -1; 712 for (item = fstab->head; item != NULL; item = item->next) { 713 BEGET_LOGI("Umount %s.", item->mountPoint); 714 MountStatus status = GetMountStatusForMountPoint(item->mountPoint); 715 if (status == MOUNT_ERROR) { 716 BEGET_LOGW("Cannot get mount status of mount point \" %s \"", item->mountPoint); 717 continue; // Cannot get mount status, just ignore it and try next one. 718 } else if (status == MOUNT_UMOUNTED) { 719 BEGET_LOGI("Mount point \" %s \" already unmounted. device path: %s, fs type: %s.", 720 item->mountPoint, item->deviceName, item->fsType); 721 continue; 722 } else { 723 rc = umount(item->mountPoint); 724 if (rc == -1) { 725 BEGET_LOGE("Umount %s failed, device path: %s, fs type: %s, err = %d.", 726 item->mountPoint, item->deviceName, item->fsType, errno); 727 } else { 728 BEGET_LOGE("Umount %s successfully.", item->mountPoint); 729 } 730 } 731 } 732 ReleaseFstab(fstab); 733 fstab = NULL; 734 return rc; 735} 736 737int FsManagerDmRemoveDevice(const char *devName) 738{ 739#ifdef SUPPORT_HVB 740 return FsDmRemoveDevice(devName); 741#endif 742 return 0; 743} 744 745int MountOneWithFstabFile(const char *fstabFile, const char *devName, bool required) 746{ 747 bool isFile = fstabFile == NULL || *fstabFile == '\0'; 748 BEGET_CHECK(!isFile, return -1); 749 750 Fstab *fstab = NULL; 751 fstab = ReadFstabFromFile(fstabFile, false); 752 BEGET_ERROR_CHECK(fstab != NULL, return -1, "Read fstab file \" %s \" failed.", fstabFile); 753 754 FstabItem *item = NULL; 755 int rc = -1; 756 757#ifdef SUPPORT_HVB 758 if (required) { 759 rc = HvbDmVerityinit(fstab); 760 if (rc != 0) { 761 BEGET_LOGE("set dm_verity init, ret = 0x%x", rc); 762 return rc; 763 } 764 } 765#endif 766 767 for (item = fstab->head; item != NULL; item = item->next) { 768 if (strcmp(item->mountPoint, devName) == 0) { 769 rc = CheckRequiredAndMount(item, required); 770 break; 771 } 772 } 773 774#ifdef SUPPORT_HVB 775 if (required) { 776 HvbDmVerityFinal(); 777 } 778#endif 779 780 ReleaseFstab(fstab); 781 fstab = NULL; 782 return rc; 783} 784 785#ifdef __cplusplus 786#if __cplusplus 787} 788#endif 789#endif 790