Exemplo n.º 1
0
/*
 * Handle a EC_DEV_ADD.ESC_DISK event.
 *
 * illumos
 *	Expects: DEV_PHYS_PATH string in schema
 *	Matches: vdev's ZPOOL_CONFIG_PHYS_PATH or ZPOOL_CONFIG_DEVID
 *
 *      path: '/dev/dsk/c0t1d0s0' (persistent)
 *     devid: 'id1,sd@SATA_____Hitachi_HDS72101______JP2940HZ3H74MC/a'
 * phys_path: '/pci@0,0/pci103c,1609@11/disk@1,0:a'
 *
 * linux
 *	provides: DEV_PHYS_PATH and DEV_IDENTIFIER strings in schema
 *	Matches: vdev's ZPOOL_CONFIG_PHYS_PATH or ZPOOL_CONFIG_DEVID
 *
 *      path: '/dev/sdc1' (not persistent)
 *     devid: 'ata-SAMSUNG_HD204UI_S2HGJD2Z805891-part1'
 * phys_path: 'pci-0000:04:00.0-sas-0x4433221106000000-lun-0'
 */
static int
zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
{
	char *devpath = NULL, *devid;
	boolean_t is_slice;

	/*
	 * Expecting a devid string and an optional physical location
	 */
	if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0)
		return (-1);

	(void) nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devpath);

	is_slice = (nvlist_lookup_boolean(nvl, DEV_IS_PART) == 0);

	zed_log_msg(LOG_INFO, "zfs_deliver_add: adding %s (%s) (is_slice %d)",
	    devid, devpath ? devpath : "NULL", is_slice);

	/*
	 * Iterate over all vdevs looking for a match in the folllowing order:
	 * 1. ZPOOL_CONFIG_DEVID (identifies the unique disk)
	 * 2. ZPOOL_CONFIG_PHYS_PATH (identifies disk physical location).
	 *
	 * For disks, we only want to pay attention to vdevs marked as whole
	 * disks or are a multipath device.
	 */
	if (!devid_iter(devid, zfs_process_add, is_slice) && devpath != NULL)
		(void) devphys_iter(devpath, devid, zfs_process_add, is_slice);

	return (0);
}
Exemplo n.º 2
0
/*
 * This function is called when we receive a devfs add event.  This can be
 * either a disk event or a lofi event, and the behavior is slightly different
 * depending on which it is.
 */
static int
zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
{
	char *devpath, *devname;
	char path[PATH_MAX], realpath[PATH_MAX];
	char *colon, *raw;
	int ret;

	/*
	 * The main unit of operation is the physical device path.  For disks,
	 * this is the device node, as all minor nodes are affected.  For lofi
	 * devices, this includes the minor path.  Unfortunately, this isn't
	 * represented in the DEV_PHYS_PATH for various reasons.
	 */
	if (nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devpath) != 0)
		return (-1);

	/*
	 * If this is a lofi device, then also get the minor instance name.
	 * Unfortunately, the current payload doesn't include an easy way to get
	 * this information.  So we cheat by resolving the 'dev_name' (which
	 * refers to the raw device) and taking the portion between ':(*),raw'.
	 */
	(void) strlcpy(realpath, devpath, sizeof (realpath));
	if (is_lofi) {
		if (nvlist_lookup_string(nvl, DEV_NAME,
		    &devname) == 0 &&
		    (ret = resolvepath(devname, path,
		    sizeof (path))) > 0) {
			path[ret] = '\0';
			colon = strchr(path, ':');
			if (colon != NULL)
				raw = strstr(colon + 1, ",raw");
			if (colon != NULL && raw != NULL) {
				*raw = '\0';
				(void) snprintf(realpath,
				    sizeof (realpath), "%s%s",
				    devpath, colon);
				*raw = ',';
			}
		}
	}

	/*
	 * Iterate over all vdevs with a matching devid, and then those with a
	 * matching /devices path.  For disks, we only want to pay attention to
	 * vdevs marked as whole disks.  For lofi, we don't care (because we're
	 * matching an exact minor name).
	 */
	if (!devid_iter(realpath, zfs_process_add, !is_lofi))
		(void) devpath_iter(realpath, zfs_process_add, !is_lofi);

	return (0);
}