imsm: Add --controller-path option for --detail-platform. From: Maciej Naruszewicz Usually, 'mdadm --detail-platform -e imsm' scans all the controllers looking for IMSM capabilities. This patch provides the possibility to specify a controller to scan, enabling custom usage by other processes - especially with the --export switch. Signed-off-by: Maciej Naruszewicz --- Create.c | 2 +- Detail.c | 10 +++++----- ReadMe.c | 2 ++ mdadm.8.in | 8 ++++++++ mdadm.c | 20 +++++++++++++++++++- mdadm.h | 8 +++++--- super-intel.c | 46 ++++++++++++++++++++++++++++++---------------- 7 files changed, 70 insertions(+), 26 deletions(-) diff --git a/Create.c b/Create.c index 32683a8..2da07d0 100644 --- a/Create.c +++ b/Create.c @@ -492,7 +492,7 @@ int Create(struct supertype *st, char *mddev, warn = 1; } - if (st->ss->detail_platform && st->ss->detail_platform(0, 1) != 0) { + if (st->ss->detail_platform && st->ss->detail_platform(0, 1, NULL) != 0) { if (c->runstop != 1 || c->verbose >= 0) pr_err("%s unable to enumerate platform support\n" " array may not be compatible with hardware/firmware\n", diff --git a/Detail.c b/Detail.c index 4cca913..1d67bd2 100644 --- a/Detail.c +++ b/Detail.c @@ -615,7 +615,7 @@ out: return rv; } -int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export) +int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path) { /* display platform capabilities for the given metadata format * 'scan' in this context means iterate over all metadata types @@ -624,9 +624,9 @@ int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export) int err = 1; if (ss && export && ss->export_detail_platform) - err = ss->export_detail_platform(verbose); + err = ss->export_detail_platform(verbose, controller_path); else if (ss && ss->detail_platform) - err = ss->detail_platform(verbose, 0); + err = ss->detail_platform(verbose, 0, controller_path); else if (ss) { if (verbose > 0) pr_err("%s metadata is platform independent\n", @@ -652,9 +652,9 @@ int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export) pr_err("%s metadata is platform independent\n", meta->name ? : "[no name]"); } else if (export){ - err |= meta->export_detail_platform(verbose); + err |= meta->export_detail_platform(verbose, controller_path); } else - err |= meta->detail_platform(verbose, 0); + err |= meta->detail_platform(verbose, 0, controller_path); } return err; diff --git a/ReadMe.c b/ReadMe.c index 346f08c..0c9c80b 100644 --- a/ReadMe.c +++ b/ReadMe.c @@ -159,6 +159,7 @@ struct option long_options[] = { {"sparc2.2", 0, 0, Sparc22}, {"test", 0, 0, 't'}, {"prefer", 1, 0, Prefer}, + {"controller-path",1, 0, ControllerPath}, /* For Follow/monitor */ {"mail", 1, 0, EMail}, @@ -240,6 +241,7 @@ char OptionHelp[] = " --brief -b : Be less verbose, more brief\n" " --export -Y : With --detail, --detail-platform or --examine use\n" " key=value format for easy import into environment\n" +" --controller-path : Specify controller for --detail-platform\n" " --force -f : Override normal checks and be more forceful\n" "\n" " --assemble -A : Assemble an array\n" diff --git a/mdadm.8.in b/mdadm.8.in index 38c8bc8..8792e54 100644 --- a/mdadm.8.in +++ b/mdadm.8.in @@ -1329,6 +1329,14 @@ output will be formatted as pairs for easy import into the environment. .TP +.BR \-\-controller\-path +When used with +.BR \-\-detail\-platform , +mdadm will only print information about the specified controller. The +controller should be given in form of an absolute filepath, e.g. +.B \-\-controller\-path /sys/devices/pci0000:00/0000:00:1f.0 . + +.TP .BR \-E ", " \-\-examine Print contents of the metadata stored on the named device(s). Note the contrast between diff --git a/mdadm.c b/mdadm.c index 3ee7ddb..b5ca3b3 100644 --- a/mdadm.c +++ b/mdadm.c @@ -151,6 +151,24 @@ int main(int argc, char *argv[]) case 'Y': c.export++; continue; + case ControllerPath: + if (c.controller_path) + free(c.controller_path); + if (asprintf(&c.controller_path, "%s", optarg) <= 0) { + pr_err("Empty or wrong controller path, \'%s\' ignored.\n", + c.controller_path); + c.controller_path = NULL; + } + else { + struct stat st; + if (stat(c.controller_path, &st) != 0) { + pr_err("Specified controller path %s doesn't exist.\n", + c.controller_path); + exit(2); + } + } + continue; + case HomeHost: if (strcasecmp(optarg, "") == 0) c.require_homehost = 0; @@ -1344,7 +1362,7 @@ int main(int argc, char *argv[]) } rv = Examine(devlist, &c, ss); } else if (devmode == DetailPlatform) { - rv = Detail_Platform(ss ? ss->ss : NULL, ss ? c.scan : 1, c.verbose, c.export); + rv = Detail_Platform(ss ? ss->ss : NULL, ss ? c.scan : 1, c.verbose, c.export, c.controller_path); } else if (devlist == NULL) { if (devmode == 'S' && c.scan) rv = stop_scan(c.verbose); diff --git a/mdadm.h b/mdadm.h index da5bee9..c5faa37 100644 --- a/mdadm.h +++ b/mdadm.h @@ -326,6 +326,7 @@ enum special_options { OffRootOpt, Prefer, KillOpt, + ControllerPath, }; /* structures read from config file */ @@ -394,6 +395,7 @@ struct context { int freeze_reshape; char *backup_file; int invalid_backup; + char *controller_path; }; struct shape { @@ -654,8 +656,8 @@ extern struct superswitch { void (*export_detail_super)(struct supertype *st); /* Optional: platform hardware / firmware details */ - int (*detail_platform)(int verbose, int enumerate_only); - int (*export_detail_platform)(int verbose); + int (*detail_platform)(int verbose, int enumerate_only, char *controller_path); + int (*export_detail_platform)(int verbose, char *controller_path); /* Used: * to get uuid to storing in bitmap metadata @@ -1122,7 +1124,7 @@ extern int Create(struct supertype *st, char *mddev, struct context *c); extern int Detail(char *dev, struct context *c); -extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export); +extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path); extern int Query(char *dev); extern int Examine(struct mddev_dev *devlist, struct context *c, struct supertype *forcest); diff --git a/super-intel.c b/super-intel.c index 7af3ed5..bcd7286 100644 --- a/super-intel.c +++ b/super-intel.c @@ -1833,7 +1833,7 @@ static void print_imsm_capability_export(const struct imsm_orom *orom) printf("IMSM_MAX_VOLUMES_PER_CONTROLLER=%d\n",orom->vphba); } -static int detail_platform_imsm(int verbose, int enumerate_only) +static int detail_platform_imsm(int verbose, int enumerate_only, char *controller_path) { /* There are two components to imsm platform support, the ahci SATA * controller and the option-rom. To find the SATA controller we @@ -1851,6 +1851,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only) int host_base = 0; int port_count = 0; int result=0; + int controller_found = 0; if (enumerate_only) { if (check_env("IMSM_NO_PLATFORM")) @@ -1880,38 +1881,45 @@ static int detail_platform_imsm(int verbose, int enumerate_only) print_found_intel_controllers(list); for (hba = list; hba; hba = hba->next) { + if (controller_path != NULL && ( strcmp(hba->path,controller_path) != 0 )) + continue; orom = find_imsm_capability(hba->type); if (!orom) pr_err("imsm capabilities not found for controller: %s (type %s)\n", hba->path, get_sys_dev_type(hba->type)); - else + else { + controller_found++; print_imsm_capability(orom); - } + printf(" I/O Controller : %s (%s)\n", + hba->path, get_sys_dev_type(hba->type)); - for (hba = list; hba; hba = hba->next) { - printf(" I/O Controller : %s (%s)\n", - hba->path, get_sys_dev_type(hba->type)); - - if (hba->type == SYS_DEV_SATA) { - host_base = ahci_get_port_count(hba->path, &port_count); - if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) { - if (verbose > 0) - pr_err("failed to enumerate " - "ports on SATA controller at %s.\n", hba->pci_id); - result |= 2; + if (hba->type == SYS_DEV_SATA) { + host_base = ahci_get_port_count(hba->path, &port_count); + if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) { + if (verbose > 0) + pr_err("failed to enumerate " + "ports on SATA controller at %s.\n", hba->pci_id); + result |= 2; + } } } } + if (controller_path != NULL && controller_found == 0) + pr_err("no active Intel(R) RAID " + "controller found under %s\n",controller_path); + free_sys_dev(&list); return result; } -static int export_detail_platform_imsm(int verbose) +static int export_detail_platform_imsm(int verbose, char *controller_path) { const struct imsm_orom *orom; struct sys_dev *list, *hba; int result=0; + int controller_found = 0; + list = find_intel_devices(); if (!list) { @@ -1923,16 +1931,22 @@ static int export_detail_platform_imsm(int verbose) print_found_intel_controllers(list); for (hba = list; hba; hba = hba->next) { + if (controller_path != NULL && ( strcmp(hba->path,controller_path) != 0 )) + continue; orom = find_imsm_capability(hba->type); if (!orom) pr_err("imsm capabilities not found for controller: %s (type %s)\n", hba->path, get_sys_dev_type(hba->type)); else { print_imsm_capability_export(orom); + controller_found++; } - } + if (controller_path != NULL && controller_found == 0) + pr_err("no active Intel(R) RAID " + "controller found under %s\n",controller_path); + return result; }