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