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;
|
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 "
|
||||||
|
|
36
Create.c
36
Create.c
|
@ -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,12 +568,8 @@ 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]) {
|
if (st->ss->external && st->subarray[0]) {
|
||||||
/* member */
|
/* member */
|
||||||
|
|
||||||
|
@ -604,25 +600,9 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
||||||
} else
|
} else
|
||||||
need_mdmon = 1;
|
need_mdmon = 1;
|
||||||
}
|
}
|
||||||
if ((vers % 100) < 2 ||
|
rv = set_array_info(mdfd, st, &info);
|
||||||
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 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));
|
||||||
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, ¶m)) {
|
if (ioctl(mdfd, RUN_ARRAY, ¶m)) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
5
mdadm.h
5
mdadm.h
|
@ -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);
|
||||||
|
|
|
@ -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 +
|
||||||
|
|
|
@ -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
76
sysfs.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
30
util.c
30
util.c
|
@ -1009,17 +1009,47 @@ 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;
|
||||||
|
for (sd2 = sra->devs; sd2; sd2=sd2->next)
|
||||||
|
if (sd2 == info)
|
||||||
|
break;
|
||||||
|
if (sd2 == NULL) {
|
||||||
sd2 = malloc(sizeof(*sd2));
|
sd2 = malloc(sizeof(*sd2));
|
||||||
*sd2 = *info;
|
*sd2 = *info;
|
||||||
sd2->next = sra->devs;
|
sd2->next = sra->devs;
|
||||||
sra->devs = sd2;
|
sra->devs = sd2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
rv = ioctl(mdfd, ADD_NEW_DISK, &info->disk);
|
rv = ioctl(mdfd, ADD_NEW_DISK, &info->disk);
|
||||||
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];
|
||||||
|
|
Loading…
Reference in New Issue