Print this page
8708 Want diskinfo(1m) to list all disk bays, including those don't have disk installed

@@ -28,32 +28,45 @@
 
 #include <libdiskmgt.h>
 #include <sys/nvpair.h>
 #include <sys/param.h>
 #include <sys/ccompile.h>
+#include <sys/list.h>
 
 #include <fm/libtopo.h>
 #include <fm/topo_hc.h>
 #include <fm/topo_list.h>
 #include <sys/fm/protocol.h>
 #include <modules/common/disk/disk.h>
 
 typedef struct di_opts {
+        boolean_t di_allslots;
         boolean_t di_scripted;
         boolean_t di_parseable;
         boolean_t di_physical;
         boolean_t di_condensed;
 } di_opts_t;
 
+static list_t g_disks;
+static di_opts_t g_opts = { B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE };
+
 typedef struct di_phys {
-        const char *dp_dev;
-        const char *dp_serial;
-        const char *dp_slotname;
+        uint64_t dp_size;
+        uint32_t dp_blksize;
+        char *dp_vid;
+        char *dp_pid;
+        boolean_t dp_removable;
+        boolean_t dp_ssd;
+        char *dp_dev;
+        char *dp_ctype;
+        char *dp_serial;
+        char *dp_slotname;
         int dp_chassis;
         int dp_slot;
         int dp_faulty;
         int dp_locate;
+        list_node_t dp_next;
 } di_phys_t;
 
 static void __NORETURN
 fatal(int rv, const char *fmt, ...)
 {

@@ -64,14 +77,47 @@
         va_end(ap);
 
         exit(rv);
 }
 
+static void *
+safe_zmalloc(size_t size)
+{
+        void *ptr = malloc(size);
+        if (ptr == NULL)
+                fatal(-1, "failed to allocate memeory");
+        memset(ptr, 0, size);
+        return (ptr);
+}
+
+static char *
+safe_strdup(const char *s1)
+{
+        char *s2 = strdup(s1);
+        if (s2 == NULL)
+                fatal(-1, "failed to allocate memeory");
+        return (s2);
+}
+
+static int
+safe_asprintf(char **ret, const char *fmt, ...)
+{
+        va_list ap;
+        int v;
+
+        va_start(ap, fmt);
+        v = vasprintf(ret, fmt, ap);
+        va_end(ap);
+        if (v == -1)
+                fatal(-1, "failed to allocate memeory");
+        return (v);
+}
+
 static void
 usage(const char *execname)
 {
-        (void) fprintf(stderr, "Usage: %s [-Hp] [{-c|-P}]\n", execname);
+        (void) fprintf(stderr, "Usage: %s [-aHp] [{-c|-P}]\n", execname);
 }
 
 static void
 nvlist_query_string(nvlist_t *nvl, const char *label, char **val)
 {

@@ -104,43 +150,24 @@
         if (val == 1)
                 return (c);
 
         return ('?');
 }
