#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,
}
devices = malloc(num_devs * sizeof(*devices));
+ if (!ss && ident->ss) ss = ident->ss;
if (verbose)
fprintf(stderr, Name ": looking for devices for %s\n",
char *devname;
int dfd;
struct stat stb;
+ struct superswitch *tss = ss;
devname = devlist->devname;
devlist = devlist->next;
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);
}
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);
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)
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
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);
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);
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);
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;
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",
}
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);
}
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);
#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)
return 1;
}
- init_super0(&super, &array);
+ ss->init_super(&super, &array);
for (pass=1; pass <=2 ; pass++) {
}
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",
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;
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;
* 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);
}
free_mdstat(ms);
- if (super)
- detail_super0(super);
+ if (super && ss)
+ ss->detail_super(super);
printf(" Number Major Minor RaidDevice State\n");
}
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");
struct array {
void *super;
+ struct superswitch *ss;
struct mdinfo info;
void *devs;
struct array *next;
} *arrays = NULL;
for (; devlist ; devlist=devlist->next) {
+ struct superswitch *ss;
+
fd = open(devlist->devname, O_RDONLY);
if (fd < 0) {
if (!scan)
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)
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) {
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))
dl_add(ap->devs, d);
} else {
printf("%s:\n",devlist->devname);
- examine_super0(super);
+ ss->examine_super(super);
free(super);
}
}
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)) {
struct stat stb;
int nfd, fd2;
int d, nd;
+ struct superswitch *ss = NULL;
if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) {
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;
}
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;
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;
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;
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;
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;
struct mdinfo info;
mdu_array_info_t array;
void *super;
+ struct superswitch *ss = NULL;
unsigned long long larray_size;
unsigned long array_size;
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";
* 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, '#'},
{"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'},
} 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)
#include <ctype.h>
-
int main(int argc, char *argv[])
{
int mode = 0;
char *help_text;
char *c;
int rv;
+ int i;
int chunk = 0;
int size = -1;
int daemonise = 0;
char *pidfile = NULL;
int oneshot = 0;
+ struct superswitch *ss = NULL;
int copies;
}
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) {
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) {
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);
/* 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);
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;
int level;
unsigned int raid_disks;
unsigned int spare_disks;
+ struct superswitch *ss;
int autof; /* 1 for normal, 2 for partitioned */
char *spare_group;
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);
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,
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);
#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);
return newcsum;
}
-void examine_super0(void *sbv)
+static void examine_super0(void *sbv)
{
mdp_super_t *sb = sbv;
time_t atime;
}
}
-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);
printf("\n");
}
-void detail_super0(void *sbv)
+static void detail_super0(void *sbv)
{
mdp_super_t *sb = sbv;
printf(" UUID : ");
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=");
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;
}
}
-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;
}
-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;
return rv;
}
-__u64 event_super0(void *sbv)
+static __u64 event_super0(void *sbv)
{
mdp_super_t *sb = sbv;
return md_event(sb);
-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;
}
/* 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];
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)
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);
return rv;
}
-int compare_super0(void **firstp, void *secondv)
+static int compare_super0(void **firstp, void *secondv)
{
/*
* return:
}
-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:
*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,
+};
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;
}
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;
+}