X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=Monitor.c;h=f6fd95cdfa9401c9bef67bdefd3403f8a3a5e852;hp=2677f7bf9d9c5f14243776c48237a945847104e7;hb=148acb7baaa810b68d55df4c1784d6bd0dfd1b78;hpb=2800528713cd32a4d12d7e17c14eba34eb8a4ec2 diff --git a/Monitor.c b/Monitor.c index 2677f7bf..f6fd95cd 100644 --- a/Monitor.c +++ b/Monitor.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2006 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: */ #include "mdadm.h" @@ -168,10 +163,18 @@ int Monitor(mddev_dev_t devlist, struct state *st; if (mdlist->devname == NULL) continue; + if (strcasecmp(mdlist->devname, "") == 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; @@ -276,6 +279,10 @@ int Monitor(mddev_dev_t devlist, 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 && @@ -473,16 +480,25 @@ int Monitor(mddev_dev_t devlist, } } 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); @@ -633,107 +649,3 @@ int Wait(char *dev) 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, NULL, NULL, &fds, &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; -} - -