]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Kill.c
mdadm: improve the dlm locking mechanism for clustered raid
[thirdparty/mdadm.git] / Kill.c
diff --git a/Kill.c b/Kill.c
index 63442a628313b5dce794455c9a17220c2435b34d..ff52561d0cbb988c7e3977b2f939ba2e7670c6f2 100644 (file)
--- a/Kill.c
+++ b/Kill.c
 #include       "md_u.h"
 #include       "md_p.h"
 
-int Kill(char *dev, struct supertype *st, int force, int quiet, int noexcl)
+int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
 {
        /*
         * Nothing fancy about Kill.  It just zeroes out a superblock
         * Definitely not safe.
+        * Returns:
+        *  0 - a zero superblock was successfully written out
+        *  1 - failed to write the zero superblock
+        *  2 - failed to open the device or find a superblock.
         */
 
        int fd, rv = 0;
@@ -42,37 +46,101 @@ int Kill(char *dev, struct supertype *st, int force, int quiet, int noexcl)
                noexcl = 1;
        fd = open(dev, O_RDWR|(noexcl ? 0 : O_EXCL));
        if (fd < 0) {
-               if (!quiet)
-                       fprintf(stderr, Name ": Couldn't open %s for write - not zeroing\n",
+               if (verbose >= 0)
+                       pr_err("Couldn't open %s for write - not zeroing\n",
                                dev);
-               close(fd);
-               return 1;
+               return 2;
        }
        if (st == NULL)
                st = guess_super(fd);
-       if (st == NULL) {
-               if (!quiet)
-                       fprintf(stderr, Name ": Unrecognised md component device - %s\n", dev);
+       if (st == NULL || st->ss->init_super == NULL) {
+               if (verbose >= 0)
+                       pr_err("Unrecognised md component device - %s\n", dev);
                close(fd);
                return 2;
        }
+       st->ignore_hw_compat = 1;
        rv = st->ss->load_super(st, fd, dev);
-       if (force && rv >= 2)
-               rv = 0; /* ignore bad data in superblock */
-       if (rv== 0 || (force && rv >= 2)) {
+       if (rv == 0 || (force && rv >= 2)) {
                st->ss->free_super(st);
-               st->ss->init_super(st, NULL, 0, "", NULL, NULL);
+               st->ss->init_super(st, NULL, NULL, "", NULL, NULL,
+                                  INVALID_SECTORS);
                if (st->ss->store_super(st, fd)) {
-                       if (!quiet)
-                               fprintf(stderr, Name ": Could not zero superblock on %s\n",
+                       if (verbose >= 0)
+                               pr_err("Could not zero superblock on %s\n",
                                        dev);
                        rv = 1;
                } else if (rv) {
-                       if (!quiet)
-                               fprintf(stderr, Name ": superblock zeroed anyway\n");
+                       if (verbose >= 0)
+                               pr_err("superblock zeroed anyway\n");
                        rv = 0;
                }
        }
        close(fd);
        return rv;
 }
+
+int Kill_subarray(char *dev, char *subarray, int verbose)
+{
+       /* Delete a subarray out of a container, the subarry must be
+        * inactive.  The subarray string must be a subarray index
+        * number.
+        *
+        * 0 = successfully deleted subarray from all container members
+        * 1 = failed to sync metadata to one or more devices
+        * 2 = failed to find the container, subarray, or other resource
+        *     issue
+        */
+       struct supertype supertype, *st = &supertype;
+       int fd, rv = 2;
+
+       memset(st, 0, sizeof(*st));
+
+       fd = open_subarray(dev, subarray, st, verbose < 0);
+       if (fd < 0)
+               return 2;
+
+       if (!st->ss->kill_subarray) {
+               if (verbose >= 0)
+                       pr_err("Operation not supported for %s metadata\n",
+                              st->ss->name);
+               goto free_super;
+       }
+
+       if (is_subarray_active(subarray, st->devnm)) {
+               if (verbose >= 0)
+                       pr_err("Subarray-%s still active, aborting\n",
+                              subarray);
+               goto free_super;
+       }
+
+       if (mdmon_running(st->devnm))
+               st->update_tail = &st->updates;
+
+       /* ok we've found our victim, drop the axe */
+       rv = st->ss->kill_subarray(st);
+       if (rv) {
+               if (verbose >= 0)
+                       pr_err("Failed to delete subarray-%s from %s\n",
+                              subarray, dev);
+               goto free_super;
+       }
+
+       /* FIXME these routines do not report success/failure */
+       if (st->update_tail)
+               flush_metadata_updates(st);
+       else
+               st->ss->sync_metadata(st);
+
+       if (verbose >= 0)
+               pr_err("Deleted subarray-%s from %s, UUIDs may have changed\n",
+                      subarray, dev);
+
+       rv = 0;
+
+ free_super:
+       st->ss->free_super(st);
+       close(fd);
+
+       return rv;
+}