diff options
author | Hans Rosenfeld <hans.rosenfeld@nexenta.com> | 2015-06-27 12:16:04 +0200 |
---|---|---|
committer | Hans Rosenfeld <hans.rosenfeld@nexenta.com> | 2015-11-05 17:59:02 +0100 |
commit | f1bf06561684fdb7e38b282b7a4508d35a50985b (patch) | |
tree | 0f3c02d23fc539d6244c08a04fd803272882a5a0 | |
parent | 510a68476ba6e33759b7603130d76db4cec783d1 (diff) | |
download | illumos-joyent-f1bf06561684fdb7e38b282b7a4508d35a50985b.tar.gz |
6301 format(1M) should be able to use device inquiry properties
Reviewed by: Dan McDonald <danmcd@omniti.com>
-rw-r--r-- | usr/src/cmd/format/Makefile | 4 | ||||
-rw-r--r-- | usr/src/cmd/format/auto_sense.c | 62 | ||||
-rw-r--r-- | usr/src/cmd/format/hardware_structs.h | 13 | ||||
-rw-r--r-- | usr/src/cmd/format/io.c | 31 | ||||
-rw-r--r-- | usr/src/cmd/format/label.c | 184 | ||||
-rw-r--r-- | usr/src/cmd/format/label.h | 22 | ||||
-rw-r--r-- | usr/src/cmd/format/menu_command.c | 9 | ||||
-rw-r--r-- | usr/src/cmd/format/startup.c | 46 |
8 files changed, 258 insertions, 113 deletions
diff --git a/usr/src/cmd/format/Makefile b/usr/src/cmd/format/Makefile index f04050cd7c..34f25b7cc2 100644 --- a/usr/src/cmd/format/Makefile +++ b/usr/src/cmd/format/Makefile @@ -22,6 +22,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# PROG= format @@ -58,7 +60,7 @@ $(ROOTETCDATA) := FILEMODE = 0644 LDLIBS_i386= -lfdisk LDLIBS_sparc= -LDLIBS += -ladm -lefi -ldiskmgt -lnvpair -ldevid $(LDLIBS_$(MACH)) +LDLIBS += -ladm -lefi -ldiskmgt -lnvpair -ldevid -ldevinfo $(LDLIBS_$(MACH)) LINTFLAGS += -xerroff=E_NAME_DEF_NOT_USED2 CPPFLAGS += -D_EXTVTOC diff --git a/usr/src/cmd/format/auto_sense.c b/usr/src/cmd/format/auto_sense.c index 5f0f767bef..5ea76569ca 100644 --- a/usr/src/cmd/format/auto_sense.c +++ b/usr/src/cmd/format/auto_sense.c @@ -23,6 +23,7 @@ * * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* @@ -257,10 +258,27 @@ auto_efi_sense(int fd, struct efi_info *label) struct dk_cinfo dkinfo; struct partition_info *part; + if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { + if (option_msg && diag_msg) { + err_print("DKIOCINFO failed\n"); + } + return (NULL); + } + if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_DIRECT)) { + ctlr = find_direct_ctlr_info(&dkinfo); + disk_info = find_direct_disk_info(&dkinfo); + } else if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_VBD)) { + ctlr = find_vbd_ctlr_info(&dkinfo); + disk_info = find_vbd_disk_info(&dkinfo); + } else { + ctlr = find_scsi_ctlr_info(&dkinfo); + disk_info = find_scsi_disk_info(&dkinfo); + } + /* * get vendor, product, revision and capacity info. */ - if (get_disk_info(fd, label) == -1) { + if (get_disk_info(fd, label, disk_info) == -1) { return ((struct disk_type *)NULL); } /* @@ -304,22 +322,6 @@ auto_efi_sense(int fd, struct efi_info *label) * Now stick all of it into the disk_type struct */ - if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { - if (option_msg && diag_msg) { - err_print("DKIOCINFO failed\n"); - } - return (NULL); - } - if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_DIRECT)) { - ctlr = find_direct_ctlr_info(&dkinfo); - disk_info = find_direct_disk_info(&dkinfo); - } else if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_VBD)) { - ctlr = find_vbd_ctlr_info(&dkinfo); - disk_info = find_vbd_disk_info(&dkinfo); - } else { - ctlr = find_scsi_ctlr_info(&dkinfo); - disk_info = find_scsi_disk_info(&dkinfo); - } disk = (struct disk_type *)zalloc(sizeof (struct disk_type)); assert(disk_info->disk_ctlr == ctlr); dp = ctlr->ctlr_ctype->ctype_dlist; @@ -333,12 +335,20 @@ auto_efi_sense(int fd, struct efi_info *label) } disk->dtype_next = NULL; - (void) strlcpy(disk->vendor, label->vendor, - sizeof (disk->vendor)); - (void) strlcpy(disk->product, label->product, - sizeof (disk->product)); - (void) strlcpy(disk->revision, label->revision, - sizeof (disk->revision)); + disk->vendor = strdup(label->vendor); + disk->product = strdup(label->product); + disk->revision = strdup(label->revision); + + if (disk->vendor == NULL || + disk->product == NULL || + disk->revision == NULL) { + free(disk->vendor); + free(disk->product); + free(disk->revision); + free(disk); + return (NULL); + } + disk->capacity = label->capacity; part = (struct partition_info *) @@ -2022,6 +2032,9 @@ delete_disk_type( if (cur_label == L_TYPE_EFI) free(disk->dtype_plist->etoc); free(disk->dtype_plist); + free(disk->vendor); + free(disk->product); + free(disk->revision); free(disk); return (0); } else { @@ -2032,6 +2045,9 @@ delete_disk_type( if (cur_label == L_TYPE_EFI) free(dp->dtype_plist->etoc); free(dp->dtype_plist); + free(dp->vendor); + free(dp->product); + free(dp->revision); free(dp); return (0); } diff --git a/usr/src/cmd/format/hardware_structs.h b/usr/src/cmd/format/hardware_structs.h index 81bc40d202..76e6472039 100644 --- a/usr/src/cmd/format/hardware_structs.h +++ b/usr/src/cmd/format/hardware_structs.h @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ #ifndef _HARDWARE_STRUCTS_H @@ -111,16 +112,16 @@ struct disk_type { char *dtype_filename; /* filename where defined */ int dtype_lineno; /* line number in file */ - char vendor[9]; - char product[17]; - char revision[5]; + char *vendor; + char *product; + char *revision; uint64_t capacity; }; struct efi_info { - char vendor[9]; - char product[17]; - char revision[5]; + char *vendor; + char *product; + char *revision; uint64_t capacity; struct dk_gpt *e_parts; }; diff --git a/usr/src/cmd/format/io.c b/usr/src/cmd/format/io.c index 6e9e4064a9..e98589c5b8 100644 --- a/usr/src/cmd/format/io.c +++ b/usr/src/cmd/format/io.c @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* @@ -2514,15 +2515,18 @@ void print_efi_string(char *vendor, char *product, char *revision, uint64_t capacity) { - char new_vendor[9]; - char new_product[17]; - char new_revision[5]; + char *new_vendor; + char *new_product; + char *new_revision; char capacity_string[10]; float scaled; int i; /* Strip whitespace from the end of inquiry strings */ - (void) strlcpy(new_vendor, vendor, sizeof (new_vendor)); + new_vendor = strdup(vendor); + if (new_vendor == NULL) + return; + for (i = (strlen(new_vendor) - 1); i >= 0; i--) { if (new_vendor[i] != 0x20) { new_vendor[i+1] = '\0'; @@ -2530,7 +2534,12 @@ print_efi_string(char *vendor, char *product, char *revision, } } - (void) strlcpy(new_product, product, sizeof (new_product)); + new_product = strdup(product); + if (new_product == NULL) { + free(new_vendor); + return; + } + for (i = (strlen(new_product) - 1); i >= 0; i--) { if (new_product[i] != 0x20) { new_product[i+1] = '\0'; @@ -2538,7 +2547,13 @@ print_efi_string(char *vendor, char *product, char *revision, } } - (void) strlcpy(new_revision, revision, sizeof (new_revision)); + new_revision = strdup(revision); + if (new_product == NULL) { + free(new_vendor); + free(new_product); + return; + } + for (i = (strlen(new_revision) - 1); i >= 0; i--) { if (new_revision[i] != 0x20) { new_revision[i+1] = '\0'; @@ -2561,4 +2576,8 @@ print_efi_string(char *vendor, char *product, char *revision, fmt_print("<%s-%s-%s-%s>", new_vendor, new_product, new_revision, capacity_string); + + free(new_revision); + free(new_product); + free(new_vendor); } diff --git a/usr/src/cmd/format/label.c b/usr/src/cmd/format/label.c index 3da51d9cc7..f4fde20d68 100644 --- a/usr/src/cmd/format/label.c +++ b/usr/src/cmd/format/label.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* @@ -36,6 +37,7 @@ #include <sys/uuid.h> #include <errno.h> #include <devid.h> +#include <libdevinfo.h> #include "global.h" #include "label.h" #include "misc.h" @@ -496,14 +498,99 @@ read_label(int fd, struct dk_label *label) } int -get_disk_info_from_devid(int fd, struct efi_info *label) +get_disk_inquiry_prop(char *devpath, char **vid, char **pid, char **rid) +{ + char *v, *p, *r; + di_node_t node; + int ret = -1; + + node = di_init(devpath, DINFOCPYALL); + + if (node == DI_NODE_NIL) + goto out; + + if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, + "inquiry-vendor-id", &v) != 1) + goto out; + + if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, + "inquiry-product-id", &p) != 1) + goto out; + + if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, + "inquiry-revision-id", &r) != 1) + goto out; + + *vid = strdup(v); + *pid = strdup(p); + *rid = strdup(r); + + if (*vid == NULL || *pid == NULL || *rid == NULL) { + free(*vid); + free(*pid); + free(*rid); + goto out; + } + + ret = 0; + +out: + di_fini(node); + return (ret); +} + +int +get_disk_inquiry_uscsi(int fd, char **vid, char **pid, char **rid) +{ + struct scsi_inquiry inquiry; + + if (uscsi_inquiry(fd, (char *)&inquiry, sizeof (inquiry))) + return (-1); + + *vid = strndup(inquiry.inq_vid, 8); + *pid = strndup(inquiry.inq_pid, 16); + *rid = strndup(inquiry.inq_revision, 4); + + if (*vid == NULL || *pid == NULL || *rid == NULL) { + free(*vid); + free(*pid); + free(*rid); + return (-1); + } + + return (0); +} + +int +get_disk_capacity(int fd, uint64_t *capacity) +{ + struct dk_minfo minf; + struct scsi_capacity_16 cap16; + + if (ioctl(fd, DKIOCGMEDIAINFO, &minf) == 0) { + *capacity = minf.dki_capacity * minf.dki_lbsize / cur_blksz; + return (0); + } + + if (uscsi_read_capacity(fd, &cap16) == 0) { + *capacity = cap16.sc_capacity; + + /* Since we are counting from zero, add 1 to capacity */ + (*capacity)++; + + return (0); + } + + err_print("Fetch Capacity failed\n"); + return (-1); +} + +int +get_disk_inquiry_devid(int fd, char **vid, char **pid, char **rid) { ddi_devid_t devid; char *s; - int n; - char *vid, *pid; - int nvid, npid; - struct dk_minfo minf; + char *v, *p; struct dk_cinfo dkinfo; if (devid_get(fd, &devid)) { @@ -512,7 +599,6 @@ get_disk_info_from_devid(int fd, struct efi_info *label) return (-1); } - n = devid_sizeof(devid); s = (char *)devid; if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { @@ -524,31 +610,23 @@ get_disk_info_from_devid(int fd, struct efi_info *label) if (dkinfo.dki_ctype != DKC_DIRECT) return (-1); - vid = s+12; - if (!(pid = strchr(vid, '='))) + v = s+12; + if (!(p = strchr(v, '='))) return (-1); - nvid = pid - vid; - pid += 1; - npid = n - nvid - 13; - - if (nvid > 9) - nvid = 9; - if (npid > 17) { - pid = pid + npid - 17; - npid = 17; - } + p += 1; - if (ioctl(fd, DKIOCGMEDIAINFO, &minf) == -1) { - devid_free(devid); + *vid = strdup(v); + *pid = strdup(p); + *rid = strdup("0001"); + devid_free(devid); + + if (*vid == NULL || *pid == NULL || *rid == NULL) { + free(*vid); + free(*pid); + free(*rid); return (-1); } - (void) strlcpy(label->vendor, vid, nvid); - (void) strlcpy(label->product, pid, npid); - (void) strlcpy(label->revision, "0001", 5); - label->capacity = minf.dki_capacity * minf.dki_lbsize / 512; - - devid_free(devid); return (0); } @@ -558,44 +636,36 @@ get_disk_info_from_devid(int fd, struct efi_info *label) * Capacity information. */ int -get_disk_info(int fd, struct efi_info *label) +get_disk_info(int fd, struct efi_info *label, struct disk_info *disk_info) { - struct scsi_inquiry inquiry; - struct scsi_capacity_16 capacity; - struct dk_minfo minf; - - if (!get_disk_info_from_devid(fd, label)) - return (0); - - if (uscsi_inquiry(fd, (char *)&inquiry, sizeof (inquiry))) { - (void) strlcpy(label->vendor, "Unknown", 8); - (void) strlcpy(label->product, "Unknown", 8); - (void) strlcpy(label->revision, "0001", 5); - } else { - (void) strlcpy(label->vendor, inquiry.inq_vid, 9); - (void) strlcpy(label->product, inquiry.inq_pid, 17); - (void) strlcpy(label->revision, inquiry.inq_revision, 5); - } - - if (uscsi_read_capacity(fd, &capacity)) { - if (ioctl(fd, DKIOCGMEDIAINFO, &minf) == -1) { - err_print("Fetch Capacity failed\n"); - return (-1); + (void) get_disk_capacity(fd, &label->capacity); + + if (get_disk_inquiry_prop(disk_info->devfs_name, + &label->vendor, &label->product, &label->revision) != 0) { + if (get_disk_inquiry_devid(fd, &label->vendor, &label->product, + &label->revision) != 0) { + if (get_disk_inquiry_uscsi(fd, &label->vendor, + &label->product, &label->revision) != 0) { + label->vendor = strdup("Unknown"); + label->product = strdup("Unknown"); + label->revision = strdup("0001"); + if (label->vendor == NULL || + label->product == NULL || + label->revision == NULL) { + free(label->vendor); + free(label->product); + free(label->revision); + return (-1); + } + } } - label->capacity = - minf.dki_capacity * minf.dki_lbsize / cur_blksz; - } else { - label->capacity = capacity.sc_capacity; - - /* Since we are counting from zero, add 1 to capacity */ - label->capacity++; } return (0); } int -read_efi_label(int fd, struct efi_info *label) +read_efi_label(int fd, struct efi_info *label, struct disk_info *disk_info) { struct dk_gpt *vtoc64; @@ -608,7 +678,7 @@ read_efi_label(int fd, struct efi_info *label) return (-1); } efi_free(vtoc64); - if (get_disk_info(fd, label) != 0) { + if (get_disk_info(fd, label, disk_info) != 0) { return (-1); } return (0); diff --git a/usr/src/cmd/format/label.h b/usr/src/cmd/format/label.h index e7dbba9d36..d1be86c766 100644 --- a/usr/src/cmd/format/label.h +++ b/usr/src/cmd/format/label.h @@ -21,6 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LABEL_H @@ -33,17 +34,18 @@ extern "C" { /* * Prototypes for ANSI C compilers */ -int checklabel(struct dk_label *label); -int checksum(struct dk_label *label, int mode); -int trim_id(char *id); +int checklabel(struct dk_label *); +int checksum(struct dk_label *, int); +int trim_id(char *); int write_label(void); -int read_label(int fd, struct dk_label *label); -int read_efi_label(int fd, struct efi_info *label); -int get_disk_info(int fd, struct efi_info *label); -int label_to_vtoc(struct extvtoc *vtoc, struct dk_label *label); -int SMI_vtoc_to_EFI(int fd, struct dk_gpt **new_vtoc); -void err_check(struct dk_gpt *vtoc); -extern int is_efi_type(int fd); +int read_label(int, struct dk_label *); +int read_efi_label(int, struct efi_info *, struct disk_info *); +int get_disk_inquiry_prop(char *, char **, char **, char **); +int get_disk_info(int, struct efi_info *, struct disk_info *); +int label_to_vtoc(struct extvtoc *, struct dk_label *); +int SMI_vtoc_to_EFI(int, struct dk_gpt **); +void err_check(struct dk_gpt *); +extern int is_efi_type(int); #ifdef __cplusplus } diff --git a/usr/src/cmd/format/menu_command.c b/usr/src/cmd/format/menu_command.c index 0f5246a9c6..838813dde6 100644 --- a/usr/src/cmd/format/menu_command.c +++ b/usr/src/cmd/format/menu_command.c @@ -22,6 +22,7 @@ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. * Copyright 2014 Toomas Soome <tsoome@me.com> + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* @@ -1670,7 +1671,7 @@ c_label() } } - if (get_disk_info(cur_file, &efinfo) != 0) { + if (get_disk_info(cur_file, &efinfo, cur_disk) != 0) { return (-1); } (void) memset((char *)&label, 0, sizeof (struct dk_label)); @@ -2056,7 +2057,7 @@ c_verify_efi() struct partition_info tmp_pinfo; int status; - status = read_efi_label(cur_file, &efi_info); + status = read_efi_label(cur_file, &efi_info, cur_disk); if (status != 0) { err_print("Warning: Could not read label.\n"); return (-1); @@ -2086,6 +2087,10 @@ c_verify_efi() cur_parts->etoc->efi_last_u_lba); print_map(&tmp_pinfo); + + free(efi_info.vendor); + free(efi_info.product); + free(efi_info.revision); return (0); } diff --git a/usr/src/cmd/format/startup.c b/usr/src/cmd/format/startup.c index a75cb21cb4..ba71cd8bbc 100644 --- a/usr/src/cmd/format/startup.c +++ b/usr/src/cmd/format/startup.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * * Copyright (c) 2011 Gary Mills * @@ -150,7 +150,7 @@ static char **search_path = NULL; static int name_represents_wholedisk(char *name); -static void get_disk_name(int fd, char *disk_name); +static void get_disk_name(int fd, char *disk_name, struct disk_info *disk_info); /* * This routine digests the options on the command line. It returns @@ -1546,9 +1546,21 @@ search_for_logical_dev(char *devname) * Get the disk name from the inquiry data */ static void -get_disk_name(int fd, char *disk_name) +get_disk_name(int fd, char *disk_name, struct disk_info *disk_info) { struct scsi_inquiry inquiry; + char *vid, *pid, *rid; + + if (get_disk_inquiry_prop(disk_info->devfs_name, &vid, &pid, &rid) + == 0) { + (void) snprintf(disk_name, MAXNAMELEN - 1, "%s-%s-%s", + vid, pid, rid); + free(vid); + free(pid); + free(rid); + + return; + } if (uscsi_inquiry(fd, (char *)&inquiry, sizeof (inquiry))) { if (option_msg) @@ -1880,7 +1892,7 @@ add_device_to_disklist(char *devname, char *devpath) if (search_disk->label_type == L_TYPE_SOLARIS) { status = read_label(search_file, &search_label); } else { - status = read_efi_label(search_file, &efi_info); + status = read_efi_label(search_file, &efi_info, search_disk); } /* * If reading the label failed, and this is a SCSI @@ -1964,9 +1976,20 @@ add_device_to_disklist(char *devname, char *devpath) } search_dtype->dtype_next = NULL; - (void) strlcpy(search_dtype->vendor, efi_info.vendor, 9); - (void) strlcpy(search_dtype->product, efi_info.product, 17); - (void) strlcpy(search_dtype->revision, efi_info.revision, 5); + search_dtype->vendor = strdup(efi_info.vendor); + search_dtype->product = strdup(efi_info.product); + search_dtype->revision = strdup(efi_info.revision); + + if (search_dtype->vendor == NULL || + search_dtype->product == NULL || + search_dtype->revision == NULL) { + free(search_dtype->vendor); + free(search_dtype->product); + free(search_dtype->revision); + free(search_dtype); + goto out; + } + search_dtype->capacity = efi_info.capacity; search_disk->disk_type = search_dtype; @@ -1996,7 +2019,12 @@ add_device_to_disklist(char *devname, char *devpath) break; } } + out: (void) close(search_file); + + free(efi_info.vendor); + free(efi_info.product); + free(efi_info.revision); return; } @@ -2035,7 +2063,8 @@ add_device_to_disklist(char *devname, char *devpath) search_dtype->dtype_next = NULL; if (strncmp(search_label.dkl_asciilabel, "DEFAULT", strlen("DEFAULT")) == 0) { - (void) get_disk_name(search_file, disk_name); + (void) get_disk_name(search_file, disk_name, + search_disk); search_dtype->dtype_asciilabel = (char *) zalloc(strlen(disk_name) + 1); (void) strcpy(search_dtype->dtype_asciilabel, @@ -2989,6 +3018,7 @@ name_represents_wholedisk(char *name) else return (1); } + (void) strcpy(localname, symname); } return (0); |