/* * 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); }
/* returns B_TRUE if the entry exists */ boolean_t fnvlist_lookup_boolean(nvlist_t *nvl, const char *name) { return (nvlist_lookup_boolean(nvl, name) == 0); }
/* * Set the properties of the disk node, from dev_di_node_t data. * Properties include: * group: protocol properties: resource, asru, label, fru * group: authority properties: product-id, chasis-id, server-id * group: io properties: devfs-path, devid * group: storage properties: * - logical-disk, disk-model, disk-manufacturer, serial-number * - firmware-revision, capacity-in-bytes * * NOTE: the io and storage groups won't be present if the dnode passed in is * NULL. This happens when a disk is found through ses, but is not enumerated * in the devinfo tree. */ static int disk_set_props(topo_mod_t *mod, tnode_t *parent, tnode_t *dtn, dev_di_node_t *dnode) { nvlist_t *asru = NULL, *drive_attrs; char *label = NULL; nvlist_t *fmri = NULL; dm_descriptor_t drive_descr = NULL; uint32_t rpm; int err; /* pull the label property down from our parent 'bay' node */ if (topo_node_label(parent, &label, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "label error %s\n", topo_strerror(err)); goto error; } if (topo_node_label_set(dtn, label, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "label_set error %s\n", topo_strerror(err)); goto error; } /* get the resource fmri, and use it as the fru */ if (topo_node_resource(dtn, &fmri, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "resource error: %s\n", topo_strerror(err)); goto error; } if (topo_node_fru_set(dtn, fmri, 0, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "fru_set error: %s\n", topo_strerror(err)); goto error; } /* create/set the authority group */ if ((topo_pgroup_create(dtn, &disk_auth_pgroup, &err) != 0) && (err != ETOPO_PROP_DEFD)) { topo_mod_dprintf(mod, "disk_set_props: " "create disk_auth error %s\n", topo_strerror(err)); goto error; } /* create the storage group */ if (topo_pgroup_create(dtn, &storage_pgroup, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "create storage error %s\n", topo_strerror(err)); goto error; } /* no dnode was found for this disk - skip the io and storage groups */ if (dnode == NULL) { err = 0; goto out; } /* form and set the asru */ if ((asru = topo_mod_devfmri(mod, FM_DEV_SCHEME_VERSION, dnode->ddn_dpath, dnode->ddn_devid)) == NULL) { err = ETOPO_FMRI_UNKNOWN; topo_mod_dprintf(mod, "disk_set_props: " "asru error %s\n", topo_strerror(err)); goto error; } if (topo_node_asru_set(dtn, asru, 0, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "asru_set error %s\n", topo_strerror(err)); goto error; } /* create/set the devfs-path and devid in the io group */ if (topo_pgroup_create(dtn, &io_pgroup, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "create io error %s\n", topo_strerror(err)); goto error; } if (topo_prop_set_string(dtn, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH, TOPO_PROP_IMMUTABLE, dnode->ddn_dpath, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set dev error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_devid && topo_prop_set_string(dtn, TOPO_PGROUP_IO, TOPO_IO_DEVID, TOPO_PROP_IMMUTABLE, dnode->ddn_devid, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set devid error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_ppath_count != 0 && topo_prop_set_string_array(dtn, TOPO_PGROUP_IO, TOPO_IO_PHYS_PATH, TOPO_PROP_IMMUTABLE, (const char **)dnode->ddn_ppath, dnode->ddn_ppath_count, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set phys-path error %s\n", topo_strerror(err)); goto error; } /* set the storage group public /dev name */ if (dnode->ddn_lpath != NULL && topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_LOGICAL_DISK_NAME, TOPO_PROP_IMMUTABLE, dnode->ddn_lpath, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set disk_name error %s\n", topo_strerror(err)); goto error; } /* populate other misc storage group properties */ if (dnode->ddn_mfg && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_MANUFACTURER, TOPO_PROP_IMMUTABLE, dnode->ddn_mfg, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set mfg error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_model && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_MODEL, TOPO_PROP_IMMUTABLE, dnode->ddn_model, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set model error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_serial && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_SERIAL_NUM, TOPO_PROP_IMMUTABLE, dnode->ddn_serial, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set serial error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_firm && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_FIRMWARE_REV, TOPO_PROP_IMMUTABLE, dnode->ddn_firm, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set firm error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_cap && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_CAPACITY, TOPO_PROP_IMMUTABLE, dnode->ddn_cap, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set cap error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_devid == NULL || (drive_descr = dm_get_descriptor_by_name(DM_DRIVE, dnode->ddn_devid, &err)) == NULL || (drive_attrs = dm_get_attributes(drive_descr, &err)) == NULL) goto out; if (nvlist_lookup_boolean(drive_attrs, DM_SOLIDSTATE) == 0 || nvlist_lookup_uint32(drive_attrs, DM_RPM, &rpm) != 0) goto out; if (topo_prop_set_uint32(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_RPM, TOPO_PROP_IMMUTABLE, rpm, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set rpm error %s\n", topo_strerror(err)); dm_free_descriptor(drive_descr); goto error; } err = 0; out: if (drive_descr != NULL) dm_free_descriptor(drive_descr); nvlist_free(fmri); if (label) topo_mod_strfree(mod, label); nvlist_free(asru); return (err); error: err = topo_mod_seterrno(mod, err); goto out; }