-static int
-disk_walker(topo_hdl_t *hp, tnode_t *np, void *arg)
+
+static void
+set_disk_bay_info(topo_hdl_t *hp, tnode_t *np, di_phys_t *dip)
 {
-        di_phys_t *pp = arg;
-        tnode_t *pnp;
-        tnode_t *ppnp;
         topo_faclist_t fl;
         topo_faclist_t *lp;
-        int err;
         topo_led_state_t mode;
         topo_led_type_t type;
-        char *name, *slotname, *serial;
+        int err;
 
-        if (strcmp(topo_node_name(np), DISK) != 0)
-                return (TOPO_WALK_NEXT);
+        if (strcmp(topo_node_name(np), BAY) != 0)
+                return;
 
-        if (topo_prop_get_string(np, TOPO_PGROUP_STORAGE,
-            TOPO_STORAGE_LOGICAL_DISK_NAME, &name, &err) != 0) {
-                return (TOPO_WALK_NEXT);
-        }
-
-        if (strcmp(name, pp->dp_dev) != 0)
-                return (TOPO_WALK_NEXT);
-
-        if (topo_prop_get_string(np, TOPO_PGROUP_STORAGE,
-            TOPO_STORAGE_SERIAL_NUM, &serial, &err) == 0) {
-                pp->dp_serial = serial;
-        }
-
-        pnp = topo_node_parent(np);
-        ppnp = topo_node_parent(pnp);
-        if (strcmp(topo_node_name(pnp), BAY) == 0) {
-                if (topo_node_facility(hp, pnp, TOPO_FAC_TYPE_INDICATOR,
+        if (topo_node_facility(hp, np, TOPO_FAC_TYPE_INDICATOR,
                     TOPO_FAC_TYPE_ANY, &fl, &err) == 0) {
                         for (lp = topo_list_next(&fl.tf_list); lp != NULL;
                             lp = topo_list_next(lp)) {
                                 uint32_t prop;
 

@@ -158,304 +185,400 @@
                                 }
                                 mode = (topo_led_state_t)prop;
 
                                 switch (type) {
                                 case TOPO_LED_TYPE_SERVICE:
-                                        pp->dp_faulty = mode ? 1 : 0;
+                                dip->dp_faulty = mode ? 1 : 0;
                                         break;
                                 case TOPO_LED_TYPE_LOCATE:
-                                        pp->dp_locate = mode ? 1 : 0;
+                                dip->dp_locate = mode ? 1 : 0;
                                         break;
                                 default:
                                         break;
                                 }
                         }
                 }
 
-                if (topo_prop_get_string(pnp, TOPO_PGROUP_PROTOCOL,
-                    TOPO_PROP_LABEL, &slotname, &err) == 0) {
-                        pp->dp_slotname = slotname;
+        if (topo_prop_get_string(np, TOPO_PGROUP_PROTOCOL,
+            TOPO_PROP_LABEL, &dip->dp_slotname, &err) == 0) {
+                dip->dp_slotname = safe_strdup(dip->dp_slotname);
                 }
 
-                pp->dp_slot = topo_node_instance(pnp);
+        dip->dp_slot = topo_node_instance(np);
+        dip->dp_chassis = topo_node_instance(topo_node_parent(np));
+}
+
+static int
+bay_walker(topo_hdl_t *hp, tnode_t *np, void *arg)
+{
+        di_phys_t *dip;
+        int slot, chassis;
+
+        if (strcmp(topo_node_name(np), BAY) != 0)
+                return (TOPO_WALK_NEXT);
+
+        slot = topo_node_instance(np);
+        chassis = topo_node_instance(topo_node_parent(np));
+
+        for (dip = list_head(&g_disks); dip != NULL;
+            dip = list_next(&g_disks, dip)) {
+                if (dip->dp_slot == slot && dip->dp_chassis == chassis)
+                        return (TOPO_WALK_NEXT);
         }
 
-        pp->dp_chassis = topo_node_instance(ppnp);
+        dip = safe_zmalloc(sizeof (di_phys_t));
+        set_disk_bay_info(hp, np, dip);
+        list_insert_tail(&g_disks, dip);
+        return (TOPO_WALK_NEXT);
+}
 
-        return (TOPO_WALK_TERMINATE);
+static int
+disk_walker(topo_hdl_t *hp, tnode_t *np, void *arg)
+{
+        char *dev;
+        di_phys_t *dip;
+        int err;
+
+        if (strcmp(topo_node_name(np), DISK) != 0)
+                return (TOPO_WALK_NEXT);
+
+        if (topo_prop_get_string(np, TOPO_PGROUP_STORAGE,
+            TOPO_STORAGE_LOGICAL_DISK_NAME, &dev, &err) != 0) {
+                return (TOPO_WALK_NEXT);
+        }
+
+        for (dip = list_head(&g_disks); dip != NULL;
+            dip = list_next(&g_disks, dip)) {
+                if (strcmp(dip->dp_dev, dev) == 0) {
+                        if (topo_prop_get_string(np, TOPO_PGROUP_STORAGE,
+                            TOPO_STORAGE_SERIAL_NUM,
+                            &dip->dp_serial, &err) == 0) {
+                                dip->dp_serial = safe_strdup(dip->dp_serial);
+                        }
+                        set_disk_bay_info(hp, topo_node_parent(np), dip);
+                }
+        }
+        return (TOPO_WALK_NEXT);
 }
 
 static void
-populate_physical(topo_hdl_t *hp, di_phys_t *pp)
+walk_topo_snapshot(topo_hdl_t *hp, topo_walk_cb_t cb)
 {
-        int err;
+        int err = 0;
         topo_walk_t *wp;
 
-        pp->dp_faulty = pp->dp_locate = -1;
-        pp->dp_chassis = pp->dp_slot = -1;
-
-        err = 0;
-        wp = topo_walk_init(hp, FM_FMRI_SCHEME_HC, disk_walker, pp, &err);
-        if (wp == NULL) {
+        if ((wp = topo_walk_init(hp, FM_FMRI_SCHEME_HC, cb, NULL,
+            &err)) == NULL) {
                 fatal(-1, "unable to initialise topo walker: %s",
                     topo_strerror(err));
         }
 
         while ((err = topo_walk_step(wp, TOPO_WALK_CHILD)) == TOPO_WALK_NEXT)
                 ;
 
         if (err == TOPO_WALK_ERR)
                 fatal(-1, "topo walk failed");
-
         topo_walk_fini(wp);
 }
 
 static void
-enumerate_disks(di_opts_t *opts)
+enumerate_disks()
 {
         topo_hdl_t *hp;
         dm_descriptor_t *media;
-        int err, i;
         int filter[] = { DM_DT_FIXED, -1 };
         dm_descriptor_t *disk, *controller;
-        nvlist_t *mattrs, *dattrs, *cattrs = NULL;
+        nvlist_t *mattrs, *dattrs, *cattrs;
 
-        uint64_t size, total;
-        uint32_t blocksize;
-        double total_in_GiB;
-        char sizestr[32];
-        char slotname[32];
-        char statestr[8];
-
-        char *vid, *pid, *opath, *c, *ctype = NULL;
-        boolean_t removable;
-        boolean_t ssd;
-        char device[MAXPATHLEN];
-        di_phys_t phys;
+        char *s, *c;
+        di_phys_t *dip;
         size_t len;
+        int err, i;
 
+        list_create(&g_disks, sizeof (di_phys_t), offsetof(di_phys_t, dp_next));
+
         err = 0;
         if ((media = dm_get_descriptors(DM_MEDIA, filter, &err)) == NULL) {
                 fatal(-1, "failed to obtain media descriptors: %s\n",
                     strerror(err));
         }
 
-        err = 0;
-        hp = topo_open(TOPO_VERSION, NULL, &err);
-        if (hp == NULL) {
-                fatal(-1, "unable to obtain topo handle: %s",
-                    topo_strerror(err));
-        }
-
-        err = 0;
-        (void) topo_snap_hold(hp, NULL, &err);
-        if (err != 0) {
-                fatal(-1, "unable to hold topo snapshot: %s",
-                    topo_strerror(err));
-        }
-
         for (i = 0; media != NULL && media[i] != NULL; i++) {
                 if ((disk = dm_get_associated_descriptors(media[i],
                     DM_DRIVE, &err)) == NULL) {
                         continue;
                 }
 
+                dip = safe_zmalloc(sizeof (di_phys_t));
+
                 mattrs = dm_get_attributes(media[i], &err);
-                err = nvlist_lookup_uint64(mattrs, DM_SIZE, &size);
+                err = nvlist_lookup_uint64(mattrs, DM_SIZE, &dip->dp_size);
                 assert(err == 0);
-                err = nvlist_lookup_uint32(mattrs, DM_BLOCKSIZE, &blocksize);
+                err = nvlist_lookup_uint32(mattrs, DM_BLOCKSIZE,
+                    &dip->dp_blksize);
                 assert(err == 0);
                 nvlist_free(mattrs);
 
                 dattrs = dm_get_attributes(disk[0], &err);
 
-                nvlist_query_string(dattrs, DM_VENDOR_ID, &vid);
-                nvlist_query_string(dattrs, DM_PRODUCT_ID, &pid);
-                nvlist_query_string(dattrs, DM_OPATH, &opath);
+                nvlist_query_string(dattrs, DM_VENDOR_ID, &dip->dp_vid);
+                nvlist_query_string(dattrs, DM_PRODUCT_ID, &dip->dp_pid);
+                nvlist_query_string(dattrs, DM_OPATH, &dip->dp_dev);
 
-                removable = B_FALSE;
+                dip->dp_vid = safe_strdup(dip->dp_vid);
+                dip->dp_pid = safe_strdup(dip->dp_pid);
+                dip->dp_dev = safe_strdup(dip->dp_dev);
+
+                dip->dp_removable = B_FALSE;
                 if (nvlist_lookup_boolean(dattrs, DM_REMOVABLE) == 0)
-                        removable = B_TRUE;
+                        dip->dp_removable = B_TRUE;
 
-                ssd = B_FALSE;
+                dip->dp_ssd = B_FALSE;
                 if (nvlist_lookup_boolean(dattrs, DM_SOLIDSTATE) == 0)
-                        ssd = B_TRUE;
+                        dip->dp_ssd = B_TRUE;
 
+                nvlist_free(dattrs);
+
                 if ((controller = dm_get_associated_descriptors(disk[0],
                     DM_CONTROLLER, &err)) != NULL) {
                         cattrs = dm_get_attributes(controller[0], &err);
-                        nvlist_query_string(cattrs, DM_CTYPE, &ctype);
-                        ctype = strdup(ctype);
-                        for (c = ctype; *c != '\0'; c++)
+                        nvlist_query_string(cattrs, DM_CTYPE, &dip->dp_ctype);
+                        dip->dp_ctype = safe_strdup(dip->dp_ctype);
+                        for (c = dip->dp_ctype; *c != '\0'; c++)
                                 *c = toupper(*c);
+                        nvlist_free(cattrs);
                 }
 
+                dm_free_descriptors(controller);
+                dm_free_descriptors(disk);
+
                 /*
                  * Parse full device path to only show the device name,
                  * i.e. c0t1d0.  Many paths will reference a particular
                  * slice (c0t1d0s0), so remove the slice if present.
                  */
-                if ((c = strrchr(opath, '/')) != NULL)
-                        (void) strlcpy(device, c + 1, sizeof (device));
-                else
-                        (void) strlcpy(device, opath, sizeof (device));
-                len = strlen(device);
-                if (device[len - 2] == 's' &&
-                    (device[len - 1] >= '0' && device[len - 1] <= '9'))
-                        device[len - 2] = '\0';
+                if ((c = strrchr(dip->dp_dev, '/')) != NULL) {
+                        s = dip->dp_dev;
+                        while ((*s++ = *++c))
+                                ;
+                }
+                len = strlen(dip->dp_dev);
+                if (dip->dp_dev[len - 2] == 's' &&
+                    dip->dp_dev[len - 1] >= '0' &&
+                    dip->dp_dev[len - 1] <= '9')
+                        dip->dp_dev[len - 2] = '\0';
 
-                bzero(&phys, sizeof (phys));
-                phys.dp_dev = device;
-                populate_physical(hp, &phys);
+                dip->dp_faulty = dip->dp_locate = -1;
+                dip->dp_chassis = dip->dp_slot = -1;
+                list_insert_tail(&g_disks, dip);
+        }
 
+        dm_free_descriptors(media);
+
                 /*
+         * Walk toplogy information to populate serial, chassis,
+         * slot, faulty and locator information.
+         */
+
+        err = 0;
+        hp = topo_open(TOPO_VERSION, NULL, &err);
+        if (hp == NULL) {
+                fatal(-1, "unable to obtain topo handle: %s",
+                    topo_strerror(err));
+        }
+
+        err = 0;
+        (void) topo_snap_hold(hp, NULL, &err);
+        if (err != 0) {
+                fatal(-1, "unable to hold topo snapshot: %s",
+                    topo_strerror(err));
+        }
+
+        walk_topo_snapshot(hp, disk_walker);
+
+        if (g_opts.di_allslots)
+                walk_topo_snapshot(hp, bay_walker);
+
+        topo_snap_release(hp);
+        topo_close(hp);
+}
+
+static void
+show_disks()
+{
+        uint64_t total;
+        double total_in_GiB;
+        char *sizestr = NULL, *slotname = NULL, *statestr = NULL;
+        di_phys_t *dip;
+
+        for (dip = list_head(&g_disks); dip != NULL;
+            dip = list_next(&g_disks, dip)) {
+                /*
                  * The size is given in blocks, so multiply the number
                  * of blocks by the block size to get the total size,
                  * then convert to GiB.
                  */
-                total = size * blocksize;
+                total = dip->dp_size * dip->dp_blksize;
 
-                if (opts->di_parseable) {
-                        (void) snprintf(sizestr, sizeof (sizestr),
-                            "%llu", total);
+                if (g_opts.di_parseable) {
+                        (void) safe_asprintf(&sizestr, "%llu", total);
                 } else {
                         total_in_GiB = (double)total /
                             1024.0 / 1024.0 / 1024.0;
-                        (void) snprintf(sizestr, sizeof (sizestr),
-                            "%7.2f GiB", total_in_GiB);
+                        (void) safe_asprintf(&sizestr,
+                            "%7.2f GiB", (total_in_GiB));
                 }
 
-                if (opts->di_parseable) {
-                        (void) snprintf(slotname, sizeof (slotname), "%d,%d",
-                            phys.dp_chassis, phys.dp_slot);
-                } else if (phys.dp_slotname != NULL) {
-                        (void) snprintf(slotname, sizeof (slotname),
-                            "[%d] %s", phys.dp_chassis, phys.dp_slotname);
+                if (g_opts.di_parseable) {
+                        (void) safe_asprintf(&slotname, "%d,%d",
+                            dip->dp_chassis, dip->dp_slot);
+                } else if (dip->dp_slotname != NULL) {
+                        (void) safe_asprintf(&slotname, "[%d] %s",
+                            dip->dp_chassis, dip->dp_slotname);
                 } else {
-                        slotname[0] = '-';
-                        slotname[1] = '\0';
+                        slotname = safe_strdup("-");
                 }
 
-                if (opts->di_condensed) {
-                        (void) snprintf(statestr, sizeof (statestr), "%c%c%c%c",
-                            condensed_tristate(phys.dp_faulty, 'F'),
-                            condensed_tristate(phys.dp_locate, 'L'),
-                            condensed_tristate(removable, 'R'),
-                            condensed_tristate(ssd, 'S'));
+                if (g_opts.di_condensed) {
+                        (void) safe_asprintf(&statestr, "%c%c%c%c",
+                            condensed_tristate(dip->dp_faulty, 'F'),
+                            condensed_tristate(dip->dp_locate, 'L'),
+                            condensed_tristate(dip->dp_removable, 'R'),
+                            condensed_tristate(dip->dp_ssd, 'S'));
                 }
 
-                if (opts->di_physical) {
-                        if (opts->di_scripted) {
+                if (g_opts.di_physical) {
+                        if (g_opts.di_scripted) {
                                 printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
-                                    device, vid, pid,
-                                    display_string(phys.dp_serial),
-                                    display_tristate(phys.dp_faulty),
-                                    display_tristate(phys.dp_locate), slotname);
+                                    display_string(dip->dp_dev),
+                                    display_string(dip->dp_vid),
+                                    display_string(dip->dp_pid),
+                                    display_string(dip->dp_serial),
+                                    display_tristate(dip->dp_faulty),
+                                    display_tristate(dip->dp_locate), slotname);
                         } else {
                                 printf("%-22s  %-8s %-16s "
                                     "%-20s %-3s %-3s %s\n",
-                                    device, vid, pid,
-                                    display_string(phys.dp_serial),
-                                    display_tristate(phys.dp_faulty),
-                                    display_tristate(phys.dp_locate), slotname);
+                                    display_string(dip->dp_dev),
+                                    display_string(dip->dp_vid),
+                                    display_string(dip->dp_pid),
+                                    display_string(dip->dp_serial),
+                                    display_tristate(dip->dp_faulty),
+                                    display_tristate(dip->dp_locate), slotname);
                         }
-                } else if (opts->di_condensed) {
-                        if (opts->di_scripted) {
+                } else if (g_opts.di_condensed) {
+                        if (g_opts.di_scripted) {
                                 printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
-                                    ctype, device, vid, pid,
-                                    display_string(phys.dp_serial),
+                                    display_string(dip->dp_ctype),
+                                    display_string(dip->dp_dev),
+                                    display_string(dip->dp_vid),
+                                    display_string(dip->dp_pid),
+                                    display_string(dip->dp_serial),
                                     sizestr, statestr, slotname);
                         } else {
                                 printf("%-7s %-22s  %-8s %-16s "
                                     "%-20s\n\t%-13s %-4s %s\n",
-                                    ctype, device, vid, pid,
-                                    display_string(phys.dp_serial),
+                                    display_string(dip->dp_ctype),
+                                    display_string(dip->dp_dev),
+                                    display_string(dip->dp_vid),
+                                    display_string(dip->dp_pid),
+                                    display_string(dip->dp_serial),
                                     sizestr, statestr, slotname);
                         }
                 } else {
-                        if (opts->di_scripted) {
+                        if (g_opts.di_scripted) {
                                 printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
-                                    ctype, device, vid, pid, sizestr,
-                                    display_tristate(removable),
-                                    display_tristate(ssd));
+                                    display_string(dip->dp_ctype),
+                                    display_string(dip->dp_dev),
+                                    display_string(dip->dp_vid),
+                                    display_string(dip->dp_pid), sizestr,
+                                    display_tristate(dip->dp_removable),
+                                    display_tristate(dip->dp_ssd));
                         } else {
                                 printf("%-7s %-22s  %-8s %-16s "
-                                    "%-13s %-3s %-3s\n", ctype, device,
-                                    vid, pid, sizestr,
-                                    display_tristate(removable),
-                                    display_tristate(ssd));
+                                    "%-13s %-3s %-3s\n",
+                                    display_string(dip->dp_ctype),
+                                    display_string(dip->dp_dev),
+                                    display_string(dip->dp_vid),
+                                    display_string(dip->dp_pid), sizestr,
+                                    display_tristate(dip->dp_removable),
+                                    display_tristate(dip->dp_ssd));
                         }
                 }
-
-                free(ctype);
-                nvlist_free(cattrs);
-                nvlist_free(dattrs);
-                dm_free_descriptors(controller);
-                dm_free_descriptors(disk);
+        free(sizestr); free(slotname); free(statestr);
+        sizestr = slotname = statestr = NULL;
         }
+}
 
-        dm_free_descriptors(media);
-        topo_snap_release(hp);
-        topo_close(hp);
+static void
+cleanup()
+{
+        di_phys_t *dip;
+        while ((dip = list_head(&g_disks)) != NULL) {
+                list_remove(&g_disks, dip);
+                free(dip->dp_vid);
+                free(dip->dp_pid);
+                free(dip->dp_dev);
+                free(dip->dp_ctype);
+                free(dip->dp_serial);
+                free(dip->dp_slotname);
+                free(dip);
+        }
+        list_destroy(&g_disks);
 }
 
 int
 main(int argc, char *argv[])
 {
         char c;
 
-        di_opts_t opts = {
-                .di_condensed = B_FALSE,
-                .di_scripted = B_FALSE,
-                .di_physical = B_FALSE,
-                .di_parseable = B_FALSE
-        };
-
-        while ((c = getopt(argc, argv, ":cHPp")) != EOF) {
+        while ((c = getopt(argc, argv, ":acHPp")) != EOF) {
                 switch (c) {
+                case 'a':
+                        g_opts.di_allslots = B_TRUE;
+                        break;
                 case 'c':
-                        if (opts.di_physical) {
-                                usage(argv[0]);
-                                fatal(1, "-c and -P are mutually exclusive\n");
-                        }
-                        opts.di_condensed = B_TRUE;
+                        g_opts.di_condensed = B_TRUE;
                         break;
                 case 'H':
-                        opts.di_scripted = B_TRUE;
+                        g_opts.di_scripted = B_TRUE;
                         break;
                 case 'P':
-                        if (opts.di_condensed) {
-                                usage(argv[0]);
-                                fatal(1, "-c and -P are mutually exclusive\n");
-                        }
-                        opts.di_physical = B_TRUE;
+                        g_opts.di_physical = B_TRUE;
                         break;
                 case 'p':
-                        opts.di_parseable = B_TRUE;
+                        g_opts.di_parseable = B_TRUE;
                         break;
                 case '?':
                         usage(argv[0]);
                         fatal(1, "unknown option -%c\n", optopt);
                 default:
                         fatal(-1, "unexpected error on option -%c\n", optopt);
                 }
         }
 
-        if (!opts.di_scripted) {
-                if (opts.di_physical) {
+        if (g_opts.di_condensed && g_opts.di_physical) {
+                usage(argv[0]);
+                fatal(1, "-c and -P are mutually exclusive\n");
+        }
+
+        if (!g_opts.di_scripted) {
+                if (g_opts.di_physical) {
                         printf("DISK                    VID      PID"
                             "              SERIAL               FLT LOC"
                             " LOCATION\n");
-                } else if (opts.di_condensed) {
+                } else if (g_opts.di_condensed) {
                         printf("TYPE    DISK                    VID      PID"
                             "              SERIAL\n");
                         printf("\tSIZE          FLRS LOCATION\n");
                 } else {
                         printf("TYPE    DISK                    VID      PID"
                             "              SIZE          RMV SSD\n");
                 }
         }
 
-        enumerate_disks(&opts);
+        enumerate_disks();
+        show_disks();
+        cleanup();
 
         return (0);
 }