Use ADD_NEW_DISK to hot-add to non-version-0 arrays
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
This commit is contained in:
parent
eaac7dde09
commit
892debc820
71
Manage.c
71
Manage.c
|
@ -169,8 +169,8 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
int j;
|
int j;
|
||||||
int tfd;
|
int tfd;
|
||||||
int save_errno;
|
struct supertype *st;
|
||||||
static char buf[4096];
|
void *dsuper = NULL;
|
||||||
|
|
||||||
if (ioctl(fd, GET_ARRAY_INFO, &array)) {
|
if (ioctl(fd, GET_ARRAY_INFO, &array)) {
|
||||||
fprintf(stderr, Name ": cannot get array info for %s\n",
|
fprintf(stderr, Name ": cannot get array info for %s\n",
|
||||||
|
@ -203,26 +203,54 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
close(tfd);
|
close(tfd);
|
||||||
if (ioctl(fd, HOT_ADD_DISK, (unsigned long)stb.st_rdev)==0) {
|
if (array.major_version == 0) {
|
||||||
fprintf(stderr, Name ": hot added %s\n",
|
if (ioctl(fd, HOT_ADD_DISK,
|
||||||
dv->devname);
|
(unsigned long)stb.st_rdev)==0) {
|
||||||
continue;
|
fprintf(stderr, Name ": hot added %s\n",
|
||||||
}
|
dv->devname);
|
||||||
save_errno = errno;
|
continue;
|
||||||
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",
|
fprintf(stderr, Name ": hot add failed for %s: %s\n",
|
||||||
dv->devname, strerror(save_errno));
|
dv->devname, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* try ADD_NEW_DISK.
|
|
||||||
* we might be creating, we might be assembling,
|
/* need to find a sample superblock to copy, and
|
||||||
* it is hard to tell.
|
* a spare slot to use
|
||||||
* set up number/raid_disk/state just
|
|
||||||
* in case
|
|
||||||
*/
|
*/
|
||||||
|
st = super_by_version(array.major_version,
|
||||||
|
array.minor_version);
|
||||||
|
if (!st) {
|
||||||
|
fprintf(stderr, Name ": unsupport array - version %d.%d\n",
|
||||||
|
array.major_version, array.minor_version);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (j=0; j<array.active_disks+array.spare_disks+ array.failed_disks; 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<array.nr_disks; j++) {
|
for (j=0; j<array.nr_disks; j++) {
|
||||||
disc.number = j;
|
disc.number = j;
|
||||||
if (ioctl(fd, GET_DISK_INFO, &disc))
|
if (ioctl(fd, GET_DISK_INFO, &disc))
|
||||||
|
@ -232,11 +260,12 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
if (disc.state & 8) /* removed */
|
if (disc.state & 8) /* removed */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
disc.number =j;
|
|
||||||
disc.raid_disk = j;
|
|
||||||
disc.state = 0;
|
|
||||||
disc.major = major(stb.st_rdev);
|
disc.major = major(stb.st_rdev);
|
||||||
disc.minor = minor(stb.st_rdev);
|
disc.minor = minor(stb.st_rdev);
|
||||||
|
disc.number =j;
|
||||||
|
disc.state = 0;
|
||||||
|
if (st->ss->write_init_super(st, dsuper, &disc, dv->devname))
|
||||||
|
return 1;
|
||||||
if (ioctl(fd,ADD_NEW_DISK, &disc)) {
|
if (ioctl(fd,ADD_NEW_DISK, &disc)) {
|
||||||
fprintf(stderr, Name ": add new device failed for %s: %s\n",
|
fprintf(stderr, Name ": add new device failed for %s: %s\n",
|
||||||
dv->devname, strerror(errno));
|
dv->devname, strerror(errno));
|
||||||
|
|
16
super1.c
16
super1.c
|
@ -459,10 +459,13 @@ static int store_super1(int fd, void *sbv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int load_super1(struct supertype *st, int fd, void **sbp, char *devname);
|
||||||
|
|
||||||
static int write_init_super1(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname)
|
static int write_init_super1(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname)
|
||||||
{
|
{
|
||||||
struct mdp_superblock_1 *sb = sbv;
|
struct mdp_superblock_1 *sb = sbv;
|
||||||
int fd = open(devname, O_RDWR, O_EXCL);
|
struct mdp_superblock_1 *refsb = NULL;
|
||||||
|
int fd = open(devname, O_RDWR | O_EXCL);
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
long size;
|
long size;
|
||||||
|
@ -476,11 +479,22 @@ static int write_init_super1(struct supertype *st, void *sbv, mdu_disk_info_t *d
|
||||||
}
|
}
|
||||||
|
|
||||||
sb->dev_number = __cpu_to_le32(dinfo->number);
|
sb->dev_number = __cpu_to_le32(dinfo->number);
|
||||||
|
|
||||||
*(__u32*)(sb->device_uuid) = random();
|
*(__u32*)(sb->device_uuid) = random();
|
||||||
*(__u32*)(sb->device_uuid+4) = random();
|
*(__u32*)(sb->device_uuid+4) = random();
|
||||||
*(__u32*)(sb->device_uuid+8) = random();
|
*(__u32*)(sb->device_uuid+8) = random();
|
||||||
*(__u32*)(sb->device_uuid+12) = random();
|
*(__u32*)(sb->device_uuid+12) = random();
|
||||||
|
sb->events = 0;
|
||||||
|
|
||||||
|
if (load_super1(st, fd, (void**)&refsb, NULL)==0) {
|
||||||
|
memcpy(sb->device_uuid, refsb->device_uuid, 16);
|
||||||
|
if (memcmp(sb->set_uuid, refsb->set_uuid, 16)==0) {
|
||||||
|
/* same array, so preserve events and dev_number */
|
||||||
|
sb->events = refsb->events;
|
||||||
|
sb->dev_number = refsb->dev_number;
|
||||||
|
}
|
||||||
|
free(refsb);
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(fd, BLKGETSIZE, &size)) {
|
if (ioctl(fd, BLKGETSIZE, &size)) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
Loading…
Reference in New Issue