/*
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Neil Brown
- * Email: <neilb@cse.unsw.edu.au>
- * Paper: Neil Brown
- * School of Computer Science and Engineering
- * The University of New South Wales
- * Sydney, 2052
- * Australia
+ * Email: <neilb@suse.de>
*/
#include "mdadm.h"
struct state *st;
if (mdlist->devname == NULL)
continue;
+ if (strcasecmp(mdlist->devname, "<ignore>") == 0)
+ continue;
st = malloc(sizeof *st);
if (st == NULL)
continue;
- st->devname = strdup(mdlist->devname);
+ if (mdlist->devname[0] == '/')
+ st->devname = strdup(mdlist->devname);
+ else {
+ st->devname = malloc(8+strlen(mdlist->devname)+1);
+ strcpy(strcpy(st->devname, "/dev/md/"),
+ mdlist->devname);
+ }
st->utime = 0;
st->next = statelist;
st->err = 0;
mse = mse2;
}
+ if (array.utime == 0)
+ /* external arrays don't update utime */
+ array.utime = time(0);
+
if (st->utime == array.utime &&
st->failed == array.failed_disks &&
st->working == array.working_disks &&
st->spare_group = NULL;
st->expected_spares = -1;
statelist = st;
+ if (test)
+ alert("TestMessage", st->devname, NULL, mailaddr, mailfrom, alert_cmd, dosyslog);
alert("NewArray", st->devname, NULL, mailaddr, mailfrom, alert_cmd, dosyslog);
new_found = 1;
}
}
}
if (dev > 0) {
- if (ioctl(fd2, HOT_REMOVE_DISK,
- (unsigned long)dev) == 0) {
- if (ioctl(fd1, HOT_ADD_DISK,
- (unsigned long)dev) == 0) {
+ struct mddev_dev_s devlist;
+ char devname[20];
+ devlist.next = NULL;
+ devlist.used = 0;
+ devlist.re_add = 0;
+ devlist.writemostly = 0;
+ devlist.devname = devname;
+ sprintf(devname, "%d:%d", major(dev), minor(dev));
+
+ devlist.disposition = 'r';
+ if (Manage_subdevs(st2->devname, fd2, &devlist, -1) == 0) {
+ devlist.disposition = 'a';
+ if (Manage_subdevs(st->devname, fd1, &devlist, -1) == 0) {
alert("MoveSpare", st->devname, st2->devname, mailaddr, mailfrom, alert_cmd, dosyslog);
close(fd1);
close(fd2);
break;
}
- else ioctl(fd2, HOT_ADD_DISK, (unsigned long) dev);
+ else Manage_subdevs(st2->devname, fd2, &devlist, -1);
}
}
close(fd1);
mdstat_wait(5);
}
}
-
-static char *clean_states[] = {
- "clear", "inactive", "readonly", "read-auto", "clean", NULL };
-
-int WaitClean(char *dev, int verbose)
-{
- int fd;
- struct mdinfo *mdi;
- int rv = 1;
- int devnum;
-
- fd = open(dev, O_RDONLY);
- if (fd < 0) {
- if (verbose)
- fprintf(stderr, Name ": Couldn't open %s: %s\n", dev, strerror(errno));
- return 1;
- }
-
- devnum = fd2devnum(fd);
- mdi = sysfs_read(fd, devnum, GET_VERSION|GET_LEVEL|GET_SAFEMODE);
- if (!mdi) {
- if (verbose)
- fprintf(stderr, Name ": Failed to read sysfs attributes for "
- "%s\n", dev);
- close(fd);
- return 0;
- }
-
- switch(mdi->array.level) {
- case LEVEL_LINEAR:
- case LEVEL_MULTIPATH:
- case 0:
- /* safemode delay is irrelevant for these levels */
- rv = 0;
-
- }
-
- /* for internal metadata the kernel handles the final clean
- * transition, containers can never be dirty
- */
- if (!is_subarray(mdi->text_version))
- rv = 0;
-
- /* safemode disabled ? */
- if (mdi->safe_mode_delay == 0)
- rv = 0;
-
- if (rv) {
- int state_fd = sysfs_open(fd2devnum(fd), NULL, "array_state");
- char buf[20];
- fd_set fds;
- struct timeval tm;
-
- /* minimize the safe_mode_delay and prepare to wait up to 5s
- * for writes to quiesce
- */
- sysfs_set_safemode(mdi, 1);
- tm.tv_sec = 5;
- tm.tv_usec = 0;
-
- /* give mdmon a chance to checkpoint resync */
- sysfs_set_str(mdi, NULL, "sync_action", "idle");
-
- FD_ZERO(&fds);
-
- /* wait for array_state to be clean */
- while (1) {
- rv = read(state_fd, buf, sizeof(buf));
- if (rv < 0)
- break;
- if (sysfs_match_word(buf, clean_states) <= 4)
- break;
- FD_SET(state_fd, &fds);
- rv = select(state_fd + 1, &fds, NULL, NULL, &tm);
- if (rv < 0 && errno != EINTR)
- break;
- lseek(state_fd, 0, SEEK_SET);
- }
- if (rv < 0)
- rv = 1;
- else if (ping_monitor(mdi->text_version) == 0) {
- /* we need to ping to close the window between array
- * state transitioning to clean and the metadata being
- * marked clean
- */
- rv = 0;
- } else
- rv = 1;
- if (rv && verbose)
- fprintf(stderr, Name ": Error waiting for %s to be clean\n",
- dev);
-
- /* restore the original safe_mode_delay */
- sysfs_set_safemode(mdi, mdi->safe_mode_delay);
- close(state_fd);
- }
-
- sysfs_free(mdi);
- close(fd);
-
- return rv;
-}
-
-