diff options
author | Toomas Soome <tsoome@me.com> | 2017-02-07 00:40:29 +0200 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2018-06-01 17:19:41 +0000 |
commit | fe12dc752b42da16028a16f4226e5295506fdb28 (patch) | |
tree | b35ccf170aa71b8ae14b63e5cf117aa74f5957ba /usr/src/lib/libdiskmgt/common/slice.c | |
parent | e53a4a814812099ec255c98f18f7ae1d0639ae57 (diff) | |
download | illumos-joyent-fe12dc752b42da16028a16f4226e5295506fdb28.tar.gz |
9529 libefi: efi_alloc_and_read should check for PMBR
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src/lib/libdiskmgt/common/slice.c')
-rw-r--r-- | usr/src/lib/libdiskmgt/common/slice.c | 555 |
1 files changed, 281 insertions, 274 deletions
diff --git a/usr/src/lib/libdiskmgt/common/slice.c b/usr/src/lib/libdiskmgt/common/slice.c index 311b8285e6..979145f9eb 100644 --- a/usr/src/lib/libdiskmgt/common/slice.c +++ b/usr/src/lib/libdiskmgt/common/slice.c @@ -83,15 +83,15 @@ slice_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, int *errp) { if (!desc_ok(desc)) { - *errp = ENODEV; - return (NULL); + *errp = ENODEV; + return (NULL); } switch (type) { case DM_MEDIA: - return (media_get_assocs(desc, errp)); + return (media_get_assocs(desc, errp)); case DM_PARTITION: - return (partition_get_assocs(desc, errp)); + return (partition_get_assocs(desc, errp)); } *errp = EINVAL; @@ -109,8 +109,8 @@ slice_get_assocs(descriptor_t *desc, int *errp) { /* Just check the first drive name. */ if (desc->p.disk->aliases == NULL) { - *errp = 0; - return (libdiskmgt_empty_desc_array(errp)); + *errp = 0; + return (libdiskmgt_empty_desc_array(errp)); } return (get_fixed_assocs(desc, errp)); @@ -124,13 +124,13 @@ slice_get_attributes(descriptor_t *dp, int *errp) char devpath[MAXPATHLEN]; if (!desc_ok(dp)) { - *errp = ENODEV; - return (NULL); + *errp = ENODEV; + return (NULL); } if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) { - *errp = ENOMEM; - return (NULL); + *errp = ENOMEM; + return (NULL); } /* dp->name is /dev/dsk, need to convert back to /dev/rdsk */ @@ -138,12 +138,12 @@ slice_get_attributes(descriptor_t *dp, int *errp) fd = open(devpath, O_RDONLY|O_NDELAY); if ((*errp = get_attrs(dp, fd, attrs)) != 0) { - nvlist_free(attrs); - attrs = NULL; + nvlist_free(attrs); + attrs = NULL; } if (fd >= 0) { - (void) close(fd); + (void) close(fd); } return (attrs); @@ -165,7 +165,7 @@ slice_get_descriptor_by_name(char *name, int *errp) char mname[MAXPATHLEN]; if (*errp != 0) { - return (NULL); + return (NULL); } mname[0] = 0; @@ -199,15 +199,15 @@ slice_get_stats(descriptor_t *dp, int stat_type, int *errp) nvlist_t *stats; if (stat_type != DM_SLICE_STAT_USE) { - *errp = EINVAL; - return (NULL); + *errp = EINVAL; + return (NULL); } *errp = 0; if (nvlist_alloc(&stats, NVATTRS_STAT, 0) != 0) { - *errp = ENOMEM; - return (NULL); + *errp = ENOMEM; + return (NULL); } if ((*errp = add_inuse(dp->name, stats)) != 0) { @@ -229,14 +229,14 @@ slice_make_descriptors() dp = cache_get_disklist(); while (dp != NULL) { - int error; + int error; - error = make_fixed_descriptors(dp); - if (error != 0) { - return (error); - } + error = make_fixed_descriptors(dp); + if (error != 0) { + return (error); + } - dp = dp->next; + dp = dp->next; } return (0); @@ -251,18 +251,18 @@ slice_rdsk2dsk(char *rdsk, char *dsk, int size) (void) strlcpy(dsk, rdsk, size); if ((strp = strstr(dsk, "/rdsk/")) == NULL) { - /* not rdsk, check for floppy */ - strp = strstr(dsk, "/rdiskette"); + /* not rdsk, check for floppy */ + strp = strstr(dsk, "/rdiskette"); } if (strp != NULL) { - strp++; /* move ptr to the r in rdsk or rdiskette */ + strp++; /* move ptr to the r in rdsk or rdiskette */ - /* move the succeeding chars over by one */ - do { - *strp = *(strp + 1); - strp++; - } while (*strp); + /* move the succeeding chars over by one */ + do { + *strp = *(strp + 1); + strp++; + } while (*strp); } } @@ -276,12 +276,12 @@ add_inuse(char *name, nvlist_t *attrs) int error; for (i = 0; detectors[i] != NULL; i ++) { - if (detectors[i](name, attrs, &error) || error != 0) { - if (error != 0) { - return (error); + if (detectors[i](name, attrs, &error) || error != 0) { + if (error != 0) { + return (error); + } + break; } - break; - } } return (0); @@ -293,17 +293,17 @@ desc_ok(descriptor_t *dp) { /* First verify the media name for removable media */ if (dp->p.disk->removable) { - char mname[MAXPATHLEN]; + char mname[MAXPATHLEN]; - if (!media_read_name(dp->p.disk, mname, sizeof (mname))) { - return (0); - } + if (!media_read_name(dp->p.disk, mname, sizeof (mname))) { + return (0); + } - if (mname[0] == 0) { - return (libdiskmgt_str_eq(dp->secondary_name, NULL)); - } else { - return (libdiskmgt_str_eq(dp->secondary_name, mname)); - } + if (mname[0] == 0) { + return (libdiskmgt_str_eq(dp->secondary_name, NULL)); + } else { + return (libdiskmgt_str_eq(dp->secondary_name, mname)); + } } /* @@ -326,25 +326,25 @@ dsk2rdsk(char *dsk, char *rdsk, int size) /* make sure there is enough room to add the r to dsk */ len = strlen(dsk); if (len + 2 > size) { - return; + return; } if ((slashp = strstr(rdsk, "/dsk/")) == NULL) { - /* not dsk, check for floppy */ - slashp = strstr(rdsk, "/diskette"); + /* not dsk, check for floppy */ + slashp = strstr(rdsk, "/diskette"); } if (slashp != NULL) { - char *endp; + char *endp; - endp = rdsk + len; /* point to terminating 0 */ - /* move the succeeding chars over by one */ - do { - *(endp + 1) = *endp; - endp--; - } while (endp != slashp); + endp = rdsk + len; /* point to terminating 0 */ + /* move the succeeding chars over by one */ + do { + *(endp + 1) = *endp; + endp--; + } while (endp != slashp); - *(endp + 1) = 'r'; + *(endp + 1) = 'r'; } } @@ -363,114 +363,113 @@ get_attrs(descriptor_t *dp, int fd, nvlist_t *attrs) struct stat buf; if (fd < 0) { - return (ENODEV); + return (ENODEV); } /* First make sure media is inserted and spun up. */ if (!media_read_info(fd, &minfo)) { - return (ENODEV); + return (ENODEV); } if ((status = read_extvtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; + data_format = FMT_VTOC; } else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; - if (nvlist_add_boolean(attrs, DM_EFI) != 0) { - efi_free(efip); - return (ENOMEM); - } + data_format = FMT_EFI; + if (nvlist_add_boolean(attrs, DM_EFI) != 0) { + efi_free(efip); + return (ENOMEM); + } } if (data_format == FMT_UNKNOWN) { - return (ENODEV); + return (ENODEV); } if (ioctl(fd, DKIOCINFO, &dkinfo) >= 0) { - snum = dkinfo.dki_partition; + snum = dkinfo.dki_partition; } /* check the slice */ if (data_format == FMT_VTOC) { - if (snum < 0 || snum >= vtoc.v_nparts || - vtoc.v_part[snum].p_size == 0) { - return (ENODEV); - } + if (snum < 0 || snum >= vtoc.v_nparts || + vtoc.v_part[snum].p_size == 0) { + return (ENODEV); + } } else { /* data_format == FMT_EFI */ - if (snum < 0 || snum >= efip->efi_nparts || - efip->efi_parts[snum].p_size == 0) { - efi_free(efip); - return (ENODEV); - } + if (snum < 0 || snum >= efip->efi_nparts || + efip->efi_parts[snum].p_size == 0) { + efi_free(efip); + return (ENODEV); + } } /* the slice exists */ if (nvlist_add_uint32(attrs, DM_INDEX, snum) != 0) { - if (data_format == FMT_EFI) { - efi_free(efip); - } - return (ENOMEM); + if (data_format == FMT_EFI) { + efi_free(efip); + } + return (ENOMEM); } if (data_format == FMT_VTOC) { - if (nvlist_add_uint64(attrs, DM_START, vtoc.v_part[snum].p_start) - != 0) { - return (ENOMEM); - } - - if (nvlist_add_uint64(attrs, DM_SIZE, vtoc.v_part[snum].p_size) - != 0) { - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_START, + vtoc.v_part[snum].p_start) != 0) { + return (ENOMEM); + } - if (nvlist_add_uint32(attrs, DM_TAG, vtoc.v_part[snum].p_tag) - != 0) { - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_SIZE, + vtoc.v_part[snum].p_size) != 0) { + return (ENOMEM); + } - if (nvlist_add_uint32(attrs, DM_FLAG, vtoc.v_part[snum].p_flag) - != 0) { - return (ENOMEM); - } + if (nvlist_add_uint32(attrs, DM_TAG, + vtoc.v_part[snum].p_tag) != 0) { + return (ENOMEM); + } + if (nvlist_add_uint32(attrs, DM_FLAG, + vtoc.v_part[snum].p_flag) != 0) { + return (ENOMEM); + } } else { /* data_format == FMT_EFI */ - if (nvlist_add_uint64(attrs, DM_START, - efip->efi_parts[snum].p_start) != 0) { - efi_free(efip); - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_START, + efip->efi_parts[snum].p_start) != 0) { + efi_free(efip); + return (ENOMEM); + } - if (nvlist_add_uint64(attrs, DM_SIZE, efip->efi_parts[snum].p_size) - != 0) { - efi_free(efip); - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_SIZE, + efip->efi_parts[snum].p_size) != 0) { + efi_free(efip); + return (ENOMEM); + } - if (efip->efi_parts[snum].p_name[0] != 0) { - char label[EFI_PART_NAME_LEN + 1]; + if (efip->efi_parts[snum].p_name[0] != 0) { + char label[EFI_PART_NAME_LEN + 1]; - (void) snprintf(label, sizeof (label), "%.*s", - EFI_PART_NAME_LEN, efip->efi_parts[snum].p_name); - if (nvlist_add_string(attrs, DM_EFI_NAME, label) != 0) { - efi_free(efip); - return (ENOMEM); + (void) snprintf(label, sizeof (label), "%.*s", + EFI_PART_NAME_LEN, efip->efi_parts[snum].p_name); + if (nvlist_add_string(attrs, DM_EFI_NAME, label) != 0) { + efi_free(efip); + return (ENOMEM); + } } - } } if (data_format == FMT_EFI) { - efi_free(efip); + efi_free(efip); } if (inuse_mnt(dp->name, attrs, &error)) { - if (error != 0) - return (error); + if (error != 0) + return (error); } if (fstat(fd, &buf) != -1) { - if (nvlist_add_uint64(attrs, DM_DEVT, buf.st_rdev) != 0) { - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_DEVT, buf.st_rdev) != 0) { + return (ENOMEM); + } } /* @@ -480,33 +479,34 @@ get_attrs(descriptor_t *dp, int fd, nvlist_t *attrs) cooked_fd = open(dp->name, O_RDONLY|O_NDELAY); if (cooked_fd >= 0) { - int no_mem = 0; - ddi_devid_t devid; + int no_mem = 0; + ddi_devid_t devid; - if (devid_get(cooked_fd, &devid) == 0) { - char *minor; + if (devid_get(cooked_fd, &devid) == 0) { + char *minor; - if (devid_get_minor_name(cooked_fd, &minor) == 0) { - char *devidstr; + if (devid_get_minor_name(cooked_fd, &minor) == 0) { + char *devidstr; - if ((devidstr = devid_str_encode(devid, minor)) != 0) { + devidstr = devid_str_encode(devid, minor); + if (devidstr != NULL) { - if (nvlist_add_string(attrs, DM_DEVICEID, devidstr) - != 0) { - no_mem = 1; - } + if (nvlist_add_string(attrs, + DM_DEVICEID, devidstr) != 0) { + no_mem = 1; + } - devid_str_free(devidstr); - } - devid_str_free(minor); + devid_str_free(devidstr); + } + devid_str_free(minor); + } + devid_free(devid); } - devid_free(devid); - } - (void) close(cooked_fd); + (void) close(cooked_fd); - if (no_mem) { - return (ENOMEM); - } + if (no_mem) { + return (ENOMEM); + } } return (0); @@ -527,84 +527,85 @@ get_fixed_assocs(descriptor_t *desc, int *errp) descriptor_t **slices; if ((fd = drive_open_disk(desc->p.disk, NULL, 0)) < 0) { - *errp = ENODEV; - return (NULL); + *errp = ENODEV; + return (NULL); } if ((status = read_extvtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; + data_format = FMT_VTOC; } else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; + data_format = FMT_EFI; } else { - (void) close(fd); - *errp = 0; - return (libdiskmgt_empty_desc_array(errp)); + (void) close(fd); + *errp = 0; + return (libdiskmgt_empty_desc_array(errp)); } (void) close(fd); /* count the number of slices */ - for (cnt = 0, devp = desc->p.disk->aliases->devpaths; devp != NULL; - devp = devp->next, cnt++); + devp = desc->p.disk->aliases->devpaths; + for (cnt = 0; devp != NULL; devp = devp->next) + cnt++; /* allocate the array for the descriptors */ slices = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *)); if (slices == NULL) { - if (data_format == FMT_EFI) { - efi_free(efip); - } - *errp = ENOMEM; - return (NULL); + if (data_format == FMT_EFI) { + efi_free(efip); + } + *errp = ENOMEM; + return (NULL); } /* get the media name from the descriptor */ if (desc->type == DM_MEDIA) { - media_name = desc->name; + media_name = desc->name; } else { - /* must be a DM_PARTITION */ - media_name = desc->secondary_name; + /* must be a DM_PARTITION */ + media_name = desc->secondary_name; } pos = 0; for (devp = desc->p.disk->aliases->devpaths; devp != NULL; devp = devp->next) { - int slice_num; - char devpath[MAXPATHLEN]; - - slice_num = get_slice_num(devp); - /* can't get slicenum, so no need to keep trying the drive */ - if (slice_num == -1) { - break; - } + int slice_num; + char devpath[MAXPATHLEN]; - if (data_format == FMT_VTOC) { - if (slice_num >= vtoc.v_nparts || - vtoc.v_part[slice_num].p_size == 0) { - continue; + slice_num = get_slice_num(devp); + /* can't get slicenum, so no need to keep trying the drive */ + if (slice_num == -1) { + break; } - } else { /* data_format == FMT_EFI */ - if (slice_num >= efip->efi_nparts || - efip->efi_parts[slice_num].p_size == 0) { - continue; + + if (data_format == FMT_VTOC) { + if (slice_num >= vtoc.v_nparts || + vtoc.v_part[slice_num].p_size == 0) { + continue; + } + } else { /* data_format == FMT_EFI */ + if (slice_num >= efip->efi_nparts || + efip->efi_parts[slice_num].p_size == 0) { + continue; + } } - } - slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath)); - slices[pos] = cache_get_desc(DM_SLICE, desc->p.disk, devpath, - media_name, errp); - if (*errp != 0) { - cache_free_descriptors(slices); - if (data_format == FMT_EFI) { - efi_free(efip); + slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath)); + slices[pos] = cache_get_desc(DM_SLICE, desc->p.disk, devpath, + media_name, errp); + if (*errp != 0) { + cache_free_descriptors(slices); + if (data_format == FMT_EFI) { + efi_free(efip); + } + return (NULL); } - return (NULL); - } - pos++; + pos++; } slices[pos] = NULL; if (data_format == FMT_EFI) { - efi_free(efip); + efi_free(efip); } *errp = 0; @@ -616,15 +617,15 @@ get_slice_num(slice_t *devp) { /* check if we already determined the devpath slice number */ if (devp->slice_num == -1) { - int fd; + int fd; - if ((fd = open(devp->devpath, O_RDONLY|O_NDELAY)) >= 0) { - struct dk_cinfo dkinfo; - if (ioctl(fd, DKIOCINFO, &dkinfo) >= 0) { - devp->slice_num = dkinfo.dki_partition; + if ((fd = open(devp->devpath, O_RDONLY|O_NDELAY)) >= 0) { + struct dk_cinfo dkinfo; + if (ioctl(fd, DKIOCINFO, &dkinfo) >= 0) { + devp->slice_num = dkinfo.dki_partition; + } + (void) close(fd); } - (void) close(fd); - } } return (devp->slice_num); @@ -643,63 +644,63 @@ make_fixed_descriptors(disk_t *dp) /* Just check the first drive name. */ if ((ap = dp->aliases) == NULL) { - return (0); + return (0); } mname[0] = 0; (void) media_read_name(dp, mname, sizeof (mname)); for (devp = ap->devpaths; devp != NULL; devp = devp->next) { - int slice_num; - char devpath[MAXPATHLEN]; - - slice_num = get_slice_num(devp); - /* can't get slicenum, so no need to keep trying the drive */ - if (slice_num == -1) { - break; - } - - if (data_format == FMT_UNKNOWN) { - int fd; - int status; - - if ((fd = drive_open_disk(dp, NULL, 0)) >= 0) { - if ((status = read_extvtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; - } else if (status == VT_ENOTSUP && - efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; - } - (void) close(fd); + int slice_num; + char devpath[MAXPATHLEN]; + + slice_num = get_slice_num(devp); + /* can't get slicenum, so no need to keep trying the drive */ + if (slice_num == -1) { + break; } - } - /* can't get slice data, so no need to keep trying the drive */ - if (data_format == FMT_UNKNOWN) { - break; - } + if (data_format == FMT_UNKNOWN) { + int fd; + int status; + + if ((fd = drive_open_disk(dp, NULL, 0)) >= 0) { + if ((status = read_extvtoc(fd, &vtoc)) >= 0) { + data_format = FMT_VTOC; + } else if (status == VT_ENOTSUP && + efi_alloc_and_read(fd, &efip) >= 0) { + data_format = FMT_EFI; + } + (void) close(fd); + } + } - if (data_format == FMT_VTOC) { - if (slice_num >= vtoc.v_nparts || - vtoc.v_part[slice_num].p_size == 0) { - continue; + /* can't get slice data, so no need to keep trying the drive */ + if (data_format == FMT_UNKNOWN) { + break; } - } else { /* data_format == FMT_EFI */ - if (slice_num >= efip->efi_nparts || - efip->efi_parts[slice_num].p_size == 0) { - continue; + + if (data_format == FMT_VTOC) { + if (slice_num >= vtoc.v_nparts || + vtoc.v_part[slice_num].p_size == 0) { + continue; + } + } else { /* data_format == FMT_EFI */ + if (slice_num >= efip->efi_nparts || + efip->efi_parts[slice_num].p_size == 0) { + continue; + } } - } - slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath)); - cache_load_desc(DM_SLICE, dp, devpath, mname, &error); - if (error != 0) { - break; - } + slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath)); + cache_load_desc(DM_SLICE, dp, devpath, mname, &error); + if (error != 0) { + break; + } } if (data_format == FMT_EFI) { - efi_free(efip); + efi_free(efip); } return (error); @@ -723,32 +724,32 @@ match_fixed_name(disk_t *diskp, char *name, int *errp) ap = diskp->aliases; while (ap != NULL) { - slice_t *devp; + slice_t *devp; - devp = ap->devpaths; - while (devp != NULL) { - char path[MAXPATHLEN]; + devp = ap->devpaths; + while (devp != NULL) { + char path[MAXPATHLEN]; - slice_rdsk2dsk(devp->devpath, path, sizeof (path)); - if (libdiskmgt_str_eq(path, name)) { - /* found it */ - dp = devp; - break; - } + slice_rdsk2dsk(devp->devpath, path, sizeof (path)); + if (libdiskmgt_str_eq(path, name)) { + /* found it */ + dp = devp; + break; + } - devp = devp->next; - } + devp = devp->next; + } - if (dp != NULL) { - break; - } + if (dp != NULL) { + break; + } - ap = ap->next; + ap = ap->next; } if (dp == NULL) { - *errp = 0; - return (0); + *errp = 0; + return (0); } /* @@ -759,40 +760,46 @@ match_fixed_name(disk_t *diskp, char *name, int *errp) slice_num = get_slice_num(dp); /* can't get slicenum, so no slice */ if (slice_num == -1) { - *errp = ENODEV; - return (1); + *errp = ENODEV; + return (1); } if ((fd = drive_open_disk(diskp, NULL, 0)) < 0) { - *errp = ENODEV; - return (1); + *errp = ENODEV; + return (1); } if ((status = read_extvtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; - } else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; + data_format = FMT_VTOC; + } else if (status == VT_ENOTSUP) { + status = efi_alloc_and_read(fd, &efip); + if (status >= 0) { + data_format = FMT_EFI; + } else if (status == VT_ERROR && errno == ENOTTY) { + *errp = 0; + return (1); + } } else { - (void) close(fd); - *errp = ENODEV; - return (1); + (void) close(fd); + *errp = ENODEV; + return (1); } (void) close(fd); if (data_format == FMT_VTOC) { - if (slice_num < vtoc.v_nparts && - vtoc.v_part[slice_num].p_size > 0) { - *errp = 0; - return (1); - } + if (slice_num < vtoc.v_nparts && + vtoc.v_part[slice_num].p_size > 0) { + *errp = 0; + return (1); + } } else { /* data_format == FMT_EFI */ - if (slice_num < efip->efi_nparts && - efip->efi_parts[slice_num].p_size > 0) { + if (slice_num < efip->efi_nparts && + efip->efi_parts[slice_num].p_size > 0) { + efi_free(efip); + *errp = 0; + return (1); + } efi_free(efip); - *errp = 0; - return (1); - } - efi_free(efip); } *errp = ENODEV; |