1c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* 2c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * Copyright (C) 2012 The Android Open Source Project 3c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 4c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * Licensed under the Apache License, Version 2.0 (the "License"); 5c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * you may not use this file except in compliance with the License. 6c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * You may obtain a copy of the License at 7c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 8c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * http://www.apache.org/licenses/LICENSE-2.0 9c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 10c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * Unless required by applicable law or agreed to in writing, software 11c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * distributed under the License is distributed on an "AS IS" BASIS, 12c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * See the License for the specific language governing permissions and 14c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * limitations under the License. 15c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 16c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 17c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* TO DO: 18c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 1. Re-direct fsck output to the kernel log? 19c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 20c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 21c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 22c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <stdio.h> 23c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <stdlib.h> 24c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <string.h> 25c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <unistd.h> 26c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <fcntl.h> 27c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <ctype.h> 28c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <sys/mount.h> 29c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <sys/stat.h> 30c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <errno.h> 31c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <sys/types.h> 32c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <sys/wait.h> 33c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <libgen.h> 34c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <time.h> 35c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 36c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <private/android_filesystem_config.h> 37c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <cutils/partition_utils.h> 38c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <cutils/properties.h> 39c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 40c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include "fs_mgr_priv.h" 41c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 42c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define KEY_LOC_PROP "ro.crypto.keyfile.userdata" 43c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define KEY_IN_FOOTER "footer" 44c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 45c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define E2FSCK_BIN "/system/bin/e2fsck" 46c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 47c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstruct flag_list { 48c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall const char *name; 49c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall unsigned flag; 50c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}; 51c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 52c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic struct flag_list mount_flags[] = { 53c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "noatime", MS_NOATIME }, 54c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "noexec", MS_NOEXEC }, 55c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "nosuid", MS_NOSUID }, 56c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "nodev", MS_NODEV }, 57c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "nodiratime", MS_NODIRATIME }, 58c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "ro", MS_RDONLY }, 59c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "rw", 0 }, 60c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "remount", MS_REMOUNT }, 61e50ac5f7771872331df70251d23d6bd8155da4a7Jeff Sharkey { "bind", MS_BIND }, 62e50ac5f7771872331df70251d23d6bd8155da4a7Jeff Sharkey { "rec", MS_REC }, 63e50ac5f7771872331df70251d23d6bd8155da4a7Jeff Sharkey { "unbindable", MS_UNBINDABLE }, 64e50ac5f7771872331df70251d23d6bd8155da4a7Jeff Sharkey { "private", MS_PRIVATE }, 65e50ac5f7771872331df70251d23d6bd8155da4a7Jeff Sharkey { "slave", MS_SLAVE }, 66e50ac5f7771872331df70251d23d6bd8155da4a7Jeff Sharkey { "shared", MS_SHARED }, 67c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "defaults", 0 }, 68c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { 0, 0 }, 69c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}; 70c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 71c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic struct flag_list fs_mgr_flags[] = { 72c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "wait", MF_WAIT }, 73c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "check", MF_CHECK }, 74c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "encryptable=",MF_CRYPT }, 75c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "defaults", 0 }, 76c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { 0, 0 }, 77c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}; 78c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 79c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* 80c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * gettime() - returns the time in seconds of the system's monotonic clock or 81c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * zero on error. 82c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 83c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic time_t gettime(void) 84c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 85c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct timespec ts; 86c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret; 87c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 88c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = clock_gettime(CLOCK_MONOTONIC, &ts); 89c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (ret < 0) { 90c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno)); 91c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 92c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 93c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 94c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ts.tv_sec; 95c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 96c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 97c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int wait_for_file(const char *filename, int timeout) 98c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 99c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct stat info; 100c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall time_t timeout_time = gettime() + timeout; 101c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret = -1; 102c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 103c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0)) 104c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall usleep(10000); 105c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 106c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 107c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 108c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 109c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int parse_flags(char *flags, struct flag_list *fl, char **key_loc, 110c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *fs_options, int fs_options_len) 111c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 112c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int f = 0; 113c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i; 114c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *p; 115c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *savep; 116c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 117c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* initialize key_loc to null, if we find an MF_CRYPT flag, 118c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * then we'll set key_loc to the proper value */ 119c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (key_loc) { 120c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *key_loc = NULL; 121c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 122c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* initialize fs_options to the null string */ 123c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fs_options && (fs_options_len > 0)) { 124c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fs_options[0] = '\0'; 125c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 126c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 127c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p = strtok_r(flags, ",", &savep); 128c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (p) { 129c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Look for the flag "p" in the flag list "fl" 130c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * If not found, the loop exits with fl[i].name being null. 131c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 132c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall for (i = 0; fl[i].name; i++) { 133c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!strncmp(p, fl[i].name, strlen(fl[i].name))) { 134c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall f |= fl[i].flag; 135c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if ((fl[i].flag == MF_CRYPT) && key_loc) { 136c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* The encryptable flag is followed by an = and the 137c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * location of the keys. Get it and return it. 138c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 139c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *key_loc = strdup(strchr(p, '=') + 1); 140c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 141c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 142c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 143c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 144c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 145c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!fl[i].name) { 146c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fs_options) { 147c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* It's not a known flag, so it must be a filesystem specific 148c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * option. Add it to fs_options if it was passed in. 149c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 150c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall strlcat(fs_options, p, fs_options_len); 151c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall strlcat(fs_options, ",", fs_options_len); 152c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 153c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* fs_options was not passed in, so if the flag is unknown 154c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * it's an error. 155c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 156c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Warning: unknown flag %s\n", p); 157c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 158c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 159c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p = strtok_r(NULL, ",", &savep); 160c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 161c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 162c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout: 163c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fs_options && fs_options[0]) { 164c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* remove the last trailing comma from the list of options */ 165c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fs_options[strlen(fs_options) - 1] = '\0'; 166c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 167c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 168c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return f; 169c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 170c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 171c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* Read a line of text till the next newline character. 172c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * If no newline is found before the buffer is full, continue reading till a new line is seen, 173c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * then return an empty buffer. This effectively ignores lines that are too long. 174c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * On EOF, return null. 175c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 176c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic char *getline(char *buf, int size, FILE *file) 177c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 178c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int cnt = 0; 179c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int eof = 0; 180c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int eol = 0; 181c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int c; 182c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 183c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (size < 1) { 184c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return NULL; 185c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 186c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 187c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (cnt < (size - 1)) { 188c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall c = getc(file); 189c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (c == EOF) { 190c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall eof = 1; 191c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 192c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 193c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 194c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *(buf + cnt) = c; 195c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall cnt++; 196c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 197c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (c == '\n') { 198c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall eol = 1; 199c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 200c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 201c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 202c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 203c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Null terminate what we've read */ 204c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *(buf + cnt) = '\0'; 205c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 206c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (eof) { 207c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (cnt) { 208c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return buf; 209c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 210c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return NULL; 211c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 212c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else if (eol) { 213c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return buf; 214c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 215c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* The line is too long. Read till a newline or EOF. 216c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * If EOF, return null, if newline, return an empty buffer. 217c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 218c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while(1) { 219c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall c = getc(file); 220c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (c == EOF) { 221c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return NULL; 222c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else if (c == '\n') { 223c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *buf = '\0'; 224c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return buf; 225c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 226c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 227c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 228c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 229c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 230c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic struct fstab_rec *read_fstab(char *fstab_path) 231c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 232c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall FILE *fstab_file; 233c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int cnt, entries; 234c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int len; 235c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char line[256]; 236c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall const char *delim = " \t"; 237c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *save_ptr, *p; 238c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab; 239c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *key_loc; 240c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define FS_OPTIONS_LEN 1024 241c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char tmp_fs_options[FS_OPTIONS_LEN]; 242c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 243c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab_file = fopen(fstab_path, "r"); 244c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!fstab_file) { 245c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot open file %s\n", fstab_path); 246c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 247c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 248c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 249c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall entries = 0; 250c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (getline(line, sizeof(line), fstab_file)) { 251c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* if the last character is a newline, shorten the string by 1 byte */ 252c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall len = strlen(line); 253c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (line[len - 1] == '\n') { 254c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall line[len - 1] = '\0'; 255c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 256c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Skip any leading whitespace */ 257c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p = line; 258c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (isspace(*p)) { 259c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p++; 260c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 261c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* ignore comments or empty lines */ 262c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (*p == '#' || *p == '\0') 263c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 264c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall entries++; 265c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 266c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 267c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!entries) { 268c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("No entries found in fstab\n"); 269c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 270c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 271c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 272c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab = calloc(entries + 1, sizeof(struct fstab_rec)); 273c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 274c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fseek(fstab_file, 0, SEEK_SET); 275c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 276c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall cnt = 0; 277c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (getline(line, sizeof(line), fstab_file)) { 278c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* if the last character is a newline, shorten the string by 1 byte */ 279c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall len = strlen(line); 280c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (line[len - 1] == '\n') { 281c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall line[len - 1] = '\0'; 282c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 283c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 284c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Skip any leading whitespace */ 285c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p = line; 286c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (isspace(*p)) { 287c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p++; 288c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 289c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* ignore comments or empty lines */ 290c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (*p == '#' || *p == '\0') 291c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 292c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 293c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* If a non-comment entry is greater than the size we allocated, give an 294c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * error and quit. This can happen in the unlikely case the file changes 295c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * between the two reads. 296c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 297c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (cnt >= entries) { 298c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Tried to process more entries than counted\n"); 299c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 300c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 301c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 302c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(line, delim, &save_ptr))) { 303c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing mount source\n"); 304c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 305c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 306c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].blk_dev = strdup(p); 307c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 308c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(NULL, delim, &save_ptr))) { 309c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing mnt_point\n"); 310c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 311c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 312c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].mnt_point = strdup(p); 313c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 314c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(NULL, delim, &save_ptr))) { 315c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing fs_type\n"); 316c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 317c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 318c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].type = strdup(p); 319c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 320c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(NULL, delim, &save_ptr))) { 321c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing mount_flags\n"); 322c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 323c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 324c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall tmp_fs_options[0] = '\0'; 325c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].flags = parse_flags(p, mount_flags, 0, tmp_fs_options, FS_OPTIONS_LEN); 326c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 327c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* fs_options are optional */ 328c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (tmp_fs_options[0]) { 329c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].fs_options = strdup(tmp_fs_options); 330c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 331c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].fs_options = NULL; 332c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 333c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 334c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(NULL, delim, &save_ptr))) { 335c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing fs_mgr_options\n"); 336c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 337c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 338c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags, &key_loc, 0, 0); 339c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].key_loc = key_loc; 340c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 341c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall cnt++; 342c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 343c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fclose(fstab_file); 344c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 345c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return fstab; 346c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 347c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 348c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic void free_fstab(struct fstab_rec *fstab) 349c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 350c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 351c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 352c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (fstab[i].blk_dev) { 353c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Free the pointers return by strdup(3) */ 354c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].blk_dev); 355c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].mnt_point); 356c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].type); 357c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].fs_options); 358c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].key_loc); 359c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 360c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall i++; 361c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 362c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 363c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Free the actual fstab array created by calloc(3) */ 364c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab); 365c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 366c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 3675dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrallstatic void check_fs(char *blk_dev, char *type, char *target) 368c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 369c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall pid_t pid; 370c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int status; 3715dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall int ret; 3725dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID; 3735dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro"; 374c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 375c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Check for the types of filesystems we know how to check */ 376c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!strcmp(type, "ext2") || !strcmp(type, "ext3") || !strcmp(type, "ext4")) { 3775dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall /* 3785dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * First try to mount and unmount the filesystem. We do this because 3795dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * the kernel is more efficient than e2fsck in running the journal and 3805dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * processing orphaned inodes, and on at least one device with a 3815dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes 3825dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * to do what the kernel does in about a second. 3835dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * 3845dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * After mounting and unmounting the filesystem, run e2fsck, and if an 3855dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * error is recorded in the filesystem superblock, e2fsck will do a full 3865dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * check. Otherwise, it does nothing. If the kernel cannot mount the 3875dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * filesytsem due to an error, e2fsck is still run to do a full check 3885dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall * fix the filesystem. 3895dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall */ 3905dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall ret = mount(blk_dev, target, type, tmpmnt_flags, tmpmnt_opts); 3915dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall if (! ret) { 3925dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall umount(target); 3935dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall } 3945dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall 395c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall INFO("Running %s on %s\n", E2FSCK_BIN, blk_dev); 396c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall pid = fork(); 397c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (pid > 0) { 398c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Parent, wait for the child to return */ 399c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall waitpid(pid, &status, 0); 400c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else if (pid == 0) { 401c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* child, run checker */ 402c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall execlp(E2FSCK_BIN, E2FSCK_BIN, "-y", blk_dev, (char *)NULL); 403c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 404c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Only gets here on error */ 405c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot run fs_mgr binary %s\n", E2FSCK_BIN); 406c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 407c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* No need to check for error in fork, we can't really handle it now */ 408c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Fork failed trying to run %s\n", E2FSCK_BIN); 409c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 410c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 411c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 412c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return; 413c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 414c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 415c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic void remove_trailing_slashes(char *n) 416c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 417c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int len; 418c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 419c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall len = strlen(n) - 1; 420c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while ((*(n + len) == '/') && len) { 421c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *(n + len) = '\0'; 422c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall len--; 423c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 424c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 425c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 426c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int fs_match(char *in1, char *in2) 427c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 428c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *n1; 429c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *n2; 430c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret; 431c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 432c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall n1 = strdup(in1); 433c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall n2 = strdup(in2); 434c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 435c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall remove_trailing_slashes(n1); 436c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall remove_trailing_slashes(n2); 437c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 438c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = !strcmp(n1, n2); 439c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 440c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(n1); 441c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(n2); 442c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 443c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 444c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 445c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 446c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_mount_all(char *fstab_file) 447c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 448c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 449c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int encrypted = 0; 450c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret = -1; 451c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int mret; 452c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab = 0; 453c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 454c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab = read_fstab(fstab_file))) { 455c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 456c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 457c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 458c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall for (i = 0; fstab[i].blk_dev; i++) { 459c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fstab[i].fs_mgr_flags & MF_WAIT) { 460c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT); 461c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 462c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 463c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fstab[i].fs_mgr_flags & MF_CHECK) { 4645dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall check_fs(fstab[i].blk_dev, fstab[i].type, fstab[i].mnt_point); 465c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 466c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 467c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall mret = mount(fstab[i].blk_dev, fstab[i].mnt_point, fstab[i].type, 468c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[i].flags, fstab[i].fs_options); 469c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!mret) { 470c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Success! Go get the next one */ 471c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 472c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 473c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 474c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* mount(2) returned an error, check if it's encrypted and deal with it */ 475c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if ((fstab[i].fs_mgr_flags & MF_CRYPT) && !partition_wiped(fstab[i].blk_dev)) { 476c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Need to mount a tmpfs at this mountpoint for now, and set 477c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * properties that vold will query later for decrypting 478c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 479c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (mount("tmpfs", fstab[i].mnt_point, "tmpfs", 480c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) { 481c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s\n", 482c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[i].mnt_point); 483c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall goto out; 484c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 485c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall encrypted = 1; 486c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 487c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot mount filesystem on %s at %s\n", 488c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[i].blk_dev, fstab[i].mnt_point); 489c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall goto out; 490c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 491c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 492c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 493c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (encrypted) { 494c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = 1; 495c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 496c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = 0; 497c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 498c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 499c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout: 500c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free_fstab(fstab); 501c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 502c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 503c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 504c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* If tmp_mnt_point is non-null, mount the filesystem there. This is for the 505c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * tmp mount we do to check the user password 506c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 507c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_do_mount(char *fstab_file, char *n_name, char *n_blk_dev, char *tmp_mnt_point) 508c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 509c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 510c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret = -1; 511c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab = 0; 512c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *m; 513c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 514c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab = read_fstab(fstab_file))) { 515c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 516c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 517c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 518c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall for (i = 0; fstab[i].blk_dev; i++) { 519c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!fs_match(fstab[i].mnt_point, n_name)) { 520c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 521c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 522c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 523c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* We found our match */ 524c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* First check the filesystem if requested */ 525c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fstab[i].fs_mgr_flags & MF_WAIT) { 526c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT); 527c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 528c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 529c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fstab[i].fs_mgr_flags & MF_CHECK) { 5305dc5bfefa078f2aded34f85db4613ba91ad49b76Ken Sumrall check_fs(fstab[i].blk_dev, fstab[i].type, fstab[i].mnt_point); 531c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 532c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 533c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Now mount it where requested */ 534c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (tmp_mnt_point) { 535c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall m = tmp_mnt_point; 536c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 537c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall m = fstab[i].mnt_point; 538c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 539c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (mount(n_blk_dev, m, fstab[i].type, 540c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[i].flags, fstab[i].fs_options)) { 541c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot mount filesystem on %s at %s\n", 542c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall n_blk_dev, m); 543c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall goto out; 544c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 545c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = 0; 546c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall goto out; 547c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 548c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 549c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 550c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* We didn't find a match, say so and return an error */ 551c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot find mount point %s in fstab\n", fstab[i].mnt_point); 552c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 553c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout: 554c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free_fstab(fstab); 555c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 556c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 557c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 558c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* 559c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * mount a tmpfs filesystem at the given point. 560c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * return 0 on success, non-zero on failure. 561c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 562c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_do_tmpfs_mount(char *n_name) 563c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 564c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret; 565c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 566c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = mount("tmpfs", n_name, "tmpfs", 567c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS); 568c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (ret < 0) { 569c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot mount tmpfs filesystem at %s\n", n_name); 570c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return -1; 571c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 572c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 573c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Success */ 574c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 575c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 576c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 577c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_unmount_all(char *fstab_file) 578c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 579c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 580c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret = 0; 581c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab = 0; 582c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 583c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab = read_fstab(fstab_file))) { 584c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return -1; 585c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 586c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 587c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (fstab[i].blk_dev) { 588c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (umount(fstab[i].mnt_point)) { 589c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot unmount filesystem at %s\n", fstab[i].mnt_point); 590c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = -1; 591c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 592c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall i++; 593c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 594c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 595c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free_fstab(fstab); 596c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 597c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 598c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* 599c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * key_loc must be at least PROPERTY_VALUE_MAX bytes long 600c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 601c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * real_blk_dev must be at least PROPERTY_VALUE_MAX bytes long 602c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 603c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_get_crypt_info(char *fstab_file, char *key_loc, char *real_blk_dev, int size) 604c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 605c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 606c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab = 0; 607c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 608c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab = read_fstab(fstab_file))) { 609c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return -1; 610c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 611c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Initialize return values to null strings */ 612c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (key_loc) { 613c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *key_loc = '\0'; 614c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 615c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (real_blk_dev) { 616c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *real_blk_dev = '\0'; 617c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 618c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 619c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Look for the encryptable partition to find the data */ 620c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall for (i = 0; fstab[i].blk_dev; i++) { 621c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab[i].fs_mgr_flags & MF_CRYPT)) { 622c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 623c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 624c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 625c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* We found a match */ 626c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (key_loc) { 627c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall strlcpy(key_loc, fstab[i].key_loc, size); 628c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 629c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (real_blk_dev) { 630c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall strlcpy(real_blk_dev, fstab[i].blk_dev, size); 631c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 632c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 633c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 634c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 635c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free_fstab(fstab); 636c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 637c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 638c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 639