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:
parent
7801ac2092
commit
f35f252592
36
Assemble.c
36
Assemble.c
|
@ -140,6 +140,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
|
|||
char *avail;
|
||||
int nextspare = 0;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if (get_linux_version() < 2004000)
|
||||
old_linux = 1;
|
||||
|
||||
|
@ -736,6 +738,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
|
|||
return 1;
|
||||
}
|
||||
st->ss->getinfo_super(st, &info);
|
||||
#ifndef MDASSEMBLE
|
||||
sysfs_init(&info, mdfd, 0);
|
||||
#endif
|
||||
for (i=0; i<bestcnt; i++) {
|
||||
int j = best[i];
|
||||
unsigned int desired_state;
|
||||
|
@ -844,36 +849,11 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
|
|||
|
||||
/* Almost ready to actually *do* something */
|
||||
if (!old_linux) {
|
||||
struct mdinfo *sra = NULL;
|
||||
int rv;
|
||||
|
||||
#ifndef MDASSEMBLE
|
||||
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);
|
||||
|
||||
rv = set_array_info(mdfd, st, &info);
|
||||
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));
|
||||
if (must_close) close(mdfd);
|
||||
return 1;
|
||||
|
@ -913,7 +893,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
|
|||
j = chosen_drive;
|
||||
|
||||
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) {
|
||||
fprintf(stderr, Name ": failed to add "
|
||||
|
|
90
Create.c
90
Create.c
|
@ -75,7 +75,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
int container_fd = -1;
|
||||
int need_mdmon = 0;
|
||||
unsigned long long bitmapsize;
|
||||
struct mdinfo *sra;
|
||||
struct mdinfo info, *infos;
|
||||
int did_default = 0;
|
||||
unsigned long safe_mode_delay = 0;
|
||||
|
@ -521,6 +520,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
return 1;
|
||||
|
||||
total_slots = info.array.nr_disks;
|
||||
sysfs_init(&info, mdfd, 0);
|
||||
st->ss->getinfo_super(st, &info);
|
||||
|
||||
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) {
|
||||
char ver[100];
|
||||
strcat(strcpy(ver, "external:"),
|
||||
info.text_version);
|
||||
if (st->ss->external && st->subarray[0]) {
|
||||
/* member */
|
||||
if (st->ss->external && st->subarray[0]) {
|
||||
/* member */
|
||||
|
||||
/* When creating a member, we need to be careful
|
||||
* to negotiate with mdmon properly.
|
||||
* If it is already running, we cannot write to
|
||||
* the devices and must ask it to do that part.
|
||||
* If it isn't running, we write to the devices,
|
||||
* and then start it.
|
||||
* We hold an exclusive open on the container
|
||||
* device to make sure mdmon doesn't exit after
|
||||
* we checked that it is running.
|
||||
*
|
||||
* For now, fail if it is already running.
|
||||
*/
|
||||
container_fd = open_dev_excl(st->container_dev);
|
||||
if (container_fd < 0) {
|
||||
fprintf(stderr, Name ": Cannot get exclusive "
|
||||
"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");
|
||||
/* When creating a member, we need to be careful
|
||||
* to negotiate with mdmon properly.
|
||||
* If it is already running, we cannot write to
|
||||
* the devices and must ask it to do that part.
|
||||
* If it isn't running, we write to the devices,
|
||||
* and then start it.
|
||||
* We hold an exclusive open on the container
|
||||
* device to make sure mdmon doesn't exit after
|
||||
* we checked that it is running.
|
||||
*
|
||||
* For now, fail if it is already running.
|
||||
*/
|
||||
container_fd = open_dev_excl(st->container_dev);
|
||||
if (container_fd < 0) {
|
||||
fprintf(stderr, Name ": Cannot get exclusive "
|
||||
"open on container - weird.\n");
|
||||
return 1;
|
||||
}
|
||||
rv = sysfs_set_array(sra, &info);
|
||||
} else 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 (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;
|
||||
}
|
||||
rv = set_array_info(mdfd, st, &info);
|
||||
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));
|
||||
return 1;
|
||||
}
|
||||
|
@ -714,7 +694,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
inf->errors = 0;
|
||||
rv = 0;
|
||||
|
||||
rv = add_disk(mdfd, st, sra, inf);
|
||||
rv = add_disk(mdfd, st, &info, inf);
|
||||
|
||||
if (rv) {
|
||||
fprintf(stderr,
|
||||
|
@ -746,16 +726,16 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
case LEVEL_LINEAR:
|
||||
case LEVEL_MULTIPATH:
|
||||
case 0:
|
||||
sysfs_set_str(sra, NULL, "array_state",
|
||||
sysfs_set_str(&info, NULL, "array_state",
|
||||
"active");
|
||||
need_mdmon = 0;
|
||||
break;
|
||||
default:
|
||||
sysfs_set_str(sra, NULL, "array_state",
|
||||
sysfs_set_str(&info, NULL, "array_state",
|
||||
"readonly");
|
||||
break;
|
||||
}
|
||||
sysfs_set_safemode(sra, safe_mode_delay);
|
||||
sysfs_set_safemode(&info, safe_mode_delay);
|
||||
} else {
|
||||
mdu_param_t param;
|
||||
if (ioctl(mdfd, RUN_ARRAY, ¶m)) {
|
||||
|
|
|
@ -74,7 +74,7 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
* start the array (auto-readonly).
|
||||
*/
|
||||
struct stat stb;
|
||||
struct mdinfo info, info2;
|
||||
struct mdinfo info;
|
||||
struct mddev_ident_s *array_list, *match;
|
||||
char chosen_name[1024];
|
||||
int rv;
|
||||
|
@ -150,6 +150,7 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
autof);
|
||||
}
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
st->ss->getinfo_super(st, &info);
|
||||
/* 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));
|
||||
return 2;
|
||||
}
|
||||
sysfs_init(&info, mdfd, 0);
|
||||
|
||||
/* 5/ Find out if array already exists */
|
||||
if (! mddev_busy(devnum)) {
|
||||
/* 5a/ if it does not */
|
||||
/* - choose a name, from mdadm.conf or 'name' field in array. */
|
||||
/* - create the array */
|
||||
/* - add the device */
|
||||
mdu_array_info_t ainf;
|
||||
struct mdinfo *sra;
|
||||
|
||||
memset(&ainf, 0, sizeof(ainf));
|
||||
ainf.major_version = info.array.major_version;
|
||||
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",
|
||||
if (set_array_info(mdfd, st, &info) != 0) {
|
||||
fprintf(stderr, Name ": failed to set array info for %s: %s\n",
|
||||
chosen_name, strerror(errno));
|
||||
close(mdfd);
|
||||
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.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",
|
||||
devname, chosen_name, strerror(errno));
|
||||
ioctl(mdfd, STOP_ARRAY, 0);
|
||||
close(mdfd);
|
||||
sysfs_free(sra);
|
||||
return 2;
|
||||
}
|
||||
sysfs_free(sra);
|
||||
sra = sysfs_read(mdfd, devnum, GET_DEVS);
|
||||
if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
|
||||
/* It really should be 'none' - must be old buggy
|
||||
|
@ -340,6 +333,7 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
sysfs_free(sra);
|
||||
return 2;
|
||||
}
|
||||
sysfs_free(sra);
|
||||
} else {
|
||||
/* 5b/ if it does */
|
||||
/* - 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;
|
||||
struct mdinfo *sra;
|
||||
struct supertype *st2;
|
||||
struct mdinfo info2;
|
||||
sra = sysfs_read(mdfd, devnum, (GET_DEVS | GET_STATE));
|
||||
|
||||
sprintf(dn, "%d:%d", sra->devs->disk.major,
|
||||
|
@ -367,6 +362,7 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
return 2;
|
||||
}
|
||||
close(dfd2);
|
||||
memset(&info2, 0, sizeof(info2));
|
||||
st2->ss->getinfo_super(st2, &info2);
|
||||
st2->ss->free_super(st2);
|
||||
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) {
|
||||
struct mdinfo *sra;
|
||||
struct mdinfo *dev;
|
||||
int devnum = -1;
|
||||
int mdfd;
|
||||
|
@ -759,7 +754,6 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
|
|||
int usepart = 1;
|
||||
char *n;
|
||||
int working = 0;
|
||||
char ver[100];
|
||||
|
||||
if ((autof&7) == 3 || (autof&7) == 5)
|
||||
usepart = 0;
|
||||
|
@ -813,14 +807,10 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
|
|||
return 2;
|
||||
}
|
||||
|
||||
sra = sysfs_read(mdfd, 0, 0);
|
||||
|
||||
sprintf(ver, "external:%s", ra->text_version);
|
||||
sysfs_set_str(sra, NULL, "metadata_version", ver);
|
||||
|
||||
sysfs_set_array(sra, ra);
|
||||
sysfs_init(ra, mdfd, 0);
|
||||
sysfs_set_array(ra, md_get_version(mdfd));
|
||||
for (dev = ra->devs; dev; dev = dev->next)
|
||||
if (sysfs_add_disk(sra, dev) == 0)
|
||||
if (sysfs_add_disk(ra, dev) == 0)
|
||||
working++;
|
||||
|
||||
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_MULTIPATH:
|
||||
case 0:
|
||||
sysfs_set_str(sra, NULL, "array_state",
|
||||
sysfs_set_str(ra, NULL, "array_state",
|
||||
"active");
|
||||
break;
|
||||
default:
|
||||
sysfs_set_str(sra, NULL, "array_state",
|
||||
sysfs_set_str(ra, NULL, "array_state",
|
||||
"readonly");
|
||||
/* start mdmon if needed. */
|
||||
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));
|
||||
break;
|
||||
}
|
||||
sysfs_set_safemode(sra, ra->safe_mode_delay);
|
||||
sysfs_set_safemode(ra, ra->safe_mode_delay);
|
||||
if (verbose >= 0)
|
||||
printf("Started %s with %d devices\n",
|
||||
chosen_name, working);
|
||||
|
|
5
mdadm.h
5
mdadm.h
|
@ -340,6 +340,7 @@ extern void map_add(struct map_ent **melp,
|
|||
* else use devnum. >=0 -> major9. <0.....
|
||||
*/
|
||||
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 struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options);
|
||||
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,
|
||||
char *name, unsigned long long *val);
|
||||
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
|
||||
extern int sysfs_set_array(struct mdinfo *sra,
|
||||
struct mdinfo *info);
|
||||
extern int sysfs_set_array(struct mdinfo *info, int vers);
|
||||
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_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,
|
||||
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);
|
||||
char *human_size_brief(long long bytes);
|
||||
|
|
|
@ -1248,6 +1248,8 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
|
|||
|
||||
info->reshape_active = 0;
|
||||
|
||||
info->array.major_version = -1;
|
||||
info->array.minor_version = -2;
|
||||
strcpy(info->text_version, "ddf");
|
||||
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);
|
||||
|
||||
info->container_member = atoi(st->subarray);
|
||||
info->array.major_version = -1;
|
||||
info->array.minor_version = -2;
|
||||
sprintf(info->text_version, "/%s/%s",
|
||||
devnum2devname(st->container_dev),
|
||||
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.raid_disks);
|
||||
this->array.md_minor = -1;
|
||||
this->array.major_version = -1;
|
||||
this->array.minor_version = -2;
|
||||
this->array.ctime = DECADE +
|
||||
__be32_to_cpu(*(__u32*)(vc->conf.guid+16));
|
||||
this->array.utime = DECADE +
|
||||
|
|
|
@ -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);
|
||||
info->name[MAX_RAID_SERIAL_LEN] = 0;
|
||||
|
||||
info->array.major_version = -1;
|
||||
info->array.minor_version = -2;
|
||||
sprintf(info->text_version, "/%s/%d",
|
||||
devnum2devname(st->container_dev),
|
||||
info->container_member);
|
||||
|
@ -700,6 +702,8 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
|||
info->disk.minor = 0;
|
||||
info->disk.raid_disk = -1;
|
||||
info->reshape_active = 0;
|
||||
info->array.major_version = -1;
|
||||
info->array.minor_version = -2;
|
||||
strcpy(info->text_version, "imsm");
|
||||
info->safe_mode_delay = 0;
|
||||
info->disk.number = -1;
|
||||
|
|
76
sysfs.c
76
sysfs.c
|
@ -74,6 +74,29 @@ int sysfs_open(int devnum, char *devname, char *attr)
|
|||
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)
|
||||
{
|
||||
/* 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));
|
||||
if (sra == NULL)
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
int sysfs_set_array(struct mdinfo *sra,
|
||||
struct mdinfo *info)
|
||||
int sysfs_set_array(struct mdinfo *info, int vers)
|
||||
{
|
||||
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)
|
||||
return 0; /* FIXME */
|
||||
rv |= sysfs_set_str(sra, NULL, "level",
|
||||
rv |= sysfs_set_str(info, NULL, "level",
|
||||
map_num(pers, info->array.level));
|
||||
rv |= sysfs_set_num(sra, NULL, "raid_disks", info->array.raid_disks);
|
||||
rv |= sysfs_set_num(sra, NULL, "chunk_size", info->array.chunk_size);
|
||||
rv |= sysfs_set_num(sra, NULL, "layout", info->array.layout);
|
||||
rv |= sysfs_set_num(sra, NULL, "component_size", info->component_size/2);
|
||||
rv |= sysfs_set_num(sra, NULL, "resync_start", info->resync_start);
|
||||
sra->array = info->array;
|
||||
rv |= sysfs_set_num(info, NULL, "raid_disks", info->array.raid_disks);
|
||||
rv |= sysfs_set_num(info, NULL, "chunk_size", info->array.chunk_size);
|
||||
rv |= sysfs_set_num(info, NULL, "layout", info->array.layout);
|
||||
rv |= sysfs_set_num(info, NULL, "component_size", info->component_size/2);
|
||||
if (info->array.level > 0)
|
||||
rv |= sysfs_set_num(info, NULL, "resync_start", info->resync_start);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
38
util.c
38
util.c
|
@ -1009,10 +1009,15 @@ int add_disk(int mdfd, struct supertype *st,
|
|||
rv = sysfs_add_disk(sra, info);
|
||||
if (! rv) {
|
||||
struct mdinfo *sd2;
|
||||
sd2 = malloc(sizeof(*sd2));
|
||||
*sd2 = *info;
|
||||
sd2->next = sra->devs;
|
||||
sra->devs = sd2;
|
||||
for (sd2 = sra->devs; sd2; sd2=sd2->next)
|
||||
if (sd2 == info)
|
||||
break;
|
||||
if (sd2 == NULL) {
|
||||
sd2 = malloc(sizeof(*sd2));
|
||||
*sd2 = *info;
|
||||
sd2->next = sra->devs;
|
||||
sra->devs = sd2;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
|
@ -1020,6 +1025,31 @@ int add_disk(int mdfd, struct supertype *st,
|
|||
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 name[100];
|
||||
|
|
Loading…
Reference in New Issue