diff options
author | NeilBrown <neilb@suse.de> | 2012-04-18 11:00:07 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-04-18 11:00:07 +1000 |
commit | c2ecf5f61aca2d73b7d5a6cb3a26973916d5c0d1 (patch) | |
tree | 747e82e252a746c42c01879ec41587ae6c336935 | |
parent | 480f3566411675ec41f18e5f6e15429f891e144c (diff) | |
download | mdadm-c2ecf5f61aca2d73b7d5a6cb3a26973916d5c0d1.tar.gz |
Add --prefer option for --detail and --monitor
Both --detail and --monitor can report the names of member
devices on an array, and do so by searching /dev and finding
the shortest name that matches.
If
--prefer=foo
is given, they will instead prefer a name that contain /foo/.
So
mdadm --detail /dev/md0 --prefer=by-path
will list the component devices via their /dev/disk/by-path/xxx
names.
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | Detail.c | 11 | ||||
-rw-r--r-- | Monitor.c | 18 | ||||
-rw-r--r-- | ReadMe.c | 1 | ||||
-rw-r--r-- | lib.c | 9 | ||||
-rw-r--r-- | mdadm.8.in | 22 | ||||
-rw-r--r-- | mdadm.c | 15 | ||||
-rw-r--r-- | mdadm.h | 12 |
7 files changed, 68 insertions, 20 deletions
@@ -27,7 +27,7 @@ #include "md_u.h" #include <dirent.h> -int Detail(char *dev, int brief, int export, int test, char *homehost) +int Detail(char *dev, int brief, int export, int test, char *homehost, char *prefer) { /* * Print out details for an md array by using @@ -105,7 +105,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) int dn = st->container_dev; member = subarray; - container = map_dev(dev2major(dn), dev2minor(dn), 1); + container = map_dev_preferred(dev2major(dn), dev2minor(dn), 1, prefer); } /* try to load a superblock */ @@ -491,8 +491,9 @@ This is pretty boring vbuf[10+nlen] != '/') continue; dn = devname2devnum(de->d_name); - printf(" %s", map_dev(dev2major(dn), - dev2minor(dn), 1)); + printf(" %s", map_dev_preferred( + dev2major(dn), + dev2minor(dn), 1, prefer)); } if (dir) closedir(dir); @@ -558,7 +559,7 @@ This is pretty boring if (test && d < array.raid_disks && !(disk.state & (1<<MD_DISK_SYNC))) rv |= 1; - if ((dv=map_dev(disk.major, disk.minor, 0))) { + if ((dv=map_dev_preferred(disk.major, disk.minor, 0, prefer))) { if (brief) { if (devices) { devices = realloc(devices, @@ -69,7 +69,7 @@ static int check_one_sharer(int scan); static void alert(char *event, char *dev, char *disc, struct alert_info *info); static int check_array(struct state *st, struct mdstat_ent *mdstat, int test, struct alert_info *info, - int increments); + int increments, char *prefer); static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, int test, struct alert_info *info); static void try_spare_migration(struct state *statelist, struct alert_info *info); @@ -79,7 +79,7 @@ int Monitor(struct mddev_dev *devlist, char *mailaddr, char *alert_cmd, int period, int daemonise, int scan, int oneshot, int dosyslog, int test, char *pidfile, int increments, - int share) + int share, char *prefer) { /* * Every few seconds, scan every md device looking for changes @@ -221,7 +221,8 @@ int Monitor(struct mddev_dev *devlist, mdstat = mdstat_read(oneshot?0:1, 0); for (st=statelist; st; st=st->next) - if (check_array(st, mdstat, test, &info, increments)) + if (check_array(st, mdstat, test, &info, + increments, prefer)) anydegraded = 1; /* now check if there are any new devices found in mdstat */ @@ -445,7 +446,7 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) static int check_array(struct state *st, struct mdstat_ent *mdstat, int test, struct alert_info *ainfo, - int increments) + int increments, char *prefer) { /* Update the state 'st' to reflect any changes shown in mdstat, * or found by directly examining the array, and return @@ -617,7 +618,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, disc.major = disc.minor = 0; } else if (info[i].major || info[i].minor) { newstate = info[i].state; - dv = map_dev(info[i].major, info[i].minor, 1); + dv = map_dev_preferred( + info[i].major, info[i].minor, 1, + prefer); disc.state = newstate; disc.major = info[i].major; disc.minor = info[i].minor; @@ -629,8 +632,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, disc.major = disc.minor = 0; } if (dv == NULL && st->devid[i]) - dv = map_dev(major(st->devid[i]), - minor(st->devid[i]), 1); + dv = map_dev_preferred( + major(st->devid[i]), + minor(st->devid[i]), 1, prefer); change = newstate ^ st->devstate[i]; if (st->utime && change && !st->err) { if (i < array.raid_disks && @@ -174,6 +174,7 @@ struct option long_options[] = { {"export", 0, 0, 'Y'}, {"sparc2.2", 0, 0, Sparc22}, {"test", 0, 0, 't'}, + {"prefer", 1, 0, Prefer}, /* For Follow/monitor */ {"mail", 1, 0, EMail}, @@ -188,8 +188,11 @@ int nftw(const char *path, int (*han)(const char *name, const struct stat *stb, * If we find multiple names, choose the shortest. * If we find a name in /dev/md/, we prefer that. * This applies only to names for MD devices. + * If 'prefer' is set (normally to e.g. /by-path/) + * then we prefer a name which contains that string. */ -char *map_dev(int major, int minor, int create) +char *map_dev_preferred(int major, int minor, int create, + char *prefer) { struct devmap *p; char *regular = NULL, *preferred=NULL; @@ -219,7 +222,8 @@ char *map_dev(int major, int minor, int create) for (p=devlist; p; p=p->next) if (p->major == major && p->minor == minor) { - if (strncmp(p->name, "/dev/md/",8) == 0) { + if (strncmp(p->name, "/dev/md/",8) == 0 + || (prefer && strstr(p->name, prefer))) { if (preferred == NULL || strlen(p->name) < strlen(preferred)) preferred = p->name; @@ -243,6 +247,7 @@ char *map_dev(int major, int minor, int create) } + /* conf_word gets one word from the conf file. * if "allow_key", then accept words at the start of a line, * otherwise stop when such a word is found. @@ -389,6 +389,28 @@ will be allowed to use 'local' names (i.e. not ending in '_' followed by a digit string). See below under .BR "Auto Assembly" . +.TP +.B \-\-prefer= +When +.I mdadm +needs to print the name for a device it normally finds the name in +.B /dev +which refers to the device and is shortest. When a path component is +given with +.B \-\-prefer +.I mdadm +will prefer a longer name if it contains that component. For example +.B \-\-prefer=by-uuid +will prefer a name in a subdirectory of +.B /dev +called +.BR by-uuid . + +This functionality is currently only provided by +.B \-\-detail +and +.BR \-\-monitor . + .SH For create, build, or grow: .TP @@ -73,6 +73,7 @@ int main(int argc, char *argv[]) int test = 0; int export = 0; int assume_clean = 0; + char *prefer = NULL; char *symlinks = NULL; int grow_continue = 0; /* autof indicates whether and how to create device node. @@ -184,6 +185,13 @@ int main(int argc, char *argv[]) __offroot = 1; continue; + case Prefer: + if (prefer) + free(prefer); + if (asprintf(&prefer, "/%s/", optarg) <= 0) + prefer = NULL; + continue; + case ':': case '?': fputs(Usage, stderr); @@ -1498,7 +1506,7 @@ int main(int argc, char *argv[]) if (devmode == 'D') rv |= Detail(name, v, export, test, - homehost); + homehost, prefer); else rv |= WaitClean(name, -1, v); put_md_name(name); @@ -1552,7 +1560,7 @@ int main(int argc, char *argv[]) case 'D': rv |= Detail(dv->devname, brief?1+verbose:0, - export, test, homehost); + export, test, homehost, prefer); continue; case 'K': /* Zero superblock */ if (ss) @@ -1626,7 +1634,8 @@ int main(int argc, char *argv[]) } rv= Monitor(devlist, mailaddr, program, delay?delay:60, daemonise, scan, oneshot, - dosyslog, test, pidfile, increments, spare_sharing); + dosyslog, test, pidfile, increments, + spare_sharing, prefer); break; case GROW: @@ -322,6 +322,7 @@ enum special_options { FreezeReshape, Continue, OffRootOpt, + Prefer, }; /* structures read from config file */ @@ -532,7 +533,12 @@ extern char *map_num(mapping_t *map, int num); extern int map_name(mapping_t *map, char *name); extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[]; -extern char *map_dev(int major, int minor, int create); +extern char *map_dev_preferred(int major, int minor, int create, + char *prefer); +static inline char *map_dev(int major, int minor, int create) +{ + return map_dev_preferred(major, minor, create, NULL); +} struct active_array; struct metadata_update; @@ -1080,7 +1086,7 @@ extern int Create(struct supertype *st, char *mddev, int runstop, int verbose, int force, int assume_clean, char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int autof); -extern int Detail(char *dev, int brief, int export, int test, char *homehost); +extern int Detail(char *dev, int brief, int export, int test, char *homehost, char *prefer); extern int Detail_Platform(struct superswitch *ss, int scan, int verbose); extern int Query(char *dev); extern int Examine(struct mddev_dev *devlist, int brief, int export, int scan, @@ -1089,7 +1095,7 @@ extern int Monitor(struct mddev_dev *devlist, char *mailaddr, char *alert_cmd, int period, int daemonise, int scan, int oneshot, int dosyslog, int test, char *pidfile, int increments, - int share); + int share, char *prefer); extern int Kill(char *dev, struct supertype *st, int force, int quiet, int noexcl); extern int Kill_subarray(char *dev, char *subarray, int quiet); |