diff --git a/Makefile.am b/Makefile.am index 30403afa..afa2a21e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,8 @@ ACLOCAL_AMFLAGS = -I m4 sbin_PROGRAMS = finit initctl reboot -finit_SOURCES = finit.c api.c client.c conf.c exec.c getty.c helpers.c \ - mount.c pid.c sig.c svc.c service.c plugin.c tty.c \ - cond.c cond-w.c sm.c utmp-api.c utmp-api.h +finit_SOURCES = finit.c api.c client.c cond.c cond-w.c conf.c exec.c \ + getty.c helpers.c mdadm.c mount.c pid.c plugin.c \ + service.c sig.c svc.c sm.c tty.c utmp-api.c utmp-api.h pkginclude_HEADERS = cond.h finit.h helpers.h inetd.h plugin.h svc.h if INETD finit_SOURCES += inetd.c diff --git a/helpers.h b/helpers.h index 25cd3168..74c5d259 100644 --- a/helpers.h +++ b/helpers.h @@ -28,6 +28,7 @@ #include #include /* strerror() */ #include +#include #define DO_LOG(level, fmt, args...) \ do { \ diff --git a/mdadm.c b/mdadm.c new file mode 100644 index 00000000..f79b1da3 --- /dev/null +++ b/mdadm.c @@ -0,0 +1,72 @@ +/* Handle MD arrays + * + * Copyright (c) 2016 Joachim Nilsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#include "helpers.h" + + +static glob_t *get_arrays(void) +{ + static glob_t arrays; + + glob("/sys/block/md*", 0, NULL, &arrays); + if (arrays.gl_pathc > 0) + return &arrays; + + return NULL; +} + +/* + * If system has an MD raid, we must tell it to stop before continuing + * with the shutdown. Some controller cards, in particular the Intel(R) + * Matrix Storage Manager, must be properly notified. + */ +void mdadm_wait(void) +{ + size_t i; + glob_t *gl; + char cmd[160]; + + /* Setup kernel specific settings, e.g. allow broadcast ping, etc. */ + gl = get_arrays(); + if (gl) { + for (i = 0; i < gl->gl_pathc; i++) { + char *array; + + array = basename(gl->gl_pathv[i]); + snprintf(cmd, sizeof(cmd), "mdadm --wait-clean /dev/%s >/dev/null", array); + run_interactive(cmd, "Marking MD array %s as clean", array); + } + globfree(gl); + } +} + +/** + * Local Variables: + * indent-tabs-mode: t + * c-file-style: "linux" + * End: + */ diff --git a/sig.c b/sig.c index 448a1bdf..e4d0e665 100644 --- a/sig.c +++ b/sig.c @@ -86,6 +86,7 @@ static uev_t sighup_watcher, sigint_watcher, sigpwr_watcher; static uev_t sigchld_watcher, sigsegv_watcher; static uev_t sigstop_watcher, sigtstp_watcher, sigcont_watcher; +void mdadm_wait(void); void unmount_tmpfs(void); void unmount_regular(void); @@ -155,7 +156,8 @@ void do_shutdown(shutop_t op) run("/bin/mount -n -o remount,ro dummydev /"); run("/bin/mount -n -o remount,ro /"); - /* XXX: Call mdadm to mark RAID array(s) as clean before halting. */ + /* Call mdadm to mark any RAID array(s) as clean before halting. */ + mdadm_wait(); _d("%s.", op == SHUT_REBOOT ? "Rebooting" : "Halting"); if (op == SHUT_REBOOT)