summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2005-05-03 23:44:32 +0000
committerNeil Brown <neilb@suse.de>2005-05-03 23:44:32 +0000
commitf9ce90ba509d0b624cc38635861b9c27550fbefc (patch)
treede5576f6c939e0fd95f76030b4d273fdfc9f5945 /util.c
parent4b1ac34b51a3783ab528b1af307156fab057b543 (diff)
downloadmdadm-f9ce90ba509d0b624cc38635861b9c27550fbefc.tar.gz
mdadm-f9ce90ba509d0b624cc38635861b9c27550fbefc.tar.xz
mdadm-f9ce90ba509d0b624cc38635861b9c27550fbefc.zip
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>
Diffstat (limited to 'util.c')
-rw-r--r--util.c70
1 files changed, 55 insertions, 15 deletions
diff --git a/util.c b/util.c
index e9bce2a..f243d88 100644
--- a/util.c
+++ b/util.c
@@ -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;
+}