Stop using a shutdown hook for softraid(4) and explicitly shutdown
authormpi <mpi@openbsd.org>
Thu, 10 Jul 2014 12:21:08 +0000 (12:21 +0000)
committermpi <mpi@openbsd.org>
Thu, 10 Jul 2014 12:21:08 +0000 (12:21 +0000)
the disciplines right after vfs_shutdown().

This change is required in order to be able to set `cold' to 1 before
traversing the device (mainbus) tree for DVACT_POWERDOWN when halting
a machine.  Yes, this is ugly because sr_shutdown() needs to sleep.  But
at least it is obvious and hopefully somebody will be ofended and fix
it.

In order to properly flush the cache of the disks under softraid0,
sr_shutdown() now propagates DVACT_POWERDOWN for this particular subtree
of devices which are not under mainbus.  As a side effect sd(4) shutdown
hook should no longer be necessary.

Tested by stsp@ and Jean-Philippe Ouellet.

ok deraadt@, stsp@, jsing@

sys/dev/softraid.c
sys/dev/softraidvar.h
sys/kern/vfs_subr.c

index 1318d13..91bca8a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid.c,v 1.331 2014/01/22 23:32:42 jsing Exp $ */
+/* $OpenBSD: softraid.c,v 1.332 2014/07/10 12:21:09 mpi Exp $ */
 /*
  * Copyright (c) 2007, 2008, 2009 Marco Peereboom <marco@peereboom.us>
  * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@@ -125,8 +125,7 @@ void                        sr_set_chunk_state(struct sr_discipline *, int, int);
 void                   sr_set_vol_state(struct sr_discipline *);
 
 /* utility functions */
-void                   sr_shutdown(struct sr_softc *);
-void                   sr_shutdownhook(void *);
+void                   sr_shutdown(void);
 void                   sr_uuid_generate(struct sr_uuid *);
 char                   *sr_uuid_format(struct sr_uuid *);
 void                   sr_uuid_print(struct sr_uuid *, int);
@@ -1827,8 +1826,6 @@ sr_attach(struct device *parent, struct device *self, void *aux)
 
        softraid_disk_attach = sr_disk_attach;
 
-       sc->sc_shutdownhook = shutdownhook_establish(sr_shutdownhook, sc);
-
        sr_boot_assembly(sc);
 
        explicit_bzero(sr_bootkey, sizeof(sr_bootkey));
@@ -1842,12 +1839,9 @@ sr_detach(struct device *self, int flags)
 
        DNPRINTF(SR_D_MISC, "%s: sr_detach\n", DEVNAME(sc));
 
-       if (sc->sc_shutdownhook)
-               shutdownhook_disestablish(sc->sc_shutdownhook);
-
        softraid_disk_attach = NULL;
 
-       sr_shutdown(sc);
+       sr_shutdown();
 
 #ifndef SMALL_KERNEL
        if (sc->sc_sensor_task != NULL)
@@ -4503,18 +4497,20 @@ sr_validate_stripsize(u_int32_t b)
 }
 
 void
-sr_shutdownhook(void *arg)
-{
-       sr_shutdown((struct sr_softc *)arg);
-}
-
-void
-sr_shutdown(struct sr_softc *sc)
+sr_shutdown(void)
 {
+       struct sr_softc         *sc = softraid0;
        struct sr_discipline    *sd;
 
        DNPRINTF(SR_D_MISC, "%s: sr_shutdown\n", DEVNAME(sc));
 
+       /*
+        * Since softraid is not under mainbus, we have to explicitly
+        * notify its children that the power is going down, so they
+        * can execute their shutdown hooks.
+        */
+       config_suspend((struct device *)sc, DVACT_POWERDOWN);
+
        /* Shutdown disciplines in reverse attach order. */
        while ((sd = TAILQ_LAST(&sc->sc_dis_list, sr_discipline_list)) != NULL)
                sr_discipline_shutdown(sd, 1);
index 13e07e9..6de87be 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraidvar.h,v 1.154 2014/01/22 09:42:13 jsing Exp $ */
+/* $OpenBSD: softraidvar.h,v 1.155 2014/07/10 12:21:09 mpi Exp $ */
 /*
  * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
  * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@@ -626,8 +626,6 @@ TAILQ_HEAD(sr_discipline_list, sr_discipline);
 struct sr_softc {
        struct device           sc_dev;
 
-       void                    (*sc_shutdownhook)(void *);
-
        struct rwlock           sc_lock;
 
        struct bio_status       sc_status;      /* Status and messages. */
index 7fad896..120ca5b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfs_subr.c,v 1.215 2014/07/08 17:19:25 deraadt Exp $  */
+/*     $OpenBSD: vfs_subr.c,v 1.216 2014/07/10 12:21:08 mpi Exp $      */
 /*     $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $   */
 
 /*
 
 #include <netinet/in.h>
 
+#include "softraid.h"
+
+void sr_shutdown(void);
+
 enum vtype iftovt_tab[16] = {
        VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
        VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
@@ -1645,6 +1649,10 @@ vfs_shutdown(void)
                printf("giving up\n");
        else
                printf("done\n");
+
+#if NSOFTRAID > 0
+       sr_shutdown();
+#endif
 }
 
 /*