Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[PATCH] raidframe detachment



The attached patch gracefully shuts down a raid unit when you detach it
with 'drvctl -d raid0', or when you shut down the system.  Please review
and test.

Below is a typescript I recorded while I stacked up some disks and
filesystems in a Xen DOMU and shut it down.  Everything was torn down
completely and in an orderly way.  When I started the DOMU back up, the
RAIDs were clean.

/mnt on raid0 on {xbd0, xbd1, xbd2}
~root/mnt2 on vnd3 on ~root/mnt on raid1 on {vnd0, vnd1, vnd2}

ascension# raidctl -c ./raid0.conf raid0
raid0: Summary of serial numbers:
2009072200 3
raid0: Summary of mod counters:
101 3
raid0: Component /dev/xbd1e being configured at col: 0
         Column: 0 Num Columns: 3
         Version: 2 Serial Number: 2009072200 Mod Counter: 101
         Clean: Yes Status: 0
raid0: Component /dev/xbd2e being configured at col: 1
         Column: 1 Num Columns: 3
         Version: 2 Serial Number: 2009072200 Mod Counter: 101
         Clean: Yes Status: 0
raid0: Component /dev/xbd3e being configured at col: 2
         Column: 2 Num Columns: 3
         Version: 2 Serial Number: 2009072200 Mod Counter: 101
         Clean: Yes Status: 0
raid0: allocating 30 buffers of 16384 bytes.
raid0: RAID Level 5
raid0: Components: /dev/xbd1e /dev/xbd2e /dev/xbd3e
raid0: Total Sectors: 130944 (63 MB)
ascension# mount /dev/raid0a /mnt 
ascension# vnconfig vnd0 ./zero0
ascension# vnconfig vnd1 ./zero1
ascension# vnconfig vnd2 ./zero2
ascension# raidctl -c ./raid1.conf raid1
raid1: Summary of serial numbers:
20090723 3
raid1: Summary of mod counters:
13 3
raid1: Component /dev/vnd0e being configured at col: 0
         Column: 0 Num Columns: 3
         Version: 2 Serial Number: 20090723 Mod Counter: 13
         Clean: Yes Status: 0
raid1: Component /dev/vnd1e being configured at col: 1
         Column: 1 Num Columns: 3
         Version: 2 Serial Number: 20090723 Mod Counter: 13
         Clean: Yes Status: 0
raid1: Component /dev/vnd2e being configured at col: 2
         Column: 2 Num Columns: 3
         Version: 2 Serial Number: 20090723 Mod Counter: 13
         Clean: Yes Status: 0
raid1: allocating 30 buffers of 16384 bytes.
raid1: RAID Level 5
raid1: Components: /dev/vnd0e /dev/vnd1e /dev/vnd2e
raid1: Total Sectors: 3968 (1 MB)
ascension# mount /dev/raid1a ./mnt
ascension# dd if=/dev/zero of=mnt/zero count=1k bs=1k
1024+0 records in
1024+0 records out
1048576 bytes transferred in 0.028 secs (37449142 bytes/sec)
ascension# vnconfig vnd3 mnt/zero
ascension# newfs /dev/rvnd3a
/dev/rvnd3a: 1.0MB (2048 sectors) block size 4096, fragment size 512
        using 4 cylinder groups of 0.25MB, 64 blks, 128 inodes.
