summaryrefslogtreecommitdiff
path: root/Manage.c
diff options
context:
space:
mode:
Diffstat (limited to 'Manage.c')
-rw-r--r--Manage.c147
1 files changed, 47 insertions, 100 deletions
diff --git a/Manage.c b/Manage.c
index 5c3d2b9b..21536f5e 100644
--- a/Manage.c
+++ b/Manage.c
@@ -27,10 +27,6 @@
#include "md_p.h"
#include <ctype.h>
-#define REGISTER_DEV _IO (MD_MAJOR, 1)
-#define START_MD _IO (MD_MAJOR, 2)
-#define STOP_MD _IO (MD_MAJOR, 3)
-
int Manage_ro(char *devname, int fd, int readonly)
{
/* switch to readonly or rw
@@ -40,17 +36,9 @@ int Manage_ro(char *devname, int fd, int readonly)
* use RESTART_ARRAY_RW or STOP_ARRAY_RO
*
*/
- mdu_array_info_t array;
-#ifndef MDASSEMBLE
struct mdinfo *mdi;
-#endif
int rv = 0;
- if (md_get_version(fd) < 9000) {
- pr_err("need md driver version 0.90.0 or later\n");
- return 1;
- }
-#ifndef MDASSEMBLE
/* If this is an externally-managed array, we need to modify the
* metadata_version so that mdmon doesn't undo our change.
*/
@@ -94,10 +82,9 @@ int Manage_ro(char *devname, int fd, int readonly)
}
goto out;
}
-#endif
- if (ioctl(fd, GET_ARRAY_INFO, &array)) {
- pr_err("%s does not appear to be active.\n",
- devname);
+
+ if (!md_array_active(fd)) {
+ pr_err("%s does not appear to be active.\n", devname);
rv = 1;
goto out;
}
@@ -118,14 +105,10 @@ int Manage_ro(char *devname, int fd, int readonly)
}
}
out:
-#ifndef MDASSEMBLE
sysfs_free(mdi);
-#endif
return rv;
}
-#ifndef MDASSEMBLE
-
static void remove_devices(char *devnm, char *path)
{
/*
@@ -176,10 +159,6 @@ int Manage_run(char *devname, int fd, struct context *c)
*/
char nm[32], *nmp;
- if (md_get_version(fd) < 9000) {
- pr_err("need md driver version 0.90.0 or later\n");
- return 1;
- }
nmp = fd2devnm(fd);
if (!nmp) {
pr_err("Cannot find %s in sysfs!!\n", devname);
@@ -207,14 +186,6 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
if (will_retry && verbose == 0)
verbose = -1;
- if (md_get_version(fd) < 9000) {
- if (ioctl(fd, STOP_MD, 0) == 0)
- return 0;
- pr_err("stopping device %s failed: %s\n",
- devname, strerror(errno));
- return 1;
- }
-
strcpy(devnm, fd2devnm(fd));
/* Get EXCL access first. If this fails, then attempting
* to stop is probably a bad idea.
@@ -233,11 +204,9 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
count = 5;
while (((fd = ((devname[0] == '/')
?open(devname, O_RDONLY|O_EXCL)
- :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0
- || strcmp(fd2devnm(fd), devnm) != 0)
- && container[0]
- && mdmon_running(container)
- && count) {
+ :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0 ||
+ strcmp(fd2devnm(fd), devnm) != 0) && container[0] &&
+ mdmon_running(container) && count) {
/* Can't open, so something might be wrong. However it
* is a container, so we might be racing with mdmon, so
* retry for a bit.
@@ -273,8 +242,8 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
while (count &&
(err = sysfs_set_str(mdi, NULL,
"array_state",
- "inactive")) < 0
- && errno == EBUSY) {
+ "inactive")) < 0 &&
+ errno == EBUSY) {
usleep(200000);
count--;
}
@@ -476,9 +445,8 @@ done:
* so it is reasonable to retry for a while - 5 seconds.
*/
count = 25; err = 0;
- while (count && fd >= 0
- && (err = ioctl(fd, STOP_ARRAY, NULL)) < 0
- && errno == EBUSY) {
+ while (count && fd >= 0 &&
+ (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) {
usleep(200000);
count --;
}
@@ -539,14 +507,14 @@ static void add_faulty(struct mddev_dev *dv, int fd, char disp)
int remaining_disks;
int i;
- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0)
+ if (md_get_array_info(fd, &array) != 0)
return;
remaining_disks = array.nr_disks;
for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
char buf[40];
disk.number = i;
- if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
+ if (md_get_disk_info(fd, &disk) != 0)
continue;
if (disk.major == 0 && disk.minor == 0)
continue;
@@ -565,7 +533,7 @@ static void add_detached(struct mddev_dev *dv, int fd, char disp)
int remaining_disks;
int i;
- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0)
+ if (md_get_array_info(fd, &array) != 0)
return;
remaining_disks = array.nr_disks;
@@ -573,7 +541,7 @@ static void add_detached(struct mddev_dev *dv, int fd, char disp)
char buf[40];
int sfd;
disk.number = i;
- if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
+ if (md_get_disk_info(fd, &disk) != 0)
continue;
if (disk.major == 0 && disk.minor == 0)
continue;
@@ -602,7 +570,7 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char)
int copies, set;
int i;
- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0)
+ if (md_get_array_info(fd, &array) != 0)
return;
if (array.level != 10)
return;
@@ -615,7 +583,7 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char)
for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
char buf[40];
disk.number = i;
- if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
+ if (md_get_disk_info(fd, &disk) != 0)
continue;
if (disk.major == 0 && disk.minor == 0)
continue;
@@ -661,9 +629,8 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv,
get_linux_version() <= 2006018)
goto skip_re_add;
disc.number = mdi.disk.number;
- if (ioctl(fd, GET_DISK_INFO, &disc) != 0
- || disc.major != 0 || disc.minor != 0
- )
+ if (md_get_disk_info(fd, &disc) != 0 ||
+ disc.major != 0 || disc.minor != 0)
goto skip_re_add;
disc.major = major(rdev);
disc.minor = minor(rdev);
@@ -688,8 +655,8 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv,
if (dv->failfast == FlagClear)
disc.state &= ~(1 << MD_DISK_FAILFAST);
remove_partitions(tfd);
- if (update || dv->writemostly != FlagDefault
- || dv->failfast != FlagDefault) {
+ if (update || dv->writemostly != FlagDefault ||
+ dv->failfast != FlagDefault) {
int rv = -1;
tfd = dev_open(dv->devname, O_RDWR);
if (tfd < 0) {
@@ -774,9 +741,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
" Adding anyway as --force was given.\n",
dv->devname, devname);
}
- if (!tst->ss->external &&
- array->major_version == 0 &&
- md_get_version(fd)%100 < 2) {
+ if (!tst->ss->external && array->major_version == 0) {
if (ioctl(fd, HOT_ADD_DISK, rdev)==0) {
if (verbose >= 0)
pr_err("hot added %s\n",
@@ -805,7 +770,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
char *dev;
int dfd;
disc.number = j;
- if (ioctl(fd, GET_DISK_INFO, &disc))
+ if (md_get_disk_info(fd, &disc))
continue;
if (disc.major==0 && disc.minor==0)
continue;
@@ -827,8 +792,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
break;
}
/* FIXME this is a bad test to be using */
- if (!tst->sb && (dv->disposition != 'a'
- && dv->disposition != 'S')) {
+ if (!tst->sb && (dv->disposition != 'a' &&
+ dv->disposition != 'S')) {
/* we are re-adding a device to a
* completely dead array - have to depend
* on kernel to check
@@ -888,7 +853,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
for (d = 0; d < MAX_DISKS && found < array->nr_disks; d++) {
disc.number = d;
- if (ioctl(fd, GET_DISK_INFO, &disc))
+ if (md_get_disk_info(fd, &disc))
continue;
if (disc.major == 0 && disc.minor == 0)
continue;
@@ -929,7 +894,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
*/
for (j = array->raid_disks; j < tst->max_devs; j++) {
disc.number = j;
- if (ioctl(fd, GET_DISK_INFO, &disc))
+ if (md_get_disk_info(fd, &disc))
break;
if (disc.major==0 && disc.minor==0)
break;
@@ -946,7 +911,6 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
/* only add journal to array that supports journaling */
if (dv->disposition == 'j') {
- struct mdinfo mdi;
struct mdinfo *mdp;
mdp = sysfs_read(fd, NULL, GET_ARRAY_STATE);
@@ -955,7 +919,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
return -1;
}
- if (strncmp(mdp->sysfs_array_state, "readonly", 8) != 0) {
+ if (mdp->array_state != ARRAY_READONLY) {
sysfs_free(mdp);
pr_err("%s is not readonly, cannot add journal.\n", devname);
return -1;
@@ -963,11 +927,6 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
sysfs_free(mdp);
- tst->ss->getinfo_super(tst, &mdi, NULL);
- if (mdi.journal_device_required == 0) {
- pr_err("%s does not support journal device.\n", devname);
- return -1;
- }
disc.raid_disk = 0;
}
@@ -994,7 +953,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
for (j = 0; j < tst->max_devs; j++) {
mdu_disk_info_t disc2;
disc2.number = j;
- if (ioctl(fd, GET_DISK_INFO, &disc2))
+ if (md_get_disk_info(fd, &disc2))
continue;
if (disc2.major==0 && disc2.minor==0)
continue;
@@ -1110,7 +1069,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
}
int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
- int sysfd, unsigned long rdev, int verbose, char *devname)
+ int sysfd, unsigned long rdev, int force, int verbose, char *devname)
{
int lfd = -1;
int err;
@@ -1177,13 +1136,9 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
/* device has been removed and we don't know
* the major:minor number
*/
- int n = write(sysfd, "remove", 6);
- if (n != 6)
- err = -1;
- else
- err = 0;
+ err = sys_hot_remove_disk(sysfd, force);
} else {
- err = ioctl(fd, HOT_REMOVE_DISK, rdev);
+ err = hot_remove_disk(fd, rdev, force);
if (err && errno == ENODEV) {
/* Old kernels rejected this if no personality
* is registered */
@@ -1387,13 +1342,15 @@ int Manage_subdevs(char *devname, int fd,
int busy = 0;
int raid_slot = -1;
- if (ioctl(fd, GET_ARRAY_INFO, &array)) {
- pr_err("Cannot get array info for %s\n",
- devname);
+ if (sysfs_init(&info, fd, NULL)) {
+ pr_err("sysfs not availabile for %s\n", devname);
goto abort;
}
- sysfs_init(&info, fd, NULL);
+ if (md_get_array_info(fd, &array)) {
+ pr_err("Cannot get array info for %s\n", devname);
+ goto abort;
+ }
/* array.size is only 32 bits and may be truncated.
* So read from sysfs if possible, and record number of sectors
*/
@@ -1410,7 +1367,7 @@ int Manage_subdevs(char *devname, int fd,
}
for (dv = devlist; dv; dv = dv->next) {
- unsigned long rdev = 0; /* device to add/remove etc */
+ dev_t rdev = 0; /* device to add/remove etc */
int rv;
int mj,mn;
@@ -1427,8 +1384,7 @@ int Manage_subdevs(char *devname, int fd,
if (strcmp(dv->devname, "failed") == 0 ||
strcmp(dv->devname, "faulty") == 0) {
- if (dv->disposition != 'A'
- && dv->disposition != 'r') {
+ if (dv->disposition != 'A' && dv->disposition != 'r') {
pr_err("%s only meaningful with -r or --re-add, not -%c\n",
dv->devname, dv->disposition);
goto abort;
@@ -1461,7 +1417,7 @@ int Manage_subdevs(char *devname, int fd,
}
add_devlist = conf_get_devs();
if (add_devlist == NULL) {
- pr_err("no devices to scan for missing members.");
+ pr_err("no devices to scan for missing members.\n");
continue;
}
for (dp = &add_devlist; *dp; dp = & (*dp)->next)
@@ -1533,31 +1489,24 @@ int Manage_subdevs(char *devname, int fd,
goto abort;
}
}
- } else if ((dv->disposition == 'r' || dv->disposition == 'f')
- && get_maj_min(dv->devname, &mj, &mn)) {
+ } else if ((dv->disposition == 'r' ||
+ dv->disposition == 'f') &&
+ get_maj_min(dv->devname, &mj, &mn)) {
/* for 'fail' and 'remove', the device might
* not exist.
*/
rdev = makedev(mj, mn);
} else {
- struct stat stb;
tfd = dev_open(dv->devname, O_RDONLY);
if (tfd >= 0) {
- fstat(tfd, &stb);
+ fstat_is_blkdev(tfd, dv->devname, &rdev);
close(tfd);
} else {
int open_err = errno;
- if (stat(dv->devname, &stb) != 0) {
- pr_err("Cannot find %s: %s\n",
- dv->devname, strerror(errno));
- goto abort;
- }
- if ((stb.st_mode & S_IFMT) != S_IFBLK) {
+ if (!stat_is_blkdev(dv->devname, &rdev)) {
if (dv->disposition == 'M')
/* non-fatal. Also improbable */
continue;
- pr_err("%s is not a block device.\n",
- dv->devname);
goto abort;
}
if (dv->disposition == 'r')
@@ -1574,7 +1523,6 @@ int Manage_subdevs(char *devname, int fd,
goto abort;
}
}
- rdev = stb.st_rdev;
}
switch(dv->disposition){
default:
@@ -1607,7 +1555,7 @@ int Manage_subdevs(char *devname, int fd,
if (dv->disposition == 'F')
/* Need to remove first */
- ioctl(fd, HOT_REMOVE_DISK, rdev);
+ hot_remove_disk(fd, rdev, force);
/* Make sure it isn't in use (in 2.6 or later) */
tfd = dev_open(dv->devname, O_RDONLY|O_EXCL);
if (tfd >= 0) {
@@ -1649,7 +1597,7 @@ int Manage_subdevs(char *devname, int fd,
rv = -1;
} else
rv = Manage_remove(tst, fd, dv, sysfd,
- rdev, verbose,
+ rdev, verbose, force,
devname);
if (sysfd >= 0)
close(sysfd);
@@ -1823,4 +1771,3 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
close(fd2);
return 0;
}
-#endif