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 <maciej.naruszewicz@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
Maciej Naruszewicz 2012-10-04 16:34:11 +10:00 committed by NeilBrown
parent 12c7b44ebe
commit 9eafa1de73
7 changed files with 72 additions and 32 deletions

View File

@ -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",

View File

@ -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;

View File

@ -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

13
mdadm.c
View File

@ -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);

View File

@ -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);

View File

@ -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;
}

21
util.c
View File

@ -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;
}