4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
43 #include <auth_attr.h>
44 #include <auth_list.h>
46 #include <libdevinfo.h>
49 #include <libdllink.h>
50 #include <libdlstat.h>
51 #include <libdlaggr.h>
52 #include <libinetutil.h>
54 #include <bsm/adt_event.h>
58 typedef struct link_chain_s
{
59 datalink_id_t lc_linkid
;
61 dladm_stat_chain_t
*lc_statchain
[DLADM_STAT_NUM_STATS
];
62 struct link_chain_s
*lc_next
;
65 typedef void * (*stats2str_t
)(const char *, void *,
68 typedef struct show_state
{
69 link_chain_t
*ls_linkchain
;
70 boolean_t ls_stattype
[DLADM_STAT_NUM_STATS
];
71 stats2str_t ls_stats2str
[DLADM_STAT_NUM_STATS
];
72 ofmt_handle_t ls_ofmt
;
74 boolean_t ls_parsable
;
77 typedef struct show_history_state_s
{
79 boolean_t hs_parsable
;
80 boolean_t hs_printheader
;
83 ofmt_handle_t hs_ofmt
;
84 } show_history_state_t
;
87 * callback functions for printing output and error diagnostics.
89 static ofmt_cb_t print_default_cb
;
91 static void dlstat_ofmt_check(ofmt_status_t
, boolean_t
, ofmt_handle_t
);
93 typedef void cmdfunc_t(int, char **, const char *);
95 static cmdfunc_t do_show
, do_show_history
, do_show_phys
, do_show_link
;
96 static cmdfunc_t do_show_aggr
;
98 static void die(const char *, ...);
99 static void die_optdup(int);
100 static void die_opterr(int, int, const char *);
101 static void die_dlerr(dladm_status_t
, const char *, ...);
102 static void warn(const char *, ...);
110 static cmd_t cmds
[] = {
112 "dlstat [-r | -t] [-i <interval>] [link]\n"
113 " dlstat [-a | -A] [-i <interval>] [-p] [ -o field[,...]]\n"
114 " [-u R|K|M|G|T|P] [link]"},
115 { "show-phys", do_show_phys
,
116 "dlstat show-phys [-r | -t] [-i interval] [-a]\n"
117 " [-p] [ -o field[,...]] [-u R|K|M|G|T|P] "
119 { "show-link", do_show_link
,
120 "dlstat show-link [-r [-F] | -t] [-i interval] [-a]\n"
121 " [-p] [ -o field[,...]] [-u R|K|M|G|T|P] "
123 " dlstat show-link -h [-a] [-d] [-F <format>]\n"
124 " [-s <DD/MM/YYYY,HH:MM:SS>] "
125 "[-e <DD/MM/YYYY,HH:MM:SS>]\n"
126 " -f <logfile> [<link>]" },
127 { "show-aggr", do_show_aggr
,
128 "dlstat show-aggr [-r | -t] [-i interval] [-p]\n"
129 " [ -o field[,...]] [-u R|K|M|G|T|P] "
133 #define MAXSTATLEN 15
136 * dlstat : total stat fields
138 typedef struct total_fields_buf_s
{
139 char t_linkname
[MAXLINKNAMELEN
];
140 char t_ipackets
[MAXSTATLEN
];
141 char t_rbytes
[MAXSTATLEN
];
142 char t_opackets
[MAXSTATLEN
];
143 char t_obytes
[MAXSTATLEN
];
144 } total_fields_buf_t
;
146 static ofmt_field_t total_s_fields
[] = {
148 offsetof(total_fields_buf_t
, t_linkname
), print_default_cb
},
150 offsetof(total_fields_buf_t
, t_ipackets
), print_default_cb
},
152 offsetof(total_fields_buf_t
, t_rbytes
), print_default_cb
},
154 offsetof(total_fields_buf_t
, t_opackets
), print_default_cb
},
156 offsetof(total_fields_buf_t
, t_obytes
), print_default_cb
},
157 { NULL
, 0, 0, NULL
}};
160 * dlstat show-phys: both Rx and Tx stat fields
162 typedef struct ring_fields_buf_s
{
163 char r_linkname
[MAXLINKNAMELEN
];
164 char r_type
[MAXSTATLEN
];
165 char r_id
[MAXSTATLEN
];
166 char r_index
[MAXSTATLEN
];
167 char r_packets
[MAXSTATLEN
];
168 char r_bytes
[MAXSTATLEN
];
171 static ofmt_field_t ring_s_fields
[] = {
173 offsetof(ring_fields_buf_t
, r_linkname
), print_default_cb
},
175 offsetof(ring_fields_buf_t
, r_type
), print_default_cb
},
177 offsetof(ring_fields_buf_t
, r_id
), print_default_cb
},
179 offsetof(ring_fields_buf_t
, r_index
), print_default_cb
},
181 offsetof(ring_fields_buf_t
, r_packets
), print_default_cb
},
183 offsetof(ring_fields_buf_t
, r_bytes
), print_default_cb
},
184 { NULL
, 0, 0, NULL
}};
187 * dlstat show-phys -r: Rx Ring stat fields
189 typedef struct rx_ring_fields_buf_s
{
190 char rr_linkname
[MAXLINKNAMELEN
];
191 char rr_type
[MAXSTATLEN
];
192 char rr_id
[MAXSTATLEN
];
193 char rr_index
[MAXSTATLEN
];
194 char rr_ipackets
[MAXSTATLEN
];
195 char rr_rbytes
[MAXSTATLEN
];
196 } rx_ring_fields_buf_t
;
198 static ofmt_field_t rx_ring_s_fields
[] = {
200 offsetof(rx_ring_fields_buf_t
, rr_linkname
), print_default_cb
},
202 offsetof(rx_ring_fields_buf_t
, rr_type
), print_default_cb
},
204 offsetof(rx_ring_fields_buf_t
, rr_id
), print_default_cb
},
206 offsetof(rx_ring_fields_buf_t
, rr_index
), print_default_cb
},
208 offsetof(rx_ring_fields_buf_t
, rr_ipackets
), print_default_cb
},
210 offsetof(rx_ring_fields_buf_t
, rr_rbytes
), print_default_cb
},
211 { NULL
, 0, 0, NULL
}};
214 * dlstat show-phys -t: Tx Ring stat fields
216 typedef struct tx_ring_fields_buf_s
{
217 char tr_linkname
[MAXLINKNAMELEN
];
218 char tr_type
[MAXSTATLEN
];
219 char tr_id
[MAXSTATLEN
];
220 char tr_index
[MAXSTATLEN
];
221 char tr_opackets
[MAXSTATLEN
];
222 char tr_obytes
[MAXSTATLEN
];
223 } tx_ring_fields_buf_t
;
225 static ofmt_field_t tx_ring_s_fields
[] = {
227 offsetof(tx_ring_fields_buf_t
, tr_linkname
), print_default_cb
},
229 offsetof(tx_ring_fields_buf_t
, tr_type
), print_default_cb
},
231 offsetof(tx_ring_fields_buf_t
, tr_id
), print_default_cb
},
233 offsetof(tx_ring_fields_buf_t
, tr_index
), print_default_cb
},
235 offsetof(tx_ring_fields_buf_t
, tr_opackets
), print_default_cb
},
237 offsetof(tx_ring_fields_buf_t
, tr_obytes
), print_default_cb
},
238 { NULL
, 0, 0, NULL
}};
241 * dlstat show-link: both Rx and Tx lane fields
243 typedef struct lane_fields_buf_s
{
244 char l_linkname
[MAXLINKNAMELEN
];
245 char l_type
[MAXSTATLEN
];
246 char l_id
[MAXSTATLEN
];
247 char l_index
[MAXSTATLEN
];
248 char l_packets
[MAXSTATLEN
];
249 char l_bytes
[MAXSTATLEN
];
252 static ofmt_field_t lane_s_fields
[] = {
254 offsetof(lane_fields_buf_t
, l_linkname
), print_default_cb
},
256 offsetof(lane_fields_buf_t
, l_type
), print_default_cb
},
258 offsetof(lane_fields_buf_t
, l_id
), print_default_cb
},
260 offsetof(lane_fields_buf_t
, l_index
), print_default_cb
},
262 offsetof(lane_fields_buf_t
, l_packets
), print_default_cb
},
264 offsetof(lane_fields_buf_t
, l_bytes
), print_default_cb
},
265 { NULL
, 0, 0, NULL
}};
268 * dlstat show-link -r, dlstat -r: Rx Lane stat fields
270 typedef struct rx_lane_fields_buf_s
{
271 char rl_linkname
[MAXLINKNAMELEN
];
272 char rl_type
[MAXSTATLEN
];
273 char rl_id
[MAXSTATLEN
];
274 char rl_index
[MAXSTATLEN
];
275 char rl_ipackets
[MAXSTATLEN
];
276 char rl_rbytes
[MAXSTATLEN
];
277 char rl_intrs
[MAXSTATLEN
];
278 char rl_polls
[MAXSTATLEN
];
279 char rl_sdrops
[MAXSTATLEN
];
280 char rl_chl10
[MAXSTATLEN
];
281 char rl_ch10_50
[MAXSTATLEN
];
282 char rl_chg50
[MAXSTATLEN
];
283 } rx_lane_fields_buf_t
;
285 static ofmt_field_t rx_lane_s_fields
[] = {
287 offsetof(rx_lane_fields_buf_t
, rl_linkname
), print_default_cb
},
289 offsetof(rx_lane_fields_buf_t
, rl_type
), print_default_cb
},
291 offsetof(rx_lane_fields_buf_t
, rl_id
), print_default_cb
},
293 offsetof(rx_lane_fields_buf_t
, rl_index
), print_default_cb
},
295 offsetof(rx_lane_fields_buf_t
, rl_ipackets
), print_default_cb
},
297 offsetof(rx_lane_fields_buf_t
, rl_rbytes
), print_default_cb
},
299 offsetof(rx_lane_fields_buf_t
, rl_intrs
), print_default_cb
},
301 offsetof(rx_lane_fields_buf_t
, rl_polls
), print_default_cb
},
303 offsetof(rx_lane_fields_buf_t
, rl_sdrops
), print_default_cb
},
305 offsetof(rx_lane_fields_buf_t
, rl_chl10
), print_default_cb
},
307 offsetof(rx_lane_fields_buf_t
, rl_ch10_50
), print_default_cb
},
309 offsetof(rx_lane_fields_buf_t
, rl_chg50
), print_default_cb
},
310 { NULL
, 0, 0, NULL
}};
313 * dlstat show-link -r -F: Rx fanout stat fields
315 typedef struct rx_fanout_lane_fields_buf_s
{
316 char rfl_linkname
[MAXLINKNAMELEN
];
317 char rfl_type
[MAXSTATLEN
];
318 char rfl_id
[MAXSTATLEN
];
319 char rfl_index
[MAXSTATLEN
];
320 char rfl_fout
[MAXSTATLEN
];
321 char rfl_ipackets
[MAXSTATLEN
];
322 char rfl_rbytes
[MAXSTATLEN
];
323 } rx_fanout_lane_fields_buf_t
;
325 static ofmt_field_t rx_fanout_lane_s_fields
[] = {
327 offsetof(rx_fanout_lane_fields_buf_t
, rfl_linkname
), print_default_cb
},
329 offsetof(rx_fanout_lane_fields_buf_t
, rfl_type
), print_default_cb
},
331 offsetof(rx_fanout_lane_fields_buf_t
, rfl_id
), print_default_cb
},
333 offsetof(rx_fanout_lane_fields_buf_t
, rfl_index
), print_default_cb
},
335 offsetof(rx_fanout_lane_fields_buf_t
, rfl_fout
), print_default_cb
},
337 offsetof(rx_fanout_lane_fields_buf_t
, rfl_ipackets
), print_default_cb
},
339 offsetof(rx_fanout_lane_fields_buf_t
, rfl_rbytes
), print_default_cb
},
340 { NULL
, 0, 0, NULL
}};
343 * dlstat show-link -t: Tx Lane stat fields
345 typedef struct tx_lane_fields_buf_s
{
346 char tl_linkname
[MAXLINKNAMELEN
];
347 char tl_index
[MAXSTATLEN
];
348 char tl_type
[MAXSTATLEN
];
349 char tl_id
[MAXSTATLEN
];
350 char tl_opackets
[MAXSTATLEN
];
351 char tl_obytes
[MAXSTATLEN
];
352 char tl_blockcnt
[MAXSTATLEN
];
353 char tl_unblockcnt
[MAXSTATLEN
];
354 char tl_sdrops
[MAXSTATLEN
];
355 } tx_lane_fields_buf_t
;
357 static ofmt_field_t tx_lane_s_fields
[] = {
359 offsetof(tx_lane_fields_buf_t
, tl_linkname
), print_default_cb
},
361 offsetof(tx_lane_fields_buf_t
, tl_type
), print_default_cb
},
363 offsetof(tx_lane_fields_buf_t
, tl_id
), print_default_cb
},
365 offsetof(tx_lane_fields_buf_t
, tl_index
), print_default_cb
},
367 offsetof(tx_lane_fields_buf_t
, tl_opackets
), print_default_cb
},
369 offsetof(tx_lane_fields_buf_t
, tl_obytes
), print_default_cb
},
371 offsetof(tx_lane_fields_buf_t
, tl_blockcnt
), print_default_cb
},
373 offsetof(tx_lane_fields_buf_t
, tl_unblockcnt
), print_default_cb
},
375 offsetof(tx_lane_fields_buf_t
, tl_sdrops
), print_default_cb
},
376 { NULL
, 0, 0, NULL
}};
379 * dlstat show-aggr: aggr port stat fields
381 typedef struct aggr_port_fields_buf_s
{
382 char ap_linkname
[MAXLINKNAMELEN
];
383 char ap_portname
[MAXLINKNAMELEN
];
384 char ap_ipackets
[MAXSTATLEN
];
385 char ap_rbytes
[MAXSTATLEN
];
386 char ap_opackets
[MAXSTATLEN
];
387 char ap_obytes
[MAXSTATLEN
];
388 } aggr_port_fields_buf_t
;
390 static ofmt_field_t aggr_port_s_fields
[] = {
392 offsetof(aggr_port_fields_buf_t
, ap_linkname
), print_default_cb
},
394 offsetof(aggr_port_fields_buf_t
, ap_portname
), print_default_cb
},
396 offsetof(aggr_port_fields_buf_t
, ap_ipackets
), print_default_cb
},
398 offsetof(aggr_port_fields_buf_t
, ap_rbytes
), print_default_cb
},
400 offsetof(aggr_port_fields_buf_t
, ap_opackets
), print_default_cb
},
402 offsetof(aggr_port_fields_buf_t
, ap_obytes
), print_default_cb
},
403 { NULL
, 0, 0, NULL
}};
406 * structures for 'dlstat show-link -h'
408 typedef struct history_fields_buf_s
{
415 char h_bandwidth
[14];
416 } history_fields_buf_t
;
418 static ofmt_field_t history_fields
[] = {
420 offsetof(history_fields_buf_t
, h_link
), print_default_cb
},
422 offsetof(history_fields_buf_t
, h_duration
), print_default_cb
},
424 offsetof(history_fields_buf_t
, h_ipackets
), print_default_cb
},
426 offsetof(history_fields_buf_t
, h_rbytes
), print_default_cb
},
428 offsetof(history_fields_buf_t
, h_opackets
), print_default_cb
},
430 offsetof(history_fields_buf_t
, h_obytes
), print_default_cb
},
432 offsetof(history_fields_buf_t
, h_bandwidth
), print_default_cb
},
433 { NULL
, 0, 0, NULL
}};
436 * structures for 'dlstat show-link -h link'
438 typedef struct history_l_fields_buf_s
{
444 char hl_bandwidth
[14];
445 } history_l_fields_buf_t
;
447 static ofmt_field_t history_l_fields
[] = {
448 /* name, field width, offset */
450 offsetof(history_l_fields_buf_t
, hl_link
), print_default_cb
},
452 offsetof(history_l_fields_buf_t
, hl_stime
), print_default_cb
},
454 offsetof(history_l_fields_buf_t
, hl_etime
), print_default_cb
},
456 offsetof(history_l_fields_buf_t
, hl_rbytes
), print_default_cb
},
458 offsetof(history_l_fields_buf_t
, hl_obytes
), print_default_cb
},
460 offsetof(history_l_fields_buf_t
, hl_bandwidth
), print_default_cb
},
464 static char *progname
;
467 * Handle to libdladm. Opened in main() before the sub-command
468 * specific function is called.
470 static dladm_handle_t handle
= NULL
;
478 (void) fprintf(stderr
, gettext("usage: "));
479 for (i
= 0; i
< sizeof (cmds
) / sizeof (cmds
[0]); i
++) {
481 if (cmdp
->c_usage
!= NULL
)
482 (void) fprintf(stderr
, "%s\n", gettext(cmdp
->c_usage
));
485 /* close dladm handle if it was opened */
493 main(int argc
, char *argv
[])
497 dladm_status_t status
;
499 (void) setlocale(LC_ALL
, "");
500 #if !defined(TEXT_DOMAIN)
501 #define TEXT_DOMAIN "SYS_TEST"
503 (void) textdomain(TEXT_DOMAIN
);
507 /* Open the libdladm handle */
508 if ((status
= dladm_open(&handle
)) != DLADM_STATUS_OK
)
509 die_dlerr(status
, "could not open /dev/dld");
512 do_show(argc
- 1, NULL
, cmds
[0].c_usage
);
516 for (i
= 0; i
< sizeof (cmds
) / sizeof (cmds
[0]); i
++) {
518 if (strcmp(argv
[1], cmdp
->c_name
) == 0) {
519 cmdp
->c_fn(argc
- 1, &argv
[1], cmdp
->c_usage
);
524 do_show(argc
, &argv
[0], cmds
[0].c_usage
);
533 show_history_date(dladm_usage_t
*history
, void *arg
)
535 show_history_state_t
*state
= arg
;
538 dladm_status_t status
;
542 * Only show history information for existing links unless '-a'
545 if (!state
->hs_showall
) {
546 if ((status
= dladm_name2info(handle
, history
->du_name
,
547 NULL
, &flags
, NULL
, NULL
)) != DLADM_STATUS_OK
) {
550 if ((flags
& DLADM_OPT_ACTIVE
) == 0)
551 return (DLADM_STATUS_LINKINVAL
);
554 stime
= history
->du_stime
;
555 (void) strftime(timebuf
, sizeof (timebuf
), "%m/%d/%Y",
557 (void) printf("%s\n", timebuf
);
559 return (DLADM_STATUS_OK
);
563 show_history_time(dladm_usage_t
*history
, void *arg
)
565 show_history_state_t
*state
= arg
;
566 char buf
[DLADM_STRSIZE
];
567 history_l_fields_buf_t ubuf
;
570 dladm_status_t status
;
574 * Only show history information for existing links unless '-a'
577 if (!state
->hs_showall
) {
578 if ((status
= dladm_name2info(handle
, history
->du_name
,
579 NULL
, &flags
, NULL
, NULL
)) != DLADM_STATUS_OK
) {
582 if ((flags
& DLADM_OPT_ACTIVE
) == 0)
583 return (DLADM_STATUS_LINKINVAL
);
586 if (state
->hs_plot
) {
587 if (!state
->hs_printheader
) {
588 if (state
->hs_first
) {
589 (void) printf("# Time");
590 state
->hs_first
= B_FALSE
;
592 (void) printf(" %s", history
->du_name
);
593 if (history
->du_last
) {
595 state
->hs_first
= B_TRUE
;
596 state
->hs_printheader
= B_TRUE
;
599 if (state
->hs_first
) {
600 time
= history
->du_etime
;
601 (void) strftime(buf
, sizeof (buf
), "%T",
603 state
->hs_first
= B_FALSE
;
604 (void) printf("%s", buf
);
606 bw
= (double)history
->du_bandwidth
/1000;
607 (void) printf(" %.2f", bw
);
608 if (history
->du_last
) {
610 state
->hs_first
= B_TRUE
;
613 return (DLADM_STATUS_OK
);
616 bzero(&ubuf
, sizeof (ubuf
));
618 (void) snprintf(ubuf
.hl_link
, sizeof (ubuf
.hl_link
), "%s",
620 time
= history
->du_stime
;
621 (void) strftime(buf
, sizeof (buf
), "%T", localtime(&time
));
622 (void) snprintf(ubuf
.hl_stime
, sizeof (ubuf
.hl_stime
), "%s",
624 time
= history
->du_etime
;
625 (void) strftime(buf
, sizeof (buf
), "%T", localtime(&time
));
626 (void) snprintf(ubuf
.hl_etime
, sizeof (ubuf
.hl_etime
), "%s",
628 (void) snprintf(ubuf
.hl_rbytes
, sizeof (ubuf
.hl_rbytes
),
629 "%llu", history
->du_rbytes
);
630 (void) snprintf(ubuf
.hl_obytes
, sizeof (ubuf
.hl_obytes
),
631 "%llu", history
->du_obytes
);
632 (void) snprintf(ubuf
.hl_bandwidth
, sizeof (ubuf
.hl_bandwidth
),
633 "%s Mbps", dladm_bw2str(history
->du_bandwidth
, buf
));
635 ofmt_print(state
->hs_ofmt
, &ubuf
);
636 return (DLADM_STATUS_OK
);
640 show_history_res(dladm_usage_t
*history
, void *arg
)
642 show_history_state_t
*state
= arg
;
643 char buf
[DLADM_STRSIZE
];
644 history_fields_buf_t ubuf
;
645 dladm_status_t status
;
649 * Only show history information for existing links unless '-a'
652 if (!state
->hs_showall
) {
653 if ((status
= dladm_name2info(handle
, history
->du_name
,
654 NULL
, &flags
, NULL
, NULL
)) != DLADM_STATUS_OK
) {
657 if ((flags
& DLADM_OPT_ACTIVE
) == 0)
658 return (DLADM_STATUS_LINKINVAL
);
661 bzero(&ubuf
, sizeof (ubuf
));
663 (void) snprintf(ubuf
.h_link
, sizeof (ubuf
.h_link
), "%s",
665 (void) snprintf(ubuf
.h_duration
, sizeof (ubuf
.h_duration
),
666 "%llu", history
->du_duration
);
667 (void) snprintf(ubuf
.h_ipackets
, sizeof (ubuf
.h_ipackets
),
668 "%llu", history
->du_ipackets
);
669 (void) snprintf(ubuf
.h_rbytes
, sizeof (ubuf
.h_rbytes
),
670 "%llu", history
->du_rbytes
);
671 (void) snprintf(ubuf
.h_opackets
, sizeof (ubuf
.h_opackets
),
672 "%llu", history
->du_opackets
);
673 (void) snprintf(ubuf
.h_obytes
, sizeof (ubuf
.h_obytes
),
674 "%llu", history
->du_obytes
);
675 (void) snprintf(ubuf
.h_bandwidth
, sizeof (ubuf
.h_bandwidth
),
676 "%s Mbps", dladm_bw2str(history
->du_bandwidth
, buf
));
678 ofmt_print(state
->hs_ofmt
, &ubuf
);
680 return (DLADM_STATUS_OK
);
684 valid_formatspec(char *formatspec_str
)
686 return (strcmp(formatspec_str
, "gnuplot") == 0);
691 do_show_history(int argc
, char *argv
[], const char *use
)
695 dladm_status_t status
;
696 boolean_t d_arg
= B_FALSE
;
699 char *resource
= NULL
;
700 show_history_state_t state
;
701 boolean_t o_arg
= B_FALSE
;
702 boolean_t F_arg
= B_FALSE
;
703 char *fields_str
= NULL
;
704 char *formatspec_str
= NULL
;
706 "link,start,end,rbytes,obytes,bandwidth";
709 uint_t ofmtflags
= 0;
711 bzero(&state
, sizeof (show_history_state_t
));
712 state
.hs_parsable
= B_FALSE
;
713 state
.hs_printheader
= B_FALSE
;
714 state
.hs_plot
= B_FALSE
;
715 state
.hs_first
= B_TRUE
;
717 while ((opt
= getopt(argc
, argv
, "das:e:o:f:F:")) != -1) {
723 state
.hs_showall
= B_TRUE
;
739 state
.hs_plot
= F_arg
= B_TRUE
;
740 formatspec_str
= optarg
;
743 die_opterr(optopt
, opt
, use
);
749 die("show-link -h requires a file");
751 if (optind
== (argc
-1)) {
754 resource
= argv
[optind
];
755 if (!state
.hs_showall
&&
756 (((status
= dladm_name2info(handle
, resource
, NULL
, &flags
,
757 NULL
, NULL
)) != DLADM_STATUS_OK
) ||
758 ((flags
& DLADM_OPT_ACTIVE
) == 0))) {
759 die("invalid link: '%s'", resource
);
764 die("incompatible -d and -F options");
766 if (F_arg
&& !valid_formatspec(formatspec_str
))
767 die("Format specifier %s not supported", formatspec_str
);
769 if (state
.hs_parsable
)
770 ofmtflags
|= OFMT_PARSABLE
;
772 if (resource
== NULL
&& stime
== NULL
&& etime
== NULL
) {
773 oferr
= ofmt_open(fields_str
, history_fields
, ofmtflags
, 0,
776 if (!o_arg
|| (o_arg
&& strcasecmp(fields_str
, "all") == 0))
777 fields_str
= all_l_fields
;
778 oferr
= ofmt_open(fields_str
, history_l_fields
, ofmtflags
, 0,
782 dlstat_ofmt_check(oferr
, state
.hs_parsable
, ofmt
);
783 state
.hs_ofmt
= ofmt
;
786 /* Print log dates */
787 status
= dladm_usage_dates(show_history_date
,
788 DLADM_LOGTYPE_LINK
, file
, resource
, &state
);
789 } else if (resource
== NULL
&& stime
== NULL
&& etime
== NULL
&&
792 status
= dladm_usage_summary(show_history_res
,
793 DLADM_LOGTYPE_LINK
, file
, &state
);
794 } else if (resource
!= NULL
) {
795 /* Print log entries for named resource */
796 status
= dladm_walk_usage_res(show_history_time
,
797 DLADM_LOGTYPE_LINK
, file
, resource
, stime
, etime
, &state
);
799 /* Print time and information for each link */
800 status
= dladm_walk_usage_time(show_history_time
,
801 DLADM_LOGTYPE_LINK
, file
, stime
, etime
, &state
);
804 if (status
!= DLADM_STATUS_OK
)
805 die_dlerr(status
, "show-link -h");
810 dlstat_unit(char *oarg
, char *unit
)
812 if ((strcmp(oarg
, "R") == 0) || (strcmp(oarg
, "K") == 0) ||
813 (strcmp(oarg
, "M") == 0) || (strcmp(oarg
, "G") == 0) ||
814 (strcmp(oarg
, "T") == 0) || (strcmp(oarg
, "P") == 0)) {
823 map_to_units(char *buf
, uint_t bufsize
, double num
, char unit
,
827 (void) snprintf(buf
, bufsize
, "%.0lf", num
);
834 for (index
= 0; (int)(num
/1000) != 0; index
++, num
/= 1000)
854 /* Largest unit supported */
862 /* Already raw numbers */
872 num
/= (1000*1000*1000);
875 num
/= (1000.0*1000.0*1000.0*1000.0);
878 /* Largest unit supported */
880 num
/= (1000.0*1000.0*1000.0*1000.0*1000.0);
886 (void) snprintf(buf
, bufsize
, " %7.0lf%c", num
, unit
);
888 (void) snprintf(buf
, bufsize
, " %6.2lf%c", num
, unit
);
892 get_link_prev_stat(datalink_id_t linkid
, void *arg
)
894 show_state_t
*state
= (show_state_t
*)arg
;
895 link_chain_t
*link_curr
= NULL
;
897 /* Scan prev linkid list and look for entry matching this entry */
898 for (link_curr
= state
->ls_linkchain
; link_curr
;
899 link_curr
= link_curr
->lc_next
) {
900 if (link_curr
->lc_linkid
== linkid
)
903 /* New link, add it */
904 if (link_curr
== NULL
) {
905 link_curr
= (link_chain_t
*)malloc(sizeof (link_chain_t
));
906 if (link_curr
== NULL
)
908 link_curr
->lc_linkid
= linkid
;
909 bzero(&link_curr
->lc_statchain
,
910 sizeof (link_curr
->lc_statchain
));
911 link_curr
->lc_next
= state
->ls_linkchain
;
912 state
->ls_linkchain
= link_curr
;
919 * Number of links may change while dlstat with -i is executing.
920 * Free memory allocated for links that are no longer there.
921 * Prepare for next iteration by marking visited = false for existing stat
925 cleanup_removed_links(show_state_t
*state
)
929 link_chain_t
*tofree
;
932 /* Delete all nodes from the list that have lc_visited marked false */
933 lcurr
= state
->ls_linkchain
;
934 while (lcurr
!= NULL
) {
935 if (lcurr
->lc_visited
) {
936 lcurr
->lc_visited
= B_FALSE
;
938 lcurr
= lcurr
->lc_next
;
941 /* Is it head of the list? */
942 if (lcurr
== state
->ls_linkchain
)
943 state
->ls_linkchain
= lcurr
->lc_next
;
945 lprev
->lc_next
= lcurr
->lc_next
;
946 /* lprev remains the same */
948 lcurr
= lcurr
->lc_next
;
950 /* Free stats memory for the removed link */
951 for (i
= 0; i
< DLADM_STAT_NUM_STATS
; i
++) {
952 if (state
->ls_stattype
[i
])
953 dladm_link_stat_free(tofree
->lc_statchain
[i
]);
960 print_total_stats(const char *linkname
, void *statentry
, char unit
,
963 total_stat_entry_t
*sentry
= statentry
;
964 total_stat_t
*link_stats
= &sentry
->tse_stats
;
965 total_fields_buf_t
*buf
;
967 buf
= malloc(sizeof (total_fields_buf_t
));
971 (void) snprintf(buf
->t_linkname
, sizeof (buf
->t_linkname
), "%s",
974 map_to_units(buf
->t_ipackets
, sizeof (buf
->t_ipackets
),
975 link_stats
->ts_ipackets
, unit
, parsable
);
977 map_to_units(buf
->t_rbytes
, sizeof (buf
->t_rbytes
),
978 link_stats
->ts_rbytes
, unit
, parsable
);
980 map_to_units(buf
->t_opackets
, sizeof (buf
->t_opackets
),
981 link_stats
->ts_opackets
, unit
, parsable
);
983 map_to_units(buf
->t_obytes
, sizeof (buf
->t_obytes
),
984 link_stats
->ts_obytes
, unit
, parsable
);
991 print_rx_generic_ring_stats(const char *linkname
, void *statentry
, char unit
,
994 ring_stat_entry_t
*sentry
= statentry
;
995 ring_stat_t
*link_stats
= &sentry
->re_stats
;
996 ring_fields_buf_t
*buf
;
998 buf
= malloc(sizeof (ring_fields_buf_t
));
1002 (void) snprintf(buf
->r_linkname
, sizeof (buf
->r_linkname
), "%s",
1005 (void) snprintf(buf
->r_type
, sizeof (buf
->r_type
), "rx");
1007 if (sentry
->re_index
== DLSTAT_INVALID_ENTRY
) {
1008 (void) snprintf(buf
->r_index
, sizeof (buf
->r_index
), "--");
1010 (void) snprintf(buf
->r_index
, sizeof (buf
->r_index
),
1011 "%llu", sentry
->re_index
);
1014 map_to_units(buf
->r_packets
, sizeof (buf
->r_packets
),
1015 link_stats
->r_packets
, unit
, parsable
);
1017 map_to_units(buf
->r_bytes
, sizeof (buf
->r_bytes
),
1018 link_stats
->r_bytes
, unit
, parsable
);
1025 print_tx_generic_ring_stats(const char *linkname
, void *statentry
, char unit
,
1028 ring_stat_entry_t
*sentry
= statentry
;
1029 ring_stat_t
*link_stats
= &sentry
->re_stats
;
1030 ring_fields_buf_t
*buf
;
1032 buf
= malloc(sizeof (ring_fields_buf_t
));
1036 (void) snprintf(buf
->r_linkname
, sizeof (buf
->r_linkname
), "%s",
1039 (void) snprintf(buf
->r_type
, sizeof (buf
->r_type
), "tx");
1041 if (sentry
->re_index
== DLSTAT_INVALID_ENTRY
) {
1042 (void) snprintf(buf
->r_index
, sizeof (buf
->r_index
), "--");
1044 (void) snprintf(buf
->r_index
, sizeof (buf
->r_index
),
1045 "%llu", sentry
->re_index
);
1048 map_to_units(buf
->r_packets
, sizeof (buf
->r_packets
),
1049 link_stats
->r_packets
, unit
, parsable
);
1051 map_to_units(buf
->r_bytes
, sizeof (buf
->r_bytes
),
1052 link_stats
->r_bytes
, unit
, parsable
);
1059 print_rx_ring_stats(const char *linkname
, void *statentry
, char unit
,
1062 ring_stat_entry_t
*sentry
= statentry
;
1063 ring_stat_t
*link_stats
= &sentry
->re_stats
;
1064 rx_ring_fields_buf_t
*buf
;
1066 buf
= malloc(sizeof (rx_ring_fields_buf_t
));
1070 (void) snprintf(buf
->rr_linkname
, sizeof (buf
->rr_linkname
), "%s",
1073 (void) snprintf(buf
->rr_type
, sizeof (buf
->rr_type
), "rx");
1075 if (sentry
->re_index
== DLSTAT_INVALID_ENTRY
) {
1076 (void) snprintf(buf
->rr_index
, sizeof (buf
->rr_index
), "--");
1078 (void) snprintf(buf
->rr_index
, sizeof (buf
->rr_index
),
1079 "%llu", sentry
->re_index
);
1082 map_to_units(buf
->rr_ipackets
, sizeof (buf
->rr_ipackets
),
1083 link_stats
->r_packets
, unit
, parsable
);
1085 map_to_units(buf
->rr_rbytes
, sizeof (buf
->rr_rbytes
),
1086 link_stats
->r_bytes
, unit
, parsable
);
1093 print_tx_ring_stats(const char *linkname
, void *statentry
, char unit
,
1096 ring_stat_entry_t
*sentry
= statentry
;
1097 ring_stat_t
*link_stats
= &sentry
->re_stats
;
1098 tx_ring_fields_buf_t
*buf
;
1100 buf
= malloc(sizeof (tx_ring_fields_buf_t
));
1104 (void) snprintf(buf
->tr_linkname
, sizeof (buf
->tr_linkname
), "%s",
1107 (void) snprintf(buf
->tr_type
, sizeof (buf
->tr_type
), "tx");
1109 if (sentry
->re_index
== DLSTAT_INVALID_ENTRY
) {
1110 (void) snprintf(buf
->tr_index
, sizeof (buf
->tr_index
), "--");
1112 (void) snprintf(buf
->tr_index
, sizeof (buf
->tr_index
),
1113 "%llu", sentry
->re_index
);
1116 map_to_units(buf
->tr_opackets
, sizeof (buf
->tr_opackets
),
1117 link_stats
->r_packets
, unit
, parsable
);
1119 map_to_units(buf
->tr_obytes
, sizeof (buf
->tr_obytes
),
1120 link_stats
->r_bytes
, unit
, parsable
);
1127 print_rx_generic_lane_stats(const char *linkname
, void *statentry
, char unit
,
1130 rx_lane_stat_entry_t
*sentry
= statentry
;
1131 rx_lane_stat_t
*link_stats
= &sentry
->rle_stats
;
1132 lane_fields_buf_t
*buf
;
1134 if (sentry
->rle_id
== L_DFNCT
)
1137 buf
= malloc(sizeof (lane_fields_buf_t
));
1141 (void) snprintf(buf
->l_linkname
, sizeof (buf
->l_linkname
), "%s",
1144 (void) snprintf(buf
->l_type
, sizeof (buf
->l_type
), "rx");
1146 if (sentry
->rle_id
== L_HWLANE
)
1147 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "hw");
1148 else if (sentry
->rle_id
== L_SWLANE
)
1149 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "sw");
1150 else if (sentry
->rle_id
== L_LOCAL
)
1151 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "local");
1152 else if (sentry
->rle_id
== L_BCAST
)
1153 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "bcast");
1155 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "--");
1157 if (sentry
->rle_index
== DLSTAT_INVALID_ENTRY
) {
1158 (void) snprintf(buf
->l_index
, sizeof (buf
->l_index
), "--");
1160 (void) snprintf(buf
->l_index
, sizeof (buf
->l_index
),
1161 "%llu", sentry
->rle_index
);
1164 map_to_units(buf
->l_packets
, sizeof (buf
->l_packets
),
1165 link_stats
->rl_ipackets
, unit
, parsable
);
1167 map_to_units(buf
->l_bytes
, sizeof (buf
->l_bytes
),
1168 link_stats
->rl_rbytes
, unit
, parsable
);
1175 print_tx_generic_lane_stats(const char *linkname
, void *statentry
, char unit
,
1178 tx_lane_stat_entry_t
*sentry
= statentry
;
1179 tx_lane_stat_t
*link_stats
= &sentry
->tle_stats
;
1180 lane_fields_buf_t
*buf
;
1182 if (sentry
->tle_id
== L_DFNCT
)
1185 buf
= malloc(sizeof (lane_fields_buf_t
));
1189 (void) snprintf(buf
->l_linkname
, sizeof (buf
->l_linkname
), "%s",
1192 (void) snprintf(buf
->l_type
, sizeof (buf
->l_type
), "tx");
1194 if (sentry
->tle_id
== L_HWLANE
)
1195 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "hw");
1196 else if (sentry
->tle_id
== L_SWLANE
)
1197 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "sw");
1198 else if (sentry
->tle_id
== L_BCAST
)
1199 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "bcast");
1201 (void) snprintf(buf
->l_id
, sizeof (buf
->l_id
), "--");
1203 if (sentry
->tle_index
== DLSTAT_INVALID_ENTRY
) {
1204 (void) snprintf(buf
->l_index
, sizeof (buf
->l_index
), "--");
1206 (void) snprintf(buf
->l_index
, sizeof (buf
->l_index
),
1207 "%llu", sentry
->tle_index
);
1209 map_to_units(buf
->l_packets
, sizeof (buf
->l_packets
),
1210 link_stats
->tl_opackets
, unit
, parsable
);
1212 map_to_units(buf
->l_bytes
, sizeof (buf
->l_bytes
),
1213 link_stats
->tl_obytes
, unit
, parsable
);
1220 print_rx_lane_stats(const char *linkname
, void *statentry
, char unit
,
1223 rx_lane_stat_entry_t
*sentry
= statentry
;
1224 rx_lane_stat_t
*link_stats
= &sentry
->rle_stats
;
1225 rx_lane_fields_buf_t
*buf
;
1227 if (sentry
->rle_id
== L_DFNCT
)
1230 buf
= malloc(sizeof (rx_lane_fields_buf_t
));
1234 (void) snprintf(buf
->rl_linkname
, sizeof (buf
->rl_linkname
), "%s",
1237 (void) snprintf(buf
->rl_type
, sizeof (buf
->rl_type
), "rx");
1239 if (sentry
->rle_id
== L_HWLANE
)
1240 (void) snprintf(buf
->rl_id
, sizeof (buf
->rl_id
), "hw");
1241 else if (sentry
->rle_id
== L_SWLANE
)
1242 (void) snprintf(buf
->rl_id
, sizeof (buf
->rl_id
), "sw");
1243 else if (sentry
->rle_id
== L_LOCAL
)
1244 (void) snprintf(buf
->rl_id
, sizeof (buf
->rl_id
), "local");
1245 else if (sentry
->rle_id
== L_BCAST
)
1246 (void) snprintf(buf
->rl_id
, sizeof (buf
->rl_id
), "bcast");
1248 (void) snprintf(buf
->rl_id
, sizeof (buf
->rl_id
), "--");
1250 if (sentry
->rle_index
== DLSTAT_INVALID_ENTRY
) {
1251 (void) snprintf(buf
->rl_index
, sizeof (buf
->rl_index
), "--");
1253 (void) snprintf(buf
->rl_index
, sizeof (buf
->rl_index
),
1254 "%llu", sentry
->rle_index
);
1257 map_to_units(buf
->rl_ipackets
, sizeof (buf
->rl_ipackets
),
1258 link_stats
->rl_ipackets
, unit
, parsable
);
1260 map_to_units(buf
->rl_rbytes
, sizeof (buf
->rl_rbytes
),
1261 link_stats
->rl_rbytes
, unit
, parsable
);
1263 map_to_units(buf
->rl_intrs
, sizeof (buf
->rl_intrs
),
1264 link_stats
->rl_intrs
, unit
, parsable
);
1266 map_to_units(buf
->rl_polls
, sizeof (buf
->rl_polls
),
1267 link_stats
->rl_polls
, unit
, parsable
);
1269 map_to_units(buf
->rl_sdrops
, sizeof (buf
->rl_sdrops
),
1270 link_stats
->rl_sdrops
, unit
, parsable
);
1272 map_to_units(buf
->rl_chl10
, sizeof (buf
->rl_chl10
),
1273 link_stats
->rl_chl10
, unit
, parsable
);
1275 map_to_units(buf
->rl_ch10_50
, sizeof (buf
->rl_ch10_50
),
1276 link_stats
->rl_ch10_50
, unit
, parsable
);
1278 map_to_units(buf
->rl_chg50
, sizeof (buf
->rl_chg50
),
1279 link_stats
->rl_chg50
, unit
, parsable
);
1286 print_tx_lane_stats(const char *linkname
, void *statentry
, char unit
,
1289 tx_lane_stat_entry_t
*sentry
= statentry
;
1290 tx_lane_stat_t
*link_stats
= &sentry
->tle_stats
;
1291 tx_lane_fields_buf_t
*buf
= NULL
;
1293 if (sentry
->tle_id
== L_DFNCT
)
1296 buf
= malloc(sizeof (tx_lane_fields_buf_t
));
1300 (void) snprintf(buf
->tl_linkname
, sizeof (buf
->tl_linkname
), "%s",
1303 (void) snprintf(buf
->tl_type
, sizeof (buf
->tl_type
), "tx");
1305 if (sentry
->tle_id
== L_HWLANE
)
1306 (void) snprintf(buf
->tl_id
, sizeof (buf
->tl_id
), "hw");
1307 else if (sentry
->tle_id
== L_SWLANE
)
1308 (void) snprintf(buf
->tl_id
, sizeof (buf
->tl_id
), "sw");
1309 else if (sentry
->tle_id
== L_BCAST
)
1310 (void) snprintf(buf
->tl_id
, sizeof (buf
->tl_id
), "bcast");
1312 (void) snprintf(buf
->tl_id
, sizeof (buf
->tl_id
), "--");
1314 if (sentry
->tle_index
== DLSTAT_INVALID_ENTRY
) {
1315 (void) snprintf(buf
->tl_index
, sizeof (buf
->tl_index
), "--");
1317 (void) snprintf(buf
->tl_index
, sizeof (buf
->tl_index
),
1318 "%llu", sentry
->tle_index
);
1321 map_to_units(buf
->tl_opackets
, sizeof (buf
->tl_opackets
),
1322 link_stats
->tl_opackets
, unit
, parsable
);
1324 map_to_units(buf
->tl_obytes
, sizeof (buf
->tl_obytes
),
1325 link_stats
->tl_obytes
, unit
, parsable
);
1327 map_to_units(buf
->tl_blockcnt
, sizeof (buf
->tl_blockcnt
),
1328 link_stats
->tl_blockcnt
, unit
, parsable
);
1330 map_to_units(buf
->tl_unblockcnt
, sizeof (buf
->tl_unblockcnt
),
1331 link_stats
->tl_unblockcnt
, unit
, parsable
);
1333 map_to_units(buf
->tl_sdrops
, sizeof (buf
->tl_sdrops
),
1334 link_stats
->tl_sdrops
, unit
, parsable
);
1341 print_fanout_stats(const char *linkname
, void *statentry
, char unit
,
1344 fanout_stat_entry_t
*sentry
= statentry
;
1345 fanout_stat_t
*link_stats
= &sentry
->fe_stats
;
1346 rx_fanout_lane_fields_buf_t
*buf
;
1348 buf
= malloc(sizeof (rx_fanout_lane_fields_buf_t
));
1352 (void) snprintf(buf
->rfl_linkname
, sizeof (buf
->rfl_linkname
), "%s",
1355 (void) snprintf(buf
->rfl_type
, sizeof (buf
->rfl_type
), "rx");
1357 if (sentry
->fe_id
== L_HWLANE
)
1358 (void) snprintf(buf
->rfl_id
, sizeof (buf
->rfl_id
), "hw");
1359 else if (sentry
->fe_id
== L_SWLANE
)
1360 (void) snprintf(buf
->rfl_id
, sizeof (buf
->rfl_id
), "sw");
1361 else if (sentry
->fe_id
== L_LCLSWLANE
)
1362 (void) snprintf(buf
->rfl_id
, sizeof (buf
->rfl_id
), "lcl/sw");
1363 else if (sentry
->fe_id
== L_LOCAL
)
1364 (void) snprintf(buf
->rfl_id
, sizeof (buf
->rfl_id
), "local");
1365 else if (sentry
->fe_id
== L_BCAST
)
1366 (void) snprintf(buf
->rfl_id
, sizeof (buf
->rfl_id
), "bcast");
1368 (void) snprintf(buf
->rfl_id
, sizeof (buf
->rfl_id
), "--");
1370 if (sentry
->fe_index
== DLSTAT_INVALID_ENTRY
) {
1371 (void) snprintf(buf
->rfl_index
, sizeof (buf
->rfl_index
), "--");
1373 (void) snprintf(buf
->rfl_index
, sizeof (buf
->rfl_index
),
1374 "%llu", sentry
->fe_index
);
1377 if (sentry
->fe_foutindex
== DLSTAT_INVALID_ENTRY
)
1378 (void) snprintf(buf
->rfl_fout
, sizeof (buf
->rfl_fout
), "--");
1380 (void) snprintf(buf
->rfl_fout
, sizeof (buf
->rfl_fout
), "%llu",
1381 sentry
->fe_foutindex
);
1384 map_to_units(buf
->rfl_ipackets
, sizeof (buf
->rfl_ipackets
),
1385 link_stats
->f_ipackets
, unit
, parsable
);
1387 map_to_units(buf
->rfl_rbytes
, sizeof (buf
->rfl_rbytes
),
1388 link_stats
->f_rbytes
, unit
, parsable
);
1395 print_aggr_port_stats(const char *linkname
, void *statentry
, char unit
,
1398 aggr_port_stat_entry_t
*sentry
= statentry
;
1399 aggr_port_stat_t
*link_stats
= &sentry
->ape_stats
;
1400 aggr_port_fields_buf_t
*buf
;
1401 char portname
[MAXLINKNAMELEN
];
1403 buf
= malloc(sizeof (aggr_port_fields_buf_t
));
1407 (void) snprintf(buf
->ap_linkname
, sizeof (buf
->ap_linkname
), "%s",
1410 if (dladm_datalink_id2info(handle
, sentry
->ape_portlinkid
, NULL
,
1411 NULL
, NULL
, portname
, DLPI_LINKNAME_MAX
)
1412 != DLADM_STATUS_OK
) {
1413 (void) snprintf(buf
->ap_portname
,
1414 sizeof (buf
->ap_portname
), "--");
1416 (void) snprintf(buf
->ap_portname
,
1417 sizeof (buf
->ap_portname
), "%s", portname
);
1420 map_to_units(buf
->ap_ipackets
, sizeof (buf
->ap_ipackets
),
1421 link_stats
->ap_ipackets
, unit
, parsable
);
1423 map_to_units(buf
->ap_rbytes
, sizeof (buf
->ap_rbytes
),
1424 link_stats
->ap_rbytes
, unit
, parsable
);
1426 map_to_units(buf
->ap_opackets
, sizeof (buf
->ap_opackets
),
1427 link_stats
->ap_opackets
, unit
, parsable
);
1429 map_to_units(buf
->ap_obytes
, sizeof (buf
->ap_obytes
),
1430 link_stats
->ap_obytes
, unit
, parsable
);
1436 dladm_stat_chain_t
*
1437 query_link_stats(dladm_handle_t dh
, datalink_id_t linkid
, void *arg
,
1438 dladm_stat_type_t stattype
)
1440 link_chain_t
*link_node
;
1441 dladm_stat_chain_t
*curr_stat
;
1442 dladm_stat_chain_t
*prev_stat
= NULL
;
1443 dladm_stat_chain_t
*diff_stat
= NULL
;
1445 /* Get prev iteration stat for this link */
1446 link_node
= get_link_prev_stat(linkid
, arg
);
1447 if (link_node
== NULL
)
1450 link_node
->lc_visited
= B_TRUE
;
1451 prev_stat
= link_node
->lc_statchain
[stattype
];
1453 /* Query library for current stats */
1454 curr_stat
= dladm_link_stat_query(dh
, linkid
, stattype
);
1455 if (curr_stat
== NULL
)
1458 /* current stats - prev iteration stats */
1459 diff_stat
= dladm_link_stat_diffchain(curr_stat
, prev_stat
, stattype
);
1461 /* Free prev stats */
1462 dladm_link_stat_free(prev_stat
);
1464 /* Prev <- curr stats */
1465 link_node
->lc_statchain
[stattype
] = curr_stat
;
1472 walk_dlstat_stats(show_state_t
*state
, const char *linkname
,
1473 dladm_stat_type_t stattype
, dladm_stat_chain_t
*diff_stat
)
1475 dladm_stat_chain_t
*curr
;
1477 /* Unpack invidual stat entry and call library consumer's callback */
1478 for (curr
= diff_stat
; curr
!= NULL
; curr
= curr
->dc_next
) {
1481 /* Format the raw numbers for printing */
1482 fields_buf
= state
->ls_stats2str
[stattype
](linkname
,
1483 curr
->dc_statentry
, state
->ls_unit
, state
->ls_parsable
);
1484 /* Print the stats */
1485 if (fields_buf
!= NULL
)
1486 ofmt_print(state
->ls_ofmt
, fields_buf
);
1492 show_queried_stats(dladm_handle_t dh
, datalink_id_t linkid
, void *arg
)
1494 show_state_t
*state
= arg
;
1496 dladm_stat_chain_t
*diff_stat
;
1497 char linkname
[DLPI_LINKNAME_MAX
];
1499 if (dladm_datalink_id2info(dh
, linkid
, NULL
, NULL
, NULL
, linkname
,
1500 DLPI_LINKNAME_MAX
) != DLADM_STATUS_OK
) {
1504 for (i
= 0; i
< DLADM_STAT_NUM_STATS
; i
++) {
1505 if (state
->ls_stattype
[i
]) {
1507 * Query library for stats
1508 * Stats are returned as chain of raw numbers
1510 diff_stat
= query_link_stats(handle
, linkid
, arg
, i
);
1511 walk_dlstat_stats(state
, linkname
, i
, diff_stat
);
1512 dladm_link_stat_free(diff_stat
);
1516 return (DLADM_WALK_CONTINUE
);
1520 show_link_stats(datalink_id_t linkid
, show_state_t state
, uint32_t interval
)
1523 if (linkid
== DATALINK_ALL_LINKID
) {
1524 (void) dladm_walk_datalink_id(show_queried_stats
,
1525 handle
, &state
, DATALINK_CLASS_ALL
,
1526 DATALINK_ANY_MEDIATYPE
, DLADM_OPT_ACTIVE
);
1528 (void) show_queried_stats(handle
, linkid
, &state
);
1534 cleanup_removed_links(&state
);
1535 (void) sleep(interval
);
1540 print_all_stats(dladm_handle_t dh
, datalink_id_t linkid
,
1541 dladm_stat_chain_t
*stat_chain
)
1543 dladm_stat_chain_t
*curr
;
1544 name_value_stat_entry_t
*stat_entry
;
1545 name_value_stat_t
*curr_stat
;
1546 boolean_t stat_printed
= B_FALSE
;
1547 char linkname
[MAXLINKNAMELEN
];
1548 char prev_linkname
[MAXLINKNAMELEN
];
1550 if (dladm_datalink_id2info(dh
, linkid
, NULL
, NULL
, NULL
, linkname
,
1551 DLPI_LINKNAME_MAX
) != DLADM_STATUS_OK
)
1554 for (curr
= stat_chain
; curr
!= NULL
; curr
= curr
->dc_next
) {
1555 stat_entry
= curr
->dc_statentry
;
1558 * If link name is already printed in previous iteration,
1561 if (strcmp(prev_linkname
, linkname
) != 0)
1562 printf("%s \n", linkname
);
1563 printf(" %s \n", stat_entry
->nve_header
);
1565 /* Print stat fields */
1566 for (curr_stat
= stat_entry
->nve_stats
; curr_stat
!= NULL
;
1567 curr_stat
= curr_stat
->nv_nextstat
) {
1568 printf("\t%15s", curr_stat
->nv_statname
);
1569 printf("\t\t%15llu\n", curr_stat
->nv_statval
);
1572 strncpy(prev_linkname
, linkname
, MAXLINKNAMELEN
);
1573 stat_printed
= B_TRUE
;
1576 printf("---------------------------------------------------\n");
1580 dump_queried_stats(dladm_handle_t dh
, datalink_id_t linkid
, void *arg
)
1582 boolean_t
*stattype
= arg
;
1584 dladm_stat_chain_t
*stat_chain
;
1586 for (i
= 0; i
< DLADM_STAT_NUM_STATS
; i
++) {
1588 stat_chain
= dladm_link_stat_query_all(dh
, linkid
, i
);
1589 print_all_stats(dh
, linkid
, stat_chain
);
1590 dladm_link_stat_query_all_free(stat_chain
);
1594 return (DLADM_WALK_CONTINUE
);
1598 dump_all_link_stats(datalink_id_t linkid
, boolean_t
*stattype
)
1600 if (linkid
== DATALINK_ALL_LINKID
) {
1601 (void) dladm_walk_datalink_id(dump_queried_stats
,
1602 handle
, stattype
, DATALINK_CLASS_ALL
,
1603 DATALINK_ANY_MEDIATYPE
, DLADM_OPT_ACTIVE
);
1605 (void) dump_queried_stats(handle
, linkid
, stattype
);
1610 do_show(int argc
, char *argv
[], const char *use
)
1613 boolean_t r_arg
= B_FALSE
;
1614 boolean_t t_arg
= B_FALSE
;
1615 boolean_t i_arg
= B_FALSE
;
1616 boolean_t p_arg
= B_FALSE
;
1617 boolean_t o_arg
= B_FALSE
;
1618 boolean_t u_arg
= B_FALSE
;
1619 boolean_t a_arg
= B_FALSE
;
1620 boolean_t A_arg
= B_FALSE
;
1621 uint32_t flags
= DLADM_OPT_ACTIVE
;
1622 datalink_id_t linkid
= DATALINK_ALL_LINKID
;
1623 uint32_t interval
= 0;
1626 dladm_status_t status
;
1627 char *fields_str
= NULL
;
1628 char *o_fields_str
= NULL
;
1630 char *total_stat_fields
=
1631 "link,ipkts,rbytes,opkts,obytes";
1632 char *rx_total_stat_fields
=
1633 "link,ipkts,rbytes,intrs,polls,ch<10,ch10-50,ch>50";
1634 char *tx_total_stat_fields
=
1635 "link,opkts,obytes,blkcnt,ublkcnt";
1638 ofmt_status_t oferr
;
1639 uint_t ofmtflags
= OFMT_RIGHTJUST
;
1640 ofmt_field_t
*oftemplate
;
1642 bzero(&state
, sizeof (state
));
1644 while ((option
= getopt_long(argc
, argv
, ":rtaApi:o:u:",
1645 NULL
, NULL
)) != -1) {
1676 if (!dladm_str2interval(optarg
, &interval
))
1677 die("invalid interval value '%s'", optarg
);
1687 o_fields_str
= optarg
;
1694 if (!dlstat_unit(optarg
, &unit
))
1695 die("invalid unit value '%s',"
1696 "unit must be R|K|M|G|T|P", optarg
);
1699 die_opterr(optopt
, option
, use
);
1705 die("the options -t and -r are not compatible");
1708 die("the options -u and -p are not compatible");
1710 if (p_arg
&& !o_arg
)
1711 die("-p requires -o");
1713 if (p_arg
&& strcasecmp(o_fields_str
, "all") == 0)
1714 die("\"-o all\" is invalid with -p");
1717 die("the options -a and -A are not compatible");
1720 (p_arg
|| o_arg
|| u_arg
|| i_arg
)) {
1721 die("the option -a is not compatible with "
1726 (r_arg
|| t_arg
|| p_arg
|| o_arg
|| u_arg
|| i_arg
)) {
1727 die("the option -A is not compatible with "
1728 "-r, -t, -p, -o, -u, -i");
1731 /* get link name (optional last argument) */
1732 if (optind
== (argc
-1)) {
1733 if (strlen(argv
[optind
]) >= MAXLINKNAMELEN
)
1734 die("link name too long");
1736 if ((status
= dladm_name2info(handle
, argv
[optind
], &linkid
,
1737 NULL
, NULL
, NULL
)) != DLADM_STATUS_OK
) {
1738 die_dlerr(status
, "link %s is not valid", argv
[optind
]);
1740 } else if (optind
!= argc
) {
1746 boolean_t stattype
[DLADM_STAT_NUM_STATS
];
1748 bzero(&stattype
, sizeof (stattype
));
1750 stattype
[DLADM_STAT_RX_LANE_TOTAL
] = B_TRUE
;
1752 stattype
[DLADM_STAT_TX_LANE_TOTAL
] = B_TRUE
;
1753 } else { /* Display both Rx and Tx lanes */
1754 stattype
[DLADM_STAT_TOTAL
] = B_TRUE
;
1757 dump_all_link_stats(linkid
, stattype
);
1762 boolean_t stattype
[DLADM_STAT_NUM_STATS
];
1765 for (i
= 0; i
< DLADM_STAT_NUM_STATS
; i
++)
1766 stattype
[i
] = B_TRUE
;
1768 dump_all_link_stats(linkid
, stattype
);
1772 state
.ls_unit
= unit
;
1773 state
.ls_parsable
= p_arg
;
1775 if (state
.ls_parsable
)
1776 ofmtflags
|= OFMT_PARSABLE
;
1779 fields_str
= rx_total_stat_fields
;
1780 oftemplate
= rx_lane_s_fields
;
1781 state
.ls_stattype
[DLADM_STAT_RX_LANE_TOTAL
] = B_TRUE
;
1782 state
.ls_stats2str
[DLADM_STAT_RX_LANE_TOTAL
] =
1783 print_rx_lane_stats
;
1785 fields_str
= tx_total_stat_fields
;
1786 oftemplate
= tx_lane_s_fields
;
1787 state
.ls_stattype
[DLADM_STAT_TX_LANE_TOTAL
] = B_TRUE
;
1788 state
.ls_stats2str
[DLADM_STAT_TX_LANE_TOTAL
] =
1789 print_tx_lane_stats
;
1790 } else { /* Display both Rx and Tx lanes total */
1791 fields_str
= total_stat_fields
;
1792 oftemplate
= total_s_fields
;
1793 state
.ls_stattype
[DLADM_STAT_TOTAL
] = B_TRUE
;
1794 state
.ls_stats2str
[DLADM_STAT_TOTAL
] = print_total_stats
;
1798 fields_str
= (strcasecmp(o_fields_str
, "all") == 0) ?
1799 fields_str
: o_fields_str
;
1802 oferr
= ofmt_open(fields_str
, oftemplate
, ofmtflags
, 0, &ofmt
);
1803 dlstat_ofmt_check(oferr
, state
.ls_parsable
, ofmt
);
1804 state
.ls_ofmt
= ofmt
;
1806 show_link_stats(linkid
, state
, interval
);
1812 do_show_phys(int argc
, char *argv
[], const char *use
)
1815 boolean_t r_arg
= B_FALSE
;
1816 boolean_t t_arg
= B_FALSE
;
1817 boolean_t i_arg
= B_FALSE
;
1818 boolean_t p_arg
= B_FALSE
;
1819 boolean_t o_arg
= B_FALSE
;
1820 boolean_t u_arg
= B_FALSE
;
1821 boolean_t a_arg
= B_FALSE
;
1822 uint32_t flags
= DLADM_OPT_ACTIVE
;
1823 datalink_id_t linkid
= DATALINK_ALL_LINKID
;
1824 char linkname
[MAXLINKNAMELEN
];
1825 uint32_t interval
= 0;
1828 dladm_status_t status
;
1829 char *fields_str
= NULL
;
1830 char *o_fields_str
= NULL
;
1831 char *ring_stat_fields
=
1832 "link,type,index,pkts,bytes";
1833 char *rx_ring_stat_fields
=
1834 "link,type,index,ipkts,rbytes";
1835 char *tx_ring_stat_fields
=
1836 "link,type,index,opkts,obytes";
1839 ofmt_status_t oferr
;
1840 uint_t ofmtflags
= OFMT_RIGHTJUST
;
1841 ofmt_field_t
*oftemplate
;
1843 bzero(&state
, sizeof (state
));
1845 while ((option
= getopt_long(argc
, argv
, ":rtapi:o:u:",
1846 NULL
, NULL
)) != -1) {
1871 if (!dladm_str2interval(optarg
, &interval
))
1872 die("invalid interval value '%s'", optarg
);
1882 o_fields_str
= optarg
;
1889 if (!dlstat_unit(optarg
, &unit
))
1890 die("invalid unit value '%s',"
1891 "unit must be R|K|M|G|T|P", optarg
);
1894 die_opterr(optopt
, option
, use
);
1900 die("the options -t and -r are not compatible");
1903 die("the options -u and -p are not compatible");
1905 if (p_arg
&& !o_arg
)
1906 die("-p requires -o");
1908 if (p_arg
&& strcasecmp(o_fields_str
, "all") == 0)
1909 die("\"-o all\" is invalid with -p");
1912 (p_arg
|| o_arg
|| u_arg
|| i_arg
)) {
1913 die("the option -a is not compatible with "
1918 /* get link name (optional last argument) */
1919 if (optind
== (argc
-1)) {
1920 if (strlen(argv
[optind
]) >= MAXLINKNAMELEN
)
1921 die("link name too long");
1923 if ((status
= dladm_name2info(handle
, argv
[optind
], &linkid
,
1924 NULL
, NULL
, NULL
)) != DLADM_STATUS_OK
) {
1925 die_dlerr(status
, "link %s is not valid", argv
[optind
]);
1927 } else if (optind
!= argc
) {
1932 boolean_t stattype
[DLADM_STAT_NUM_STATS
];
1934 bzero(&stattype
, sizeof (stattype
));
1937 stattype
[DLADM_STAT_RX_RING
] = B_TRUE
;
1939 stattype
[DLADM_STAT_TX_RING
] = B_TRUE
;
1940 } else { /* Display both Rx and Tx lanes */
1941 stattype
[DLADM_STAT_RX_RING
] = B_TRUE
;
1942 stattype
[DLADM_STAT_TX_RING
] = B_TRUE
;
1945 dump_all_link_stats(linkid
, stattype
);
1949 state
.ls_unit
= unit
;
1950 state
.ls_parsable
= p_arg
;
1952 if (state
.ls_parsable
)
1953 ofmtflags
|= OFMT_PARSABLE
;
1956 fields_str
= rx_ring_stat_fields
;
1957 oftemplate
= rx_ring_s_fields
;
1958 state
.ls_stattype
[DLADM_STAT_RX_RING
] = B_TRUE
;
1959 state
.ls_stats2str
[DLADM_STAT_RX_RING
] = print_rx_ring_stats
;
1961 fields_str
= tx_ring_stat_fields
;
1962 oftemplate
= tx_ring_s_fields
;
1963 state
.ls_stattype
[DLADM_STAT_TX_RING
] = B_TRUE
;
1964 state
.ls_stats2str
[DLADM_STAT_TX_RING
] = print_tx_ring_stats
;
1965 } else { /* Display both Rx and Tx lanes */
1966 fields_str
= ring_stat_fields
;
1967 oftemplate
= ring_s_fields
;
1968 state
.ls_stattype
[DLADM_STAT_RX_RING
] = B_TRUE
;
1969 state
.ls_stattype
[DLADM_STAT_TX_RING
] = B_TRUE
;
1970 state
.ls_stats2str
[DLADM_STAT_RX_RING
] =
1971 print_rx_generic_ring_stats
;
1972 state
.ls_stats2str
[DLADM_STAT_TX_RING
] =
1973 print_tx_generic_ring_stats
;
1977 fields_str
= (strcasecmp(o_fields_str
, "all") == 0) ?
1978 fields_str
: o_fields_str
;
1981 oferr
= ofmt_open(fields_str
, oftemplate
, ofmtflags
, 0, &ofmt
);
1982 dlstat_ofmt_check(oferr
, state
.ls_parsable
, ofmt
);
1983 state
.ls_ofmt
= ofmt
;
1985 show_link_stats(linkid
, state
, interval
);
1991 do_show_link(int argc
, char *argv
[], const char *use
)
1994 boolean_t r_arg
= B_FALSE
;
1995 boolean_t F_arg
= B_FALSE
;
1996 boolean_t t_arg
= B_FALSE
;
1997 boolean_t i_arg
= B_FALSE
;
1998 boolean_t p_arg
= B_FALSE
;
1999 boolean_t o_arg
= B_FALSE
;
2000 boolean_t u_arg
= B_FALSE
;
2001 boolean_t a_arg
= B_FALSE
;
2002 uint32_t flags
= DLADM_OPT_ACTIVE
;
2003 datalink_id_t linkid
= DATALINK_ALL_LINKID
;
2004 uint32_t interval
= 0;
2007 dladm_status_t status
;
2008 char *fields_str
= NULL
;
2009 char *o_fields_str
= NULL
;
2011 char *lane_stat_fields
=
2012 "link,type,id,index,pkts,bytes";
2013 char *rx_lane_stat_fields
=
2014 "link,type,id,index,ipkts,rbytes,intrs,polls,ch<10,ch10-50,ch>50";
2015 char *tx_lane_stat_fields
=
2016 "link,type,id,index,opkts,obytes,blkcnt,ublkcnt";
2017 char *rx_fanout_stat_fields
=
2018 "link,id,index,fout,ipkts,rbytes";
2021 ofmt_status_t oferr
;
2022 uint_t ofmtflags
= OFMT_RIGHTJUST
;
2023 ofmt_field_t
*oftemplate
;
2025 bzero(&state
, sizeof (state
));
2027 while ((option
= getopt_long(argc
, argv
, ":hrtFapi:o:u:",
2028 NULL
, NULL
)) != -1) {
2031 if (r_arg
|| F_arg
|| t_arg
|| i_arg
|| p_arg
||
2032 o_arg
|| u_arg
|| a_arg
) {
2033 die("the option -h is not compatible with "
2034 "-r, -F, -t, -i, -p, -o, -u, -a");
2036 do_show_history(argc
, &argv
[0], use
);
2067 if (!dladm_str2interval(optarg
, &interval
))
2068 die("invalid interval value '%s'", optarg
);
2078 o_fields_str
= optarg
;
2085 if (!dlstat_unit(optarg
, &unit
))
2086 die("invalid unit value '%s',"
2087 "unit must be R|K|M|G|T|P", optarg
);
2090 die_opterr(optopt
, option
, use
);
2096 die("the options -t and -r are not compatible");
2099 die("the options -u and -p are not compatible");
2101 if (F_arg
&& !r_arg
)
2102 die("-F must be used with -r");
2104 if (p_arg
&& !o_arg
)
2105 die("-p requires -o");
2107 if (p_arg
&& strcasecmp(o_fields_str
, "all") == 0)
2108 die("\"-o all\" is invalid with -p");
2111 (p_arg
|| o_arg
|| u_arg
|| i_arg
)) {
2112 die("the option -a is not compatible with "
2116 /* get link name (optional last argument) */
2117 if (optind
== (argc
-1)) {
2118 if (strlen(argv
[optind
]) >= MAXLINKNAMELEN
)
2119 die("link name too long");
2121 if ((status
= dladm_name2info(handle
, argv
[optind
], &linkid
,
2122 NULL
, NULL
, NULL
)) != DLADM_STATUS_OK
) {
2123 die_dlerr(status
, "link %s is not valid", argv
[optind
]);
2125 } else if (optind
!= argc
) {
2130 boolean_t stattype
[DLADM_STAT_NUM_STATS
];
2132 bzero(&stattype
, sizeof (stattype
));
2136 stattype
[DLADM_STAT_RX_LANE_FOUT
] = B_TRUE
;
2138 stattype
[DLADM_STAT_RX_LANE
] = B_TRUE
;
2141 stattype
[DLADM_STAT_TX_LANE
] = B_TRUE
;
2142 } else { /* Display both Rx and Tx lanes */
2143 stattype
[DLADM_STAT_RX_LANE
] = B_TRUE
;
2144 stattype
[DLADM_STAT_TX_LANE
] = B_TRUE
;
2147 dump_all_link_stats(linkid
, stattype
);
2151 state
.ls_unit
= unit
;
2152 state
.ls_parsable
= p_arg
;
2154 if (state
.ls_parsable
)
2155 ofmtflags
|= OFMT_PARSABLE
;
2159 fields_str
= rx_fanout_stat_fields
;
2160 oftemplate
= rx_fanout_lane_s_fields
;
2161 state
.ls_stattype
[DLADM_STAT_RX_LANE_FOUT
] = B_TRUE
;
2162 state
.ls_stats2str
[DLADM_STAT_RX_LANE_FOUT
] =
2165 fields_str
= rx_lane_stat_fields
;
2166 oftemplate
= rx_lane_s_fields
;
2167 state
.ls_stattype
[DLADM_STAT_RX_LANE
] = B_TRUE
;
2168 state
.ls_stats2str
[DLADM_STAT_RX_LANE
] =
2169 print_rx_lane_stats
;
2172 fields_str
= tx_lane_stat_fields
;
2173 oftemplate
= tx_lane_s_fields
;
2174 state
.ls_stattype
[DLADM_STAT_TX_LANE
] = B_TRUE
;
2175 state
.ls_stats2str
[DLADM_STAT_TX_LANE
] = print_tx_lane_stats
;
2176 } else { /* Display both Rx and Tx lanes */
2177 fields_str
= lane_stat_fields
;
2178 oftemplate
= lane_s_fields
;
2179 state
.ls_stattype
[DLADM_STAT_RX_LANE
] = B_TRUE
;
2180 state
.ls_stattype
[DLADM_STAT_TX_LANE
] = B_TRUE
;
2181 state
.ls_stats2str
[DLADM_STAT_RX_LANE
] =
2182 print_rx_generic_lane_stats
;
2183 state
.ls_stats2str
[DLADM_STAT_TX_LANE
] =
2184 print_tx_generic_lane_stats
;
2187 fields_str
= (strcasecmp(o_fields_str
, "all") == 0) ?
2188 fields_str
: o_fields_str
;
2191 oferr
= ofmt_open(fields_str
, oftemplate
, ofmtflags
, 0, &ofmt
);
2192 dlstat_ofmt_check(oferr
, state
.ls_parsable
, ofmt
);
2194 state
.ls_ofmt
= ofmt
;
2196 show_link_stats(linkid
, state
, interval
);
2202 do_show_aggr(int argc
, char *argv
[], const char *use
)
2205 boolean_t r_arg
= B_FALSE
;
2206 boolean_t t_arg
= B_FALSE
;
2207 boolean_t i_arg
= B_FALSE
;
2208 boolean_t p_arg
= B_FALSE
;
2209 boolean_t o_arg
= B_FALSE
;
2210 boolean_t u_arg
= B_FALSE
;
2211 uint32_t flags
= DLADM_OPT_ACTIVE
;
2212 datalink_id_t linkid
= DATALINK_ALL_LINKID
;
2213 uint32_t interval
= 0;
2216 dladm_status_t status
;
2217 char *fields_str
= NULL
;
2218 char *o_fields_str
= NULL
;
2220 char *aggr_stat_fields
=
2221 "link,port,ipkts,rbytes,opkts,obytes";
2222 char *rx_aggr_stat_fields
= "link,port,ipkts,rbytes";
2223 char *tx_aggr_stat_fields
= "link,port,opkts,obytes";
2226 ofmt_status_t oferr
;
2227 uint_t ofmtflags
= OFMT_RIGHTJUST
;
2228 ofmt_field_t
*oftemplate
;
2230 bzero(&state
, sizeof (state
));
2232 while ((option
= getopt_long(argc
, argv
, ":rtpi:o:u:",
2233 NULL
, NULL
)) != -1) {
2252 if (!dladm_str2interval(optarg
, &interval
))
2253 die("invalid interval value '%s'", optarg
);
2263 o_fields_str
= optarg
;
2270 if (!dlstat_unit(optarg
, &unit
))
2271 die("invalid unit value '%s',"
2272 "unit must be R|K|M|G|T|P", optarg
);
2275 die_opterr(optopt
, option
, use
);
2281 die("the options -t and -r are not compatible");
2284 die("the options -u and -p are not compatible");
2286 if (p_arg
&& !o_arg
)
2287 die("-p requires -o");
2289 if (p_arg
&& strcasecmp(o_fields_str
, "all") == 0)
2290 die("\"-o all\" is invalid with -p");
2293 /* get link name (optional last argument) */
2294 if (optind
== (argc
-1)) {
2295 if (strlen(argv
[optind
]) >= MAXLINKNAMELEN
)
2296 die("link name too long");
2298 if ((status
= dladm_name2info(handle
, argv
[optind
], &linkid
,
2299 NULL
, NULL
, NULL
)) != DLADM_STATUS_OK
) {
2300 die_dlerr(status
, "link %s is not valid", argv
[optind
]);
2302 } else if (optind
!= argc
) {
2306 state
.ls_unit
= unit
;
2307 state
.ls_parsable
= p_arg
;
2309 if (state
.ls_parsable
)
2310 ofmtflags
|= OFMT_PARSABLE
;
2312 oftemplate
= aggr_port_s_fields
;
2313 state
.ls_stattype
[DLADM_STAT_AGGR_PORT
] = B_TRUE
;
2314 state
.ls_stats2str
[DLADM_STAT_AGGR_PORT
] = print_aggr_port_stats
;
2317 fields_str
= rx_aggr_stat_fields
;
2319 fields_str
= tx_aggr_stat_fields
;
2321 fields_str
= aggr_stat_fields
;
2324 fields_str
= (strcasecmp(o_fields_str
, "all") == 0) ?
2325 fields_str
: o_fields_str
;
2328 oferr
= ofmt_open(fields_str
, oftemplate
, ofmtflags
, 0, &ofmt
);
2329 dlstat_ofmt_check(oferr
, state
.ls_parsable
, ofmt
);
2330 state
.ls_ofmt
= ofmt
;
2332 show_link_stats(linkid
, state
, interval
);
2339 warn(const char *format
, ...)
2343 format
= gettext(format
);
2344 (void) fprintf(stderr
, "%s: warning: ", progname
);
2346 va_start(alist
, format
);
2347 (void) vfprintf(stderr
, format
, alist
);
2350 (void) putc('\n', stderr
);
2354 * Also closes the dladm handle if it is not NULL.
2358 die_dlerr(dladm_status_t err
, const char *format
, ...)
2361 char errmsg
[DLADM_STRSIZE
];
2363 format
= gettext(format
);
2364 (void) fprintf(stderr
, "%s: ", progname
);
2366 va_start(alist
, format
);
2367 (void) vfprintf(stderr
, format
, alist
);
2369 (void) fprintf(stderr
, ": %s\n", dladm_status2str(err
, errmsg
));
2371 /* close dladm handle if it was opened */
2373 dladm_close(handle
);
2380 die(const char *format
, ...)
2384 format
= gettext(format
);
2385 (void) fprintf(stderr
, "%s: ", progname
);
2387 va_start(alist
, format
);
2388 (void) vfprintf(stderr
, format
, alist
);
2391 (void) putc('\n', stderr
);
2393 /* close dladm handle if it was opened */
2395 dladm_close(handle
);
2403 die("the option -%c cannot be specified more than once", opt
);
2407 die_opterr(int opt
, int opterr
, const char *usage
)
2411 die("option '-%c' requires a value\nusage: %s", opt
,
2416 die("unrecognized option '-%c'\nusage: %s", opt
,
2423 * default output callback function that, when invoked,
2424 * prints string which is offset by ofmt_arg->ofmt_id within buf.
2427 print_default_cb(ofmt_arg_t
*ofarg
, char *buf
, uint_t bufsize
)
2431 value
= (char *)ofarg
->ofmt_cbarg
+ ofarg
->ofmt_id
;
2432 (void) strlcpy(buf
, value
, bufsize
);
2437 dlstat_ofmt_check(ofmt_status_t oferr
, boolean_t parsable
,
2440 char buf
[OFMT_BUFSIZE
];
2442 if (oferr
== OFMT_SUCCESS
)
2444 (void) ofmt_strerror(ofmt
, oferr
, buf
, sizeof (buf
));
2446 * All errors are considered fatal in parsable mode.
2447 * NOMEM errors are always fatal, regardless of mode.
2448 * For other errors, we print diagnostics in human-readable
2449 * mode and processs what we can.
2451 if (parsable
|| oferr
== OFMT_ENOFIELDS
) {