X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=Kill.c;h=f2fdb856c44b4a9a904063deb0d4d89fdcb4d821;hb=401f095c39b732b4247bd728cb493eb7bb692298;hp=ba99c6e529f423ff6a0d62c5fa94b73e73bc5e39;hpb=82d9eba687c952a9919f756203706285d6c42f07;p=thirdparty%2Fmdadm.git diff --git a/Kill.c b/Kill.c index ba99c6e5..f2fdb856 100644 --- a/Kill.c +++ b/Kill.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2002 Neil Brown + * Copyright (C) 2001-2009 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -19,12 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Neil Brown - * Email: - * Paper: Neil Brown - * School of Computer Science and Engineering - * The University of New South Wales - * Sydney, 2052 - * Australia + * Email: * * Added by Dale Stephenson * steph@snapserver.com @@ -34,45 +29,118 @@ #include "md_u.h" #include "md_p.h" -int Kill(char *dev, int force) +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. */ - void *super; int fd, rv = 0; - struct supertype *st; - - fd = open(dev, O_RDWR|O_EXCL); + + if (force) + noexcl = 1; + fd = open(dev, O_RDWR|(noexcl ? 0 : O_EXCL)); if (fd < 0) { - fprintf(stderr, Name ": Couldn't open %s for write - not zeroing\n", - dev); - return 1; + if (verbose >= 0) + pr_err("Couldn't open %s for write - not zeroing\n", + dev); + return 2; } - st = guess_super(fd); - if (st == NULL) { - fprintf(stderr, Name ": Unrecognised md component device - %s\n", dev); - return 1; + if (st == NULL) + st = guess_super(fd); + if (st == NULL || st->ss->init_super == NULL) { + if (verbose >= 0) + pr_err("Unrecognised md component device - %s\n", dev); + close(fd); + return 2; } - rv = st->ss->load_super(st, fd, &super, dev); - if (force && rv >= 2) - rv = 0; /* ignore bad data in superblock */ - if (rv== 0 || (force && rv >= 2)) { - mdu_array_info_t info; - info.major_version = -1; /* zero superblock */ - free(super); - st->ss->init_super(&super, &info); - if (st->ss->store_super(fd, super)) { - fprintf(stderr, Name ": Could not zero superblock on %s\n", - dev); + st->ignore_hw_compat = 1; + rv = st->ss->load_super(st, fd, dev); + if (rv == 0 || (force && rv >= 2)) { + st->ss->free_super(st); + st->ss->init_super(st, NULL, 0, "", NULL, NULL, + INVALID_SECTORS); + if (st->ss->store_super(st, fd)) { + if (verbose >= 0) + pr_err("Could not zero superblock on %s\n", + dev); rv = 1; } else if (rv) { - 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; +}