diff options
author | JP Abgrall <jpa@google.com> | 2015-01-23 00:50:36 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-01-23 00:50:36 +0000 |
commit | 253b9cfba53d3f45e908856d311e28de9e5c1017 (patch) | |
tree | 60ff8476a36f170b85fa123e20e7c2ac6cc73dcf /fs_mgr | |
parent | 6f355d2c8f661caa3ec6e814c5be7c3ec077de3e (diff) | |
parent | f9e2339553f70aebdd170e96ab9332b28c3851b4 (diff) | |
download | system_core-253b9cfba53d3f45e908856d311e28de9e5c1017.zip system_core-253b9cfba53d3f45e908856d311e28de9e5c1017.tar.gz system_core-253b9cfba53d3f45e908856d311e28de9e5c1017.tar.bz2 |
am f9e23395: Merge "fs_mgr: Support filesystem labels in fstab"
* commit 'f9e2339553f70aebdd170e96ab9332b28c3851b4':
fs_mgr: Support filesystem labels in fstab
Diffstat (limited to 'fs_mgr')
-rw-r--r-- | fs_mgr/fs_mgr.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c index ad02922..bd371e2 100644 --- a/fs_mgr/fs_mgr.c +++ b/fs_mgr/fs_mgr.c @@ -28,6 +28,9 @@ #include <libgen.h> #include <time.h> #include <sys/swap.h> +#include <dirent.h> +#include <ext4.h> +#include <ext4_sb.h> #include <linux/loop.h> #include <private/android_filesystem_config.h> @@ -335,6 +338,83 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ return 0; } +static int translate_ext_labels(struct fstab_rec *rec) +{ + DIR *blockdir = NULL; + struct dirent *ent; + char *label; + size_t label_len; + int ret = -1; + + if (strncmp(rec->blk_device, "LABEL=", 6)) + return 0; + + label = rec->blk_device + 6; + label_len = strlen(label); + + if (label_len > 16) { + ERROR("FS label is longer than allowed by filesystem\n"); + goto out; + } + + + blockdir = opendir("/dev/block"); + if (!blockdir) { + ERROR("couldn't open /dev/block\n"); + goto out; + } + + while ((ent = readdir(blockdir))) { + int fd; + char super_buf[1024]; + struct ext4_super_block *sb; + + if (!ent->d_type == DT_BLK) + continue; + + fd = openat(dirfd(blockdir), ent->d_name, O_RDONLY); + if (fd < 0) { + ERROR("Cannot open block device /dev/block/%s\n", ent->d_name); + goto out; + } + + if (TEMP_FAILURE_RETRY(lseek(fd, 1024, SEEK_SET)) < 0 || + TEMP_FAILURE_RETRY(read(fd, super_buf, 1024)) != 1024) { + /* Probably a loopback device or something else without a readable + * superblock. + */ + close(fd); + continue; + } + + sb = (struct ext4_super_block *)super_buf; + if (sb->s_magic != EXT4_SUPER_MAGIC) { + INFO("/dev/block/%s not ext{234}\n", ent->d_name); + continue; + } + + if (!strncmp(label, sb->s_volume_name, label_len)) { + char *new_blk_device; + + if (asprintf(&new_blk_device, "/dev/block/%s", ent->d_name) < 0) { + ERROR("Could not allocate block device string\n"); + goto out; + } + + INFO("resolved label %s to %s\n", rec->blk_device, new_blk_device); + + free(rec->blk_device); + rec->blk_device = new_blk_device; + ret = 0; + break; + } + } + +out: + closedir(blockdir); + return ret; +} + /* When multiple fstab records share the same mount_point, it will * try to mount each one in turn, and ignore any duplicates after a * first successful mount. @@ -366,6 +446,17 @@ int fs_mgr_mount_all(struct fstab *fstab) continue; } + /* Translate LABEL= file system labels into block devices */ + if (!strcmp(fstab->recs[i].fs_type, "ext2") || + !strcmp(fstab->recs[i].fs_type, "ext3") || + !strcmp(fstab->recs[i].fs_type, "ext4")) { + int tret = translate_ext_labels(&fstab->recs[i]); + if (tret < 0) { + ERROR("Could not translate label to block device\n"); + continue; + } + } + if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); } |