X-Git-Url: http://git.archive.openwrt.org/?p=project%2Ffstools.git;a=blobdiff_plain;f=block.c;h=4d823e6bec562685c4b8770fab694f94271aa9dc;hp=f41d7f6495d5fe63439daaa2d567deefd4f94522;hb=5b61e27d36e5bbf40825a4ae14920efe47d36f02;hpb=164d78a108b24515f69ada82aadcef58572ba51e diff --git a/block.c b/block.c index f41d7f6..4d823e6 100644 --- a/block.c +++ b/block.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -28,9 +29,12 @@ #include #include +#include + #include #include +#include #include #include #include @@ -42,37 +46,6 @@ #include "libubi/libubi.h" #endif -static int kmsg = 0; - -static void klog(int prio, const char *fmt, ...) -{ - va_list ap; - FILE *f = fopen("/dev/kmsg", "w"); - - if (f) { - fprintf(f, "<%d>", prio); - - va_start(ap, fmt); - vfprintf(f, fmt, ap); - va_end(ap); - - fclose(f); - } -} - -#define KINFO(fmt, ...) do { \ - if (kmsg) klog(LOG_INFO, "block: " fmt, ## __VA_ARGS__); \ - } while (0) - -#define ERROR(fmt, ...) do { \ - if (kmsg) \ - klog(LOG_ERR, "block: " fmt, ## __VA_ARGS__); \ - else { \ - syslog(LOG_ERR, fmt, ## __VA_ARGS__); \ - fprintf(stderr, "block: "fmt, ## __VA_ARGS__); \ - } \ - } while (0) - enum { TYPE_MOUNT, TYPE_SWAP, @@ -176,18 +149,6 @@ struct mount_flag { int32_t flag; }; -#ifndef MS_DIRSYNC -# define MS_DIRSYNC (1 << 7) -#endif - -#ifndef MS_RELATIME -# define MS_RELATIME (1 << 21) -#endif - -#ifndef MS_STRICTATIME -# define MS_STRICTATIME (1 << 24) -#endif - static const struct mount_flag mount_flags[] = { { "sync", MS_SYNCHRONOUS }, { "async", ~MS_SYNCHRONOUS }, @@ -209,6 +170,10 @@ static const struct mount_flag mount_flags[] = { { "relatime", MS_RELATIME }, { "norelatime", ~MS_RELATIME }, { "strictatime", MS_STRICTATIME }, + { "acl", MS_POSIXACL }, + { "noacl", ~MS_POSIXACL }, + { "nouser_xattr", MS_NOUSER }, + { "user_xattr", ~MS_NOUSER }, }; static char *blobmsg_get_strdup(struct blob_attr *attr) @@ -303,6 +268,13 @@ static int mount_add(struct uci_section *s) if (m->target && !strcmp(m->target, "/overlay")) m->extroot = m->overlay = 1; + if (m->target && *m->target != '/') { + ULOG_WARN("ignoring mount section %s due to invalid target '%s'\n", + s->e.name, m->target); + free(m); + return -1; + } + if (m->uuid) vlist_add(&mounts, &m->node, m->uuid); else if (m->label) @@ -431,11 +403,11 @@ static struct uci_package * config_try_load(struct uci_context *ctx, char *path) struct uci_package *pkg; uci_set_confdir(ctx, dir); - KINFO("attempting to load %s/%s\n", dir, file); + ULOG_INFO("attempting to load %s/%s\n", dir, file); if (uci_load(ctx, file, &pkg)) { uci_get_errorstr(ctx, &err, file); - ERROR("unable to load configuration (%s)\n", err); + ULOG_ERR("unable to load configuration (%s)\n", err); free(err); return NULL; @@ -469,7 +441,7 @@ static int config_load(char *cfg) } if (!pkg) { - ERROR("extroot: no usable configuration\n"); + ULOG_ERR("no usable configuration\n"); return -1; } @@ -534,7 +506,7 @@ static void cache_load(int mtd) if (mtd) { _cache_load("/dev/mtdblock*"); _cache_load("/dev/ubiblock*"); - _cache_load("/dev/ubi?*_?*"); + _cache_load("/dev/ubi[0-9]*"); } _cache_load("/dev/mmcblk*"); _cache_load("/dev/sd*"); @@ -649,32 +621,38 @@ static void check_filesystem(struct blkid_struct_probe *pr) { pid_t pid; struct stat statbuf; - char *e2fsck = "/usr/sbin/e2fsck"; + const char *e2fsck = "/usr/sbin/e2fsck"; + const char *dosfsck = "/usr/sbin/dosfsck"; + const char *ckfs; /* UBIFS does not need stuff like fsck */ if (!strncmp(pr->id->name, "ubifs", 5)) return; - if (strncmp(pr->id->name, "ext", 3)) { - ERROR("check_filesystem: %s is not supported\n", pr->id->name); + if (!strncmp(pr->id->name, "vfat", 4)) { + ckfs = dosfsck; + } else if (!strncmp(pr->id->name, "ext", 3)) { + ckfs = e2fsck; + } else { + ULOG_ERR("check_filesystem: %s is not supported\n", pr->id->name); return; } - if (stat(e2fsck, &statbuf) < 0) { - ERROR("check_filesystem: %s not found\n", e2fsck); + if (stat(ckfs, &statbuf) < 0) { + ULOG_ERR("check_filesystem: %s not found\n", ckfs); return; } pid = fork(); if (!pid) { - execl(e2fsck, e2fsck, "-p", pr->dev, NULL); + execl(ckfs, ckfs, "-p", pr->dev, NULL); exit(-1); } else if (pid > 0) { int status; waitpid(pid, &status, 0); if (WEXITSTATUS(status)) - ERROR("check_filesystem: %s returned %d\n", e2fsck, WEXITSTATUS(status)); + ULOG_ERR("check_filesystem: %s returned %d\n", ckfs, WEXITSTATUS(status)); } } @@ -732,7 +710,7 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug) return -1; if (find_mount_point(pr->dev)) { - ERROR("%s is already mounted\n", pr->dev); + ULOG_ERR("%s is already mounted\n", pr->dev); return -1; } @@ -757,8 +735,8 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug) err = mount(pr->dev, target, pr->id->name, m->flags, (m->options) ? (m->options) : ("")); if (err) - ERROR("mounting %s (%s) as %s failed (%d) - %s\n", - pr->dev, pr->id->name, target, err, strerror(err)); + ULOG_ERR("mounting %s (%s) as %s failed (%d) - %s\n", + pr->dev, pr->id->name, target, err, strerror(err)); else handle_swapfiles(true); return err; @@ -776,8 +754,8 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug) err = mount(pr->dev, target, pr->id->name, 0, ""); if (err) - ERROR("mounting %s (%s) as %s failed (%d) - %s\n", - pr->dev, pr->id->name, target, err, strerror(err)); + ULOG_ERR("mounting %s (%s) as %s failed (%d) - %s\n", + pr->dev, pr->id->name, target, err, strerror(err)); else handle_swapfiles(true); return err; @@ -809,11 +787,11 @@ static int umount_device(struct blkid_struct_probe *pr) err = umount2(mp, MNT_DETACH); if (err) - ERROR("unmounting %s (%s) failed (%d) - %s\n", - pr->dev, mp, err, strerror(err)); + ULOG_ERR("unmounting %s (%s) failed (%d) - %s\n", + pr->dev, mp, err, strerror(err)); else - ERROR("unmounted %s (%s)\n", - pr->dev, mp); + ULOG_INFO("unmounted %s (%s)\n", + pr->dev, mp); return err; } @@ -837,12 +815,12 @@ static int main_hotplug(int argc, char **argv) err = umount2(mount_point, MNT_DETACH); if (err) - ERROR("umount of %s failed (%d) - %s\n", - mount_point, err, strerror(err)); + ULOG_ERR("umount of %s failed (%d) - %s\n", + mount_point, err, strerror(err)); return 0; } else if (strcmp(action, "add")) { - ERROR("Unkown action %s\n", action); + ULOG_ERR("Unkown action %s\n", action); return -1; } @@ -934,7 +912,8 @@ static int find_block_ubi_RO(libubi_t libubi, char *name, char *part, int plen) return err; } -#endif + +#else static int find_root_dev(char *buf, int len) { @@ -965,31 +944,59 @@ static int find_root_dev(char *buf, int len) return -1; } +#endif + +static int test_fs_support(const char *name) +{ + char line[128], *p; + int rv = -1; + FILE *f; + + if ((f = fopen("/proc/filesystems", "r")) != NULL) { + while (fgets(line, sizeof(line), f)) { + p = strtok(line, "\t\n"); + + if (p && !strcmp(p, "nodev")) + p = strtok(NULL, "\t\n"); + + if (p && !strcmp(p, name)) { + rv = 0; + break; + } + } + fclose(f); + } + + return rv; +} + static int check_extroot(char *path) { struct blkid_struct_probe *pr = NULL; - char fs[32]; + char devpath[32]; #ifdef UBIFS_EXTROOT - if (find_block_mtd("rootfs", fs, sizeof(fs))) { + if (find_block_mtd("\"rootfs\"", devpath, sizeof(devpath))) { int err = -1; libubi_t libubi; libubi = libubi_open(); - err = find_block_ubi_RO(libubi, "rootfs", fs, sizeof(fs)); + err = find_block_ubi_RO(libubi, "rootfs", devpath, sizeof(devpath)); libubi_close(libubi); if (err) return -1; } #else - if (find_block_mtd("rootfs", fs, sizeof(fs))) { - if (find_root_dev(fs, sizeof(fs))) + if (find_block_mtd("\"rootfs\"", devpath, sizeof(devpath))) { + if (find_root_dev(devpath, sizeof(devpath))) { + ULOG_ERR("extroot: unable to determine root device\n"); return -1; + } } #endif list_for_each_entry(pr, &devices, list) { - if (!strcmp(pr->dev, fs)) { + if (!strcmp(pr->dev, devpath)) { struct stat s; FILE *fp = NULL; char tag[64]; @@ -1003,7 +1010,8 @@ static int check_extroot(char *path) if (stat(tag, &s)) { fp = fopen(tag, "w+"); if (!fp) { - ERROR("extroot: failed to write uuid tag file\n"); + ULOG_ERR("extroot: failed to write UUID to %s: %d (%s)\n", + tag, errno, strerror(errno)); /* return 0 to continue boot regardless of error */ return 0; } @@ -1014,17 +1022,26 @@ static int check_extroot(char *path) fp = fopen(tag, "r"); if (!fp) { - ERROR("extroot: failed to open uuid tag file\n"); + ULOG_ERR("extroot: failed to read UUID from %s: %d (%s)\n", + tag, errno, strerror(errno)); return -1; } - fgets(uuid, sizeof(uuid), fp); + if (!fgets(uuid, sizeof(uuid), fp)) + ULOG_ERR("extroot: failed to read UUID from %s: %d (%s)\n", + tag, errno, strerror(errno)); fclose(fp); - if (!strcasecmp(uuid, pr->uuid)) + + if (*uuid || !strcasecmp(uuid, pr->uuid)) return 0; - ERROR("extroot: uuid tag does not match rom uuid\n"); + + ULOG_ERR("extroot: UUID mismatch (root: %s, %s: %s)\n", + pr->uuid, basename(path), uuid); + return -1; } } + + ULOG_ERR("extroot: unable to lookup root device %s\n", devpath); return -1; } @@ -1051,7 +1068,7 @@ static int mount_extroot(char *cfg) if (!m || !m->extroot) { - ERROR("extroot: no root or overlay mount defined\n"); + ULOG_INFO("extroot: not configured\n"); return -1; } @@ -1059,7 +1076,7 @@ static int mount_extroot(char *cfg) pr = find_block_info(m->uuid, m->label, m->device); if (!pr && delay_root){ - ERROR("extroot: is not ready yet, retrying in %u seconds\n", delay_root); + ULOG_INFO("extroot: device not present, retrying in %u seconds\n", delay_root); sleep(delay_root); mkblkdev(); cache_load(0); @@ -1068,9 +1085,15 @@ static int mount_extroot(char *cfg) if (pr) { if (strncmp(pr->id->name, "ext", 3) && strncmp(pr->id->name, "ubifs", 5)) { - ERROR("extroot: %s is not supported, try ext4\n", pr->id->name); + ULOG_ERR("extroot: unsupported filesystem %s, try ext4\n", pr->id->name); + return -1; + } + + if (test_fs_support(pr->id->name)) { + ULOG_ERR("extroot: filesystem %s not supported by kernel\n", pr->id->name); return -1; } + if (m->overlay) path = overlay; mkdir_p(path); @@ -1078,18 +1101,21 @@ static int mount_extroot(char *cfg) if (check_fs) check_filesystem(pr); - err = mount(pr->dev, path, pr->id->name, 0, (m->options) ? (m->options) : ("")); + err = mount(pr->dev, path, pr->id->name, m->flags, + (m->options) ? (m->options) : ("")); if (err) { - ERROR("mounting %s (%s) as %s failed (%d) - %s\n", - pr->dev, pr->id->name, path, err, strerror(err)); + ULOG_ERR("extroot: mounting %s (%s) on %s failed: %d (%s)\n", + pr->dev, pr->id->name, path, err, strerror(err)); } else if (m->overlay) { err = check_extroot(path); if (err) umount(path); } } else { - ERROR("extroot: cannot find block device\n"); + ULOG_ERR("extroot: cannot find device %s%s\n", + (m->uuid ? "with UUID " : (m->label ? "with label " : "")), + (m->uuid ? m->uuid : (m->label ? m->label : m->device))); } return err; @@ -1108,22 +1134,23 @@ static int main_extroot(int argc, char **argv) return -1; if (argc != 2) { - fprintf(stderr, "Usage: block extroot mountpoint\n"); + ULOG_ERR("Usage: block extroot\n"); return -1; } - kmsg = 1; - mkblkdev(); cache_load(1); + /* enable LOG_INFO messages */ + ulog_threshold(LOG_INFO); + /* * Look for "rootfs_data". We will want to mount it and check for * extroot configuration. */ /* Start with looking for MTD partition */ - find_block_mtd("rootfs_data", blkdev_path, sizeof(blkdev_path)); + find_block_mtd("\"rootfs_data\"", blkdev_path, sizeof(blkdev_path)); if (blkdev_path[0]) { pr = find_block_info(NULL, NULL, blkdev_path); if (pr && !strcmp(pr->id->name, "jffs2")) { @@ -1237,11 +1264,11 @@ static int main_info(int argc, char **argv) struct stat s; if (stat(argv[i], &s)) { - ERROR("failed to stat %s\n", argv[i]); + ULOG_ERR("failed to stat %s\n", argv[i]); continue; } if (!S_ISBLK(s.st_mode)) { - ERROR("%s is not a block device\n", argv[i]); + ULOG_ERR("%s is not a block device\n", argv[i]); continue; } pr = find_block_info(NULL, NULL, argv[i]); @@ -1281,11 +1308,11 @@ static int main_swapon(int argc, char **argv) lineptr = NULL; if (!fp) { - ERROR("failed to open /proc/swaps\n"); + ULOG_ERR("failed to open /proc/swaps\n"); return -1; } while (getline(&lineptr, &s, fp) > 0) - printf(lineptr); + printf("%s", lineptr); if (lineptr) free(lineptr); fclose(fp); @@ -1296,7 +1323,7 @@ static int main_swapon(int argc, char **argv) if (strcmp(pr->id->name, "swap")) continue; if (swapon(pr->dev, 0)) - ERROR("failed to swapon %s\n", pr->dev); + ULOG_ERR("failed to swapon %s\n", pr->dev); } return 0; case 'p': @@ -1314,12 +1341,12 @@ static int main_swapon(int argc, char **argv) return swapon_usage(); if (stat(argv[optind], &st) || (!S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode))) { - ERROR("%s is not a block device or file\n", argv[optind]); + ULOG_ERR("%s is not a block device or file\n", argv[optind]); return -1; } err = swapon(argv[optind], flags); if (err) { - ERROR("failed to swapon %s (%d)\n", argv[optind], err); + ULOG_ERR("failed to swapon %s (%d)\n", argv[optind], err); return err; } @@ -1329,7 +1356,7 @@ static int main_swapon(int argc, char **argv) static int main_swapoff(int argc, char **argv) { if (argc != 2) { - ERROR("Usage: swapoff [-a] [DEVICE]\n\n" + ULOG_ERR("Usage: swapoff [-a] [DEVICE]\n\n" "\tStop swapping on DEVICE\n" " -a\tStop swapping on all swap devices\n"); return -1; @@ -1340,33 +1367,33 @@ static int main_swapoff(int argc, char **argv) char line[256]; if (!fp) { - ERROR("failed to open /proc/swaps\n"); + ULOG_ERR("failed to open /proc/swaps\n"); return -1; } - fgets(line, sizeof(line), fp); - while (fgets(line, sizeof(line), fp)) { - char *end = strchr(line, ' '); - int err; + if (fgets(line, sizeof(line), fp)) + while (fgets(line, sizeof(line), fp)) { + char *end = strchr(line, ' '); + int err; - if (!end) - continue; - *end = '\0'; - err = swapoff(line); - if (err) - ERROR("failed to swapoff %s (%d)\n", line, err); - } + if (!end) + continue; + *end = '\0'; + err = swapoff(line); + if (err) + ULOG_ERR("failed to swapoff %s (%d)\n", line, err); + } fclose(fp); } else { struct stat s; int err; if (stat(argv[1], &s) || (!S_ISBLK(s.st_mode) && !S_ISREG(s.st_mode))) { - ERROR("%s is not a block device or file\n", argv[1]); + ULOG_ERR("%s is not a block device or file\n", argv[1]); return -1; } err = swapoff(argv[1]); if (err) { - ERROR("fsiled to swapoff %s (%d)\n", argv[1], err); + ULOG_ERR("failed to swapoff %s (%d)\n", argv[1], err); return err; } } @@ -1380,6 +1407,9 @@ int main(int argc, char **argv) umask(0); + ulog_open(-1, -1, "block"); + ulog_threshold(LOG_NOTICE); + if (!strcmp(base, "swapon")) return main_swapon(argc, argv); @@ -1404,9 +1434,17 @@ int main(int argc, char **argv) if (!strcmp(argv[1], "umount")) return main_umount(argc, argv); + + if (!strcmp(argv[1], "remount")) { + int ret = main_umount(argc, argv); + + if (!ret) + ret = main_mount(argc, argv); + return ret; + } } - fprintf(stderr, "Usage: block \n"); + ULOG_ERR("Usage: block \n"); return -1; }