summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdiskmgt/common/findevs.c
diff options
context:
space:
mode:
authorYuri Pankov <yuri.pankov@nexenta.com>2017-10-07 04:39:30 +0300
committerRichard Lowe <richlowe@richlowe.net>2017-10-11 18:33:09 -0400
commitc470f5752f71dfecd12e42f4da179d8f8291ce52 (patch)
tree78e68f76ee97d8a1327ad2c62f0478ddeed88151 /usr/src/lib/libdiskmgt/common/findevs.c
parent571b0a139da53a3aae3b5d2370166c572eb7655c (diff)
downloadillumos-joyent-c470f5752f71dfecd12e42f4da179d8f8291ce52.tar.gz
8709 teach libdiskmgt about nvme, sata, and xen
Reviewed by: Dan Fields <dan.fields@nexenta.com> Reviewed by: Evan Layton <evan.layton@nexenta.com> Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com> Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src/lib/libdiskmgt/common/findevs.c')
-rw-r--r--usr/src/lib/libdiskmgt/common/findevs.c377
1 files changed, 52 insertions, 325 deletions
diff --git a/usr/src/lib/libdiskmgt/common/findevs.c b/usr/src/lib/libdiskmgt/common/findevs.c
index 68384c1ca1..8114f31352 100644
--- a/usr/src/lib/libdiskmgt/common/findevs.c
+++ b/usr/src/lib/libdiskmgt/common/findevs.c
@@ -18,11 +18,15 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ */
+
+/*
* Copyright (c) 2011 by Delphix. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.
*/
#include <fcntl.h>
@@ -43,12 +47,9 @@
#include "libdiskmgt.h"
#include "disks_private.h"
-#define CLUSTER_DEV "did"
-
/* specify which disk links to use in the /dev directory */
#define DEVLINK_REGEX "rdsk/.*"
#define DEVLINK_FLOPPY_REGEX "rdiskette[0-9]"
-#define DEVLINK_DID_REGEX "did/rdsk/.*"
#define FLOPPY_NAME "rdiskette"
@@ -64,9 +65,12 @@
#define WWN_PROP "node-wwn"
static char *ctrltypes[] = {
- DDI_NT_SCSI_NEXUS,
- DDI_NT_SCSI_ATTACHMENT_POINT,
DDI_NT_FC_ATTACHMENT_POINT,
+ DDI_NT_NVME_ATTACHMENT_POINT,
+ DDI_NT_SATA_ATTACHMENT_POINT,
+ DDI_NT_SATA_NEXUS,
+ DDI_NT_SCSI_ATTACHMENT_POINT,
+ DDI_NT_SCSI_NEXUS,
NULL
};
@@ -79,8 +83,6 @@ static char *bustypes[] = {
static bus_t *add_bus(struct search_args *args, di_node_t node,
di_minor_t minor, controller_t *cp);
-static int add_cluster_devs(di_node_t node, di_minor_t minor,
- void *arg);
static controller_t *add_controller(struct search_args *args,
di_node_t node, di_minor_t minor);
static int add_devpath(di_devlink_t devlink, void *arg);
@@ -103,7 +105,6 @@ static boolean_t disk_is_cdrom(const char *type);
static alias_t *find_alias(disk_t *diskp, char *kernel_name);
static bus_t *find_bus(struct search_args *args, char *name);
static controller_t *find_controller(struct search_args *args, char *name);
-static int fix_cluster_devpath(di_devlink_t devlink, void *arg);
static disk_t *get_disk_by_deviceid(disk_t *listp, char *devid);
static void get_disk_name_from_path(char *path, char *name,
int size);
@@ -118,11 +119,10 @@ static int get_prop(char *prop_name, di_node_t node);
static char *get_str_prop(char *prop_name, di_node_t node);
static int have_disk(struct search_args *args, char *devid,
char *kernel_name, disk_t **diskp);
-static int is_cluster_disk(di_node_t node, di_minor_t minor);
static int is_ctds(char *name);
static int is_drive(di_minor_t minor);
static int is_zvol(di_node_t node, di_minor_t minor);
-static int is_HBA(di_node_t node, di_minor_t minor);
+static int is_ctrl(di_node_t node, di_minor_t minor);
static int new_alias(disk_t *diskp, char *kernel_path,
char *devlink_path, struct search_args *args);
static int new_devpath(alias_t *ap, char *devpath);
@@ -130,7 +130,6 @@ static path_t *new_path(controller_t *cp, disk_t *diskp,
di_node_t node, di_path_state_t st, char *wwn);
static void remove_invalid_controller(char *name,
controller_t *currp, struct search_args *args);
-static char *str_case_index(register char *s1, register char *s2);
/*
* The functions in this file do a dev tree walk to build up a model of the
@@ -144,41 +143,29 @@ static char *str_case_index(register char *s1, register char *s2);
void
findevs(struct search_args *args)
{
- uint_t flags;
di_node_t di_root;
- args->dev_walk_status = 0;
- args->disk_listp = NULL;
- args->controller_listp = NULL;
args->bus_listp = NULL;
+ args->controller_listp = NULL;
+ args->disk_listp = NULL;
+ args->dev_walk_status = 0;
args->handle = di_devlink_init(NULL, 0);
/*
* Have to make several passes at this with the new devfs caching.
* First, we find non-mpxio devices. Then we find mpxio/multipath
- * devices. Finally, we get cluster devices.
+ * devices.
*/
- flags = DINFOCACHE;
- di_root = di_init("/", flags);
+ di_root = di_init("/", DINFOCACHE);
args->ph = di_prom_init();
(void) di_walk_minor(di_root, NULL, 0, args, add_devs);
di_fini(di_root);
- flags = DINFOCPYALL | DINFOPATH;
- di_root = di_init("/", flags);
+ di_root = di_init("/", DINFOCPYALL|DINFOPATH);
(void) di_walk_minor(di_root, NULL, 0, args, add_devs);
di_fini(di_root);
- /* do another pass to clean up cluster devpaths */
- flags = DINFOCACHE;
- di_root = di_init("/", flags);
- (void) di_walk_minor(di_root, DDI_PSEUDO, 0, args, add_cluster_devs);
- if (args->ph != DI_PROM_HANDLE_NIL) {
- (void) di_prom_fini(args->ph);
- }
- di_fini(di_root);
-
(void) di_devlink_fini(&(args->handle));
clean_paths(args);
@@ -190,7 +177,7 @@ findevs(struct search_args *args)
static bus_t *
add_bus(struct search_args *args, di_node_t node, di_minor_t minor,
- controller_t *cp)
+ controller_t *cp)
{
char *btype;
char *devpath;
@@ -299,58 +286,6 @@ add_bus(struct search_args *args, di_node_t node, di_minor_t minor,
return (bp);
}
-static int
-add_cluster_devs(di_node_t node, di_minor_t minor, void *arg)
-{
- struct search_args *args;
- char *devpath;
- char slice_path[MAXPATHLEN];
- int result = DI_WALK_CONTINUE;
-
- if (!is_cluster_disk(node, minor)) {
- return (DI_WALK_CONTINUE);
- }
-
- args = (struct search_args *)arg;
-
- if (dm_debug > 1) {
- /* This is all just debugging code */
- char *devpath;
- char dev_name[MAXPATHLEN];
-
- devpath = di_devfs_path(node);
- (void) snprintf(dev_name, sizeof (dev_name), "%s:%s", devpath,
- di_minor_name(minor));
- di_devfs_path_free((void *) devpath);
-
- (void) fprintf(stderr, "INFO: cluster dev: %s\n", dev_name);
- }
-
- args->node = node;
- args->minor = minor;
- args->dev_walk_status = 0;
-
- /*
- * Fix the devpaths for the cluster drive.
- *
- * We will come through here once for each raw slice device name.
- */
- devpath = di_devfs_path(node);
- (void) snprintf(slice_path, sizeof (slice_path), "%s:%s", devpath,
- di_minor_name(minor));
- di_devfs_path_free((void *) devpath);
-
- /* Walk the /dev tree to get the cluster devlinks. */
- (void) di_devlink_walk(args->handle, DEVLINK_DID_REGEX, slice_path,
- DI_PRIMARY_LINK, arg, fix_cluster_devpath);
-
- if (args->dev_walk_status != 0) {
- result = DI_WALK_TERMINATE;
- }
-
- return (result);
-}
-
static controller_t *
add_controller(struct search_args *args, di_node_t node, di_minor_t minor)
{
@@ -547,7 +482,7 @@ add_devs(di_node_t node, di_minor_t minor, void *arg)
result = DI_WALK_TERMINATE;
}
- } else if (is_HBA(node, minor)) {
+ } else if (is_ctrl(node, minor)) {
if (add_controller(args, node, minor) == NULL) {
args->dev_walk_status = ENOMEM;
result = DI_WALK_TERMINATE;
@@ -688,12 +623,12 @@ add_disk2controller(disk_t *diskp, struct search_args *args)
/* this is a new controller for this disk */
- /* add the disk to the controlller */
+ /* add the disk to the controller */
if (add_ptr2array(diskp, (void ***)&cp->disks) != 0) {
return (ENOMEM);
}
- /* add the controlller to the disk */
+ /* add the controller to the disk */
if (add_ptr2array(cp, (void ***)&diskp->controllers) != 0) {
return (ENOMEM);
}
@@ -1037,7 +972,7 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args)
* DVD, CD-ROM, CD-RW, MO, etc. are all reported as CD-ROMS.
* We try to use uscsi later to determine the real type.
* The cd_rom flag tells us that the kernel categorized the drive
- * as a CD-ROM. We leave the drv_type as UKNOWN for now.
+ * as a CD-ROM. We leave the drv_type as UNKNOWN for now.
* The combination of the cd_rom flag being set with the drv_type of
* unknown is what triggers the uscsi probe in drive.c.
*/
@@ -1049,49 +984,11 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args)
diskp->drv_type = DM_DT_FLOPPY;
diskp->removable = 1;
} else {
- /* not a "CD-ROM" or Floppy */
+ /* not a CD-ROM or Floppy */
diskp->removable = get_prop(REMOVABLE_PROP, args->node);
if (diskp->removable == -1) {
diskp->removable = 0;
-#if defined(i386) || defined(__amd64)
- /*
- * x86 does not have removable property.
- * Check for common removable drives, zip & jaz,
- * and mark those correctly.
- */
- if (vendor_id != NULL && prod_id != NULL) {
- if (str_case_index(vendor_id,
- "iomega") != NULL) {
- if (str_case_index(prod_id,
- "jaz") != NULL) {
- diskp->removable = 1;
- } else if (str_case_index(prod_id,
- "zip") != NULL) {
- diskp->removable = 1;
- }
- }
- }
-#endif
- }
-
- if (diskp->removable) {
- /*
- * For removable jaz or zip drives there is no way
- * to get the drive type unless media is inserted,so
- * we look at the product-id for a hint.
- */
- diskp->drv_type = DM_DT_UNKNOWN;
-
- if (prod_id != NULL) {
- if (str_case_index(prod_id, "jaz") != NULL) {
- diskp->drv_type = DM_DT_JAZ;
- } else if (str_case_index(prod_id,
- "zip") != NULL) {
- diskp->drv_type = DM_DT_ZIP;
- }
- }
- } else {
diskp->drv_type = DM_DT_FIXED;
}
}
@@ -1112,31 +1009,37 @@ ctype(di_node_t node, di_minor_t minor)
name = di_node_name(node);
/* IDE disks use SCSI nexus as the type, so handle this special case */
- if (libdiskmgt_str_eq(name, "ide")) {
+ if ((libdiskmgt_str_eq(type, DDI_NT_SCSI_NEXUS) ||
+ libdiskmgt_str_eq(type, DDI_PSEUDO)) &&
+ libdiskmgt_str_eq(name, "ide"))
return (DM_CTYPE_ATA);
- }
- if (libdiskmgt_str_eq(di_minor_name(minor), "scsa2usb")) {
- return (DM_CTYPE_USB);
- }
+ if (libdiskmgt_str_eq(type, DDI_NT_FC_ATTACHMENT_POINT) ||
+ (libdiskmgt_str_eq(type, DDI_NT_NEXUS) &&
+ libdiskmgt_str_eq(name, "fp")))
+ return (DM_CTYPE_FIBRE);
- if (libdiskmgt_str_eq(type, DDI_NT_SCSI_NEXUS) ||
- libdiskmgt_str_eq(type, DDI_NT_SCSI_ATTACHMENT_POINT)) {
- return (DM_CTYPE_SCSI);
- }
+ if (libdiskmgt_str_eq(type, DDI_NT_NVME_ATTACHMENT_POINT))
+ return (DM_CTYPE_NVME);
- if (libdiskmgt_str_eq(type, DDI_NT_FC_ATTACHMENT_POINT)) {
- return (DM_CTYPE_FIBRE);
- }
+ if (libdiskmgt_str_eq(type, DDI_NT_SATA_NEXUS) ||
+ libdiskmgt_str_eq(type, DDI_NT_SATA_ATTACHMENT_POINT))
+ return (DM_CTYPE_SATA);
- if (libdiskmgt_str_eq(type, DDI_NT_NEXUS) &&
- libdiskmgt_str_eq(name, "fp")) {
- return (DM_CTYPE_FIBRE);
- }
+ if (libdiskmgt_str_eq(type, DDI_NT_SCSI_NEXUS) ||
+ libdiskmgt_str_eq(type, DDI_NT_SCSI_ATTACHMENT_POINT))
+ return (DM_CTYPE_SCSI);
+
+ if (libdiskmgt_str_eq(di_minor_name(minor), "scsa2usb"))
+ return (DM_CTYPE_USB);
if (libdiskmgt_str_eq(type, DDI_PSEUDO) &&
- libdiskmgt_str_eq(name, "ide")) {
- return (DM_CTYPE_ATA);
+ libdiskmgt_str_eq(name, "xpvd"))
+ return (DM_CTYPE_XEN);
+
+ if (dm_debug) {
+ (void) fprintf(stderr,
+ "INFO: unknown controller type=%s name=%s\n", type, name);
}
return (DM_CTYPE_UNKNOWN);
@@ -1196,147 +1099,6 @@ find_controller(struct search_args *args, char *name)
return (NULL);
}
-static int
-fix_cluster_devpath(di_devlink_t devlink, void *arg)
-{
- int fd;
- struct search_args *args;
- char *devlink_path;
- disk_t *diskp = NULL;
- alias_t *ap = NULL;
-
- /*
- * The devlink_path is of the form /dev/did/rdsk/d1s0.
- */
-
- args = (struct search_args *)arg;
-
- /* Find the disk by the deviceid we read from the cluster disk. */
- devlink_path = (char *)di_devlink_path(devlink);
- if (devlink_path == NULL) {
- return (DI_WALK_CONTINUE);
- }
-
- if ((fd = open(devlink_path, O_RDONLY|O_NDELAY)) >= 0) {
- ddi_devid_t devid;
-
- if (dm_debug > 1) {
- (void) fprintf(stderr, "INFO: cluster devpath %s\n",
- devlink_path);
- }
-
- if (devid_get(fd, &devid) == 0) {
- char *minor;
- char *devidstr;
-
- minor = di_minor_name(args->minor);
-
- if ((devidstr =
- devid_str_encode(devid, minor)) != NULL) {
- diskp = get_disk_by_deviceid(args->disk_listp,
- devidstr);
- /*
- * This really shouldn't happen, since
- * we should have found all of the disks
- * during our first pass through
- * the dev tree, but just in case...
- */
- if (diskp == NULL) {
- if (dm_debug > 1) {
- (void) fprintf(stderr,
- "INFO: cluster create"
- " disk\n");
- }
-
- diskp = create_disk(devidstr,
- NULL, args);
- if (diskp == NULL) {
- args->dev_walk_status = ENOMEM;
- }
-
- /* add the controller relationship */
- if (args->dev_walk_status == 0) {
- if (add_disk2controller(diskp,
- args) != 0) {
- args->dev_walk_status
- = ENOMEM;
- }
- }
-
- if (new_alias(diskp, NULL,
- devlink_path, args) != 0) {
- args->dev_walk_status = ENOMEM;
- }
- }
- devid_str_free(devidstr);
- }
- devid_free(devid);
- }
- (void) close(fd);
- }
-
-
- if (diskp != NULL) {
- if (dm_debug > 1) {
- (void) fprintf(stderr, "INFO: cluster found"
- " disk\n");
- }
- ap = diskp->aliases;
- }
-
- if (ap != NULL) {
- /*
- * NOTE: if ap->next != NULL have cluster
- * disks w/ multiple paths.
- */
-
- if (!ap->cluster) {
- char *basep;
- char *namep;
- int cnt = 0;
- int size;
- char alias[MAXPATHLEN];
-
- /*
- * First time; save the /dev/rdsk devpaths and
- * update the alias info with the new alias name.
- */
- ap->orig_paths = ap->devpaths;
- ap->devpaths = NULL;
-
- free(ap->alias);
-
- /* get the new cluster alias name */
- basep = strrchr(devlink_path, '/');
- if (basep == NULL) {
- basep = devlink_path;
- } else {
- basep++;
- }
- size = sizeof (alias) - 1;
- namep = alias;
-
- while (*basep != 0 && *basep != 's' && cnt < size) {
- *namep++ = *basep++;
- cnt++;
- }
- *namep = 0;
-
- if ((ap->alias = strdup(alias)) == NULL) {
- args->dev_walk_status = ENOMEM;
- }
-
- ap->cluster = 1;
- }
-
- if (new_devpath(ap, devlink_path) != 0) {
- args->dev_walk_status = ENOMEM;
- }
- }
-
- return (DI_WALK_CONTINUE);
-}
-
/*
* Check if we have the drive in our list, based upon the device id.
* We got the device id from the dev tree walk. This is encoded
@@ -1564,18 +1326,6 @@ bus_type(di_node_t node, di_minor_t minor, di_prom_handle_t ph)
return (NULL);
}
-static int
-is_cluster_disk(di_node_t node, di_minor_t minor)
-{
- if (di_minor_spectype(minor) == S_IFCHR &&
- libdiskmgt_str_eq(di_minor_nodetype(minor), DDI_PSEUDO) &&
- libdiskmgt_str_eq(di_node_name(node), CLUSTER_DEV)) {
- return (1);
- }
-
- return (0);
-}
-
/*
* If the input name is in c[t]ds format then return 1, otherwise return 0.
*/
@@ -1643,7 +1393,7 @@ is_zvol(di_node_t node, di_minor_t minor)
}
static int
-is_HBA(di_node_t node, di_minor_t minor)
+is_ctrl(di_node_t node, di_minor_t minor)
{
char *type;
char *name;
@@ -1661,16 +1411,16 @@ is_HBA(di_node_t node, di_minor_t minor)
name = di_node_name(node);
if (libdiskmgt_str_eq(type, DDI_PSEUDO) &&
- libdiskmgt_str_eq(name, "ide")) {
+ (libdiskmgt_str_eq(name, "ide") ||
+ libdiskmgt_str_eq(name, "xpvd")))
return (1);
- }
return (0);
}
static int
new_alias(disk_t *diskp, char *kernel_name, char *devlink_path,
- struct search_args *args)
+ struct search_args *args)
{
alias_t *aliasp;
char alias[MAXPATHLEN];
@@ -1705,7 +1455,6 @@ new_alias(disk_t *diskp, char *kernel_name, char *devlink_path,
aliasp->kstat_name = NULL;
}
- aliasp->cluster = 0;
aliasp->lun = get_prop(DM_LUN, args->node);
aliasp->target = get_prop(DM_TARGET, args->node);
aliasp->wwn = get_byte_prop(WWN_PROP, args->node);
@@ -1791,7 +1540,7 @@ new_devpath(alias_t *ap, char *devpath)
static path_t *
new_path(controller_t *cp, disk_t *dp, di_node_t node, di_path_state_t st,
- char *wwn)
+ char *wwn)
{
char *devpath;
path_t *pp;
@@ -1937,25 +1686,3 @@ remove_invalid_controller(char *name, controller_t *currp,
cp = cp->next;
}
}
-
-/*
- * This is the standard strstr code modified for case independence.
- */
-static char *
-str_case_index(register char *s1, register char *s2)
-{
- uint_t s2len = strlen(s2); /* length of the second string */
-
- /* If the length of the second string is 0, return the first arg. */
- if (s2len == 0) {
- return (s1);
- }
-
- while (strlen(s1) >= s2len) {
- if (strncasecmp(s1, s2, s2len) == 0) {
- return (s1);
- }
- s1++;
- }
- return (NULL);
-}