X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=mdmon.c;h=ff985d291ee9045ede3daf68c1184af3ee0384eb;hb=895ffd992954069e4ea67efb8a85bb0fd72c3707;hp=fd136e50dad3ab443f5973e0a13ddb17035ff038;hpb=4dd2df0966ec2e43ea404df5de7adf9f0e1a8e40;p=thirdparty%2Fmdadm.git diff --git a/mdmon.c b/mdmon.c index fd136e50..ff985d29 100644 --- a/mdmon.c +++ b/mdmon.c @@ -67,6 +67,8 @@ #include "mdadm.h" #include "mdmon.h" +char const Name[] = "mdmon"; + struct active_array *discard_this; struct active_array *pending_discard; @@ -169,6 +171,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) int fd; int n; long fl; + int rv; /* first rule of survival... don't off yourself */ if (pid == getpid()) @@ -199,9 +202,16 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) fl &= ~O_NONBLOCK; fcntl(sock, F_SETFL, fl); n = read(sock, buf, 100); - /* Ignore result, it is just the wait that - * matters - */ + + /* If there is I/O going on it might took some time to get to + * clean state. Wait for monitor to exit fully to avoid races. + * Ping it with SIGUSR1 in case that it is sleeping */ + for (n = 0; n < 25; n++) { + rv = kill(pid, SIGUSR1); + if (rv < 0) + break; + usleep(200000); + } } void remove_pidfile(char *devname) @@ -232,7 +242,8 @@ static int make_control_sock(char *devname) addr.sun_family = PF_LOCAL; strcpy(addr.sun_path, path); - if (bind(sfd, &addr, sizeof(addr)) < 0) { + umask(077); /* ensure no world write access */ + if (bind(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { close(sfd); return -1; } @@ -271,7 +282,8 @@ void usage(void) "\n" "Options are:\n" " --help -h : This message\n" -" --all : All devices\n" +" --all -a : All devices\n" +" --foreground -F : Run in foreground (do not fork)\n" " --takeover -t : Takeover container\n" ); exit(2); @@ -297,10 +309,14 @@ int main(int argc, char *argv[]) {NULL, 0, NULL, 0} }; - /* - * Always change process name to @dmon to avoid systemd killing it - */ - argv[0][0] = '@'; + if (in_initrd()) { + /* + * set first char of argv[0] to @. This is used by + * systemd to signal that the task was launched from + * initrd/initramfs and should be preserved during shutdown + */ + argv[0][0] = '@'; + } while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { switch (opt) { @@ -315,7 +331,7 @@ int main(int argc, char *argv[]) dofork = 0; break; case OffRootOpt: - /* silently ignore old option */ + argv[0][0] = '@'; break; case 'h': default: @@ -373,7 +389,7 @@ int main(int argc, char *argv[]) } if (!devnm) { - fprintf(stderr, "mdmon: %s is not a valid md device name\n", + pr_err("%s is not a valid md device name\n", container_name); exit(1); } @@ -397,26 +413,19 @@ static int mdmon(char *devnm, int must_fork, int takeover) mdfd = open_dev(devnm); if (mdfd < 0) { - fprintf(stderr, "mdmon: %s: %s\n", devnm, - strerror(errno)); - return 1; - } - if (md_get_version(mdfd) < 0) { - fprintf(stderr, "mdmon: %s: Not an md device\n", - devnm); + pr_err("%s: %s\n", devnm, strerror(errno)); return 1; } /* Fork, and have the child tell us when they are ready */ if (must_fork) { if (pipe(pfd) != 0) { - fprintf(stderr, "mdmon: failed to create pipe\n"); + pr_err("failed to create pipe\n"); return 1; } switch(fork()) { case -1: - fprintf(stderr, "mdmon: failed to fork: %s\n", - strerror(errno)); + pr_err("failed to fork: %s\n", strerror(errno)); return 1; case 0: /* child */ close(pfd[0]); @@ -427,6 +436,7 @@ static int mdmon(char *devnm, int must_fork, int takeover) wait(&status); status = WEXITSTATUS(status); } + close(pfd[0]); return status; } } else @@ -440,25 +450,23 @@ static int mdmon(char *devnm, int must_fork, int takeover) mdi = sysfs_read(mdfd, container->devnm, GET_VERSION|GET_LEVEL|GET_DEVS); if (!mdi) { - fprintf(stderr, "mdmon: failed to load sysfs info for %s\n", - container->devnm); + pr_err("failed to load sysfs info for %s\n", container->devnm); exit(3); } if (mdi->array.level != UnSet) { - fprintf(stderr, "mdmon: %s is not a container - cannot monitor\n", - devnm); + pr_err("%s is not a container - cannot monitor\n", devnm); 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", + pr_err("%s does not use external metadata - cannot monitor\n", devnm); exit(3); } container->ss = version_to_superswitch(mdi->text_version); if (container->ss == NULL) { - fprintf(stderr, "mdmon: %s uses unsupported metadata: %s\n", + pr_err("%s uses unsupported metadata: %s\n", devnm, mdi->text_version); exit(3); } @@ -494,16 +502,14 @@ static int mdmon(char *devnm, int must_fork, int takeover) ignore = chdir("/"); if (!takeover && victim > 0 && victim_sock >= 0) { if (fping_monitor(victim_sock) == 0) { - fprintf(stderr, "mdmon: %s already managed\n", - container->devnm); + pr_err("%s already managed\n", container->devnm); exit(3); } close(victim_sock); victim_sock = -1; } if (container->ss->load_container(container, mdfd, devnm)) { - fprintf(stderr, "mdmon: Cannot load metadata for %s\n", - devnm); + pr_err("Cannot load metadata for %s\n", devnm); exit(3); } close(mdfd); @@ -518,15 +524,17 @@ static int mdmon(char *devnm, int must_fork, int takeover) container->sock = make_control_sock(devnm); status = 0; - if (write(pfd[1], &status, sizeof(status)) < 0) - fprintf(stderr, "mdmon: failed to notify our parent: %d\n", - getppid()); - close(pfd[1]); + if (pfd[1] >= 0) { + if (write(pfd[1], &status, sizeof(status)) < 0) + pr_err("failed to notify our parent: %d\n", + getppid()); + close(pfd[1]); + } mlockall(MCL_CURRENT | MCL_FUTURE); if (clone_monitor(container) < 0) { - fprintf(stderr, "mdmon: failed to start monitor process: %s\n", + pr_err("failed to start monitor process: %s\n", strerror(errno)); exit(2); } @@ -576,11 +584,6 @@ int restore_stripes(int *dest, unsigned long long *offsets, return 1; } -void abort_reshape(struct mdinfo *sra) -{ - return; -} - int save_stripes(int *source, unsigned long long *offsets, int raid_disks, int chunk_size, int level, int layout, int nwrites, int *dest, @@ -589,3 +592,10 @@ int save_stripes(int *source, unsigned long long *offsets, { return 0; } + +struct superswitch super0 = { + .name = "0.90", +}; +struct superswitch super1 = { + .name = "1.x", +};