X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=mdmon.c;h=5e39437c01b14986f1d9bdd446909700ba175641;hp=5aad763892d0fce60de8e46ca5768f3ecd884406;hb=1124b3cf29dad544e8a5aa01e5f9e94e7be1765a;hpb=6f4098a6fd809acd6ef6a80051eec09f4536a27d diff --git a/mdmon.c b/mdmon.c index 5aad7638..5e39437c 100644 --- a/mdmon.c +++ b/mdmon.c @@ -271,42 +271,56 @@ static int do_fork(void) void usage(void) { - fprintf(stderr, "Usage: mdmon [--switch-root dir] /device/name/for/container\n"); + fprintf(stderr, "Usage: mdmon /device/name/for/container [target_dir]\n"); exit(2); } +int mdmon(char *devname, int devnum, int scan, char *switchroot); + int main(int argc, char *argv[]) { - int mdfd; - struct mdinfo *mdi, *di; - struct supertype *container; - sigset_t set; - struct sigaction act; - int pfd[2]; - int status; - int ignore; char *container_name = NULL; char *switchroot = NULL; int devnum; char *devname; + int scan = 0; + int status = 0; switch (argc) { + case 3: + switchroot = argv[2]; case 2: container_name = argv[1]; break; - case 4: - if (strcmp(argv[1], "--switch-root") != 0) { - fprintf(stderr, "mdmon: unknown argument %s\n", argv[1]); - usage(); - } - switchroot = argv[2]; - container_name = argv[3]; - break; default: usage(); } - if (strncmp(container_name, "md", 2) == 0) { + if (strcmp(container_name, "/proc/mdstat") == 0) { + struct mdstat_ent *mdstat, *e; + + /* launch an mdmon instance for each container found */ + scan = 1; + mdstat = mdstat_read(0, 0); + for (e = mdstat; e; e = e->next) { + if (strncmp(e->metadata_version, "external:", 9) == 0 && + !is_subarray(&e->metadata_version[9])) { + devname = devnum2devname(e->devnum); + /* update cmdline so this mdmon instance can be + * distinguished from others in a call to ps(1) + */ + if (strlen(devname) <= strlen(container_name)) { + memset(container_name, 0, strlen(container_name)); + sprintf(container_name, "%s", devname); + } + status |= mdmon(devname, e->devnum, scan, + switchroot); + } + } + free_mdstat(mdstat); + + return status; + } else if (strncmp(container_name, "md", 2) == 0) { devnum = devname2devnum(container_name); devname = devnum2devname(devnum); if (strcmp(container_name, devname) != 0) @@ -328,29 +342,45 @@ int main(int argc, char *argv[]) container_name); exit(1); } + return mdmon(devname, devnum, scan, switchroot); +} + +int mdmon(char *devname, int devnum, int scan, char *switchroot) +{ + int mdfd; + struct mdinfo *mdi, *di; + struct supertype *container; + sigset_t set; + struct sigaction act; + int pfd[2]; + int status; + int ignore; + + dprintf("starting mdmon for %s in %s\n", + devname, switchroot ? : "/"); mdfd = open_dev(devnum); if (mdfd < 0) { - fprintf(stderr, "mdmon: %s: %s\n", container_name, + fprintf(stderr, "mdmon: %s: %s\n", devname, strerror(errno)); - exit(1); + return 1; } if (md_get_version(mdfd) < 0) { fprintf(stderr, "mdmon: %s: Not an md device\n", - container_name); - exit(1); + devname); + return 1; } /* Fork, and have the child tell us when they are ready */ - if (do_fork()) { + if (do_fork() || scan) { if (pipe(pfd) != 0) { fprintf(stderr, "mdmon: failed to create pipe\n"); - exit(1); + return 1; } switch(fork()) { case -1: fprintf(stderr, "mdmon: failed to fork: %s\n", strerror(errno)); - exit(1); + return 1; case 0: /* child */ close(pfd[0]); break; @@ -360,7 +390,7 @@ int main(int argc, char *argv[]) wait(&status); status = WEXITSTATUS(status); } - exit(status); + return status; } } else pfd[0] = pfd[1] = -1; @@ -377,7 +407,7 @@ int main(int argc, char *argv[]) } mdi = sysfs_read(mdfd, container->devnum, - GET_VERSION|GET_LEVEL|GET_DEVS); + GET_VERSION|GET_LEVEL|GET_DEVS|SKIP_GONE_DEVS); if (!mdi) { fprintf(stderr, "mdmon: failed to load sysfs info for %s\n", @@ -386,20 +416,20 @@ int main(int argc, char *argv[]) } if (mdi->array.level != UnSet) { fprintf(stderr, "mdmon: %s is not a container - cannot monitor\n", - container_name); + devname); exit(3); } if (mdi->array.major_version != -1 || mdi->array.minor_version != -2) { fprintf(stderr, "mdmon: %s does not use external metadata - cannot monitor\n", - container_name); + devname); exit(3); } container->ss = find_metadata_methods(mdi->text_version); if (container->ss == NULL) { fprintf(stderr, "mdmon: %s uses unknown metadata: %s\n", - container_name, mdi->text_version); + devname, mdi->text_version); exit(3); } @@ -481,9 +511,9 @@ int main(int argc, char *argv[]) } container->sock = make_control_sock(container->devname); - if (container->ss->load_super(container, mdfd, container_name)) { + if (container->ss->load_super(container, mdfd, devname)) { fprintf(stderr, "mdmon: Cannot load metadata for %s\n", - container_name); + devname); exit(3); } close(mdfd);