fs_mgr.c revision c1bf89663ca71949b508007d4df2b5b06038f96d
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 },
61c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    { "defaults",   0 },
62c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    { 0,            0 },
63c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall};
64c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
65c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic struct flag_list fs_mgr_flags[] = {
66c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    { "wait",        MF_WAIT },
67c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    { "check",       MF_CHECK },
68c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    { "encryptable=",MF_CRYPT },
69c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    { "defaults",    0 },
70c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    { 0,             0 },
71c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall};
72c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
73c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/*
74c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * gettime() - returns the time in seconds of the system's monotonic clock or
75c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * zero on error.
76c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */
77c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic time_t gettime(void)
78c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
79c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    struct timespec ts;
80c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int ret;
81c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
82c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    ret = clock_gettime(CLOCK_MONOTONIC, &ts);
83c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (ret < 0) {
84c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno));
85c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return 0;
86c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
87c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
88c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return ts.tv_sec;
89c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
90c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
91c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int wait_for_file(const char *filename, int timeout)
92c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
93c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    struct stat info;
94c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    time_t timeout_time = gettime() + timeout;
95c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int ret = -1;
96c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
97c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
98c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        usleep(10000);
99c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
100c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return ret;
101c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
102c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
103c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int parse_flags(char *flags, struct flag_list *fl, char **key_loc,
104c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                       char *fs_options, int fs_options_len)
105c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
106c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int f = 0;
107c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int i;
108c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char *p;
109c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char *savep;
110c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
111c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* initialize key_loc to null, if we find an MF_CRYPT flag,
112c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall     * then we'll set key_loc to the proper value */
113c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (key_loc) {
114c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        *key_loc = NULL;
115c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
116c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* initialize fs_options to the null string */
117c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (fs_options && (fs_options_len > 0)) {
118c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        fs_options[0] = '\0';
119c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
120c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
121c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    p = strtok_r(flags, ",", &savep);
122c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    while (p) {
123c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* Look for the flag "p" in the flag list "fl"
124c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall         * If not found, the loop exits with fl[i].name being null.
125c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall         */
126c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        for (i = 0; fl[i].name; i++) {
127c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            if (!strncmp(p, fl[i].name, strlen(fl[i].name))) {
128c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                f |= fl[i].flag;
129c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                if ((fl[i].flag == MF_CRYPT) && key_loc) {
130c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                    /* The encryptable flag is followed by an = and the
131c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                     * location of the keys.  Get it and return it.
132c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                     */
133c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                    *key_loc = strdup(strchr(p, '=') + 1);
134c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                }
135c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                break;
136c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            }
137c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
138c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
139c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!fl[i].name) {
140c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            if (fs_options) {
141c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                /* It's not a known flag, so it must be a filesystem specific
142c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                 * option.  Add it to fs_options if it was passed in.
143c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                 */
144c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                strlcat(fs_options, p, fs_options_len);
145c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                strlcat(fs_options, ",", fs_options_len);
146c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            } else {
147c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                /* fs_options was not passed in, so if the flag is unknown
148c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                 * it's an error.
149c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                 */
150c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                ERROR("Warning: unknown flag %s\n", p);
151c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            }
152c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
153c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        p = strtok_r(NULL, ",", &savep);
154c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
155c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
156c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout:
157c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (fs_options && fs_options[0]) {
158c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* remove the last trailing comma from the list of options */
159c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        fs_options[strlen(fs_options) - 1] = '\0';
160c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
161c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
162c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return f;
163c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
164c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
165c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* Read a line of text till the next newline character.
166c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * If no newline is found before the buffer is full, continue reading till a new line is seen,
167c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * then return an empty buffer.  This effectively ignores lines that are too long.
168c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * On EOF, return null.
169c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */
170c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic char *getline(char *buf, int size, FILE *file)
171c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
172c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int cnt = 0;
173c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int eof = 0;
174c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int eol = 0;
175c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int c;
176c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
177c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (size < 1) {
178c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return NULL;
179c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
180c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
181c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    while (cnt < (size - 1)) {
182c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        c = getc(file);
183c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (c == EOF) {
184c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            eof = 1;
185c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            break;
186c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
187c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
188c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        *(buf + cnt) = c;
189c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        cnt++;
190c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
191c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (c == '\n') {
192c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            eol = 1;
193c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            break;
194c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
195c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
196c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
197c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* Null terminate what we've read */
198c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    *(buf + cnt) = '\0';
199c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
200c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (eof) {
201c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (cnt) {
202c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            return buf;
203c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        } else {
204c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            return NULL;
205c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
206c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    } else if (eol) {
207c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return buf;
208c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    } else {
209c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* The line is too long.  Read till a newline or EOF.
210c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall         * If EOF, return null, if newline, return an empty buffer.
211c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall         */
212c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        while(1) {
213c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            c = getc(file);
214c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            if (c == EOF) {
215c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                return NULL;
216c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            } else if (c == '\n') {
217c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                *buf = '\0';
218c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                return buf;
219c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            }
220c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
221c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
222c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
223c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
224c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic struct fstab_rec *read_fstab(char *fstab_path)
225c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
226c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    FILE *fstab_file;
227c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int cnt, entries;
228c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int len;
229c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char line[256];
230c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    const char *delim = " \t";
231c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char *save_ptr, *p;
232c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    struct fstab_rec *fstab;
233c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char *key_loc;
234c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define FS_OPTIONS_LEN 1024
235c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char tmp_fs_options[FS_OPTIONS_LEN];
236c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
237c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    fstab_file = fopen(fstab_path, "r");
238c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (!fstab_file) {
239c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        ERROR("Cannot open file %s\n", fstab_path);
240c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return 0;
241c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
242c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
243c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    entries = 0;
244c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    while (getline(line, sizeof(line), fstab_file)) {
245c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* if the last character is a newline, shorten the string by 1 byte */
246c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        len = strlen(line);
247c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (line[len - 1] == '\n') {
248c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            line[len - 1] = '\0';
249c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
250c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* Skip any leading whitespace */
251c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        p = line;
252c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        while (isspace(*p)) {
253c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            p++;
254c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
255c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* ignore comments or empty lines */
256c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (*p == '#' || *p == '\0')
257c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            continue;
258c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        entries++;
259c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
260c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
261c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (!entries) {
262c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        ERROR("No entries found in fstab\n");
263c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return 0;
264c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
265c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
266c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    fstab = calloc(entries + 1, sizeof(struct fstab_rec));
267c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
268c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    fseek(fstab_file, 0, SEEK_SET);
269c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
270c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    cnt = 0;
271c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    while (getline(line, sizeof(line), fstab_file)) {
272c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* if the last character is a newline, shorten the string by 1 byte */
273c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        len = strlen(line);
274c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (line[len - 1] == '\n') {
275c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            line[len - 1] = '\0';
276c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
277c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
278c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* Skip any leading whitespace */
279c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        p = line;
280c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        while (isspace(*p)) {
281c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            p++;
282c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
283c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* ignore comments or empty lines */
284c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (*p == '#' || *p == '\0')
285c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            continue;
286c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
287c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* If a non-comment entry is greater than the size we allocated, give an
288c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall         * error and quit.  This can happen in the unlikely case the file changes
289c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall         * between the two reads.
290c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall         */
291c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (cnt >= entries) {
292c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Tried to process more entries than counted\n");
293c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            break;
294c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
295c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
296c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!(p = strtok_r(line, delim, &save_ptr))) {
297c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Error parsing mount source\n");
298c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            return 0;
299c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
300c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        fstab[cnt].blk_dev = strdup(p);
301c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
302c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!(p = strtok_r(NULL, delim, &save_ptr))) {
303c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Error parsing mnt_point\n");
304c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            return 0;
305c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
306c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        fstab[cnt].mnt_point = strdup(p);
307c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
308c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!(p = strtok_r(NULL, delim, &save_ptr))) {
309c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Error parsing fs_type\n");
310c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            return 0;
311c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
312c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        fstab[cnt].type = strdup(p);
313c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
314c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!(p = strtok_r(NULL, delim, &save_ptr))) {
315c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Error parsing mount_flags\n");
316c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            return 0;
317c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
318c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        tmp_fs_options[0] = '\0';
319c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        fstab[cnt].flags = parse_flags(p, mount_flags, 0, tmp_fs_options, FS_OPTIONS_LEN);
320c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
321c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* fs_options are optional */
322c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (tmp_fs_options[0]) {
323c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            fstab[cnt].fs_options = strdup(tmp_fs_options);
324c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        } else {
325c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            fstab[cnt].fs_options = NULL;
326c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
327c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
328c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!(p = strtok_r(NULL, delim, &save_ptr))) {
329c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Error parsing fs_mgr_options\n");
330c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            return 0;
331c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
332c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        fstab[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags, &key_loc, 0, 0);
333c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        fstab[cnt].key_loc = key_loc;
334c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
335c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        cnt++;
336c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
337c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    fclose(fstab_file);
338c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
339c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return fstab;
340c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
341c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
342c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic void free_fstab(struct fstab_rec *fstab)
343c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
344c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int i = 0;
345c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
346c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    while (fstab[i].blk_dev) {
347c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* Free the pointers return by strdup(3) */
348c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        free(fstab[i].blk_dev);
349c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        free(fstab[i].mnt_point);
350c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        free(fstab[i].type);
351c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        free(fstab[i].fs_options);
352c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        free(fstab[i].key_loc);
353c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
354c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        i++;
355c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
356c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
357c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* Free the actual fstab array created by calloc(3) */
358c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    free(fstab);
359c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
360c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
361c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic void check_fs(char *blk_dev, char *type)
362c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
363c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    pid_t pid;
364c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int status;
365c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
366c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* Check for the types of filesystems we know how to check */
367c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (!strcmp(type, "ext2") || !strcmp(type, "ext3") || !strcmp(type, "ext4")) {
368c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        INFO("Running %s on %s\n", E2FSCK_BIN, blk_dev);
369c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        pid = fork();
370c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (pid > 0) {
371c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            /* Parent, wait for the child to return */
372c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            waitpid(pid, &status, 0);
373c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        } else if (pid == 0) {
374c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            /* child, run checker */
375c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            execlp(E2FSCK_BIN, E2FSCK_BIN, "-y", blk_dev, (char *)NULL);
376c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
377c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            /* Only gets here on error */
378c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Cannot run fs_mgr binary %s\n", E2FSCK_BIN);
379c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        } else {
380c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            /* No need to check for error in fork, we can't really handle it now */
381c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Fork failed trying to run %s\n", E2FSCK_BIN);
382c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
383c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
384c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
385c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return;
386c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
387c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
388c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic void remove_trailing_slashes(char *n)
389c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
390c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int len;
391c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
392c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    len = strlen(n) - 1;
393c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    while ((*(n + len) == '/') && len) {
394c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall      *(n + len) = '\0';
395c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall      len--;
396c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
397c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
398c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
399c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int fs_match(char *in1, char *in2)
400c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
401c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char *n1;
402c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char *n2;
403c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int ret;
404c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
405c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    n1 = strdup(in1);
406c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    n2 = strdup(in2);
407c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
408c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    remove_trailing_slashes(n1);
409c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    remove_trailing_slashes(n2);
410c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
411c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    ret = !strcmp(n1, n2);
412c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
413c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    free(n1);
414c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    free(n2);
415c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
416c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return ret;
417c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
418c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
419c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_mount_all(char *fstab_file)
420c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
421c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int i = 0;
422c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int encrypted = 0;
423c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int ret = -1;
424c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int mret;
425c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    struct fstab_rec *fstab = 0;
426c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
427c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (!(fstab = read_fstab(fstab_file))) {
428c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return ret;
429c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
430c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
431c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    for (i = 0; fstab[i].blk_dev; i++) {
432c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (fstab[i].fs_mgr_flags & MF_WAIT) {
433c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT);
434c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
435c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
436c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (fstab[i].fs_mgr_flags & MF_CHECK) {
437c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            check_fs(fstab[i].blk_dev, fstab[i].type);
438c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
439c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
440c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        mret = mount(fstab[i].blk_dev, fstab[i].mnt_point, fstab[i].type,
441c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                     fstab[i].flags, fstab[i].fs_options);
442c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!mret) {
443c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            /* Success!  Go get the next one */
444c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            continue;
445c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
446c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
447c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* mount(2) returned an error, check if it's encrypted and deal with it */
448c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if ((fstab[i].fs_mgr_flags & MF_CRYPT) && !partition_wiped(fstab[i].blk_dev)) {
449c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            /* Need to mount a tmpfs at this mountpoint for now, and set
450c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall             * properties that vold will query later for decrypting
451c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall             */
452c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            if (mount("tmpfs", fstab[i].mnt_point, "tmpfs",
453c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                  MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
454c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s\n",
455c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                        fstab[i].mnt_point);
456c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                goto out;
457c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            }
458c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            encrypted = 1;
459c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        } else {
460c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Cannot mount filesystem on %s at %s\n",
461c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                    fstab[i].blk_dev, fstab[i].mnt_point);
462c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            goto out;
463c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
464c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
465c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
466c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (encrypted) {
467c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        ret = 1;
468c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    } else {
469c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        ret = 0;
470c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
471c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
472c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout:
473c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    free_fstab(fstab);
474c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return ret;
475c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
476c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
477c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* If tmp_mnt_point is non-null, mount the filesystem there.  This is for the
478c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * tmp mount we do to check the user password
479c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */
480c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_do_mount(char *fstab_file, char *n_name, char *n_blk_dev, char *tmp_mnt_point)
481c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
482c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int i = 0;
483c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int ret = -1;
484c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    struct fstab_rec *fstab = 0;
485c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    char *m;
486c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
487c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (!(fstab = read_fstab(fstab_file))) {
488c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return ret;
489c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
490c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
491c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    for (i = 0; fstab[i].blk_dev; i++) {
492c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!fs_match(fstab[i].mnt_point, n_name)) {
493c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            continue;
494c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
495c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
496c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* We found our match */
497c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* First check the filesystem if requested */
498c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (fstab[i].fs_mgr_flags & MF_WAIT) {
499c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT);
500c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
501c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
502c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (fstab[i].fs_mgr_flags & MF_CHECK) {
503c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            check_fs(fstab[i].blk_dev, fstab[i].type);
504c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
505c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
506c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* Now mount it where requested */
507c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (tmp_mnt_point) {
508c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            m = tmp_mnt_point;
509c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        } else {
510c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            m = fstab[i].mnt_point;
511c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
512c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (mount(n_blk_dev, m, fstab[i].type,
513c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                  fstab[i].flags, fstab[i].fs_options)) {
514c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Cannot mount filesystem on %s at %s\n",
515c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                    n_blk_dev, m);
516c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            goto out;
517c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        } else {
518c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ret = 0;
519c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            goto out;
520c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
521c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
522c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
523c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* We didn't find a match, say so and return an error */
524c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    ERROR("Cannot find mount point %s in fstab\n", fstab[i].mnt_point);
525c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
526c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout:
527c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    free_fstab(fstab);
528c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return ret;
529c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
530c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
531c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/*
532c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * mount a tmpfs filesystem at the given point.
533c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * return 0 on success, non-zero on failure.
534c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */
535c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_do_tmpfs_mount(char *n_name)
536c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
537c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int ret;
538c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
539c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    ret = mount("tmpfs", n_name, "tmpfs",
540c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall                MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
541c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (ret < 0) {
542c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        ERROR("Cannot mount tmpfs filesystem at %s\n", n_name);
543c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return -1;
544c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
545c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
546c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* Success */
547c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return 0;
548c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
549c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
550c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_unmount_all(char *fstab_file)
551c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
552c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int i = 0;
553c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int ret = 0;
554c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    struct fstab_rec *fstab = 0;
555c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
556c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (!(fstab = read_fstab(fstab_file))) {
557c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return -1;
558c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
559c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
560c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    while (fstab[i].blk_dev) {
561c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (umount(fstab[i].mnt_point)) {
562c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ERROR("Cannot unmount filesystem at %s\n", fstab[i].mnt_point);
563c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            ret = -1;
564c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
565c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        i++;
566c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
567c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
568c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    free_fstab(fstab);
569c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return ret;
570c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
571c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/*
572c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * key_loc must be at least PROPERTY_VALUE_MAX bytes long
573c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *
574c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * real_blk_dev must be at least PROPERTY_VALUE_MAX bytes long
575c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */
576c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_get_crypt_info(char *fstab_file, char *key_loc, char *real_blk_dev, int size)
577c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{
578c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    int i = 0;
579c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    struct fstab_rec *fstab = 0;
580c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
581c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (!(fstab = read_fstab(fstab_file))) {
582c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        return -1;
583c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
584c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* Initialize return values to null strings */
585c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (key_loc) {
586c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        *key_loc = '\0';
587c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
588c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    if (real_blk_dev) {
589c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        *real_blk_dev = '\0';
590c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
591c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
592c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    /* Look for the encryptable partition to find the data */
593c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    for (i = 0; fstab[i].blk_dev; i++) {
594c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (!(fstab[i].fs_mgr_flags & MF_CRYPT)) {
595c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            continue;
596c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
597c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
598c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        /* We found a match */
599c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (key_loc) {
600c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            strlcpy(key_loc, fstab[i].key_loc, size);
601c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
602c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        if (real_blk_dev) {
603c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall            strlcpy(real_blk_dev, fstab[i].blk_dev, size);
604c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        }
605c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall        break;
606c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    }
607c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
608c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    free_fstab(fstab);
609c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall    return 0;
610c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}
611c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall
612