diff options
author | Dan Williams <dan.j.williams@intel.com> | 2008-05-15 16:48:35 +1000 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2008-05-15 16:48:35 +1000 |
commit | f7dd881f909a7bc552a6de3c1fc4920bb0bfdff2 (patch) | |
tree | 57f1a18231e53bff1c3244eed448fac1a356542f /Manage.c | |
parent | 0fd5c350e55590d2adbbb6ca16ec86391abda14b (diff) |
handle Manage_subdevs() for 'external' arrays
From: Dan Williams <dan.j.williams@intel.com>
1/ Block attempts to add/remove devices from container members
2/ Forward add/remove requests to containers
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'Manage.c')
-rw-r--r-- | Manage.c | 63 |
1 files changed, 62 insertions, 1 deletions
@@ -171,6 +171,54 @@ int Manage_reconfig(char *devname, int fd, int layout) return 0; } +static int +add_remove_device_container(int fd, int add_remove, struct stat *stb) +{ + int devnum = fd2devnum(fd); + char *devname = devnum2devname(devnum); + int sfd = devname ? connect_monitor(devname) : -1; + struct md_message msg; + int err = 0; + + if (devname && sfd < 0) { + fprintf(stderr, Name ": Cannot connect to monitor for %s: %s\n", + devname, strerror(errno)); + free(devname); + return 1; + } else if (sfd < 0) { + fprintf(stderr, Name ": Cannot determine container name for" + " device number %d\n", devnum); + return 1; + } + + if (add_remove) + ack(sfd, 0, 0); + else if (send_remove_device(sfd, stb->st_rdev, 0, 0) != 0) { + fprintf(stderr, Name ": Failed to send \'%s device\'" + " message to the container monitor\n", + add_remove ? "add" : "remove"); + err = 1; + } + + /* check the reply */ + if (!err && receive_message(sfd, &msg, 0) != 0) { + fprintf(stderr, Name ": Failed to receive an acknowledgement" + " from the container monitor\n"); + err = 1; + } + + if (!err && msg.seq != 0) { + fprintf(stderr, Name ": %s device failed error code %d\n", + add_remove ? "Add" : "Remove", msg.seq); + err = 1; + } + + free(devname); + close(sfd); + + return err; +} + int Manage_subdevs(char *devname, int fd, mddev_dev_t devlist, int verbose) { @@ -306,7 +354,13 @@ int Manage_subdevs(char *devname, int fd, return 1; case 'a': /* add the device */ - + if (tst == &supertype_container_member) { + fprintf(stderr, Name ": Cannot add disks to a" + " \'member\' array, perform this" + " operation on the parent container\n"); + return 1; + } else if (tst->ss->external) + return add_remove_device_container(fd, 1, &stb); /* Make sure it isn't in use (in 2.6 or later) */ tfd = open(dv->devname, O_RDONLY|O_EXCL); if (tfd < 0) { @@ -497,6 +551,13 @@ int Manage_subdevs(char *devname, int fd, case 'r': /* hot remove */ + if (tst == &supertype_container_member) { + fprintf(stderr, Name ": Cannot remove disks from a" + " \'member\' array, perform this" + " operation on the parent container\n"); + return 1; + } else if (tst->ss->external) + return add_remove_device_container(fd, 0, &stb); /* FIXME check that it is a current member */ if (ioctl(fd, HOT_REMOVE_DISK, (unsigned long)stb.st_rdev)) { fprintf(stderr, Name ": hot remove failed " |