super-block backups (for fsck_ffs -b #) at:
32, 544, 1056, 1568,
ascension# vnconfig -l
vnd0: / (/dev/xbd0a) inode 155856
vnd1: / (/dev/xbd0a) inode 155857
vnd2: / (/dev/xbd0a) inode 155858
vnd3: /root/mnt (/dev/raid1a) inode 3
ascension# mkdir mnt2
ascension# mount /dev/vnd3a ./mnt2
ascension# bin/drvclose
mainbus0
    hypervisor0
        vcpu0
        xenbus0
            xbd0
            xbd1
            xbd2
            xbd3
            xennet0
        xencons0
        npx0
md0
raid0
vnd0
vnd1
vnd2
raid1
vnd3
ascension# shutdown -p now 
Shutdown NOW!
shutdown: [pid 559]
ascension# wall: You have write permission turned off; no reply possible
                                                                               
*** FINAL System shutdown message from root%ascension.ojctech.com@localhost *** 
       
System going down IMMEDIATELY                                                  
                                                                               
                                                                               
Jul 23 12:56:17 ascension shutdown: poweroff by root: 

System shutdown time has arrived

About to run shutdown hooks...
Stopping cron.
Stopping inetd.
Removing block-type swap devices
swapctl: removing /dev/xbd0b as swap device
Thu Jul 23 12:56:19 CDT 2009

Done running shutdown hooks.
ascension# Jul 23 12:56:24 ascension syslogd[127]: Exiting on signal 15
syncing disks... done

unmounting 0xcd10b604 /root/mnt2 (/dev/vnd3a)...unmounted /dev/vnd3a on 
/root/mnt2 type ffs

unmounting 0xcd0d7004 /root/mnt (/dev/raid1a)...
unmounting 0xcd0ae204 /mnt (/dev/raid0a)...unmounted /dev/raid0a on /mnt type 
ffs

unmounting 0xccf40004 /proc (procfs)...unmounted procfs on /proc type procfs

unmounting 0xccebf004 /dev/pts (ptyfs)...unmounted ptyfs on /dev/pts type ptyfs

unmounting 0xccebe004 /kern (kernfs)...unmounted kernfs on /kern type kernfs

unmounting 0xcc16352c / (/dev/xbd0a)...
unmounting 0xcd0d7004 /root/mnt (/dev/raid1a)...
unmounting 0xcc16352c / (/dev/xbd0a)...vnd3: detached
raid0: detached
md0: detached

unmounting 0xcd0d7004 /root/mnt (/dev/raid1a)...unmounted /dev/raid1a on 
/root/mnt type ffs

unmounting 0xcc16352c / (/dev/xbd0a)...
unmounting 0xcc16352c / (/dev/xbd0a)...raid1: detached
vnd2: detached
vnd1: detached
vnd0: detached

unmounting 0xcc16352c / (/dev/xbd0a)...
forcefully unmounting / (/dev/xbd0a)...forcefully unmounted /dev/xbd0a on / 
type ffs
skyking# 

Dave

-- 
David Young             OJC Technologies
dyoung%ojctech.com@localhost      Urbana, IL * (217) 278-3933
Index: sys/dev/raidframe/rf_netbsdkintf.c
===================================================================
RCS file: /cvsroot/src/sys/dev/raidframe/rf_netbsdkintf.c,v
retrieving revision 1.265
diff -p -u -u -p -r1.265 rf_netbsdkintf.c
--- sys/dev/raidframe/rf_netbsdkintf.c  10 Jun 2009 14:17:13 -0000      1.265
+++ sys/dev/raidframe/rf_netbsdkintf.c  23 Jul 2009 17:17:25 -0000
@@ -267,8 +267,9 @@ struct raid_softc {
 int numraid = 0;
 
 extern struct cfdriver raid_cd;
-CFATTACH_DECL_NEW(raid, sizeof(struct raid_softc),
-    raid_match, raid_attach, raid_detach, NULL);
+CFATTACH_DECL3_NEW(raid, sizeof(struct raid_softc),
+    raid_match, raid_attach, raid_detach, NULL, NULL, NULL,
+    DVF_DETACH_SHUTDOWN);
 
 /*
  * Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device.
@@ -305,6 +306,9 @@ static void raidmakedisklabel(struct rai
 static int raidlock(struct raid_softc *);
 static void raidunlock(struct raid_softc *);
 
+static int raid_do_detach_unlocked(struct raid_softc *, int);
+static int raid_do_detach(struct raid_softc *, int);
+
 static void rf_markalldirty(RF_Raid_t *);
 static void rf_set_properties(struct raid_softc *, RF_Raid_t *);
 
@@ -797,7 +801,6 @@ int
 raidclose(dev_t dev, int flags, int fmt, struct lwp *l)
 {
        int     unit = raidunit(dev);
-       cfdata_t cf;
        struct raid_softc *rs;
        int     error = 0;
        int     part;
@@ -833,24 +836,10 @@ raidclose(dev_t dev, int flags, int fmt,
 
                rf_update_component_labels(raidPtrs[unit],
                                                 RF_FINAL_COMPONENT_UPDATE);
-               if (doing_shutdown) {
-                       /* last one, and we're going down, so
-                          lights out for this RAID set too. */
-                       error = rf_Shutdown(raidPtrs[unit]);
 
-                       /* It's no longer initialized... */
-                       rs->sc_flags &= ~RAIDF_INITED;
-
-                       /* detach the device */
-                       
-                       cf = device_cfdata(rs->sc_dev);
-                       error = config_detach(rs->sc_dev, DETACH_QUIET);
-                       free(cf, M_RAIDFRAME);
-                       
-                       /* Detach the disk. */
-                       disk_detach(&rs->sc_dkdev);
-                       disk_destroy(&rs->sc_dkdev);
-               }
+               /* If the kernel is shutting down, it will detach
+                * this RAID set soon enough.
+                */
        }
 
        raidunlock(rs);
