Move calls to SET_ARRAY_INFO to common helper.

When we assemble an array, there are three different approaches
depending on whether metadata is internal or external, and on
kernel version.

Move all this to a common helper instead of duplicating in 3 places.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2008-09-18 16:01:55 +10:00
parent 7801ac2092
commit f35f252592
8 changed files with 153 additions and 144 deletions

View File

@ -140,6 +140,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
char *avail; char *avail;
int nextspare = 0; int nextspare = 0;
memset(&info, 0, sizeof(info));
if (get_linux_version() < 2004000) if (get_linux_version() < 2004000)
old_linux = 1; old_linux = 1;
@ -736,6 +738,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
return 1; return 1;
} }
st->ss->getinfo_super(st, &info); st->ss->getinfo_super(st, &info);
#ifndef MDASSEMBLE
sysfs_init(&info, mdfd, 0);
#endif
for (i=0; i<bestcnt; i++) { for (i=0; i<bestcnt; i++) {
int j = best[i]; int j = best[i];
unsigned int desired_state; unsigned int desired_state;
@ -844,36 +849,11 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
/* Almost ready to actually *do* something */ /* Almost ready to actually *do* something */
if (!old_linux) { if (!old_linux) {
struct mdinfo *sra = NULL;
int rv; int rv;
#ifndef MDASSEMBLE rv = set_array_info(mdfd, st, &info);
if (st->ss->external) {
char ver[100];
strcat(strcpy(ver, "external:"), info.text_version);
sra = sysfs_read(mdfd, 0, 0);
if ((vers % 100) < 2 ||
sra == NULL ||
sysfs_set_str(sra, NULL, "metadata_version",
ver) < 0) {
fprintf(stderr, Name ": This kernel does not "
"support external metadata.\n");
return 1;
}
rv = sysfs_set_array(sra, &info);
} else
#endif
if ((vers % 100) >= 1) { /* can use different versions */
mdu_array_info_t inf;
memset(&inf, 0, sizeof(inf));
inf.major_version = info.array.major_version;
inf.minor_version = info.array.minor_version;
rv = ioctl(mdfd, SET_ARRAY_INFO, &inf);
} else
rv = ioctl(mdfd, SET_ARRAY_INFO, NULL);
if (rv) { if (rv) {
fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n", fprintf(stderr, Name ": failed to set array info for %s: %s\n",
mddev, strerror(errno)); mddev, strerror(errno));
if (must_close) close(mdfd); if (must_close) close(mdfd);
return 1; return 1;
@ -913,7 +893,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
j = chosen_drive; j = chosen_drive;
if (j >= 0 /* && devices[j].uptodate */) { if (j >= 0 /* && devices[j].uptodate */) {
rv = add_disk(mdfd, st, sra, &devices[j].i); rv = add_disk(mdfd, st, &info, &devices[j].i);
if (rv) { if (rv) {
fprintf(stderr, Name ": failed to add " fprintf(stderr, Name ": failed to add "

View File

@ -75,7 +75,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
int container_fd = -1; int container_fd = -1;
int need_mdmon = 0; int need_mdmon = 0;
unsigned long long bitmapsize; unsigned long long bitmapsize;
struct mdinfo *sra;
struct mdinfo info, *infos; struct mdinfo info, *infos;
int did_default = 0; int did_default = 0;
unsigned long safe_mode_delay = 0; unsigned long safe_mode_delay = 0;
@ -521,6 +520,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
return 1; return 1;
total_slots = info.array.nr_disks; total_slots = info.array.nr_disks;
sysfs_init(&info, mdfd, 0);
st->ss->getinfo_super(st, &info); st->ss->getinfo_super(st, &info);
if (did_default && verbose >= 0) { if (did_default && verbose >= 0) {
@ -568,61 +568,41 @@ int Create(struct supertype *st, char *mddev, int mdfd,
} }
sra = sysfs_read(mdfd, 0, 0); sysfs_init(&info, mdfd, 0);
if (st->ss->external) { if (st->ss->external && st->subarray[0]) {
char ver[100]; /* member */
strcat(strcpy(ver, "external:"),
info.text_version);
if (st->ss->external && st->subarray[0]) {
/* member */
/* When creating a member, we need to be careful /* When creating a member, we need to be careful
* to negotiate with mdmon properly. * to negotiate with mdmon properly.
* If it is already running, we cannot write to * If it is already running, we cannot write to
* the devices and must ask it to do that part. * the devices and must ask it to do that part.
* If it isn't running, we write to the devices, * If it isn't running, we write to the devices,
* and then start it. * and then start it.
* We hold an exclusive open on the container * We hold an exclusive open on the container
* device to make sure mdmon doesn't exit after * device to make sure mdmon doesn't exit after
* we checked that it is running. * we checked that it is running.
* *
* For now, fail if it is already running. * For now, fail if it is already running.
*/ */
container_fd = open_dev_excl(st->container_dev); container_fd = open_dev_excl(st->container_dev);
if (container_fd < 0) { if (container_fd < 0) {
fprintf(stderr, Name ": Cannot get exclusive " fprintf(stderr, Name ": Cannot get exclusive "
"open on container - weird.\n"); "open on container - weird.\n");
return 1;
}
if (mdmon_running(st->container_dev)) {
if (verbose)
fprintf(stderr, Name ": reusing mdmon "
"for %s.\n",
devnum2devname(st->container_dev));
st->update_tail = &st->updates;
} else
need_mdmon = 1;
}
if ((vers % 100) < 2 ||
sra == NULL ||
sysfs_set_str(sra, NULL, "metadata_version",
ver) < 0) {
fprintf(stderr, Name ": This kernel does not "
"support external metadata.\n");
return 1; return 1;
} }
rv = sysfs_set_array(sra, &info); if (mdmon_running(st->container_dev)) {
} else if ((vers % 100) >= 1) { /* can use different versions */ if (verbose)
mdu_array_info_t inf; fprintf(stderr, Name ": reusing mdmon "
memset(&inf, 0, sizeof(inf)); "for %s.\n",
inf.major_version = info.array.major_version; devnum2devname(st->container_dev));
inf.minor_version = info.array.minor_version; st->update_tail = &st->updates;
rv = ioctl(mdfd, SET_ARRAY_INFO, &inf); } else
} else need_mdmon = 1;
rv = ioctl(mdfd, SET_ARRAY_INFO, NULL); }
rv = set_array_info(mdfd, st, &info);
if (rv) { if (rv) {
fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n", fprintf(stderr, Name ": failed to set array info for %s: %s\n",
mddev, strerror(errno)); mddev, strerror(errno));
return 1; return 1;
} }
@ -714,7 +694,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
inf->errors = 0; inf->errors = 0;
rv = 0; rv = 0;
rv = add_disk(mdfd, st, sra, inf); rv = add_disk(mdfd, st, &info, inf);
if (rv) { if (rv) {
fprintf(stderr, fprintf(stderr,
@ -746,16 +726,16 @@ int Create(struct supertype *st, char *mddev, int mdfd,
case LEVEL_LINEAR: case LEVEL_LINEAR:
case LEVEL_MULTIPATH: case LEVEL_MULTIPATH:
case 0: case 0:
sysfs_set_str(sra, NULL, "array_state", sysfs_set_str(&info, NULL, "array_state",
"active"); "active");
need_mdmon = 0; need_mdmon = 0;
break; break;
default: default:
sysfs_set_str(sra, NULL, "array_state", sysfs_set_str(&info, NULL, "array_state",
"readonly"); "readonly");
break; break;
} }
sysfs_set_safemode(sra, safe_mode_delay); sysfs_set_safemode(&info, safe_mode_delay);
} else { } else {
mdu_param_t param; mdu_param_t param;
if (ioctl(mdfd, RUN_ARRAY, &param)) { if (ioctl(mdfd, RUN_ARRAY, &param)) {

View File

@ -74,7 +74,7 @@ int Incremental(char *devname, int verbose, int runstop,
* start the array (auto-readonly). * start the array (auto-readonly).
*/ */
struct stat stb; struct stat stb;
struct mdinfo info, info2; struct mdinfo info;
struct mddev_ident_s *array_list, *match; struct mddev_ident_s *array_list, *match;
char chosen_name[1024]; char chosen_name[1024];
int rv; int rv;
@ -150,6 +150,7 @@ int Incremental(char *devname, int verbose, int runstop,
autof); autof);
} }
memset(&info, 0, sizeof(info));
st->ss->getinfo_super(st, &info); st->ss->getinfo_super(st, &info);
/* 3/ Check if there is a match in mdadm.conf */ /* 3/ Check if there is a match in mdadm.conf */
@ -292,40 +293,32 @@ int Incremental(char *devname, int verbose, int runstop,
chosen_name, strerror(errno)); chosen_name, strerror(errno));
return 2; return 2;
} }
sysfs_init(&info, mdfd, 0);
/* 5/ Find out if array already exists */ /* 5/ Find out if array already exists */
if (! mddev_busy(devnum)) { if (! mddev_busy(devnum)) {
/* 5a/ if it does not */ /* 5a/ if it does not */
/* - choose a name, from mdadm.conf or 'name' field in array. */ /* - choose a name, from mdadm.conf or 'name' field in array. */
/* - create the array */ /* - create the array */
/* - add the device */ /* - add the device */
mdu_array_info_t ainf;
struct mdinfo *sra; struct mdinfo *sra;
memset(&ainf, 0, sizeof(ainf)); if (set_array_info(mdfd, st, &info) != 0) {
ainf.major_version = info.array.major_version; fprintf(stderr, Name ": failed to set array info for %s: %s\n",
ainf.minor_version = info.array.minor_version;
if (ioctl(mdfd, SET_ARRAY_INFO, &ainf) != 0) {
fprintf(stderr, Name
": SET_ARRAY_INFO failed for %s: %s\b",
chosen_name, strerror(errno)); chosen_name, strerror(errno));
close(mdfd); close(mdfd);
return 2; return 2;
} }
sra = sysfs_read(mdfd, devnum, GET_VERSION);
sysfs_set_str(sra, NULL, "metadata_version", info.text_version);
st->ss->getinfo_super(st, &info);
info.disk.major = major(stb.st_rdev); info.disk.major = major(stb.st_rdev);
info.disk.minor = minor(stb.st_rdev); info.disk.minor = minor(stb.st_rdev);
if (add_disk(mdfd, st, sra, &info) != 0) { if (add_disk(mdfd, st, &info, &info) != 0) {
fprintf(stderr, Name ": failed to add %s to %s: %s.\n", fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
devname, chosen_name, strerror(errno)); devname, chosen_name, strerror(errno));
ioctl(mdfd, STOP_ARRAY, 0); ioctl(mdfd, STOP_ARRAY, 0);
close(mdfd); close(mdfd);
sysfs_free(sra);
return 2; return 2;
} }
sysfs_free(sra);
sra = sysfs_read(mdfd, devnum, GET_DEVS); sra = sysfs_read(mdfd, devnum, GET_DEVS);
if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) { if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
/* It really should be 'none' - must be old buggy /* It really should be 'none' - must be old buggy
@ -340,6 +333,7 @@ int Incremental(char *devname, int verbose, int runstop,
sysfs_free(sra); sysfs_free(sra);
return 2; return 2;
} }
sysfs_free(sra);
} else { } else {
/* 5b/ if it does */ /* 5b/ if it does */
/* - check one drive in array to make sure metadata is a reasonably */ /* - check one drive in array to make sure metadata is a reasonably */
@ -350,6 +344,7 @@ int Incremental(char *devname, int verbose, int runstop,
int err; int err;
struct mdinfo *sra; struct mdinfo *sra;
struct supertype *st2; struct supertype *st2;
struct mdinfo info2;
sra = sysfs_read(mdfd, devnum, (GET_DEVS | GET_STATE)); sra = sysfs_read(mdfd, devnum, (GET_DEVS | GET_STATE));
sprintf(dn, "%d:%d", sra->devs->disk.major, sprintf(dn, "%d:%d", sra->devs->disk.major,
@ -367,6 +362,7 @@ int Incremental(char *devname, int verbose, int runstop,
return 2; return 2;
} }
close(dfd2); close(dfd2);
memset(&info2, 0, sizeof(info2));
st2->ss->getinfo_super(st2, &info2); st2->ss->getinfo_super(st2, &info2);
st2->ss->free_super(st2); st2->ss->free_super(st2);
if (info.array.level != info2.array.level || if (info.array.level != info2.array.level ||
@ -751,7 +747,6 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
} }
for (ra = list ; ra ; ra = ra->next) { for (ra = list ; ra ; ra = ra->next) {
struct mdinfo *sra;
struct mdinfo *dev; struct mdinfo *dev;
int devnum = -1; int devnum = -1;
int mdfd; int mdfd;
@ -759,7 +754,6 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
int usepart = 1; int usepart = 1;
char *n; char *n;
int working = 0; int working = 0;
char ver[100];
if ((autof&7) == 3 || (autof&7) == 5) if ((autof&7) == 3 || (autof&7) == 5)
usepart = 0; usepart = 0;
@ -813,14 +807,10 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
return 2; return 2;
} }
sra = sysfs_read(mdfd, 0, 0); sysfs_init(ra, mdfd, 0);
sysfs_set_array(ra, md_get_version(mdfd));
sprintf(ver, "external:%s", ra->text_version);
sysfs_set_str(sra, NULL, "metadata_version", ver);
sysfs_set_array(sra, ra);
for (dev = ra->devs; dev; dev = dev->next) for (dev = ra->devs; dev; dev = dev->next)
if (sysfs_add_disk(sra, dev) == 0) if (sysfs_add_disk(ra, dev) == 0)
working++; working++;
if (runstop > 0 || working >= ra->array.working_disks) { if (runstop > 0 || working >= ra->array.working_disks) {
@ -828,11 +818,11 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
case LEVEL_LINEAR: case LEVEL_LINEAR:
case LEVEL_MULTIPATH: case LEVEL_MULTIPATH:
case 0: case 0:
sysfs_set_str(sra, NULL, "array_state", sysfs_set_str(ra, NULL, "array_state",
"active"); "active");
break; break;
default: default:
sysfs_set_str(sra, NULL, "array_state", sysfs_set_str(ra, NULL, "array_state",
"readonly"); "readonly");
/* start mdmon if needed. */ /* start mdmon if needed. */
if (!mdmon_running(st->container_dev)) if (!mdmon_running(st->container_dev))
@ -840,7 +830,7 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
ping_monitor(devnum2devname(st->container_dev)); ping_monitor(devnum2devname(st->container_dev));
break; break;
} }
sysfs_set_safemode(sra, ra->safe_mode_delay); sysfs_set_safemode(ra, ra->safe_mode_delay);
if (verbose >= 0) if (verbose >= 0)
printf("Started %s with %d devices\n", printf("Started %s with %d devices\n",
chosen_name, working); chosen_name, working);

View File

@ -340,6 +340,7 @@ extern void map_add(struct map_ent **melp,
* else use devnum. >=0 -> major9. <0..... * else use devnum. >=0 -> major9. <0.....
*/ */
extern int sysfs_open(int devnum, char *devname, char *attr); extern int sysfs_open(int devnum, char *devname, char *attr);
extern void sysfs_init(struct mdinfo *mdi, int fd, int devnum);
extern void sysfs_free(struct mdinfo *sra); extern void sysfs_free(struct mdinfo *sra);
extern struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options); extern struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options);
extern int sysfs_attr_match(const char *attr, const char *str); extern int sysfs_attr_match(const char *attr, const char *str);
@ -351,8 +352,7 @@ extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev, extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long *val); char *name, unsigned long long *val);
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms); extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
extern int sysfs_set_array(struct mdinfo *sra, extern int sysfs_set_array(struct mdinfo *info, int vers);
struct mdinfo *info);
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd); extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd);
extern int sysfs_disk_to_scsi_id(int fd, __u32 *id); extern int sysfs_disk_to_scsi_id(int fd, __u32 *id);
extern int sysfs_unique_holder(int devnum, long rdev); extern int sysfs_unique_holder(int devnum, long rdev);
@ -769,6 +769,7 @@ extern void append_metadata_update(struct supertype *st, void *buf, int len);
extern int add_disk(int mdfd, struct supertype *st, extern int add_disk(int mdfd, struct supertype *st,
struct mdinfo *sra, struct mdinfo *info); struct mdinfo *sra, struct mdinfo *info);
extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info);
extern char *human_size(long long bytes); extern char *human_size(long long bytes);
char *human_size_brief(long long bytes); char *human_size_brief(long long bytes);

View File

@ -1248,6 +1248,8 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
info->reshape_active = 0; info->reshape_active = 0;
info->array.major_version = -1;
info->array.minor_version = -2;
strcpy(info->text_version, "ddf"); strcpy(info->text_version, "ddf");
info->safe_mode_delay = 0; info->safe_mode_delay = 0;
@ -1303,6 +1305,8 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info)
uuid_from_super_ddf(st, info->uuid); uuid_from_super_ddf(st, info->uuid);
info->container_member = atoi(st->subarray); info->container_member = atoi(st->subarray);
info->array.major_version = -1;
info->array.minor_version = -2;
sprintf(info->text_version, "/%s/%s", sprintf(info->text_version, "/%s/%s",
devnum2devname(st->container_dev), devnum2devname(st->container_dev),
st->subarray); st->subarray);
@ -2591,6 +2595,8 @@ static struct mdinfo *container_content_ddf(struct supertype *st)
this->array.layout = rlq_to_layout(vc->conf.rlq, vc->conf.prl, this->array.layout = rlq_to_layout(vc->conf.rlq, vc->conf.prl,
this->array.raid_disks); this->array.raid_disks);
this->array.md_minor = -1; this->array.md_minor = -1;
this->array.major_version = -1;
this->array.minor_version = -2;
this->array.ctime = DECADE + this->array.ctime = DECADE +
__be32_to_cpu(*(__u32*)(vc->conf.guid+16)); __be32_to_cpu(*(__u32*)(vc->conf.guid+16));
this->array.utime = DECADE + this->array.utime = DECADE +

View File

@ -667,6 +667,8 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
strncpy(info->name, (char *) dev->volume, MAX_RAID_SERIAL_LEN); strncpy(info->name, (char *) dev->volume, MAX_RAID_SERIAL_LEN);
info->name[MAX_RAID_SERIAL_LEN] = 0; info->name[MAX_RAID_SERIAL_LEN] = 0;
info->array.major_version = -1;
info->array.minor_version = -2;
sprintf(info->text_version, "/%s/%d", sprintf(info->text_version, "/%s/%d",
devnum2devname(st->container_dev), devnum2devname(st->container_dev),
info->container_member); info->container_member);
@ -700,6 +702,8 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
info->disk.minor = 0; info->disk.minor = 0;
info->disk.raid_disk = -1; info->disk.raid_disk = -1;
info->reshape_active = 0; info->reshape_active = 0;
info->array.major_version = -1;
info->array.minor_version = -2;
strcpy(info->text_version, "imsm"); strcpy(info->text_version, "imsm");
info->safe_mode_delay = 0; info->safe_mode_delay = 0;
info->disk.number = -1; info->disk.number = -1;

76
sysfs.c
View File

@ -74,6 +74,29 @@ int sysfs_open(int devnum, char *devname, char *attr)
return fd; return fd;
} }
void sysfs_init(struct mdinfo *mdi, int fd, int devnum)
{
if (fd >= 0) {
struct stat stb;
mdu_version_t vers;
if (fstat(fd, &stb))
return;
if (ioctl(fd, RAID_VERSION, &vers) != 0)
return;
if (major(stb.st_rdev)==9)
sprintf(mdi->sys_name, "md%d", (int)minor(stb.st_rdev));
else
sprintf(mdi->sys_name, "md_d%d",
(int)minor(stb.st_rdev)>>MdpMinorShift);
} else {
if (devnum >= 0)
sprintf(mdi->sys_name, "md%d", devnum);
else
sprintf(mdi->sys_name, "md_d%d",
-1-devnum);
}
}
struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options) struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
{ {
/* Longest possible name in sysfs, mounted at /sys, is /* Longest possible name in sysfs, mounted at /sys, is
@ -93,26 +116,9 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
sra = malloc(sizeof(*sra)); sra = malloc(sizeof(*sra));
if (sra == NULL) if (sra == NULL)
return sra; return sra;
sra->next = NULL; memset(sra, 0, sizeof(*sra));
sysfs_init(sra, fd, devnum);
if (fd >= 0) {
struct stat stb;
mdu_version_t vers;
if (fstat(fd, &stb)) return NULL;
if (ioctl(fd, RAID_VERSION, &vers) != 0)
return NULL;
if (major(stb.st_rdev)==9)
sprintf(sra->sys_name, "md%d", (int)minor(stb.st_rdev));
else
sprintf(sra->sys_name, "md_d%d",
(int)minor(stb.st_rdev)>>MdpMinorShift);
} else {
if (devnum >= 0)
sprintf(sra->sys_name, "md%d", devnum);
else
sprintf(sra->sys_name, "md_d%d",
-1-devnum);
}
sprintf(fname, "/sys/block/%s/md/", sra->sys_name); sprintf(fname, "/sys/block/%s/md/", sra->sys_name);
base = fname + strlen(fname); base = fname + strlen(fname);
@ -433,22 +439,34 @@ int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms)
return sysfs_set_str(sra, NULL, "safe_mode_delay", delay); return sysfs_set_str(sra, NULL, "safe_mode_delay", delay);
} }
int sysfs_set_array(struct mdinfo *sra, int sysfs_set_array(struct mdinfo *info, int vers)
struct mdinfo *info)
{ {
int rv = 0; int rv = 0;
sra->array = info->array; char ver[100];
ver[0] = 0;
if (info->array.major_version == -1 &&
info->array.minor_version == -2) {
strcat(strcpy(ver, "external:"), info->text_version);
if ((vers % 100) < 2 ||
sysfs_set_str(info, NULL, "metadata_version",
ver) < 0) {
fprintf(stderr, Name ": This kernel does not "
"support external metadata.\n");
return 1;
}
}
if (info->array.level < 0) if (info->array.level < 0)
return 0; /* FIXME */ return 0; /* FIXME */
rv |= sysfs_set_str(sra, NULL, "level", rv |= sysfs_set_str(info, NULL, "level",
map_num(pers, info->array.level)); map_num(pers, info->array.level));
rv |= sysfs_set_num(sra, NULL, "raid_disks", info->array.raid_disks); rv |= sysfs_set_num(info, NULL, "raid_disks", info->array.raid_disks);
rv |= sysfs_set_num(sra, NULL, "chunk_size", info->array.chunk_size); rv |= sysfs_set_num(info, NULL, "chunk_size", info->array.chunk_size);
rv |= sysfs_set_num(sra, NULL, "layout", info->array.layout); rv |= sysfs_set_num(info, NULL, "layout", info->array.layout);
rv |= sysfs_set_num(sra, NULL, "component_size", info->component_size/2); rv |= sysfs_set_num(info, NULL, "component_size", info->component_size/2);
rv |= sysfs_set_num(sra, NULL, "resync_start", info->resync_start); if (info->array.level > 0)
sra->array = info->array; rv |= sysfs_set_num(info, NULL, "resync_start", info->resync_start);
return rv; return rv;
} }

38
util.c
View File

@ -1009,10 +1009,15 @@ int add_disk(int mdfd, struct supertype *st,
rv = sysfs_add_disk(sra, info); rv = sysfs_add_disk(sra, info);
if (! rv) { if (! rv) {
struct mdinfo *sd2; struct mdinfo *sd2;
sd2 = malloc(sizeof(*sd2)); for (sd2 = sra->devs; sd2; sd2=sd2->next)
*sd2 = *info; if (sd2 == info)
sd2->next = sra->devs; break;
sra->devs = sd2; if (sd2 == NULL) {
sd2 = malloc(sizeof(*sd2));
*sd2 = *info;
sd2->next = sra->devs;
sra->devs = sd2;
}
} }
} else } else
#endif #endif
@ -1020,6 +1025,31 @@ int add_disk(int mdfd, struct supertype *st,
return rv; return rv;
} }
int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
{
/* Initialise kernel's knowledge of array.
* This varies between externally managed arrays
* and older kernels
*/
int vers = md_get_version(mdfd);
int rv;
#ifndef MDASSEMBLE
if (st->ss->external)
rv = sysfs_set_array(info, vers);
else
#endif
if ((vers % 100) >= 1) { /* can use different versions */
mdu_array_info_t inf;
memset(&inf, 0, sizeof(inf));
inf.major_version = info->array.major_version;
inf.minor_version = info->array.minor_version;
rv = ioctl(mdfd, SET_ARRAY_INFO, &inf);
} else
rv = ioctl(mdfd, SET_ARRAY_INFO, NULL);
return rv;
}
char *devnum2devname(int num) char *devnum2devname(int num)
{ {
char name[100]; char name[100];