diff options
author | Neil Brown <neilb@suse.de> | 2001-06-14 05:33:53 +0000 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2001-06-14 05:33:53 +0000 |
commit | 682c705194a869b882cd710d5f996142912db390 (patch) | |
tree | f9da32bd70e47d558a84530e34c2b8feb17dbfa0 /Manage.c | |
parent | 64c4757e27fe7d688685e9a86ff87a3331a88979 (diff) | |
download | mdadm-682c705194a869b882cd710d5f996142912db390.tar.gz mdadm-682c705194a869b882cd710d5f996142912db390.tar.xz mdadm-682c705194a869b882cd710d5f996142912db390.zip |
mdctl-v0.3mdctl-v0.3
Diffstat (limited to 'Manage.c')
-rw-r--r-- | Manage.c | 160 |
1 files changed, 159 insertions, 1 deletions
@@ -28,16 +28,174 @@ */ #include "mdctl.h" +#include "md_u.h" +#include "md_p.h" int Manage_ro(char *devname, int fd, int readonly) { + /* switch to readonly or rw + * + * requires >= 0.90.0 + * first check that array is runing + * use RESTART_ARRAY_RW or STOP_ARRAY_RO + * + */ + mdu_array_info_t array; + + if (md_get_version(fd) < 9000) { + fprintf(stderr, Name ": need md driver version 0.90.0 or later\n"); + return 1; + } + if (ioctl(fd, GET_ARRAY_INFO, &array)) { + fprintf(stderr, Name ": %s does not appear to be active.\n", + devname); + return 1; + } + + if (readonly>0) { + if (ioctl(fd, STOP_ARRAY_RO, NULL)) { + fprintf(stderr, Name ": failed to set readonly for %s: %s\n", + devname, strerror(errno)); + return 1; + } + } else if (readonly < 0) { + if (ioctl(fd, RESTART_ARRAY_RW, NULL)) { + fprintf(stderr, Name ": fail to re writable for %s: %s\n", + devname, strerror(errno)); + return 1; + } + } + return 0; } int Manage_runstop(char *devname, int fd, int runstop) { + /* 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 (md_get_version(fd) < 9000) { + fprintf(stderr, Name ": need md driver version 0.90.0 or later\n"); + return 1; + } + if (ioctl(fd, GET_ARRAY_INFO, &array)) { + fprintf(stderr, Name ": %s does not appear to be active.\n", + devname); + return 1; + } + + if (runstop>0) { + if (ioctl(fd, RUN_ARRAY, ¶m)) { + fprintf(stderr, Name ": failed to run array %s: %s\n", + devname, strerror(errno)); + return 1; + } + } else if (runstop < 0){ + if (ioctl(fd, STOP_ARRAY, NULL)) { + fprintf(stderr, Name ": fail to re writable for %s: %s\n", + devname, strerror(errno)); + return 1; + } + } + return 0; } int Manage_subdevs(char *devname, int fd, int devcnt, char *devnames[], int devmodes[]) -{ + { + /* do something to each dev. + * devmode can be + * 'a' - add the device + * try HOT_ADD_DISK + * If that fails EINVAL, try ADD_NEW_DISK + * 'r' - remove the device HOT_REMOVE_DISK + * 'f' - set the device faulty SET_DISK_FAULTY + */ + mdu_array_info_t array; + mdu_disk_info_t disc; + struct stat stb; + int i,j; + + if (ioctl(fd, GET_ARRAY_INFO, &array)) { + fprintf(stderr, Name ": cannot get array info for %s\n", + devname); + return 1; + } + for (i=0 ; i<devcnt; i++) { + if (stat(devnames[i], &stb)) { + fprintf(stderr, Name ": cannot find %s: %s\n", + devnames[i], strerror(errno)); + return 1; + } + if ((stb.st_mode & S_IFMT) != S_IFBLK) { + fprintf(stderr, Name ": %s is not a block device.\n", + devnames[i]); + return 1; + } + switch(devmodes[i]){ + default: + fprintf(stderr, Name ": internal error - devmode[%d]=%d\n", + i, devmodes[i]); + return 1; + case 'a': + /* add the device - hot or cold */ + if (ioctl(fd, HOT_ADD_DISK, stb.st_rdev)==0) { + fprintf(stderr, Name ": hot added %s\n", + devnames[i]); + continue; + } + /* 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 + */ + for (j=0; j<array.nr_disks; j++) { + if (ioctl(fd, GET_DISK_INFO, &disc)) + break; + if (disc.major==0 && disc.minor==0) + break; + if (disc.state & 8) /* removed */ + break; + } + disc.number =j; + disc.raid_disk = j; + disc.state = 0; + disc.major = MAJOR(stb.st_rdev); + disc.minor = MINOR(stb.st_rdev); + if (ioctl(fd,ADD_NEW_DISK, &disc)) { + fprintf(stderr, Name ": add new disk failed for %s: %s\n", + devnames[i], strerror(errno)); + return 1; + } + fprintf(stderr, Name ": added %s\n", devnames[i]); + break; + + case 'r': + /* hot remove */ + /* FIXME check that is is a current member */ + if (ioctl(fd, HOT_REMOVE_DISK, stb.st_rdev)) { + fprintf(stderr, Name ": hot remove failed for %s: %s\n", + devnames[i], strerror(errno)); + return 1; + } + fprintf(stderr, Name ": hot removed %s\n", devnames[i]); + break; + + case 'f': /* set faulty */ + /* FIXME check current member */ + if (ioctl(fd, SET_DISK_FAULTY, stb.st_rdev)) { + fprintf(stderr, Name ": set disk faulty failed for %s: %s\n", + devnames[i], strerror(errno)); + return 1; + } + fprintf(stderr, Name ": set %s faulty in %s\n", + devnames[i], devname); + break; + } + } + return 0; + } |