X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=Manage.c;h=53accd7e9a1722013dc77d28408e3bc5ae0d913f;hb=8068890f1116c6fc5ae87596bb6b8272f79d2d1c;hp=cab49bcc04b2ed43a61e1fca8ea658197f6d1ee2;hpb=cd29a5c835c11cbcedc10487677eac6a946ad61b;p=thirdparty%2Fmdadm.git diff --git a/Manage.c b/Manage.c index cab49bcc..53accd7e 100644 --- a/Manage.c +++ b/Manage.c @@ -1,5 +1,5 @@ /* - * mdctl - manage Linux "md" devices aka RAID arrays. + * mdadm - manage Linux "md" devices aka RAID arrays. * * Copyright (C) 2001-2002 Neil Brown * @@ -27,7 +27,7 @@ * Australia */ -#include "mdctl.h" +#include "mdadm.h" #include "md_u.h" #include "md_p.h" @@ -72,18 +72,17 @@ int Manage_ro(char *devname, int fd, int readonly) return 0; } -int Manage_runstop(char *devname, int fd, int runstop) +int Manage_runstop(char *devname, int fd, int runstop, int quiet) { /* Run or stop the array. array must already be configured * required >= 0.90.0 */ - mdu_array_info_t array; mdu_param_t param; /* unused */ if (runstop == -1 && md_get_version(fd) < 9000) { if (ioctl(fd, STOP_MD, 0)) { - fprintf(stderr, Name ": stopping device %s failed: %s\n", - devname, strerror(errno)); + if (!quiet) fprintf(stderr, Name ": stopping device %s failed: %s\n", + devname, strerror(errno)); return 1; } } @@ -107,14 +106,53 @@ int Manage_runstop(char *devname, int fd, int runstop) } } else if (runstop < 0){ if (ioctl(fd, STOP_ARRAY, NULL)) { - fprintf(stderr, Name ": fail to stop array %s: %s\n", - devname, strerror(errno)); + if (!quiet) + fprintf(stderr, Name ": fail to stop array %s: %s\n", + devname, strerror(errno)); return 1; } } return 0; } +int Manage_resize(char *devname, int fd, long long size, int raid_disks) +{ + mdu_array_info_t info; + if (ioctl(fd, GET_ARRAY_INFO, &info) != 0) { + fprintf(stderr, Name ": Cannot get array information for %s: %s\n", + devname, strerror(errno)); + return 1; + } + if (size >= 0) + info.size = size; + if (raid_disks > 0) + info.raid_disks = raid_disks; + if (ioctl(fd, SET_ARRAY_INFO, &info) != 0) { + fprintf(stderr, Name ": Cannot set device size/shape for %s: %s\n", + devname, strerror(errno)); + return 1; + } + return 0; +} + +int Manage_reconfig(char *devname, int fd, int layout) +{ + mdu_array_info_t info; + if (ioctl(fd, GET_ARRAY_INFO, &info) != 0) { + fprintf(stderr, Name ": Cannot get array information for %s: %s\n", + devname, strerror(errno)); + return 1; + } + info.layout = layout; + printf("layout set to %d\n", info.layout); + if (ioctl(fd, SET_ARRAY_INFO, &info) != 0) { + fprintf(stderr, Name ": Cannot set layout for %s: %s\n", + devname, strerror(errno)); + return 1; + } + return 0; +} + int Manage_subdevs(char *devname, int fd, mddev_dev_t devlist) { @@ -130,9 +168,10 @@ int Manage_subdevs(char *devname, int fd, mdu_disk_info_t disc; mddev_dev_t dv; struct stat stb; - int i,j; - int save_errno; - static buf[4096]; + int j; + int tfd; + struct supertype *st; + void *dsuper = NULL; if (ioctl(fd, GET_ARRAY_INFO, &array)) { fprintf(stderr, Name ": cannot get array info for %s\n", @@ -152,32 +191,70 @@ int Manage_subdevs(char *devname, int fd, } switch(dv->disposition){ default: - fprintf(stderr, Name ": internal error - devmode[%d]=%d\n", - i, dv->disposition); + fprintf(stderr, Name ": internal error - devmode[%s]=%d\n", + dv->devname, dv->disposition); return 1; case 'a': /* add the device - hot or cold */ - if (ioctl(fd, HOT_ADD_DISK, (unsigned long)stb.st_rdev)==0) { - fprintf(stderr, Name ": hot added %s\n", - dv->devname); - continue; + /* Make sure it isn't in use (in 2.6 or later) */ + tfd = open(dv->devname, O_RDONLY|O_EXCL); + if (tfd < 0) { + fprintf(stderr, Name ": Cannot open %s: %s\n", + dv->devname, strerror(errno)); + return 1; } - save_errno = errno; - if (read(fd, buf, sizeof(buf)) > 0) { - /* array is active, so don't try to add. - * i.e. something is wrong - */ + close(tfd); + if (array.major_version == 0 && + md_get_version(fd)%100 < 2) { + if (ioctl(fd, HOT_ADD_DISK, + (unsigned long)stb.st_rdev)==0) { + fprintf(stderr, Name ": hot added %s\n", + dv->devname); + continue; + } + fprintf(stderr, Name ": hot add failed for %s: %s\n", - dv->devname, strerror(save_errno)); + dv->devname, strerror(errno)); return 1; } - /* try ADD_NEW_DISK. - * we might be creating, we might be assembling, - * it is hard to tell. - * set up number/raid_disk/state just - * in case + + /* need to find a sample superblock to copy, and + * a spare slot to use */ - for (j=0; jmax_devs; j++) { + char *dev; + int dfd; + disc.number = j; + if (ioctl(fd, GET_DISK_INFO, &disc)) + continue; + if (disc.major==0 && disc.minor==0) + continue; + if ((disc.state & 4)==0) continue; /* sync */ + /* Looks like a good device to try */ + dev = map_dev(disc.major, disc.minor); + if (!dev) continue; + dfd = open(dev, O_RDONLY); + if (dfd < 0) continue; + if (st->ss->load_super(st, dfd, &dsuper, NULL)) { + close(dfd); + continue; + } + close(dfd); + break; + } + if (!dsuper) { + fprintf(stderr, Name ": cannot find valid superblock in this array - HELP\n"); + return 1; + } + for (j=0; j< st->max_devs; j++) { + disc.number = j; if (ioctl(fd, GET_DISK_INFO, &disc)) break; if (disc.major==0 && disc.minor==0) @@ -185,14 +262,16 @@ int Manage_subdevs(char *devname, int fd, if (disc.state & 8) /* removed */ break; } + disc.major = major(stb.st_rdev); + disc.minor = minor(stb.st_rdev); disc.number =j; - disc.raid_disk = j; disc.state = 0; - disc.major = MAJOR(stb.st_rdev); - disc.minor = MINOR(stb.st_rdev); + st->ss->add_to_super(dsuper, &disc); + if (st->ss->write_init_super(st, dsuper, &disc, dv->devname)) + return 1; if (ioctl(fd,ADD_NEW_DISK, &disc)) { - fprintf(stderr, Name ": add new disk failed for %s: %s\n", - dv->devname, strerror(errno)); + fprintf(stderr, Name ": add new device failed for %s as %d: %s\n", + dv->devname, j, strerror(errno)); return 1; } fprintf(stderr, Name ": added %s\n", dv->devname); @@ -212,7 +291,7 @@ int Manage_subdevs(char *devname, int fd, case 'f': /* set faulty */ /* FIXME check current member */ if (ioctl(fd, SET_DISK_FAULTY, (unsigned long) stb.st_rdev)) { - fprintf(stderr, Name ": set disk faulty failed for %s: %s\n", + fprintf(stderr, Name ": set device faulty failed for %s: %s\n", dv->devname, strerror(errno)); return 1; }