X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fubox.git;a=blobdiff_plain;f=block.c;h=ea142481b0c03b749220060beb1c01a993e8a098;hp=4bbfeb0f98257bbab1e4896309dfdfc00b5861e9;hb=067bd8d3265d6e1c96dc2d5c7a330b0ee01ca171;hpb=0a4e3d257da46a7c0232362ac82a01a8c15ae6d5 diff --git a/block.c b/block.c index 4bbfeb0..ea14248 100644 --- a/block.c +++ b/block.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -57,7 +58,7 @@ struct mount { static struct vlist_tree mounts; static struct blob_buf b; static LIST_HEAD(devices); -static int anon_mount, anon_swap, auto_mount, auto_swap; +static int anon_mount, anon_swap, auto_mount, auto_swap, check_fs; static unsigned int delay_root; enum { @@ -66,6 +67,7 @@ enum { CFG_AUTO_MOUNT, CFG_AUTO_SWAP, CFG_DELAY_ROOT, + CFG_CHECK_FS, __CFG_MAX }; @@ -75,6 +77,7 @@ static const struct blobmsg_policy config_policy[__CFG_MAX] = { [CFG_AUTO_SWAP] = { .name = "auto_swap", .type = BLOBMSG_TYPE_INT32 }, [CFG_AUTO_MOUNT] = { .name = "auto_mount", .type = BLOBMSG_TYPE_INT32 }, [CFG_DELAY_ROOT] = { .name = "delay_root", .type = BLOBMSG_TYPE_INT32 }, + [CFG_CHECK_FS] = { .name = "check_fs", .type = BLOBMSG_TYPE_INT32 }, }; enum { @@ -134,6 +137,14 @@ static char *blobmsg_get_strdup(struct blob_attr *attr) return strdup(blobmsg_get_string(attr)); } +static char *blobmsg_get_basename(struct blob_attr *attr) +{ + if (!attr) + return NULL; + + return strdup(basename(blobmsg_get_string(attr))); +} + static int mount_add(struct uci_section *s) { struct blob_attr *tb[__MOUNT_MAX] = { 0 }; @@ -155,7 +166,7 @@ static int mount_add(struct uci_section *s) m->label = blobmsg_get_strdup(tb[MOUNT_LABEL]); m->target = blobmsg_get_strdup(tb[MOUNT_TARGET]); m->options = blobmsg_get_strdup(tb[MOUNT_OPTIONS]); - m->device = blobmsg_get_strdup(tb[MOUNT_DEVICE]); + m->device = blobmsg_get_basename(tb[MOUNT_DEVICE]); m->overlay = m->extroot = 0; if (m->target && !strcmp(m->target, "/")) m->extroot = 1; @@ -188,7 +199,7 @@ static int swap_add(struct uci_section *s) memset(m, 0, sizeof(struct mount)); m->type = TYPE_SWAP; m->uuid = blobmsg_get_strdup(tb[SWAP_UUID]); - m->device = blobmsg_get_strdup(tb[SWAP_DEVICE]); + m->device = blobmsg_get_basename(tb[SWAP_DEVICE]); if (tb[SWAP_PRIO]) m->prio = blobmsg_get_u32(tb[SWAP_PRIO]); if (m->prio) @@ -221,6 +232,9 @@ static int global_add(struct uci_section *s) if (tb[CFG_DELAY_ROOT]) delay_root = blobmsg_get_u32(tb[CFG_DELAY_ROOT]); + if ((tb[CFG_CHECK_FS]) && blobmsg_get_u32(tb[CFG_CHECK_FS])) + check_fs = 1; + return 0; } @@ -330,6 +344,8 @@ static void cache_load(int mtd) _cache_load("/dev/mtdblock*"); _cache_load("/dev/mmcblk*"); _cache_load("/dev/sd*"); + _cache_load("/dev/sdc*"); + _cache_load("/dev/hd*"); } static int print_block_info(struct blkid_struct_probe *pr) @@ -363,7 +379,7 @@ static int print_block_uci(struct blkid_struct_probe *pr) if (pr->uuid[0]) printf("\toption\tuuid\t'%s'\n", pr->uuid); else - printf("\toption\tdevice\t'%s'\n", basename(pr->dev)); + printf("\toption\tdevice\t'%s'\n", pr->dev); printf("\toption\tenabled\t'0'\n\n"); return 0; @@ -431,6 +447,35 @@ static void mkdir_p(char *dir) } } +static void check_filesystem(struct blkid_struct_probe *pr) +{ + pid_t pid; + struct stat statbuf; + char *e2fsck = "/usr/sbin/e2fsck"; + + if (strncmp(pr->id->name, "ext", 3)) { + fprintf(stderr, "check_filesystem: %s is not supported\n", pr->id->name); + return; + } + + if (stat(e2fsck, &statbuf) < 0) { + fprintf(stderr, "check_filesystem: %s not found\n", e2fsck); + return; + } + + pid = fork(); + if (!pid) { + execl(e2fsck, e2fsck, "-p", pr->dev, NULL); + exit(-1); + } else if (pid > 0) { + int status; + + waitpid(pid, &status, 0); + if (WEXITSTATUS(status)) + fprintf(stderr, "check_filesystem: %s returned %d\n", e2fsck, WEXITSTATUS(status)); + } +} + static int mount_device(struct blkid_struct_probe *pr, int hotplug) { struct mount *m; @@ -471,6 +516,10 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug) target = _target; } mkdir_p(target); + + if (check_fs) + check_filesystem(pr); + err = mount(pr->dev, target, pr->id->name, 0, (m->options) ? (m->options) : ("")); if (err) fprintf(stderr, "mounting %s (%s) as %s failed (%d) - %s\n", @@ -484,6 +533,10 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug) snprintf(target, sizeof(target), "/mnt/%s", device); mkdir_p(target); + + if (check_fs) + check_filesystem(pr); + err = mount(pr->dev, target, pr->id->name, 0, ""); if (err) fprintf(stderr, "mounting %s (%s) as %s failed (%d) - %s\n", @@ -661,6 +714,8 @@ static int mount_extroot(char *cfg) if (!pr && delay_root){ fprintf(stderr, "extroot: is not ready yet, retrying in %ui seconds\n", delay_root); sleep(delay_root); + mkblkdev(); + cache_load(0); pr = find_block_info(m->uuid, m->label, NULL); } if (pr) { @@ -672,6 +727,9 @@ static int mount_extroot(char *cfg) path = overlay; mkdir_p(path); + if (check_fs) + check_filesystem(pr); + err = mount(pr->dev, path, pr->id->name, 0, (m->options) ? (m->options) : ("")); if (err) { @@ -771,8 +829,9 @@ static int main_detect(int argc, char **argv) printf("\toption\tanon_swap\t'0'\n"); printf("\toption\tanon_mount\t'0'\n"); printf("\toption\tauto_swap\t'1'\n"); - printf("\toption\tauto_mount\t'1'\n\n"); - printf("\toption\tdelay_root\t'0'\n\n"); + printf("\toption\tauto_mount\t'1'\n"); + printf("\toption\tdelay_root\t'0'\n"); + printf("\toption\tcheck_fs\t'0'\n\n"); list_for_each_entry(pr, &devices, list) print_block_uci(pr);