From 9eafa1de73d1bd0b2ac0275d1389824825647df7 Mon Sep 17 00:00:00 2001 From: Maciej Naruszewicz Date: Thu, 4 Oct 2012 16:34:11 +1000 Subject: [PATCH] imsm: Allow to specify controller for --detail-platform. 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. $ mdadm --detail-platform Platform : Intel(R) Matrix Storage Manager Version : 9.5.0.1037 RAID Levels : raid0 raid1 raid10 raid5 Chunk Sizes : 4k 8k 16k 32k 64k 128k 2TB volumes : supported 2TB disks : not supported Max Disks : 7 Max Volumes : 2 per array, 4 per controller I/O Controller : /sys/devices/pci0000:00/0000:00:1f.2 (SATA) $ mdadm --detail-platform /sys/devices/pci0000:00/0000:00:1f.2 Platform : Intel(R) Matrix Storage Manager Version : 9.5.0.1037 RAID Levels : raid0 raid1 raid10 raid5 Chunk Sizes : 4k 8k 16k 32k 64k 128k 2TB volumes : supported 2TB disks : not supported Max Disks : 7 Max Volumes : 2 per array, 4 per controller I/O Controller : /sys/devices/pci0000:00/0000:00:1f.2 (SATA) $ mdadm --detail-platform /sys/devices/pci0000:00/0000:00:1f.2 --export MD_FIRMWARE_TYPE=imsm IMSM_VERSION=9.5.0.1037 IMSM_SUPPORTED_RAID_LEVELS=raid0 raid1 raid10 raid5 IMSM_SUPPORTED_CHUNK_SIZES=4k 8k 16k 32k 64k 128k IMSM_2TB_VOLUMES=yes IMSM_2TB_DISKS=no IMSM_MAX_DISKS=7 IMSM_MAX_VOLUMES_PER_ARRAY=2 IMSM_MAX_VOLUMES_PER_CONTROLLER=4 $ mdadm --detail-platform /sys/devices/pci0000:00/0000:00:1f.0 # This isn't an IMSM-capable controller mdadm: no active Intel(R) RAID controller found under /sys/devices/pci0000:00/0000:00:1f.0 Signed-off-by: Maciej Naruszewicz Signed-off-by: NeilBrown --- Create.c | 2 +- Detail.c | 10 +++++----- mdadm.8.in | 6 +++++- mdadm.c | 13 +++++++++++-- mdadm.h | 7 ++++--- super-intel.c | 45 +++++++++++++++++++++++++-------------------- util.c | 21 +++++++++++++++++++++ 7 files changed, 72 insertions(+), 32 deletions(-) diff --git a/Create.c b/Create.c index 32683a82..2da07d06 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 97712b06..9bf20618 100644 --- a/Detail.c +++ b/Detail.c @@ -616,7 +616,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 @@ -625,9 +625,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", @@ -654,9 +654,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 && meta->export_detail_platform) { - 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/mdadm.8.in b/mdadm.8.in index d9637757..845c00cd 100644 --- a/mdadm.8.in +++ b/mdadm.8.in @@ -1332,7 +1332,11 @@ Print details of one or more md devices. .TP .BR \-\-detail\-platform Print details of the platform's RAID capabilities (firmware / hardware -topology) for a given metadata format. +topology) for a given metadata format. If used without argument, mdadm +will scan all controllers looking for their capabilities. Otherwise, mdadm +will only look at the controller specified by the argument in form of an +absolute filepath or a link, e.g. +.IR /sys/devices/pci0000:00/0000:00:1f.2 . .TP .BR \-Y ", " \-\-export diff --git a/mdadm.c b/mdadm.c index 0f7bed91..870e5376 100644 --- a/mdadm.c +++ b/mdadm.c @@ -324,8 +324,15 @@ int main(int argc, char *argv[]) continue; } if (opt == 1) { - /* an undecorated option - must be a device name. + /* an undecorated option - must be a device name. */ + + if (devs_found > 0 && devmode == DetailPlatform) { + pr_err("controller may only be specified once. %s ignored\n", + optarg); + continue; + } + if (devs_found > 0 && mode == MANAGE && !devmode) { pr_err("Must give one of -a/-r/-f" " for subsequent devices at %s\n", optarg); @@ -1350,7 +1357,9 @@ 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, + devlist ? devlist->devname : NULL); } else if (devlist == NULL) { if (devmode == 'S' && c.scan) rv = stop_scan(c.verbose); diff --git a/mdadm.h b/mdadm.h index fe28d3de..1390be8d 100644 --- a/mdadm.h +++ b/mdadm.h @@ -659,8 +659,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 @@ -1127,7 +1127,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); @@ -1181,6 +1181,7 @@ extern int open_dev_flags(int devnum, int flags); extern int open_dev_excl(int devnum); extern int is_standard(char *dev, int *nump); extern int same_dev(char *one, char *two); +extern int compare_paths (char* path1,char* path2); extern int parse_auto(char *str, char *msg, int config); extern struct mddev_ident *conf_get_ident(char *dev); diff --git a/super-intel.c b/super-intel.c index fdf441a5..64f181e3 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 @@ -1850,7 +1850,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only) struct sys_dev *list, *hba; int host_base = 0; int port_count = 0; - int result=0; + int result=1; if (enumerate_only) { if (check_env("IMSM_NO_PLATFORM")) @@ -1864,6 +1864,8 @@ static int detail_platform_imsm(int verbose, int enumerate_only) result = 2; break; } + else + result = 0; } free_sys_dev(&list); return result; @@ -1880,34 +1882,38 @@ 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 && (compare_paths(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 { + result = 0; print_imsm_capability(orom); - } - - 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.", hba->pci_id); - result |= 2; + 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 (controller_path && result == 1) + 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; @@ -1923,6 +1929,8 @@ static int export_detail_platform_imsm(int verbose) } for (hba = list; hba; hba = hba->next) { + if (controller_path && (compare_paths(hba->path,controller_path) != 0)) + continue; orom = find_imsm_capability(hba->type); if (!orom) { if (verbose > 0) @@ -1934,9 +1942,6 @@ static int export_detail_platform_imsm(int verbose) } } - if (result == 1 && verbose > 0) - pr_err("IMSM_DETAIL_PLATFORM_ERROR=NO_IMSM_CAPABLE_DEVICES\n"); - return result; } diff --git a/util.c b/util.c index 427a8cf7..fad72cc9 100644 --- a/util.c +++ b/util.c @@ -1834,3 +1834,24 @@ struct mdinfo *container_choose_spares(struct supertype *st, } return disks; } + +/* Checks if paths point to the same device + * Returns 0 if they do. + * Returns 1 if they don't. + * Returns -1 if something went wrong, + * e.g. paths are empty or the files + * they point to don't exist */ +int compare_paths (char* path1, char* path2) +{ + struct stat st1,st2; + + if (path1 == NULL || path2 == NULL) + return -1; + if (stat(path1,&st1) != 0) + return -1; + if (stat(path2,&st2) != 0) + return -1; + if ((st1.st_ino == st2.st_ino) && (st1.st_dev == st2.st_dev)) + return 0; + return 1; +} -- 2.39.2