extern int select_alias (struct multipath * mp) { if (mp->mpe && mp->mpe->alias) mp->alias = STRDUP(mp->mpe->alias); else { mp->alias = NULL; if (want_user_friendly_names(mp)) { select_alias_prefix(mp); mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); } if (mp->alias == NULL) mp->alias = dm_get_name(mp->wwid); if (mp->alias == NULL) mp->alias = STRDUP(mp->wwid); } return mp->alias ? 0 : 1; }
static char * get_device_name(dm_descriptor_t device, int *error) { char *dup = NULL; char *name; *error = 0; name = dm_get_name(device, error); if (*error) { handle_error("could not determine name of device"); } else { dup = strdup(name); if (dup == NULL) { handle_error("out of memory"); *error = -1; } dm_free_name(name); } return (dup); }
/* * Checks for overlapping slices. If the given device is a slice, and it * overlaps with any non-backup slice on the disk, return true with a detailed * description similar to dm_inuse(). */ int dm_isoverlapping(char *slicename, char **overlaps_with, int *errp) { dm_descriptor_t slice = NULL; dm_descriptor_t *media = NULL; dm_descriptor_t *slices = NULL; int i = 0; uint32_t in_snum; uint64_t start_block = 0; uint64_t end_block = 0; uint64_t media_size = 0; uint64_t size = 0; nvlist_t *media_attrs = NULL; nvlist_t *slice_attrs = NULL; int ret = 0; slice = dm_get_descriptor_by_name(DM_SLICE, slicename, errp); if (slice == NULL) goto out; /* * Get the list of slices be fetching the associated media, and then all * associated slices. */ media = dm_get_associated_descriptors(slice, DM_MEDIA, errp); if (media == NULL || *media == NULL || *errp != 0) goto out; slices = dm_get_associated_descriptors(*media, DM_SLICE, errp); if (slices == NULL || *slices == NULL || *errp != 0) goto out; media_attrs = dm_get_attributes(*media, errp); if (media_attrs == NULL || *errp) goto out; *errp = nvlist_lookup_uint64(media_attrs, DM_NACCESSIBLE, &media_size); if (*errp != 0) goto out; slice_attrs = dm_get_attributes(slice, errp); if (slice_attrs == NULL || *errp != 0) goto out; *errp = nvlist_lookup_uint64(slice_attrs, DM_START, &start_block); if (*errp != 0) goto out; *errp = nvlist_lookup_uint64(slice_attrs, DM_SIZE, &size); if (*errp != 0) goto out; *errp = nvlist_lookup_uint32(slice_attrs, DM_INDEX, &in_snum); if (*errp != 0) goto out; end_block = (start_block + size) - 1; for (i = 0; slices[i]; i ++) { uint64_t other_start; uint64_t other_end; uint64_t other_size; uint32_t snum; nvlist_t *other_attrs = dm_get_attributes(slices[i], errp); if (other_attrs == NULL) continue; if (*errp != 0) goto out; *errp = nvlist_lookup_uint64(other_attrs, DM_START, &other_start); if (*errp) { nvlist_free(other_attrs); goto out; } *errp = nvlist_lookup_uint64(other_attrs, DM_SIZE, &other_size); if (*errp) { nvlist_free(other_attrs); ret = -1; goto out; } other_end = (other_size + other_start) - 1; *errp = nvlist_lookup_uint32(other_attrs, DM_INDEX, &snum); if (*errp) { nvlist_free(other_attrs); ret = -1; goto out; } /* * Check to see if there are > 2 overlapping regions * on this media in the same region as this slice. * This is done by assuming the following: * Slice 2 is the backup slice if it is the size * of the whole disk * If slice 2 is the overlap and slice 2 is the size of * the whole disk, continue. If another slice is found * that overlaps with our slice, return it. * There is the potential that there is more than one slice * that our slice overlaps with, however, we only return * the first overlapping slice we find. * */ if (start_block >= other_start && start_block <= other_end) { if ((snum == 2 && (other_size == media_size)) || snum == in_snum) { continue; } else { char *str = dm_get_name(slices[i], errp); if (*errp != 0) { nvlist_free(other_attrs); ret = -1; goto out; } *overlaps_with = strdup(str); dm_free_name(str); nvlist_free(other_attrs); ret = 1; goto out; } } else if (other_start >= start_block && other_start <= end_block) { if ((snum == 2 && (other_size == media_size)) || snum == in_snum) { continue; } else { char *str = dm_get_name(slices[i], errp); if (*errp != 0) { nvlist_free(other_attrs); ret = -1; goto out; } *overlaps_with = strdup(str); dm_free_name(str); nvlist_free(other_attrs); ret = 1; goto out; } } nvlist_free(other_attrs); } out: if (media_attrs) nvlist_free(media_attrs); if (slice_attrs) nvlist_free(slice_attrs); if (slices) dm_free_descriptors(slices); if (media) dm_free_descriptors(media); if (slice) dm_free_descriptor(slice); return (ret); }
/* ARGSUSED */ int check_disk(const char *name, dm_descriptor_t disk, int force, int isspare) { dm_descriptor_t *drive, *media, *slice; int err = 0; int i; int ret; /* * Get the drive associated with this disk. This should never fail, * because we already have an alias handle open for the device. */ if ((drive = dm_get_associated_descriptors(disk, DM_DRIVE, &err)) == NULL || *drive == NULL) { if (err) libdiskmgt_error(err); return (0); } if ((media = dm_get_associated_descriptors(*drive, DM_MEDIA, &err)) == NULL) { dm_free_descriptors(drive); if (err) libdiskmgt_error(err); return (0); } dm_free_descriptors(drive); /* * It is possible that the user has specified a removable media drive, * and the media is not present. */ if (*media == NULL) { dm_free_descriptors(media); vdev_error(gettext("'%s' has no media in drive\n"), name); return (-1); } if ((slice = dm_get_associated_descriptors(*media, DM_SLICE, &err)) == NULL) { dm_free_descriptors(media); if (err) libdiskmgt_error(err); return (0); } dm_free_descriptors(media); ret = 0; /* * Iterate over all slices and report any errors. We don't care about * overlapping slices because we are using the whole disk. */ for (i = 0; slice[i] != NULL; i++) { char *name = dm_get_name(slice[i], &err); if (check_slice(name, force, B_TRUE, isspare) != 0) ret = -1; dm_free_name(name); } dm_free_descriptors(slice); return (ret); }