vold: use unified fstab format

Change vold to use the unified fstab.  This includes both
support for sdcards, and changes to the crypto code to work
with some changes to the fs_mgr library api.

Change-Id: Id5a8aa5b699afe151db6e31aa0d76105f9c95a80
This commit is contained in:
Ken Sumrall 2013-02-13 13:00:19 -08:00
parent db5e026058
commit 56ad03cae1
2 changed files with 48 additions and 113 deletions

View file

@ -67,8 +67,8 @@ static unsigned char saved_master_key[KEY_LEN_BYTES];
static char *saved_data_blkdev; static char *saved_data_blkdev;
static char *saved_mount_point; static char *saved_mount_point;
static int master_key_saved = 0; static int master_key_saved = 0;
#define FSTAB_PREFIX "/fstab."
static char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; extern struct fstab *fstab;
static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags) static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
{ {
@ -126,19 +126,6 @@ static unsigned int get_blkdev_size(int fd)
return nr_sec; return nr_sec;
} }
/* Get and cache the name of the fstab file so we don't
* keep talking over the socket to the property service.
*/
static char *get_fstab_filename(void)
{
if (fstab_filename[0] == 0) {
strcpy(fstab_filename, FSTAB_PREFIX);
property_get("ro.hardware", fstab_filename + sizeof(FSTAB_PREFIX) - 1, "");
}
return fstab_filename;
}
/* key or salt can be NULL, in which case just skip writing that value. Useful to /* key or salt can be NULL, in which case just skip writing that value. Useful to
* update the failed mount count but not change the key. * update the failed mount count but not change the key.
*/ */
@ -153,7 +140,7 @@ static int put_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp
char key_loc[PROPERTY_VALUE_MAX]; char key_loc[PROPERTY_VALUE_MAX];
struct stat statbuf; struct stat statbuf;
fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc)); fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
if (!strcmp(key_loc, KEY_IN_FOOTER)) { if (!strcmp(key_loc, KEY_IN_FOOTER)) {
fname = real_blk_name; fname = real_blk_name;
@ -252,7 +239,7 @@ static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp
char *fname; char *fname;
struct stat statbuf; struct stat statbuf;
fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc)); fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
if (!strcmp(key_loc, KEY_IN_FOOTER)) { if (!strcmp(key_loc, KEY_IN_FOOTER)) {
fname = real_blk_name; fname = real_blk_name;
@ -777,7 +764,7 @@ int cryptfs_restart(void)
if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) { if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {
/* If that succeeded, then mount the decrypted filesystem */ /* If that succeeded, then mount the decrypted filesystem */
fs_mgr_do_mount(get_fstab_filename(), DATA_MNT_POINT, crypto_blkdev, 0); fs_mgr_do_mount(fstab, DATA_MNT_POINT, crypto_blkdev, 0);
property_set("vold.decrypt", "trigger_load_persist_props"); property_set("vold.decrypt", "trigger_load_persist_props");
/* Create necessary paths on /data */ /* Create necessary paths on /data */
@ -815,10 +802,10 @@ static int do_crypto_complete(char *mount_point)
return 1; return 1;
} }
fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) { if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc)); fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
/* /*
* Only report this error if key_loc is a file and it exists. * Only report this error if key_loc is a file and it exists.
@ -865,7 +852,7 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label)
return -1; return -1;
} }
fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) { if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
SLOGE("Error getting crypt footer and key\n"); SLOGE("Error getting crypt footer and key\n");
@ -894,7 +881,7 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label)
*/ */
sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point); sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point);
mkdir(tmp_mount_point, 0755); mkdir(tmp_mount_point, 0755);
if (fs_mgr_do_mount(get_fstab_filename(), DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) { if (fs_mgr_do_mount(fstab, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) {
SLOGE("Error temp mounting decrypted block device\n"); SLOGE("Error temp mounting decrypted block device\n");
delete_crypto_blk_dev(label); delete_crypto_blk_dev(label);
crypt_ftr.failed_decrypt_count++; crypt_ftr.failed_decrypt_count++;
@ -1025,7 +1012,7 @@ int cryptfs_verify_passwd(char *passwd)
return -1; return -1;
} }
fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) { if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
SLOGE("Error getting crypt footer and key\n"); SLOGE("Error getting crypt footer and key\n");
@ -1227,7 +1214,7 @@ int cryptfs_enable(char *howarg, char *passwd)
goto error_unencrypted; goto error_unencrypted;
} }
fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc)); fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
if (!strcmp(howarg, "wipe")) { if (!strcmp(howarg, "wipe")) {
how = CRYPTO_ENABLE_WIPE; how = CRYPTO_ENABLE_WIPE;
@ -1238,7 +1225,7 @@ int cryptfs_enable(char *howarg, char *passwd)
goto error_unencrypted; goto error_unencrypted;
} }
fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
/* Get the size of the real block device */ /* Get the size of the real block device */
fd = open(real_blkdev, O_RDONLY); fd = open(real_blkdev, O_RDONLY);
@ -1531,7 +1518,7 @@ int cryptfs_changepw(char *newpw)
return -1; return -1;
} }
fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
if (strlen(real_blkdev) == 0) { if (strlen(real_blkdev) == 0) {
SLOGE("Can't find real blkdev"); SLOGE("Can't find real blkdev");
return -1; return -1;

122
main.cpp
View file

@ -23,10 +23,12 @@
#include <fcntl.h> #include <fcntl.h>
#include <dirent.h> #include <dirent.h>
#include <fs_mgr.h>
#define LOG_TAG "Vold" #define LOG_TAG "Vold"
#include "cutils/log.h" #include "cutils/log.h"
#include "cutils/properties.h"
#include "VolumeManager.h" #include "VolumeManager.h"
#include "CommandListener.h" #include "CommandListener.h"
@ -37,6 +39,9 @@
static int process_config(VolumeManager *vm); static int process_config(VolumeManager *vm);
static void coldboot(const char *path); static void coldboot(const char *path);
#define FSTAB_PREFIX "/fstab."
struct fstab *fstab;
int main() { int main() {
VolumeManager *vm; VolumeManager *vm;
@ -142,111 +147,54 @@ static void coldboot(const char *path)
} }
} }
static int parse_mount_flags(char *mount_flags) static int process_config(VolumeManager *vm)
{ {
char *save_ptr; char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
int flags = 0; char propbuf[PROPERTY_VALUE_MAX];
int i;
int ret = -1;
int flags;
if (strcasestr(mount_flags, "encryptable")) { property_get("ro.hardware", propbuf, "");
flags |= VOL_ENCRYPTABLE; snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
}
if (strcasestr(mount_flags, "nonremovable")) { fstab = fs_mgr_read_fstab(fstab_filename);
flags |= VOL_NONREMOVABLE; if (!fstab) {
} SLOGE("failed to open %s\n", fstab_filename);
return flags;
}
static int process_config(VolumeManager *vm) {
FILE *fp;
int n = 0;
char line[255];
if (!(fp = fopen("/etc/vold.fstab", "r"))) {
return -1; return -1;
} }
while(fgets(line, sizeof(line), fp)) { /* Loop through entries looking for ones that vold manages */
const char *delim = " \t"; for (i = 0; i < fstab->num_entries; i++) {
char *save_ptr; if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
char *type, *label, *mount_point, *mount_flags, *sysfs_path;
int flags;
n++;
line[strlen(line)-1] = '\0';
if (line[0] == '#' || line[0] == '\0')
continue;
if (!(type = strtok_r(line, delim, &save_ptr))) {
SLOGE("Error parsing type");
goto out_syntax;
}
if (!(label = strtok_r(NULL, delim, &save_ptr))) {
SLOGE("Error parsing label");
goto out_syntax;
}
if (!(mount_point = strtok_r(NULL, delim, &save_ptr))) {
SLOGE("Error parsing mount point");
goto out_syntax;
}
if (!strcmp(type, "dev_mount")) {
DirectVolume *dv = NULL; DirectVolume *dv = NULL;
char *part; flags = 0;
if (!(part = strtok_r(NULL, delim, &save_ptr))) { dv = new DirectVolume(vm, fstab->recs[i].label,
SLOGE("Error parsing partition"); fstab->recs[i].mount_point,
goto out_syntax; fstab->recs[i].partnum);
}
if (strcmp(part, "auto") && atoi(part) == 0) {
SLOGE("Partition must either be 'auto' or 1 based index instead of '%s'", part);
goto out_syntax;
}
if (!strcmp(part, "auto")) { if (dv->addPath(fstab->recs[i].blk_device)) {
dv = new DirectVolume(vm, label, mount_point, -1); SLOGE("Failed to add devpath %s to volume %s",
} else { fstab->recs[i].blk_device, fstab->recs[i].label);
dv = new DirectVolume(vm, label, mount_point, atoi(part));
}
while ((sysfs_path = strtok_r(NULL, delim, &save_ptr))) {
if (*sysfs_path != '/') {
/* If the first character is not a '/', it must be flags */
break;
}
if (dv->addPath(sysfs_path)) {
SLOGE("Failed to add devpath %s to volume %s", sysfs_path,
label);
goto out_fail; goto out_fail;
} }
}
/* If sysfs_path is non-null at this point, then it contains /* Set any flags that might be set for this volume */
* the optional flags for this volume if (fs_mgr_is_nonremovable(&fstab->recs[i])) {
*/ flags |= VOL_NONREMOVABLE;
if (sysfs_path) }
flags = parse_mount_flags(sysfs_path); if (fs_mgr_is_encryptable(&fstab->recs[i])) {
else flags |= VOL_ENCRYPTABLE;
flags = 0; }
dv->setFlags(flags); dv->setFlags(flags);
vm->addVolume(dv); vm->addVolume(dv);
} else if (!strcmp(type, "map_mount")) {
} else {
SLOGE("Unknown type '%s'", type);
goto out_syntax;
} }
} }
fclose(fp); ret = 0;
return 0;
out_syntax:
SLOGE("Syntax error on config line %d", n);
errno = -EINVAL;
out_fail: out_fail:
fclose(fp); return ret;
return -1;
} }