X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=Manage.c;h=b323fd3c241b514c24a3138b7f332e09c8841fd8;hp=d8cc1362dc5c1aecfdc41a924270a763c6d9539f;hb=d7eaf49f65ecb99e24255026331b0af7a9245cc2;hpb=52826846282e9e224e05dde6d2e4cb38d1fefec7 diff --git a/Manage.c b/Manage.c index d8cc1362..b323fd3c 100644 --- a/Manage.c +++ b/Manage.c @@ -1,7 +1,7 @@ /* - * mdctl - manage Linux "md" devices aka RAID arrays. + * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001 Neil Brown + * Copyright (C) 2001-2002 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -27,7 +27,7 @@ * Australia */ -#include "mdctl.h" +#include "mdadm.h" #include "md_u.h" #include "md_p.h" @@ -77,7 +77,6 @@ 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 (runstop == -1 && md_get_version(fd) < 9000) { @@ -115,9 +114,47 @@ int Manage_runstop(char *devname, int fd, int runstop) 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, - int devcnt, char *devnames[], int devmodes[]) - { + mddev_dev_t devlist) +{ /* do something to each dev. * devmode can be * 'a' - add the device @@ -128,37 +165,57 @@ int Manage_subdevs(char *devname, int fd, */ mdu_array_info_t array; mdu_disk_info_t disc; + mddev_dev_t dv; struct stat stb; - int i,j; + int j; + int save_errno; + static char buf[4096]; if (ioctl(fd, GET_ARRAY_INFO, &array)) { fprintf(stderr, Name ": cannot get array info for %s\n", devname); return 1; } - for (i=0 ; inext) { + if (stat(dv->devname, &stb)) { fprintf(stderr, Name ": cannot find %s: %s\n", - devnames[i], strerror(errno)); + dv->devname, strerror(errno)); return 1; } if ((stb.st_mode & S_IFMT) != S_IFBLK) { fprintf(stderr, Name ": %s is not a block device.\n", - devnames[i]); + dv->devname); return 1; } - switch(devmodes[i]){ + switch(dv->disposition){ default: - fprintf(stderr, Name ": internal error - devmode[%d]=%d\n", - i, devmodes[i]); + 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, stb.st_rdev)==0) { + /* Make sure it isn' in use (in 2.6 or later) */ + fd = open(dv->devname, O_RDONLY|O_EXCL); + if (fd < 0) { + fprintf(stderr, Name ": Cannot open %s: %s\n", + dv->devname, strerror(errno)); + return 1; + } + close(fd); + if (ioctl(fd, HOT_ADD_DISK, (unsigned long)stb.st_rdev)==0) { fprintf(stderr, Name ": hot added %s\n", - devnames[i]); + dv->devname); continue; } + save_errno = errno; + if (read(fd, buf, sizeof(buf)) > 0) { + /* array is active, so don't try to add. + * i.e. something is wrong + */ + fprintf(stderr, Name ": hot add failed for %s: %s\n", + dv->devname, strerror(save_errno)); + return 1; + } /* try ADD_NEW_DISK. * we might be creating, we might be assembling, * it is hard to tell. @@ -166,6 +223,7 @@ int Manage_subdevs(char *devname, int fd, * in case */ for (j=0; jdevname, strerror(errno)); return 1; } - fprintf(stderr, Name ": added %s\n", devnames[i]); + fprintf(stderr, Name ": added %s\n", dv->devname); break; case 'r': /* hot remove */ /* FIXME check that it is a current member */ - if (ioctl(fd, HOT_REMOVE_DISK, stb.st_rdev)) { + if (ioctl(fd, HOT_REMOVE_DISK, (unsigned long)stb.st_rdev)) { fprintf(stderr, Name ": hot remove failed for %s: %s\n", - devnames[i], strerror(errno)); + dv->devname, strerror(errno)); return 1; } - fprintf(stderr, Name ": hot removed %s\n", devnames[i]); + fprintf(stderr, Name ": hot removed %s\n", dv->devname); 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)); + if (ioctl(fd, SET_DISK_FAULTY, (unsigned long) stb.st_rdev)) { + fprintf(stderr, Name ": set device faulty failed for %s: %s\n", + dv->devname, strerror(errno)); return 1; } fprintf(stderr, Name ": set %s faulty in %s\n", - devnames[i], devname); + dv->devname, devname); break; } }