@@ -964,6 +953,52 @@ raidwrite(dev_t dev, struct uio *uio, in
 
 }
 
+static int
+raid_do_detach(struct raid_softc *rs, int pmask)
+{
+       int error;
+
+       if ((error = raidlock(rs)) != 0)
+               return (error);
+
+       error = raid_do_detach_unlocked(rs, pmask);
+
+       raidunlock(rs);
+
+       return error;
+}
+
+static int
+raid_do_detach_unlocked(struct raid_softc *rs, int pmask)
+{
+       int error;
+       RF_Raid_t *raidPtr;
+
+       raidPtr = raidPtrs[device_unit(rs->sc_dev)];
+
+       /*
+        * If somebody has a partition mounted, we shouldn't
+        * shutdown.
+        */
+       if ((rs->sc_dkdev.dk_openmask & ~pmask) ||
+           ((rs->sc_dkdev.dk_bopenmask & pmask) &&
+               (rs->sc_dkdev.dk_copenmask & pmask)))
+               return EBUSY;
+
+       if ((rs->sc_flags & RAIDF_INITED) == 0)
+               ;       /* not initialized: nothing to do */
+       else if ((error = rf_Shutdown(raidPtr)) != 0)
+               return error;
+       else
+               rs->sc_flags &= ~RAIDF_INITED;
+
+       /* Detach the disk. */
+       disk_detach(&rs->sc_dkdev);
+       disk_destroy(&rs->sc_dkdev);
+
+       return 0;
+}
+
 int
 raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
 {
@@ -1176,36 +1211,17 @@ raidioctl(dev_t dev, u_long cmd, void *d
                if ((error = raidlock(rs)) != 0)
                        return (error);
 
-               /*
-                * If somebody has a partition mounted, we shouldn't
-                * shutdown.
-                */
-
                part = DISKPART(dev);
                pmask = (1 << part);
-               if ((rs->sc_dkdev.dk_openmask & ~pmask) ||
-                   ((rs->sc_dkdev.dk_bopenmask & pmask) &&
-                       (rs->sc_dkdev.dk_copenmask & pmask))) {
-                       raidunlock(rs);
-                       return (EBUSY);
-               }
 
-               retcode = rf_Shutdown(raidPtr);
-
-               /* It's no longer initialized... */
-               rs->sc_flags &= ~RAIDF_INITED;
+               if ((retcode = raid_do_detach_unlocked(rs, pmask)) != 0)
+                       return retcode;
 
                /* free the pseudo device attach bits */
 
                cf = device_cfdata(rs->sc_dev);
-               /* XXX this causes us to not return any errors
-                  from the above call to rf_Shutdown() */
-               retcode = config_detach(rs->sc_dev, DETACH_QUIET);
-               free(cf, M_RAIDFRAME);
-
-               /* Detach the disk. */
-               disk_detach(&rs->sc_dkdev);
-               disk_destroy(&rs->sc_dkdev);
+               if ((retcode = config_detach(rs->sc_dev, DETACH_QUIET)) == 0)
+                       free(cf, M_RAIDFRAME);
 
                raidunlock(rs);
 
@@ -3620,12 +3636,9 @@ raid_attach(device_t parent, device_t se
 static int
 raid_detach(device_t self, int flags)
 {
-       struct raid_softc *rs = device_private(self);
+       struct raid_softc *rs = &raid_softc[device_unit(self)];
 
-       if (rs->sc_flags & RAIDF_INITED)
-               return EBUSY;
-
-       return 0;
+       return raid_do_detach(rs, 0);
 }
 
 static void


Home | Main Index | Thread Index | Old Index