From 54bad3644f4ea8132a789e827d05d2e712b4f547 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 8 May 2007 17:17:33 +1000 Subject: [PATCH] Add --export option to --detail to use key=value pairs. udev likes to get information about a device as key=value pairs so it can create disk/by-id links etc. So add --export flag which causes the output of --detail to easily parsable. From: Kay Sievers --- Detail.c | 16 ++++++++++++++-- ReadMe.c | 3 +++ mdadm.8 | 8 ++++++++ mdadm.c | 12 ++++++++++-- mdadm.h | 3 ++- super0.c | 13 +++++++++++++ super1.c | 23 +++++++++++++++++++++++ 7 files changed, 73 insertions(+), 5 deletions(-) diff --git a/Detail.c b/Detail.c index ca34f1d..58de67e 100644 --- a/Detail.c +++ b/Detail.c @@ -31,7 +31,7 @@ #include "md_p.h" #include "md_u.h" -int Detail(char *dev, int brief, int test, char *homehost) +int Detail(char *dev, int brief, int export, int test, char *homehost) { /* * Print out details for an md array by using @@ -128,7 +128,18 @@ int Detail(char *dev, int brief, int test, char *homehost) /* Ok, we have some info to print... */ c = map_num(pers, array.level); - if (brief) + + if (export) { + if (c) + printf("MD_LEVEL=%s\n", c); + printf("MD_DEVICES=%d\n", array.raid_disks); + printf("MD_METADATA=%d.%d\n", array.major_version, + array.minor_version); + st->ss->export_super(super); + goto out; + } + + if (brief) printf("ARRAY %s level=%s num-devices=%d", dev, c?c:"-unknown-",array.raid_disks ); else { mdu_bitmap_file_t bmf; @@ -360,6 +371,7 @@ This is pretty boring if (brief > 1 && devices) printf("\n devices=%s", devices); if (brief) printf("\n"); +out: if (test && (rv&2)) rv &= ~1; close(fd); return rv; diff --git a/ReadMe.c b/ReadMe.c index 9063ace..a967b3f 100644 --- a/ReadMe.c +++ b/ReadMe.c @@ -166,6 +166,7 @@ struct option long_options[] = { /* For Detail/Examine */ {"brief", 0, 0, 'b'}, + {"export", 0, 0, 'Y'}, {"sparc2.2", 0, 0, Sparc22}, {"test", 0, 0, 't'}, @@ -239,6 +240,8 @@ char OptionHelp[] = " --verbose -v : Be more verbose about what is happening\n" " --quiet -q : Don't print un-necessary messages\n" " --brief -b : Be less verbose, more brief\n" +" --export -Y : With --detail, use key=value format for easy\n" +" import into environment\n" " --force -f : Override normal checks and be more forceful\n" "\n" " --assemble -A : Assemble an array\n" diff --git a/mdadm.8 b/mdadm.8 index 11000fd..b0aeaac 100644 --- a/mdadm.8 +++ b/mdadm.8 @@ -909,6 +909,14 @@ Information about what is discovered is presented. .BR \-D ", " \-\-detail Print detail of one or more md devices. +.TP +.BR \-Y ", " \-\-export +When used with +.BR \-\-detail , +output will be formatted as +.B key=value +pairs for easy import into the environment. + .TP .BR \-E ", " \-\-examine Print content of md superblock on device(s). diff --git a/mdadm.c b/mdadm.c index e5ed93d..2abf86b 100644 --- a/mdadm.c +++ b/mdadm.c @@ -74,6 +74,7 @@ int main(int argc, char *argv[]) int brief = 0; int force = 0; int test = 0; + int export = 0; int assume_clean = 0; char *symlinks = NULL; /* autof indicates whether and how to create device node. @@ -159,6 +160,9 @@ int main(int argc, char *argv[]) } continue; + case 'Y': export++; + continue; + case HomeHost: homehost = optarg; continue; @@ -1189,7 +1193,8 @@ int main(int argc, char *argv[]) e->dev); continue; } - rv |= Detail(name, verbose>1?0:verbose+1, test, homehost); + rv |= Detail(name, verbose>1?0:verbose+1, + export, test, homehost); put_md_name(name); } } else if (devmode == 'S' && scan) { @@ -1234,7 +1239,10 @@ int main(int argc, char *argv[]) for (dv=devlist ; dv; dv=dv->next) { switch(dv->disposition) { case 'D': - rv |= Detail(dv->devname, brief?1+verbose:0, test, homehost); continue; + rv |= Detail(dv->devname, + brief?1+verbose:0, + export, test, homehost); + continue; case 'K': /* Zero superblock */ rv |= Kill(dv->devname, force, quiet); continue; case 'Q': diff --git a/mdadm.h b/mdadm.h index 1fe58a2..da6b3b2 100644 --- a/mdadm.h +++ b/mdadm.h @@ -339,6 +339,7 @@ extern struct superswitch { void (*examine_super)(void *sbv, char *homehost); void (*brief_examine_super)(void *sbv); void (*detail_super)(void *sbv, char *homehost); + void (*export_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); @@ -443,7 +444,7 @@ extern int Create(struct supertype *st, char *mddev, int mdfd, int runstop, int verbose, int force, int assume_clean, char *bitmap_file, int bitmap_chunk, int write_behind, int delay); -extern int Detail(char *dev, int brief, int test, char *homehost); +extern int Detail(char *dev, int brief, int export, int test, char *homehost); extern int Query(char *dev); extern int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust, struct supertype *forcest, char *homehost); diff --git a/super0.c b/super0.c index aeee0b7..5828e15 100644 --- a/super0.c +++ b/super0.c @@ -280,6 +280,18 @@ static void brief_detail_super0(void *sbv) else printf("%08x", sb->set_uuid0); } + +static void export_super0(void *sbv) +{ + mdp_super_t *sb = sbv; + printf("MD_UUID="); + if (sb->minor_version >= 90) + printf("%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1, + sb->set_uuid2, sb->set_uuid3); + else + printf("%08x", sb->set_uuid0); + printf("\n"); +} #endif static int match_home0(void *sbv, char *homehost) @@ -940,6 +952,7 @@ struct superswitch super0 = { .brief_examine_super = brief_examine_super0, .detail_super = detail_super0, .brief_detail_super = brief_detail_super0, + .export_super = export_super0, #endif .match_home = match_home0, .uuid_from_super = uuid_from_super0, diff --git a/super1.c b/super1.c index effed54..efe8a46 100644 --- a/super1.c +++ b/super1.c @@ -393,6 +393,28 @@ static void brief_detail_super1(void *sbv) } } +static void export_super1(void *sbv) +{ + struct mdp_superblock_1 *sb = sbv; + int i; + int len = 32; + + for (i=0; i<32; i++) + if (sb->set_name[i] == '\n' || + sb->set_name[i] == '\0') { + len = i; + break; + } + if (len) + printf("MD_NAME=%.*s\n", len, sb->set_name); + printf("MD_UUID="); + for (i=0; i<16; i++) { + if ((i&3)==0 && i != 0) printf(":"); + printf("%02x", sb->set_uuid[i]); + } + printf("\n"); +} + #endif static int match_home1(void *sbv, char *homehost) @@ -1300,6 +1322,7 @@ struct superswitch super1 = { .brief_examine_super = brief_examine_super1, .detail_super = detail_super1, .brief_detail_super = brief_detail_super1, + .export_super = export_super1, #endif .match_home = match_home1, .uuid_from_super = uuid_from_super1,