X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=mdmon.c;h=54e12384d6b2c156cd8cf0cf182b82e9b604655d;hp=ee68e3c3b5709c0c3b34cfd8e74fe5a18470a64c;hb=refs%2Fheads%2Fmdadm-3.2.x;hpb=e4c72d1dc69e576ca97163a3d4f44394e9bdd3ed diff --git a/mdmon.c b/mdmon.c index ee68e3c3..54e12384 100644 --- a/mdmon.c +++ b/mdmon.c @@ -184,11 +184,18 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) buf[sizeof(buf)-1] = 0; close(fd); - if (n < 0 || !strstr(buf, "mdmon")) + /* Note that if started with --offroot, the name + * might be "@dmon" + */ + if (n < 0 || !(strstr(buf, "mdmon") || + strstr(buf, "@dmon"))) return; kill(pid, SIGTERM); + if (sock < 0) + return; + /* Wait for monitor to exit by reading from the socket, after * clearing the non-blocking flag */ fl = fcntl(sock, F_GETFL, 0); @@ -262,7 +269,18 @@ static int do_fork(void) void usage(void) { - fprintf(stderr, "Usage: mdmon [--all] [--takeover] CONTAINER\n"); + fprintf(stderr, +"Usage: mdmon [options] CONTAINER\n" +"\n" +"Options are:\n" +" --help -h : This message\n" +" --all : All devices\n" +" --takeover -t : Takeover container\n" +" --offroot : Set first character of argv[0] to @ to indicate the\n" +" application was launched from initrd/initramfs and\n" +" should not be shutdown by systemd as part of the\n" +" regular shutdown process.\n" +); exit(2); } @@ -274,25 +292,50 @@ int main(int argc, char *argv[]) int devnum; char *devname; int status = 0; - int arg; + int opt; int all = 0; int takeover = 0; - - for (arg = 1; arg < argc; arg++) { - if (strncmp(argv[arg], "--all",5) == 0 || - strcmp(argv[arg], "/proc/mdstat") == 0) { - container_name = argv[arg]; + static struct option options[] = { + {"all", 0, NULL, 'a'}, + {"takeover", 0, NULL, 't'}, + {"help", 0, NULL, 'h'}, + {"offroot", 0, NULL, OffRootOpt}, + {NULL, 0, NULL, 0} + }; + + while ((opt = getopt_long(argc, argv, "tha", options, NULL)) != -1) { + switch (opt) { + case 'a': + container_name = argv[optind-1]; all = 1; - } else if (strcmp(argv[arg], "--takeover") == 0) + break; + case 't': takeover = 1; - else if (container_name == NULL) - container_name = argv[arg]; - else + break; + case OffRootOpt: + argv[0][0] = '@'; + break; + case 'h': + default: usage(); + break; + } + } + + if (all == 0 && container_name == NULL) { + if (argv[optind]) + container_name = argv[optind]; } + if (container_name == NULL) usage(); + if (argc - optind > 1) + usage(); + + if (strcmp(container_name, "/proc/mdstat") == 0) + all = 1; + if (all) { struct mdstat_ent *mdstat, *e; int container_len = strlen(container_name); @@ -468,6 +511,7 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover) exit(3); } close(victim_sock); + victim_sock = -1; } if (container->ss->load_container(container, mdfd, devname)) { fprintf(stderr, "mdmon: Cannot load metadata for %s\n", @@ -501,7 +545,8 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover) if (victim > 0) { try_kill_monitor(victim, container->devname, victim_sock); - close(victim_sock); + if (victim_sock >= 0) + close(victim_sock); } setsid();