Add a 'super-switch' so that different format superblocks can be used.

This includes:
  adding --metadata= option to choose metadata format
  adding metadata= word to config file.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
This commit is contained in:
Neil Brown 2005-05-03 23:44:32 +00:00
parent 4b1ac34b51
commit f9ce90ba50
13 changed files with 262 additions and 99 deletions

View File

@ -29,7 +29,7 @@
#include "mdadm.h"
int Assemble(char *mddev, int mdfd,
int Assemble(struct superswitch *ss, char *mddev, int mdfd,
mddev_ident_t ident, char *conffile,
mddev_dev_t devlist,
int readonly, int runstop,
@ -164,6 +164,7 @@ int Assemble(char *mddev, int mdfd,
}
devices = malloc(num_devs * sizeof(*devices));
if (!ss && ident->ss) ss = ident->ss;
if (verbose)
fprintf(stderr, Name ": looking for devices for %s\n",
@ -173,6 +174,7 @@ int Assemble(char *mddev, int mdfd,
char *devname;
int dfd;
struct stat stb;
struct superswitch *tss = ss;
devname = devlist->devname;
devlist = devlist->next;
@ -203,13 +205,16 @@ int Assemble(char *mddev, int mdfd,
fprintf(stderr, Name ": %s is not a block device.\n",
devname);
close(dfd);
} else if (load_super0(dfd, &super, NULL)) {
} else if (!tss && (tss = guess_super(dfd, NULL)) == NULL) {
if (inargv || verbose)
fprintf(stderr, Name ": no recogniseable superblock\n");
} else if (tss->load_super(dfd, &super, NULL)) {
if (inargv || verbose)
fprintf( stderr, Name ": no RAID superblock on %s\n",
devname);
close(dfd);
} else {
getinfo_super0(&info, super);
tss->getinfo_super(&info, super);
close(dfd);
}
@ -253,7 +258,8 @@ int Assemble(char *mddev, int mdfd,
free(first_super);
return 1;
}
if (compare_super0(&first_super, super)) {
ss = tss; /* commit to this format, if haven't already */
if (ss->compare_super(&first_super, super)) {
fprintf(stderr, Name ": superblock on %s doesn't match others - assembly aborted\n",
devname);
free(super);
@ -268,13 +274,13 @@ int Assemble(char *mddev, int mdfd,
fstat(mdfd, &stb2);
info.array.md_minor = minor(stb2.st_rdev);
update_super0(&info, super, update, devname, verbose);
ss->update_super(&info, super, update, devname, verbose);
dfd = open(devname, O_RDWR|O_EXCL, 0);
if (dfd < 0)
fprintf(stderr, Name ": Cannot open %s for superblock update\n",
devname);
else if (store_super0(dfd, super))
else if (ss->store_super(dfd, super))
fprintf(stderr, Name ": Could not re-write superblock on %s.\n",
devname);
if (dfd >= 0)
@ -335,7 +341,7 @@ int Assemble(char *mddev, int mdfd,
return 1;
}
getinfo_super0(&info, first_super);
ss->getinfo_super(&info, first_super);
/* now we have some devices that might be suitable.
* I wonder how many
@ -393,7 +399,7 @@ int Assemble(char *mddev, int mdfd,
devices[chosen_drive].events = 0;
continue;
}
if (load_super0(fd, &super, NULL)) {
if (ss->load_super(fd, &super, NULL)) {
close(fd);
fprintf(stderr, Name ": RAID superblock disappeared from %s - not updating.\n",
devices[chosen_drive].devname);
@ -401,9 +407,9 @@ int Assemble(char *mddev, int mdfd,
continue;
}
info.events = devices[most_recent].events;
update_super0(&info, super, "force", devices[chosen_drive].devname, verbose);
ss->update_super(&info, super, "force", devices[chosen_drive].devname, verbose);
if (store_super0(fd, super)) {
if (ss->store_super(fd, super)) {
close(fd);
fprintf(stderr, Name ": Could not re-write superblock on %s\n",
devices[chosen_drive].devname);
@ -440,7 +446,7 @@ int Assemble(char *mddev, int mdfd,
devices[j].devname, strerror(errno));
return 1;
}
if (load_super0(fd, &super, NULL)) {
if (ss->load_super(fd, &super, NULL)) {
close(fd);
fprintf(stderr, Name ": RAID superblock has disappeared from %s\n",
devices[j].devname);
@ -452,7 +458,7 @@ int Assemble(char *mddev, int mdfd,
fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
return 1;
}
getinfo_super0(&info, super);
ss->getinfo_super(&info, super);
for (i=0; i<bestcnt; i++) {
int j = best[i];
unsigned int desired_state;
@ -470,7 +476,7 @@ int Assemble(char *mddev, int mdfd,
info.disk.state = desired_state;
if (devices[j].uptodate &&
update_super0(&info, super, "assemble", NULL, 0)) {
ss->update_super(&info, super, "assemble", NULL, 0)) {
if (force) {
fprintf(stderr, Name ": "
"clearing FAULTY flag for device %d in %s for %s\n",
@ -492,7 +498,7 @@ int Assemble(char *mddev, int mdfd,
}
if (force && okcnt == info.array.raid_disks-1) {
/* FIXME check event count */
change += update_super0(&info, super, "force",
change += ss->update_super(&info, super, "force",
devices[chosen_drive].devname, 0);
}
@ -504,7 +510,7 @@ int Assemble(char *mddev, int mdfd,
devices[chosen_drive].devname);
return 1;
}
if (store_super0(fd, super)) {
if (ss->store_super(fd, super)) {
close(fd);
fprintf(stderr, Name ": Could not re-write superblock on %s\n",
devices[chosen_drive].devname);

View File

@ -31,7 +31,7 @@
#include "md_u.h"
#include "md_p.h"
int Create(char *mddev, int mdfd,
int Create(struct superswitch *ss, char *mddev, int mdfd,
int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
int subdevs, mddev_dev_t devlist,
int runstop, int verbose, int force)
@ -349,7 +349,7 @@ int Create(char *mddev, int mdfd,
return 1;
}
init_super0(&super, &array);
ss->init_super(&super, &array);
for (pass=1; pass <=2 ; pass++) {
@ -389,10 +389,10 @@ int Create(char *mddev, int mdfd,
}
switch(pass){
case 1:
add_to_super0(super, &disk);
ss->add_to_super(super, &disk);
break;
case 2:
write_init_super0(super, &disk, dv->devname);
ss->write_init_super(super, &disk, dv->devname);
if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n",

View File

@ -50,6 +50,7 @@ int Detail(char *dev, int brief, int test)
int is_26 = get_linux_version() >= 2006000;
int is_rebuilding = 0;
int failed = 0;
struct superswitch *ss = NULL;
void *super = NULL;
int rv = test ? 4 : 1;
@ -82,6 +83,8 @@ int Detail(char *dev, int brief, int test)
close(fd);
return rv;
}
ss = super_by_version(array.major_version);
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
stb.st_rdev = 0;
rv = 0;
@ -103,10 +106,10 @@ int Detail(char *dev, int brief, int test)
* to get more info
*/
int fd2 = open(dv, O_RDONLY);
if (fd2 >=0 &&
load_super0(fd2, &super, NULL) == 0) {
if (fd2 >=0 && ss &&
ss->load_super(fd2, &super, NULL) == 0) {
struct mdinfo info;
getinfo_super0(&info, super);
ss->getinfo_super(&info, super);
if (info.array.ctime != array.ctime ||
info.array.level != array.level) {
free(super);
@ -202,8 +205,8 @@ int Detail(char *dev, int brief, int test)
}
free_mdstat(ms);
if (super)
detail_super0(super);
if (super && ss)
ss->detail_super(super);
printf(" Number Major Minor RaidDevice State\n");
}
@ -275,8 +278,8 @@ int Detail(char *dev, int brief, int test)
if (!brief) printf("\n");
}
if (spares && brief) printf(" spares=%d", spares);
if (super && brief)
brief_detail_super0(super);
if (super && brief && ss)
ss->brief_detail_super(super);
if (brief && devices) printf("\n devices=%s", devices);
if (brief) printf("\n");

View File

@ -60,6 +60,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
struct array {
void *super;
struct superswitch *ss;
struct mdinfo info;
void *devs;
struct array *next;
@ -67,6 +68,8 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
} *arrays = NULL;
for (; devlist ; devlist=devlist->next) {
struct superswitch *ss;
fd = open(devlist->devname, O_RDONLY);
if (fd < 0) {
if (!scan)
@ -75,7 +78,11 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
err = 1;
}
else {
err = load_super0(fd, &super, (brief||scan)?NULL:devlist->devname);
ss = guess_super(fd, devlist->devname);
if (ss)
err = ss->load_super(fd, &super, (brief||scan)?NULL:devlist->devname);
else
err = 1;
close(fd);
}
if (err)
@ -83,13 +90,13 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
if (err) rv =1;
if (SparcAdjust)
update_super0(NULL, super, "sparc2.2", devlist->devname, 0);
ss->update_super(NULL, super, "sparc2.2", devlist->devname, 0);
/* Ok, its good enough to try, though the checksum could be wrong */
if (brief) {
struct array *ap;
char *d;
for (ap=arrays; ap; ap=ap->next) {
if (compare_super0(&ap->super, super)==0)
if (ss == ap->ss && ss->compare_super(&ap->super, super)==0)
break;
}
if (!ap) {
@ -98,10 +105,11 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
ap->devs = dl_head();
ap->next = arrays;
ap->spares = 0;
ap->ss = ss;
arrays = ap;
getinfo_super0(&ap->info, super);
ss->getinfo_super(&ap->info, super);
} else {
getinfo_super0(&ap->info, super);
ss->getinfo_super(&ap->info, super);
free(super);
}
if (!(ap->info.disk.state & MD_DISK_SYNC))
@ -110,7 +118,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
dl_add(ap->devs, d);
} else {
printf("%s:\n",devlist->devname);
examine_super0(super);
ss->examine_super(super);
free(super);
}
}
@ -119,7 +127,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
for (ap=arrays; ap; ap=ap->next) {
char sep='=';
char *d;
brief_examine_super0(ap->super);
ap->ss->brief_examine_super(ap->super);
if (ap->spares) printf(" spares=%d", ap->spares);
printf(" devices");
for (d=dl_next(ap->devs); d!= ap->devs; d=dl_next(d)) {

19
Grow.c
View File

@ -51,6 +51,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
struct stat stb;
int nfd, fd2;
int d, nd;
struct superswitch *ss = NULL;
if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) {
@ -58,6 +59,12 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
return 1;
}
ss = super_by_version(info.array.major_version);
if (!ss) {
fprintf(stderr, Name ": cannot handle arrays with superblock version %d\n", info.array.major_version);
return 1;
}
if (info.array.level != -1) {
fprintf(stderr, Name ": can only add devices to linear arrays\n");
return 1;
@ -98,7 +105,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
}
if (super) free(super);
super= NULL;
if (load_super0(fd2, &super, NULL)) {
if (ss->load_super(fd2, &super, NULL)) {
fprintf(stderr, Name ": cannot find super block on %s\n", dv);
close(fd2);
return 1;
@ -114,9 +121,9 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
info.disk.minor = minor(stb.st_rdev);
info.disk.raid_disk = d;
info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
update_super0(&info, super, "grow", newdev, 0);
ss->update_super(&info, super, "grow", newdev, 0);
if (store_super0(nfd, super)) {
if (ss->store_super(nfd, super)) {
fprintf(stderr, Name ": Cannot store new superblock on %s\n", newdev);
close(nfd);
return 1;
@ -158,7 +165,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
fprintf(stderr, Name ": cannot open device file %s\n", dv);
return 1;
}
if (load_super0(fd2, &super, NULL)) {
if (ss->load_super(fd2, &super, NULL)) {
fprintf(stderr, Name ": cannot find super block on %s\n", dv);
close(fd);
return 1;
@ -172,9 +179,9 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
info.disk.minor = minor(stb.st_rdev);
info.disk.raid_disk = nd;
info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
update_super0(&info, super, "grow", dv, 0);
ss->update_super(&info, super, "grow", dv, 0);
if (store_super0(fd2, super)) {
if (ss->store_super(fd2, super)) {
fprintf(stderr, Name ": Cannot store new superblock on %s\n", dv);
close(fd2);
return 1;

17
Kill.c
View File

@ -43,19 +43,28 @@ int Kill(char *dev, int force)
void *super;
int fd, rv = 0;
struct superswitch *ss;
fd = open(dev, O_RDWR|O_EXCL);
if (fd < 0) {
fprintf(stderr, Name ": Couldn't open %s for write - not zeroing\n",
dev);
return 1;
}
rv = load_super0(fd, &super, dev);
}
ss = guess_super(fd, dev);
if (ss == NULL) {
fprintf(stderr, Name ": Unrecognised md component device - %s\n", dev);
return 1;
}
rv = ss->load_super(fd, &super, dev);
if (force && rv >= 2)
rv = 0; /* ignore bad data in superblock */
if (rv== 0 || (force && rv >= 2)) {
memset(&super, 0, sizeof(super));
if (store_super0(fd, super)) {
mdu_array_info_t info;
info.major_version = -1; /* zero superblock */
free(super);
ss->init_super(&super, &info);
if (ss->store_super(fd, super)) {
fprintf(stderr, Name ": Could not zero superblock on %s\n",
dev);
rv = 1;

11
Query.c
View File

@ -44,6 +44,7 @@ int Query(char *dev)
struct mdinfo info;
mdu_array_info_t array;
void *super;
struct superswitch *ss = NULL;
unsigned long long larray_size;
unsigned long array_size;
@ -94,12 +95,16 @@ int Query(char *dev)
array.raid_disks,
array.spare_disks, array.spare_disks==1?"":"s");
}
superror = load_super0(fd, &super, dev);
superrno = errno;
ss = guess_super(fd, dev);
if (ss) {
superror = ss->load_super(fd, &super, dev);
superrno = errno;
} else
superror = -1;
close(fd);
if (superror == 0) {
/* array might be active... */
getinfo_super0(&info, super);
ss->getinfo_super(&info, super);
mddev = get_md_name(info.array.md_minor);
disc.number = info.disk.number;
activity = "undetected";

View File

@ -91,7 +91,7 @@ char Version[] = Name " - v1.11.0 - 11 April 2005\n";
* At the time if writing, there is only minimal support.
*/
char short_options[]="-ABCDEFGQhVvbc:i:l:p:m:n:x:u:c:d:z:U:sa::rfRSow1t";
char short_options[]="-ABCDEFGQhVvbc:i:l:p:m:n:x:u:c:d:z:U:sa::rfRSow1te:";
struct option long_options[] = {
{"manage", 0, 0, '@'},
{"misc", 0, 0, '#'},
@ -127,6 +127,7 @@ struct option long_options[] = {
{"size", 1, 0, 'z'},
{"auto", 2, 0, 'a'}, /* also for --assemble */
{"assume-clean",0,0, 3 },
{"metadata", 1, 0, 'e'}, /* superblock format */
/* For assemble */
{"uuid", 1, 0, 'u'},

View File

@ -328,6 +328,17 @@ void arrayline(char *line)
} else if (strncasecmp(w, "spares=", 7) == 0 ) {
/* for warning if not all spares present */
mis.spare_disks = atoi(w+7);
} else if (strncasecmp(w, "metadata=", 9) == 0) {
/* style of metadata on the devices. */
int i;
for(i=0; superlist[i]; i++)
if (superlist[i]->match_metadata_desc(w+9)) {
mis.ss = superlist[i];
break;
}
if (!mis.ss)
fprintf(stderr, Name ": metadata format %s unknown, ignored.\n", w+9);
} else if (strncasecmp(w, "auto=", 5) == 0 ) {
/* whether to create device special files as needed */
if (strcasecmp(w+5, "no")==0)

43
mdadm.c
View File

@ -32,7 +32,6 @@
#include <ctype.h>
int main(int argc, char *argv[])
{
int mode = 0;
@ -41,6 +40,7 @@ int main(int argc, char *argv[])
char *help_text;
char *c;
int rv;
int i;
int chunk = 0;
int size = -1;
@ -81,6 +81,7 @@ int main(int argc, char *argv[])
int daemonise = 0;
char *pidfile = NULL;
int oneshot = 0;
struct superswitch *ss = NULL;
int copies;
@ -273,6 +274,24 @@ int main(int argc, char *argv[])
}
continue;
case O(CREATE,'e'):
case O(ASSEMBLE,'e'):
case O(MISC,'e'): /* set metadata (superblock) information */
if (ss) {
fprintf(stderr, Name ": metadata information already given\n");
exit(2);
}
for(i=0; superlist[i]; i++)
if (superlist[i]->match_metadata_desc(optarg)) {
ss = superlist[i];
break;
}
if (!ss) {
fprintf(stderr, Name ": unrecognised metadata identifier: %s\n", optarg);
exit(2);
}
continue;
case O(GROW,'z'):
case O(CREATE,'z'): /* size */
if (size >= 0) {
@ -736,14 +755,14 @@ int main(int argc, char *argv[])
if (mdfd < 0)
rv |= 1;
else {
rv |= Assemble(devlist->devname, mdfd, array_ident, configfile,
rv |= Assemble(ss, devlist->devname, mdfd, array_ident, configfile,
NULL,
readonly, runstop, update, verbose, force);
close(mdfd);
}
}
} else if (!scan)
rv = Assemble(devlist->devname, mdfd, &ident, configfile,
rv = Assemble(ss, devlist->devname, mdfd, &ident, configfile,
devlist->next,
readonly, runstop, update, verbose, force);
else if (devs_found>0) {
@ -764,7 +783,7 @@ int main(int argc, char *argv[])
rv |= 1;
continue;
}
rv |= Assemble(dv->devname, mdfd, array_ident, configfile,
rv |= Assemble(ss, dv->devname, mdfd, array_ident, configfile,
NULL,
readonly, runstop, update, verbose, force);
close(mdfd);
@ -786,7 +805,7 @@ int main(int argc, char *argv[])
/* already assembled, skip */
;
else
rv |= Assemble(array_list->devname, mdfd,
rv |= Assemble(ss, array_list->devname, mdfd,
array_list, configfile,
NULL,
readonly, runstop, NULL, verbose, force);
@ -798,7 +817,19 @@ int main(int argc, char *argv[])
rv = Build(devlist->devname, mdfd, chunk, level, layout, raiddisks, devlist->next, assume_clean);
break;
case CREATE:
rv = Create(devlist->devname, mdfd, chunk, level, layout, size<0 ? 0 : size,
if (ss == NULL) {
for(i=0; superlist[i]; i++)
if (superlist[i]->match_metadata_desc("default")) {
ss = superlist[i];
break;
}
}
if (!ss) {
fprintf(stderr, Name ": internal error - no default metadata style\n");
exit(2);
}
rv = Create(ss, devlist->devname, mdfd, chunk, level, layout, size<0 ? 0 : size,
raiddisks, sparedisks,
devs_found-1, devlist->next, runstop, verbose, force);
break;

42
mdadm.h
View File

@ -116,6 +116,7 @@ typedef struct mddev_ident_s {
int level;
unsigned int raid_disks;
unsigned int spare_disks;
struct superswitch *ss;
int autof; /* 1 for normal, 2 for partitioned */
char *spare_group;
@ -163,6 +164,28 @@ extern mapping_t r5layout[], pers[], modes[], faultylayout[];
extern char *map_dev(int major, int minor);
extern struct superswitch {
void (*examine_super)(void *sbv);
void (*brief_examine_super)(void *sbv);
void (*detail_super)(void *sbv);
void (*brief_detail_super)(void *sbv);
void (*uuid_from_super)(int uuid[4], void *sbv);
void (*getinfo_super)(struct mdinfo *info, void *sbv);
int (*update_super)(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose);
__u64 (*event_super)(void *sbv);
void (*init_super)(void **sbp, mdu_array_info_t *info);
void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo);
int (*store_super)(int fd, void *sbv);
int (*write_init_super)(void *sbv, mdu_disk_info_t *dinfo, char *devname);
int (*compare_super)(void **firstp, void *secondv);
int (*load_super)(int fd, void **sbp, char *devname);
int (*match_metadata_desc)(char *arg);
} super0, *superlist[];
extern struct superswitch *super_by_version(int vers);
extern struct superswitch *guess_super(int fd, char *dev);
extern int Manage_ro(char *devname, int fd, int readonly);
extern int Manage_runstop(char *devname, int fd, int runstop);
extern int Manage_resize(char *devname, int fd, long long size, int raid_disks);
@ -172,7 +195,7 @@ extern int Manage_subdevs(char *devname, int fd,
extern int Grow_Add_device(char *devname, int fd, char *newdev);
extern int Assemble(char *mddev, int mdfd,
extern int Assemble(struct superswitch *ss, char *mddev, int mdfd,
mddev_ident_t ident,
char *conffile,
mddev_dev_t devlist,
@ -185,7 +208,7 @@ extern int Build(char *mddev, int mdfd, int chunk, int level, int layout,
mddev_dev_t devlist, int assume_clean);
extern int Create(char *mddev, int mdfd,
extern int Create(struct superswitch *ss, char *mddev, int mdfd,
int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
int subdevs, mddev_dev_t devlist,
int runstop, int verbose, int force);
@ -262,18 +285,3 @@ extern int open_mddev(char *dev, int autof);
#define ModeMask 0x1f
#define ModeShift 5
extern void examine_super0(void *sbv);
extern void brief_examine_super0(void *sbv);
extern void detail_super0(void *sbv);
extern void brief_detail_super0(void *sbv);
extern void getinfo_super0(struct mdinfo *info, void *sbv);
extern int update_super0(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose);
extern __u64 event_super0(void *sbv);
extern void uuid_from_super0(int uuid[4], void * sbv);
extern void init_super0(void **sbv, mdu_array_info_t *info);
extern void add_to_super0(void *sbp, mdu_disk_info_t *dinfo);
extern int store_super0(int fd, mdp_super_t *super);
extern int write_init_super0(void *sbv, mdu_disk_info_t *dinfo, char *devname);
extern int load_super0(int fd, void **super, char *devname);
extern int compare_super0(void **first, void *second);

View File

@ -51,7 +51,7 @@ static unsigned long calc_sb0_csum(mdp_super_t *super)
return newcsum;
}
void examine_super0(void *sbv)
static void examine_super0(void *sbv)
{
mdp_super_t *sb = sbv;
time_t atime;
@ -129,7 +129,7 @@ void examine_super0(void *sbv)
}
}
void brief_examine_super0(void *sbv)
static void brief_examine_super0(void *sbv)
{
mdp_super_t *sb = sbv;
char *c=map_num(pers, sb->level);
@ -145,7 +145,7 @@ void brief_examine_super0(void *sbv)
printf("\n");
}
void detail_super0(void *sbv)
static void detail_super0(void *sbv)
{
mdp_super_t *sb = sbv;
printf(" UUID : ");
@ -157,7 +157,7 @@ void detail_super0(void *sbv)
printf("\n Events : %d.%d\n\n", sb->events_hi, sb->events_lo);
}
void brief_detail_super0(void *sbv)
static void brief_detail_super0(void *sbv)
{
mdp_super_t *sb = sbv;
printf(" UUID=");
@ -168,7 +168,7 @@ void brief_detail_super0(void *sbv)
printf("%08x", sb->set_uuid0);
}
void uuid_from_super0(int uuid[4], void * sbv)
static void uuid_from_super0(int uuid[4], void * sbv)
{
mdp_super_t *super = sbv;
uuid[0] = super->set_uuid0;
@ -183,7 +183,7 @@ void uuid_from_super0(int uuid[4], void * sbv)
}
}
void getinfo_super0(struct mdinfo *info, void *sbv)
static void getinfo_super0(struct mdinfo *info, void *sbv)
{
mdp_super_t *sb = sbv;
int working = 0;
@ -216,7 +216,7 @@ void getinfo_super0(struct mdinfo *info, void *sbv)
}
int update_super0(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose)
static int update_super0(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose)
{
int rv = 0;
mdp_super_t *sb = sbv;
@ -314,7 +314,7 @@ int update_super0(struct mdinfo *info, void *sbv, char *update, char *devname, i
return rv;
}
__u64 event_super0(void *sbv)
static __u64 event_super0(void *sbv)
{
mdp_super_t *sb = sbv;
return md_event(sb);
@ -322,11 +322,16 @@ __u64 event_super0(void *sbv)
void init_super0(void **sbp, mdu_array_info_t *info)
static void init_super0(void **sbp, mdu_array_info_t *info)
{
mdp_super_t *sb = malloc(MD_SB_BYTES);
memset(sb, 0, MD_SB_BYTES);
if (info->major_version == -1) {
/* zeroing the superblock */
return;
}
sb->md_magic = MD_SB_MAGIC;
sb->major_version = 0;
sb->minor_version = 90;
@ -359,7 +364,7 @@ void init_super0(void **sbp, mdu_array_info_t *info)
}
/* Add a device to the superblock being created */
void add_to_super0(void *sbv, mdu_disk_info_t *dinfo)
static void add_to_super0(void *sbv, mdu_disk_info_t *dinfo)
{
mdp_super_t *sb = sbv;
mdp_disk_t *dk = &sb->disks[dinfo->number];
@ -371,11 +376,12 @@ void add_to_super0(void *sbv, mdu_disk_info_t *dinfo)
dk->state = dinfo->state;
}
int store_super0(int fd, mdp_super_t *super)
static int store_super0(int fd, void *sbv)
{
unsigned long size;
unsigned long long dsize;
unsigned long long offset;
mdp_super_t *super = sbv;
#ifdef BLKGETSIZE64
if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
@ -403,7 +409,7 @@ int store_super0(int fd, mdp_super_t *super)
return 0;
}
int write_init_super0(void *sbv, mdu_disk_info_t *dinfo, char *devname)
static int write_init_super0(void *sbv, mdu_disk_info_t *dinfo, char *devname)
{
mdp_super_t *sb = sbv;
int fd = open(devname, O_RDWR, O_EXCL);
@ -423,7 +429,7 @@ int write_init_super0(void *sbv, mdu_disk_info_t *dinfo, char *devname)
return rv;
}
int compare_super0(void **firstp, void *secondv)
static int compare_super0(void **firstp, void *secondv)
{
/*
* return:
@ -463,7 +469,7 @@ int compare_super0(void **firstp, void *secondv)
}
int load_super0(int fd, void **sbp, char *devname)
static int load_super0(int fd, void **sbp, char *devname)
{
/* try to read in the superblock
* Return:
@ -537,3 +543,31 @@ int load_super0(int fd, void **sbp, char *devname)
*sbp = super;
return 0;
}
static int match_metadata_desc0(char *arg)
{
if (strcmp(arg, "0") == 0 ||
strcmp(arg, "0.90") == 0 ||
strcmp(arg, "default") == 0
)
return 1;
return 0;
}
struct superswitch super0 = {
.examine_super = examine_super0,
.brief_examine_super = brief_examine_super0,
.detail_super = detail_super0,
.brief_detail_super = brief_detail_super0,
.uuid_from_super = uuid_from_super0,
.getinfo_super = getinfo_super0,
.update_super = update_super0,
.event_super = event_super0,
.init_super = init_super0,
.add_to_super = add_to_super0,
.store_super = store_super0,
.write_init_super = write_init_super0,
.compare_super = compare_super0,
.load_super = load_super0,
.match_metadata_desc = match_metadata_desc0,
};

70
util.c
View File

@ -205,26 +205,27 @@ int check_reiser(int fd, char *name)
return 1;
}
int load_super(int fd, void **sbp, int vers)
{
return load_super0(fd, sbp, NULL);
}
int check_raid(int fd, char *name)
{
void *super;
struct mdinfo info;
time_t crtime;
if (load_super(fd, &super, -1))
return 0;
/* Looks like a raid array .. */
fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
name);
getinfo_super0(&info, super);
free(super);
crtime = info.array.ctime;
fprintf(stderr, " level=%d devices=%d ctime=%s",
info.array.level, info.array.raid_disks, ctime(&crtime));
return 1;
int i;
for (i=0; superlist[i]; i++) {
if (superlist[i]->load_super(fd, &super, name))
continue;
/* Looks like a raid array .. */
fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
name);
superlist[i]->getinfo_super(&info, super);
free(super);
crtime = info.array.ctime;
fprintf(stderr, " level=%d devices=%d ctime=%s",
info.array.level, info.array.raid_disks, ctime(&crtime));
return 1;
}
return 0;
}
@ -521,3 +522,42 @@ void put_md_name(char *name)
if (strncmp(name, "/dev/.tmp.md", 12)==0)
unlink(name);
}
struct superswitch *superlist[] = { &super0, NULL };
struct superswitch *super_by_version(int vers)
{
if (vers == 0) return &super0;
return NULL;
}
struct superswitch *guess_super(int fd, char *dev)
{
/* try each load_super to find the best match,
* and return the best superswitch
*/
struct superswitch *best = NULL, *ss;
int bestrv = 0;
void *sbp = NULL;
int i;
for (i=0 ; superlist[i]; i++) {
int rv;
ss = superlist[i];
rv = ss->load_super(fd, &sbp, NULL);
if (rv == 0) {
free(sbp);
return ss;
}
if (rv > bestrv) {
bestrv = rv;
best = ss;
}
}
if (bestrv > 2) /* FIXME */
return best;
return NULL;
}