Print this page
8708 Want diskinfo(1m) to list all disk bays, including those don't have disk installed
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/diskinfo/diskinfo.c
+++ new/usr/src/cmd/diskinfo/diskinfo.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright (c) 2013 Joyent Inc., All rights reserved.
14 14 */
15 15
16 16 #include <sys/types.h>
17 17 #include <sys/stat.h>
18 18 #include <fcntl.h>
19 19 #include <errno.h>
20 20 #include <string.h>
21 21 #include <stdio.h>
22 22 #include <unistd.h>
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
23 23 #include <limits.h>
24 24 #include <assert.h>
25 25 #include <ctype.h>
26 26 #include <stdarg.h>
27 27 #include <strings.h>
28 28
29 29 #include <libdiskmgt.h>
30 30 #include <sys/nvpair.h>
31 31 #include <sys/param.h>
32 32 #include <sys/ccompile.h>
33 +#include <sys/list.h>
33 34
34 35 #include <fm/libtopo.h>
35 36 #include <fm/topo_hc.h>
36 37 #include <fm/topo_list.h>
37 38 #include <sys/fm/protocol.h>
38 39 #include <modules/common/disk/disk.h>
39 40
40 41 typedef struct di_opts {
42 + boolean_t di_allslots;
41 43 boolean_t di_scripted;
42 44 boolean_t di_parseable;
43 45 boolean_t di_physical;
44 46 boolean_t di_condensed;
45 47 } di_opts_t;
46 48
49 +static list_t g_disks;
50 +static di_opts_t g_opts = { B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE };
51 +
47 52 typedef struct di_phys {
48 - const char *dp_dev;
49 - const char *dp_serial;
50 - const char *dp_slotname;
53 + uint64_t dp_size;
54 + uint32_t dp_blksize;
55 + char *dp_vid;
56 + char *dp_pid;
57 + boolean_t dp_removable;
58 + boolean_t dp_ssd;
59 + char *dp_dev;
60 + char *dp_ctype;
61 + char *dp_serial;
62 + char *dp_slotname;
51 63 int dp_chassis;
52 64 int dp_slot;
53 65 int dp_faulty;
54 66 int dp_locate;
67 + list_node_t dp_next;
55 68 } di_phys_t;
56 69
57 70 static void __NORETURN
58 71 fatal(int rv, const char *fmt, ...)
59 72 {
60 73 va_list ap;
61 74
62 75 va_start(ap, fmt);
63 76 (void) vfprintf(stderr, fmt, ap);
64 77 va_end(ap);
65 78
66 79 exit(rv);
67 80 }
68 81
82 +static void *
83 +safe_zmalloc(size_t size)
84 +{
85 + void *ptr = malloc(size);
86 + if (ptr == NULL)
87 + fatal(-1, "failed to allocate memeory");
88 + memset(ptr, 0, size);
89 + return (ptr);
90 +}
91 +
92 +static char *
93 +safe_strdup(const char *s1)
94 +{
95 + char *s2 = strdup(s1);
96 + if (s2 == NULL)
97 + fatal(-1, "failed to allocate memeory");
98 + return (s2);
99 +}
100 +
101 +static int
102 +safe_asprintf(char **ret, const char *fmt, ...)
103 +{
104 + va_list ap;
105 + int v;
106 +
107 + va_start(ap, fmt);
108 + v = vasprintf(ret, fmt, ap);
109 + va_end(ap);
110 + if (v == -1)
111 + fatal(-1, "failed to allocate memeory");
112 + return (v);
113 +}
114 +
69 115 static void
70 116 usage(const char *execname)
71 117 {
72 - (void) fprintf(stderr, "Usage: %s [-Hp] [{-c|-P}]\n", execname);
118 + (void) fprintf(stderr, "Usage: %s [-aHp] [{-c|-P}]\n", execname);
73 119 }
74 120
75 121 static void
76 122 nvlist_query_string(nvlist_t *nvl, const char *label, char **val)
77 123 {
78 124 if (nvlist_lookup_string(nvl, label, val) != 0)
79 125 *val = "-";
80 126 }
81 127
82 128 static const char *
83 129 display_string(const char *label)
84 130 {
85 131 return ((label) ? label : "-");
86 132 }
87 133
88 134 static const char *
89 135 display_tristate(int val)
90 136 {
91 137 if (val == 0)
92 138 return ("no");
93 139 if (val == 1)
94 140 return ("yes");
95 141
96 142 return ("-");
97 143 }
98 144
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
99 145 static char
100 146 condensed_tristate(int val, char c)
101 147 {
102 148 if (val == 0)
103 149 return ('-');
104 150 if (val == 1)
105 151 return (c);
106 152
107 153 return ('?');
108 154 }
109 -static int
110 -disk_walker(topo_hdl_t *hp, tnode_t *np, void *arg)
155 +
156 +static void
157 +set_disk_bay_info(topo_hdl_t *hp, tnode_t *np, di_phys_t *dip)
111 158 {
112 - di_phys_t *pp = arg;
113 - tnode_t *pnp;
114 - tnode_t *ppnp;
115 159 topo_faclist_t fl;
116 160 topo_faclist_t *lp;
117 - int err;
118 161 topo_led_state_t mode;
119 162 topo_led_type_t type;
120 - char *name, *slotname, *serial;
163 + int err;
121 164
122 - if (strcmp(topo_node_name(np), DISK) != 0)
123 - return (TOPO_WALK_NEXT);
165 + if (strcmp(topo_node_name(np), BAY) != 0)
166 + return;
124 167
125 - if (topo_prop_get_string(np, TOPO_PGROUP_STORAGE,
126 - TOPO_STORAGE_LOGICAL_DISK_NAME, &name, &err) != 0) {
127 - return (TOPO_WALK_NEXT);
128 - }
168 + if (topo_node_facility(hp, np, TOPO_FAC_TYPE_INDICATOR,
169 + TOPO_FAC_TYPE_ANY, &fl, &err) == 0) {
170 + for (lp = topo_list_next(&fl.tf_list); lp != NULL;
171 + lp = topo_list_next(lp)) {
172 + uint32_t prop;
129 173
130 - if (strcmp(name, pp->dp_dev) != 0)
131 - return (TOPO_WALK_NEXT);
174 + if (topo_prop_get_uint32(lp->tf_node,
175 + TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
176 + &prop, &err) != 0) {
177 + continue;
178 + }
179 + type = (topo_led_type_t)prop;
132 180
133 - if (topo_prop_get_string(np, TOPO_PGROUP_STORAGE,
134 - TOPO_STORAGE_SERIAL_NUM, &serial, &err) == 0) {
135 - pp->dp_serial = serial;
181 + if (topo_prop_get_uint32(lp->tf_node,
182 + TOPO_PGROUP_FACILITY, TOPO_LED_MODE,
183 + &prop, &err) != 0) {
184 + continue;
185 + }
186 + mode = (topo_led_state_t)prop;
187 +
188 + switch (type) {
189 + case TOPO_LED_TYPE_SERVICE:
190 + dip->dp_faulty = mode ? 1 : 0;
191 + break;
192 + case TOPO_LED_TYPE_LOCATE:
193 + dip->dp_locate = mode ? 1 : 0;
194 + break;
195 + default:
196 + break;
197 + }
198 + }
136 199 }
137 200
138 - pnp = topo_node_parent(np);
139 - ppnp = topo_node_parent(pnp);
140 - if (strcmp(topo_node_name(pnp), BAY) == 0) {
141 - if (topo_node_facility(hp, pnp, TOPO_FAC_TYPE_INDICATOR,
142 - TOPO_FAC_TYPE_ANY, &fl, &err) == 0) {
143 - for (lp = topo_list_next(&fl.tf_list); lp != NULL;
144 - lp = topo_list_next(lp)) {
145 - uint32_t prop;
201 + if (topo_prop_get_string(np, TOPO_PGROUP_PROTOCOL,
202 + TOPO_PROP_LABEL, &dip->dp_slotname, &err) == 0) {
203 + dip->dp_slotname = safe_strdup(dip->dp_slotname);
204 + }
146 205
147 - if (topo_prop_get_uint32(lp->tf_node,
148 - TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
149 - &prop, &err) != 0) {
150 - continue;
151 - }
152 - type = (topo_led_type_t)prop;
206 + dip->dp_slot = topo_node_instance(np);
207 + dip->dp_chassis = topo_node_instance(topo_node_parent(np));
208 +}
153 209
154 - if (topo_prop_get_uint32(lp->tf_node,
155 - TOPO_PGROUP_FACILITY, TOPO_LED_MODE,
156 - &prop, &err) != 0) {
157 - continue;
158 - }
159 - mode = (topo_led_state_t)prop;
210 +static int
211 +bay_walker(topo_hdl_t *hp, tnode_t *np, void *arg)
212 +{
213 + di_phys_t *dip;
214 + int slot, chassis;
160 215
161 - switch (type) {
162 - case TOPO_LED_TYPE_SERVICE:
163 - pp->dp_faulty = mode ? 1 : 0;
164 - break;
165 - case TOPO_LED_TYPE_LOCATE:
166 - pp->dp_locate = mode ? 1 : 0;
167 - break;
168 - default:
169 - break;
170 - }
171 - }
172 - }
216 + if (strcmp(topo_node_name(np), BAY) != 0)
217 + return (TOPO_WALK_NEXT);
173 218
174 - if (topo_prop_get_string(pnp, TOPO_PGROUP_PROTOCOL,
175 - TOPO_PROP_LABEL, &slotname, &err) == 0) {
176 - pp->dp_slotname = slotname;
177 - }
219 + slot = topo_node_instance(np);
220 + chassis = topo_node_instance(topo_node_parent(np));
178 221
179 - pp->dp_slot = topo_node_instance(pnp);
222 + for (dip = list_head(&g_disks); dip != NULL;
223 + dip = list_next(&g_disks, dip)) {
224 + if (dip->dp_slot == slot && dip->dp_chassis == chassis)
225 + return (TOPO_WALK_NEXT);
180 226 }
181 227
182 - pp->dp_chassis = topo_node_instance(ppnp);
228 + dip = safe_zmalloc(sizeof (di_phys_t));
229 + set_disk_bay_info(hp, np, dip);
230 + list_insert_tail(&g_disks, dip);
231 + return (TOPO_WALK_NEXT);
232 +}
183 233
184 - return (TOPO_WALK_TERMINATE);
234 +static int
235 +disk_walker(topo_hdl_t *hp, tnode_t *np, void *arg)
236 +{
237 + char *dev;
238 + di_phys_t *dip;
239 + int err;
240 +
241 + if (strcmp(topo_node_name(np), DISK) != 0)
242 + return (TOPO_WALK_NEXT);
243 +
244 + if (topo_prop_get_string(np, TOPO_PGROUP_STORAGE,
245 + TOPO_STORAGE_LOGICAL_DISK_NAME, &dev, &err) != 0) {
246 + return (TOPO_WALK_NEXT);
247 + }
248 +
249 + for (dip = list_head(&g_disks); dip != NULL;
250 + dip = list_next(&g_disks, dip)) {
251 + if (strcmp(dip->dp_dev, dev) == 0) {
252 + if (topo_prop_get_string(np, TOPO_PGROUP_STORAGE,
253 + TOPO_STORAGE_SERIAL_NUM,
254 + &dip->dp_serial, &err) == 0) {
255 + dip->dp_serial = safe_strdup(dip->dp_serial);
256 + }
257 + set_disk_bay_info(hp, topo_node_parent(np), dip);
258 + }
259 + }
260 + return (TOPO_WALK_NEXT);
185 261 }
186 262
187 263 static void
188 -populate_physical(topo_hdl_t *hp, di_phys_t *pp)
264 +walk_topo_snapshot(topo_hdl_t *hp, topo_walk_cb_t cb)
189 265 {
190 - int err;
266 + int err = 0;
191 267 topo_walk_t *wp;
192 268
193 - pp->dp_faulty = pp->dp_locate = -1;
194 - pp->dp_chassis = pp->dp_slot = -1;
195 -
196 - err = 0;
197 - wp = topo_walk_init(hp, FM_FMRI_SCHEME_HC, disk_walker, pp, &err);
198 - if (wp == NULL) {
269 + if ((wp = topo_walk_init(hp, FM_FMRI_SCHEME_HC, cb, NULL,
270 + &err)) == NULL) {
199 271 fatal(-1, "unable to initialise topo walker: %s",
200 272 topo_strerror(err));
201 273 }
202 274
203 275 while ((err = topo_walk_step(wp, TOPO_WALK_CHILD)) == TOPO_WALK_NEXT)
204 276 ;
205 277
206 278 if (err == TOPO_WALK_ERR)
207 279 fatal(-1, "topo walk failed");
208 -
209 280 topo_walk_fini(wp);
210 281 }
211 282
212 283 static void
213 -enumerate_disks(di_opts_t *opts)
284 +enumerate_disks()
214 285 {
215 286 topo_hdl_t *hp;
216 287 dm_descriptor_t *media;
217 - int err, i;
218 288 int filter[] = { DM_DT_FIXED, -1 };
219 289 dm_descriptor_t *disk, *controller;
220 - nvlist_t *mattrs, *dattrs, *cattrs = NULL;
290 + nvlist_t *mattrs, *dattrs, *cattrs;
221 291
222 - uint64_t size, total;
223 - uint32_t blocksize;
224 - double total_in_GiB;
225 - char sizestr[32];
226 - char slotname[32];
227 - char statestr[8];
228 -
229 - char *vid, *pid, *opath, *c, *ctype = NULL;
230 - boolean_t removable;
231 - boolean_t ssd;
232 - char device[MAXPATHLEN];
233 - di_phys_t phys;
292 + char *s, *c;
293 + di_phys_t *dip;
234 294 size_t len;
295 + int err, i;
235 296
297 + list_create(&g_disks, sizeof (di_phys_t), offsetof(di_phys_t, dp_next));
298 +
236 299 err = 0;
237 300 if ((media = dm_get_descriptors(DM_MEDIA, filter, &err)) == NULL) {
238 301 fatal(-1, "failed to obtain media descriptors: %s\n",
239 302 strerror(err));
240 303 }
241 304
242 - err = 0;
243 - hp = topo_open(TOPO_VERSION, NULL, &err);
244 - if (hp == NULL) {
245 - fatal(-1, "unable to obtain topo handle: %s",
246 - topo_strerror(err));
247 - }
248 -
249 - err = 0;
250 - (void) topo_snap_hold(hp, NULL, &err);
251 - if (err != 0) {
252 - fatal(-1, "unable to hold topo snapshot: %s",
253 - topo_strerror(err));
254 - }
255 -
256 305 for (i = 0; media != NULL && media[i] != NULL; i++) {
257 306 if ((disk = dm_get_associated_descriptors(media[i],
258 307 DM_DRIVE, &err)) == NULL) {
259 308 continue;
260 309 }
261 310
311 + dip = safe_zmalloc(sizeof (di_phys_t));
312 +
262 313 mattrs = dm_get_attributes(media[i], &err);
263 - err = nvlist_lookup_uint64(mattrs, DM_SIZE, &size);
314 + err = nvlist_lookup_uint64(mattrs, DM_SIZE, &dip->dp_size);
264 315 assert(err == 0);
265 - err = nvlist_lookup_uint32(mattrs, DM_BLOCKSIZE, &blocksize);
316 + err = nvlist_lookup_uint32(mattrs, DM_BLOCKSIZE,
317 + &dip->dp_blksize);
266 318 assert(err == 0);
267 319 nvlist_free(mattrs);
268 320
269 321 dattrs = dm_get_attributes(disk[0], &err);
270 322
271 - nvlist_query_string(dattrs, DM_VENDOR_ID, &vid);
272 - nvlist_query_string(dattrs, DM_PRODUCT_ID, &pid);
273 - nvlist_query_string(dattrs, DM_OPATH, &opath);
323 + nvlist_query_string(dattrs, DM_VENDOR_ID, &dip->dp_vid);
324 + nvlist_query_string(dattrs, DM_PRODUCT_ID, &dip->dp_pid);
325 + nvlist_query_string(dattrs, DM_OPATH, &dip->dp_dev);
274 326
275 - removable = B_FALSE;
327 + dip->dp_vid = safe_strdup(dip->dp_vid);
328 + dip->dp_pid = safe_strdup(dip->dp_pid);
329 + dip->dp_dev = safe_strdup(dip->dp_dev);
330 +
331 + dip->dp_removable = B_FALSE;
276 332 if (nvlist_lookup_boolean(dattrs, DM_REMOVABLE) == 0)
277 - removable = B_TRUE;
333 + dip->dp_removable = B_TRUE;
278 334
279 - ssd = B_FALSE;
335 + dip->dp_ssd = B_FALSE;
280 336 if (nvlist_lookup_boolean(dattrs, DM_SOLIDSTATE) == 0)
281 - ssd = B_TRUE;
337 + dip->dp_ssd = B_TRUE;
282 338
339 + nvlist_free(dattrs);
340 +
283 341 if ((controller = dm_get_associated_descriptors(disk[0],
284 342 DM_CONTROLLER, &err)) != NULL) {
285 343 cattrs = dm_get_attributes(controller[0], &err);
286 - nvlist_query_string(cattrs, DM_CTYPE, &ctype);
287 - ctype = strdup(ctype);
288 - for (c = ctype; *c != '\0'; c++)
344 + nvlist_query_string(cattrs, DM_CTYPE, &dip->dp_ctype);
345 + dip->dp_ctype = safe_strdup(dip->dp_ctype);
346 + for (c = dip->dp_ctype; *c != '\0'; c++)
289 347 *c = toupper(*c);
348 + nvlist_free(cattrs);
290 349 }
291 350
351 + dm_free_descriptors(controller);
352 + dm_free_descriptors(disk);
353 +
292 354 /*
293 355 * Parse full device path to only show the device name,
294 356 * i.e. c0t1d0. Many paths will reference a particular
295 357 * slice (c0t1d0s0), so remove the slice if present.
296 358 */
297 - if ((c = strrchr(opath, '/')) != NULL)
298 - (void) strlcpy(device, c + 1, sizeof (device));
299 - else
300 - (void) strlcpy(device, opath, sizeof (device));
301 - len = strlen(device);
302 - if (device[len - 2] == 's' &&
303 - (device[len - 1] >= '0' && device[len - 1] <= '9'))
304 - device[len - 2] = '\0';
359 + if ((c = strrchr(dip->dp_dev, '/')) != NULL) {
360 + s = dip->dp_dev;
361 + while ((*s++ = *++c))
362 + ;
363 + }
364 + len = strlen(dip->dp_dev);
365 + if (dip->dp_dev[len - 2] == 's' &&
366 + dip->dp_dev[len - 1] >= '0' &&
367 + dip->dp_dev[len - 1] <= '9')
368 + dip->dp_dev[len - 2] = '\0';
305 369
306 - bzero(&phys, sizeof (phys));
307 - phys.dp_dev = device;
308 - populate_physical(hp, &phys);
370 + dip->dp_faulty = dip->dp_locate = -1;
371 + dip->dp_chassis = dip->dp_slot = -1;
372 + list_insert_tail(&g_disks, dip);
373 + }
309 374
375 + dm_free_descriptors(media);
376 +
377 + /*
378 + * Walk toplogy information to populate serial, chassis,
379 + * slot, faulty and locator information.
380 + */
381 +
382 + err = 0;
383 + hp = topo_open(TOPO_VERSION, NULL, &err);
384 + if (hp == NULL) {
385 + fatal(-1, "unable to obtain topo handle: %s",
386 + topo_strerror(err));
387 + }
388 +
389 + err = 0;
390 + (void) topo_snap_hold(hp, NULL, &err);
391 + if (err != 0) {
392 + fatal(-1, "unable to hold topo snapshot: %s",
393 + topo_strerror(err));
394 + }
395 +
396 + walk_topo_snapshot(hp, disk_walker);
397 +
398 + if (g_opts.di_allslots)
399 + walk_topo_snapshot(hp, bay_walker);
400 +
401 + topo_snap_release(hp);
402 + topo_close(hp);
403 +}
404 +
405 +static void
406 +show_disks()
407 +{
408 + uint64_t total;
409 + double total_in_GiB;
410 + char *sizestr = NULL, *slotname = NULL, *statestr = NULL;
411 + di_phys_t *dip;
412 +
413 + for (dip = list_head(&g_disks); dip != NULL;
414 + dip = list_next(&g_disks, dip)) {
310 415 /*
311 416 * The size is given in blocks, so multiply the number
312 417 * of blocks by the block size to get the total size,
313 418 * then convert to GiB.
314 419 */
315 - total = size * blocksize;
420 + total = dip->dp_size * dip->dp_blksize;
316 421
317 - if (opts->di_parseable) {
318 - (void) snprintf(sizestr, sizeof (sizestr),
319 - "%llu", total);
422 + if (g_opts.di_parseable) {
423 + (void) safe_asprintf(&sizestr, "%llu", total);
320 424 } else {
321 425 total_in_GiB = (double)total /
322 426 1024.0 / 1024.0 / 1024.0;
323 - (void) snprintf(sizestr, sizeof (sizestr),
324 - "%7.2f GiB", total_in_GiB);
427 + (void) safe_asprintf(&sizestr,
428 + "%7.2f GiB", (total_in_GiB));
325 429 }
326 430
327 - if (opts->di_parseable) {
328 - (void) snprintf(slotname, sizeof (slotname), "%d,%d",
329 - phys.dp_chassis, phys.dp_slot);
330 - } else if (phys.dp_slotname != NULL) {
331 - (void) snprintf(slotname, sizeof (slotname),
332 - "[%d] %s", phys.dp_chassis, phys.dp_slotname);
431 + if (g_opts.di_parseable) {
432 + (void) safe_asprintf(&slotname, "%d,%d",
433 + dip->dp_chassis, dip->dp_slot);
434 + } else if (dip->dp_slotname != NULL) {
435 + (void) safe_asprintf(&slotname, "[%d] %s",
436 + dip->dp_chassis, dip->dp_slotname);
333 437 } else {
334 - slotname[0] = '-';
335 - slotname[1] = '\0';
438 + slotname = safe_strdup("-");
336 439 }
337 440
338 - if (opts->di_condensed) {
339 - (void) snprintf(statestr, sizeof (statestr), "%c%c%c%c",
340 - condensed_tristate(phys.dp_faulty, 'F'),
341 - condensed_tristate(phys.dp_locate, 'L'),
342 - condensed_tristate(removable, 'R'),
343 - condensed_tristate(ssd, 'S'));
441 + if (g_opts.di_condensed) {
442 + (void) safe_asprintf(&statestr, "%c%c%c%c",
443 + condensed_tristate(dip->dp_faulty, 'F'),
444 + condensed_tristate(dip->dp_locate, 'L'),
445 + condensed_tristate(dip->dp_removable, 'R'),
446 + condensed_tristate(dip->dp_ssd, 'S'));
344 447 }
345 448
346 - if (opts->di_physical) {
347 - if (opts->di_scripted) {
449 + if (g_opts.di_physical) {
450 + if (g_opts.di_scripted) {
348 451 printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
349 - device, vid, pid,
350 - display_string(phys.dp_serial),
351 - display_tristate(phys.dp_faulty),
352 - display_tristate(phys.dp_locate), slotname);
452 + display_string(dip->dp_dev),
453 + display_string(dip->dp_vid),
454 + display_string(dip->dp_pid),
455 + display_string(dip->dp_serial),
456 + display_tristate(dip->dp_faulty),
457 + display_tristate(dip->dp_locate), slotname);
353 458 } else {
354 459 printf("%-22s %-8s %-16s "
355 460 "%-20s %-3s %-3s %s\n",
356 - device, vid, pid,
357 - display_string(phys.dp_serial),
358 - display_tristate(phys.dp_faulty),
359 - display_tristate(phys.dp_locate), slotname);
461 + display_string(dip->dp_dev),
462 + display_string(dip->dp_vid),
463 + display_string(dip->dp_pid),
464 + display_string(dip->dp_serial),
465 + display_tristate(dip->dp_faulty),
466 + display_tristate(dip->dp_locate), slotname);
360 467 }
361 - } else if (opts->di_condensed) {
362 - if (opts->di_scripted) {
468 + } else if (g_opts.di_condensed) {
469 + if (g_opts.di_scripted) {
363 470 printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
364 - ctype, device, vid, pid,
365 - display_string(phys.dp_serial),
471 + display_string(dip->dp_ctype),
472 + display_string(dip->dp_dev),
473 + display_string(dip->dp_vid),
474 + display_string(dip->dp_pid),
475 + display_string(dip->dp_serial),
366 476 sizestr, statestr, slotname);
367 477 } else {
368 478 printf("%-7s %-22s %-8s %-16s "
369 479 "%-20s\n\t%-13s %-4s %s\n",
370 - ctype, device, vid, pid,
371 - display_string(phys.dp_serial),
480 + display_string(dip->dp_ctype),
481 + display_string(dip->dp_dev),
482 + display_string(dip->dp_vid),
483 + display_string(dip->dp_pid),
484 + display_string(dip->dp_serial),
372 485 sizestr, statestr, slotname);
373 486 }
374 487 } else {
375 - if (opts->di_scripted) {
488 + if (g_opts.di_scripted) {
376 489 printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
377 - ctype, device, vid, pid, sizestr,
378 - display_tristate(removable),
379 - display_tristate(ssd));
490 + display_string(dip->dp_ctype),
491 + display_string(dip->dp_dev),
492 + display_string(dip->dp_vid),
493 + display_string(dip->dp_pid), sizestr,
494 + display_tristate(dip->dp_removable),
495 + display_tristate(dip->dp_ssd));
380 496 } else {
381 497 printf("%-7s %-22s %-8s %-16s "
382 - "%-13s %-3s %-3s\n", ctype, device,
383 - vid, pid, sizestr,
384 - display_tristate(removable),
385 - display_tristate(ssd));
498 + "%-13s %-3s %-3s\n",
499 + display_string(dip->dp_ctype),
500 + display_string(dip->dp_dev),
501 + display_string(dip->dp_vid),
502 + display_string(dip->dp_pid), sizestr,
503 + display_tristate(dip->dp_removable),
504 + display_tristate(dip->dp_ssd));
386 505 }
387 506 }
388 -
389 - free(ctype);
390 - nvlist_free(cattrs);
391 - nvlist_free(dattrs);
392 - dm_free_descriptors(controller);
393 - dm_free_descriptors(disk);
507 + free(sizestr); free(slotname); free(statestr);
508 + sizestr = slotname = statestr = NULL;
394 509 }
510 +}
395 511
396 - dm_free_descriptors(media);
397 - topo_snap_release(hp);
398 - topo_close(hp);
512 +static void
513 +cleanup()
514 +{
515 + di_phys_t *dip;
516 + while ((dip = list_head(&g_disks)) != NULL) {
517 + list_remove(&g_disks, dip);
518 + free(dip->dp_vid);
519 + free(dip->dp_pid);
520 + free(dip->dp_dev);
521 + free(dip->dp_ctype);
522 + free(dip->dp_serial);
523 + free(dip->dp_slotname);
524 + free(dip);
525 + }
526 + list_destroy(&g_disks);
399 527 }
400 528
401 529 int
402 530 main(int argc, char *argv[])
403 531 {
404 532 char c;
405 533
406 - di_opts_t opts = {
407 - .di_condensed = B_FALSE,
408 - .di_scripted = B_FALSE,
409 - .di_physical = B_FALSE,
410 - .di_parseable = B_FALSE
411 - };
412 -
413 - while ((c = getopt(argc, argv, ":cHPp")) != EOF) {
534 + while ((c = getopt(argc, argv, ":acHPp")) != EOF) {
414 535 switch (c) {
536 + case 'a':
537 + g_opts.di_allslots = B_TRUE;
538 + break;
415 539 case 'c':
416 - if (opts.di_physical) {
417 - usage(argv[0]);
418 - fatal(1, "-c and -P are mutually exclusive\n");
419 - }
420 - opts.di_condensed = B_TRUE;
540 + g_opts.di_condensed = B_TRUE;
421 541 break;
422 542 case 'H':
423 - opts.di_scripted = B_TRUE;
543 + g_opts.di_scripted = B_TRUE;
424 544 break;
425 545 case 'P':
426 - if (opts.di_condensed) {
427 - usage(argv[0]);
428 - fatal(1, "-c and -P are mutually exclusive\n");
429 - }
430 - opts.di_physical = B_TRUE;
546 + g_opts.di_physical = B_TRUE;
431 547 break;
432 548 case 'p':
433 - opts.di_parseable = B_TRUE;
549 + g_opts.di_parseable = B_TRUE;
434 550 break;
435 551 case '?':
436 552 usage(argv[0]);
437 553 fatal(1, "unknown option -%c\n", optopt);
438 554 default:
439 555 fatal(-1, "unexpected error on option -%c\n", optopt);
440 556 }
441 557 }
442 558
443 - if (!opts.di_scripted) {
444 - if (opts.di_physical) {
559 + if (g_opts.di_condensed && g_opts.di_physical) {
560 + usage(argv[0]);
561 + fatal(1, "-c and -P are mutually exclusive\n");
562 + }
563 +
564 + if (!g_opts.di_scripted) {
565 + if (g_opts.di_physical) {
445 566 printf("DISK VID PID"
446 567 " SERIAL FLT LOC"
447 568 " LOCATION\n");
448 - } else if (opts.di_condensed) {
569 + } else if (g_opts.di_condensed) {
449 570 printf("TYPE DISK VID PID"
450 571 " SERIAL\n");
451 572 printf("\tSIZE FLRS LOCATION\n");
452 573 } else {
453 574 printf("TYPE DISK VID PID"
454 575 " SIZE RMV SSD\n");
455 576 }
456 577 }
457 578
458 - enumerate_disks(&opts);
579 + enumerate_disks();
580 + show_disks();
581 + cleanup();
459 582
460 583 return (0);
461 584 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX