FreeBSD/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c
/*
 * Go through and find any whole disks in the vdev specification, labelling them
 * as appropriate.  When constructing the vdev spec, we were unable to open this
 * device in order to provide a devid.  Now that we have labelled the disk and
 * know that slice 0 is valid, we can construct the devid now.
 *
 * If the disk was already labeled with an EFI label, we will have gotten the
 * devid already (because we were able to open the whole disk).  Otherwise, we
 * need to get the devid after we label the disk.
 */
Go through and find any whole disks in the vdev specification, labelling them
as appropriate.  When constructing the vdev spec, we were unable to open this
device in order to provide a devid.  Now that we have labelled the disk and
know that slice 0 is valid, we can construct the devid now.

If the disk was already labeled with an EFI label, we will have gotten the
devid already (because we were able to open the whole disk).  Otherwise, we
need to get the devid after we label the disk.
Go through and find any whole disks in the vdev specification labelling them as appropriate . When constructing the vdev spec we were unable to open this device in order to provide a devid . Now that we have labelled the disk and know that slice 0 is valid we can construct the devid now . If the disk was already labeled with an EFI label we will have gotten the devid already ( because we were able to open the whole disk ) . Otherwise we need to get the devid after we label the disk .
static int
make_disks(zpool_handle_t *zhp, nvlist_t *nv)
{
	nvlist_t **child;
	uint_t c, children;
	char *type, *path, *diskname;
	char buf[MAXPATHLEN];
	uint64_t wholedisk;
	int fd;
	int ret;
	ddi_devid_t devid;
	char *minor = NULL, *devid_str = NULL;
	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
	    &child, &children) != 0) {
		if (strcmp(type, VDEV_TYPE_DISK) != 0)
			return (0);
		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
		    &wholedisk) != 0 || !wholedisk)
			return (0);
		diskname = strrchr(path, '/');
		assert(diskname != NULL);
		diskname++;
		if (zpool_label_disk(g_zfs, zhp, diskname) == -1)
			return (-1);
		(void) snprintf(buf, sizeof (buf), "%ss0", path);
		if ((fd = open(buf, O_RDONLY)) < 0) {
			(void) fprintf(stderr,
			    gettext("cannot open '%s': %s\n"),
			    buf, strerror(errno));
			return (-1);
		}
		if (devid_get(fd, &devid) == 0) {
			if (devid_get_minor_name(fd, &minor) == 0 &&
			    (devid_str = devid_str_encode(devid, minor)) !=
			    NULL) {
				verify(nvlist_add_string(nv,
				    ZPOOL_CONFIG_DEVID, devid_str) == 0);
			}
			if (devid_str != NULL)
				devid_str_free(devid_str);
			if (minor != NULL)
				devid_str_free(minor);
			devid_free(devid);
		}
		verify(nvlist_add_string(nv, ZPOOL_CONFIG_PATH, buf) == 0);
		(void) close(fd);
		return (0);
	}
	for (c = 0; c < children; c++)
		if ((ret = make_disks(zhp, child[c])) != 0)
			return (ret);
	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
	    &child, &children) == 0)
		for (c = 0; c < children; c++)
			if ((ret = make_disks(zhp, child[c])) != 0)
				return (ret);
	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
	    &child, &children) == 0)
		for (c = 0; c < children; c++)
			if ((ret = make_disks(zhp, child[c])) != 0)
				return (ret);
	return (0);
}
static int make_disks ( zpool_handle_t * zhp , nvlist_t * nv ) { nvlist_t * * child ; uint_t c , children ; char * type , * path , * diskname ; char buf [ MAXPATHLEN ] ; uint64_t wholedisk ; int fd ; int ret ; ddi_devid_t devid ; char * minor = NULL , * devid_str = NULL ; verify ( nvlist_lookup_string ( nv , ZPOOL_CONFIG_TYPE , & type ) == 0 ) ; if ( nvlist_lookup_nvlist_array ( nv , ZPOOL_CONFIG_CHILDREN , & child , & children ) != 0 ) { if ( strcmp ( type , VDEV_TYPE_DISK ) != 0 ) return ( 0 ) ; verify ( nvlist_lookup_string ( nv , ZPOOL_CONFIG_PATH , & path ) == 0 ) ; if ( nvlist_lookup_uint64 ( nv , ZPOOL_CONFIG_WHOLE_DISK , & wholedisk ) != 0 || ! wholedisk ) return ( 0 ) ; diskname = strrchr ( path , ' ' ) ; assert ( diskname != NULL ) ; diskname ++ ; if ( zpool_label_disk ( g_zfs , zhp , diskname ) == -1 ) return ( -1 ) ; ( void ) snprintf ( buf , sizeof ( buf ) , " " , path ) ; if ( ( fd = open ( buf , O_RDONLY ) ) < 0 ) { ( void ) fprintf ( stderr , gettext ( " \n " ) , buf , strerror ( errno ) ) ; return ( -1 ) ; } if ( devid_get ( fd , & devid ) == 0 ) { if ( devid_get_minor_name ( fd , & minor ) == 0 && ( devid_str = devid_str_encode ( devid , minor ) ) != NULL ) { verify ( nvlist_add_string ( nv , ZPOOL_CONFIG_DEVID , devid_str ) == 0 ) ; } if ( devid_str != NULL ) devid_str_free ( devid_str ) ; if ( minor != NULL ) devid_str_free ( minor ) ; devid_free ( devid ) ; } verify ( nvlist_add_string ( nv , ZPOOL_CONFIG_PATH , buf ) == 0 ) ; ( void ) close ( fd ) ; return ( 0 ) ; } for ( c = 0 ; c < children ; c ++ ) if ( ( ret = make_disks ( zhp , child [ c ] ) ) != 0 ) return ( ret ) ; if ( nvlist_lookup_nvlist_array ( nv , ZPOOL_CONFIG_SPARES , & child , & children ) == 0 ) for ( c = 0 ; c < children ; c ++ ) if ( ( ret = make_disks ( zhp , child [ c ] ) ) != 0 ) return ( ret ) ; if ( nvlist_lookup_nvlist_array ( nv , ZPOOL_CONFIG_L2CACHE , & child , & children ) == 0 ) for ( c = 0 ; c < children ; c ++ ) if ( ( ret = make_disks ( zhp , child [ c ] ) ) != 0 ) return ( ret ) ; return ( 0 ) ; }
Go through and find any whole disks in the vdev specification, labelling them
 as appropriate.
Go through and find any whole disks in the vdev specification labelling them as appropriate .
/*
		 * We have a disk device.  Get the path to the device
		 * and see if it's a whole disk by appending the backup
		 * slice and stat()ing the device.
		 */ /*
		 * Fill in the devid, now that we've labeled the disk.
		 */ /*
		 * Update the path to refer to the 's0' slice.  The presence of
		 * the 'whole_disk' field indicates to the CLI that we should
		 * chop off the slice number when displaying the device in
		 * future output.
		 */