/* * Process a file to set standard arp entries */ static int file(char *name) { FILE *fp; int i, retval; char line[100], arg[5][50], *args[5], *p; if ((fp = fopen(name, "r")) == NULL) xo_err(1, "cannot open %s", name); args[0] = &arg[0][0]; args[1] = &arg[1][0]; args[2] = &arg[2][0]; args[3] = &arg[3][0]; args[4] = &arg[4][0]; retval = 0; while(fgets(line, sizeof(line), fp) != NULL) { if ((p = strchr(line, '#')) != NULL) *p = '\0'; for (p = line; isblank(*p); p++); if (*p == '\n' || *p == '\0') continue; i = sscanf(p, "%49s %49s %49s %49s %49s", arg[0], arg[1], arg[2], arg[3], arg[4]); if (i < 2) { xo_warnx("bad line: %s", line); retval = 1; continue; } if (set(i, args)) retval = 1; } fclose(fp); return (retval); }
/* * Read an array of N counters in kernel memory into array of N uint64_t's. */ int kread_counters(u_long addr, void *buf, size_t size) { uint64_t *c; u_long *counters; size_t i, n; if (kvmd_init() < 0) return (-1); if (size % sizeof(uint64_t) != 0) { xo_warnx("kread_counters: invalid counter set size"); return (-1); } n = size / sizeof(uint64_t); if ((counters = malloc(n * sizeof(u_long))) == NULL) xo_err(-1, "malloc"); if (kread(addr, counters, n * sizeof(u_long)) < 0) { free(counters); return (-1); } c = buf; for (i = 0; i < n; i++) c[i] = kvm_counter_u64_fetch(kvmd, counters[i]); free(counters); return (0); }
static char * noname(const char *name) { char *nname, *p; nname = malloc(strlen(name) + 3); if (nname == NULL) xo_err(1, "malloc"); p = strrchr(name, '.'); if (p != NULL) sprintf(nname, "%.*s.no%s", (int)(p - name), name, p + 1); else sprintf(nname, "no%s", name); return nname; }
static char * nononame(const char *name) { char *nname, *p; p = strrchr(name, '.'); if (strncmp(p ? p + 1 : name, "no", 2)) return NULL; nname = malloc(strlen(name) - 1); if (nname == NULL) xo_err(1, "malloc"); if (p != NULL) sprintf(nname, "%.*s.%s", (int)(p - name), name, p + 3); else strcpy(nname, name + 2); return nname; }
static int kvmd_init(void) { char errbuf[_POSIX2_LINE_MAX]; if (kvmd != NULL) return (0); kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); if (setgid(getgid()) != 0) xo_err(-1, "setgid"); if (kvmd == NULL) { xo_warnx("kvm not available: %s", errbuf); return (-1); } return (0); }
int main(int argc, char **argv) { u_int interval; int clientOnly = -1; int serverOnly = -1; int newStats = 0; int ch; char *memf, *nlistf; int mntlen, i; char buf[1024]; struct statfs *mntbuf; struct nfscl_dumpmntopts dumpmntopts; interval = 0; memf = nlistf = NULL; argc = xo_parse_args(argc, argv); if (argc < 0) exit(1); xo_set_version(NFSSTAT_XO_VERSION); while ((ch = getopt(argc, argv, "cdEesWM:mN:w:zq")) != -1) switch(ch) { case 'M': memf = optarg; break; case 'm': /* Display mount options for NFS mount points. */ mntlen = getmntinfo(&mntbuf, MNT_NOWAIT); for (i = 0; i < mntlen; i++) { if (strcmp(mntbuf->f_fstypename, "nfs") == 0) { dumpmntopts.ndmnt_fname = mntbuf->f_mntonname; dumpmntopts.ndmnt_buf = buf; dumpmntopts.ndmnt_blen = sizeof(buf); if (nfssvc(NFSSVC_DUMPMNTOPTS, &dumpmntopts) >= 0) printf("%s on %s\n%s\n", mntbuf->f_mntfromname, mntbuf->f_mntonname, buf); else if (errno == EPERM) errx(1, "Only priviledged users" " can use the -m option"); } mntbuf++; } exit(0); case 'N': nlistf = optarg; break; case 'W': widemode = 1; break; case 'w': interval = atoi(optarg); break; case 'c': clientOnly = 1; if (serverOnly < 0) serverOnly = 0; break; case 'd': newStats = 1; if (interval == 0) interval = 1; break; case 's': serverOnly = 1; if (clientOnly < 0) clientOnly = 0; break; case 'z': zflag = 1; break; case 'E': if (extra_output != 0) xo_err(1, "-e and -E are mutually exclusive"); extra_output = 2; break; case 'e': if (extra_output != 0) xo_err(1, "-e and -E are mutually exclusive"); extra_output = 1; break; case 'q': printtitle = 0; break; case '?': default: usage(); } argc -= optind; argv += optind; #define BACKWARD_COMPATIBILITY #ifdef BACKWARD_COMPATIBILITY if (*argv) { interval = atoi(*argv); if (*++argv) { nlistf = *argv; if (*++argv) memf = *argv; } } #endif if (modfind("nfscommon") < 0) xo_err(1, "NFS client/server not loaded"); if (interval) { exp_sidewaysintpr(interval, clientOnly, serverOnly, newStats); } else { xo_open_container("nfsstat"); if (extra_output != 0) exp_intpr(clientOnly, serverOnly, extra_output - 1); else intpr(clientOnly, serverOnly); xo_close_container("nfsstat"); } xo_finish(); exit(0); }
static void pr_header(time_t *nowp, int nusers) { double avenrun[3]; time_t uptime; struct timespec tp; int days, hrs, i, mins, secs; char buf[256]; struct sbuf *upbuf; upbuf = sbuf_new_auto(); /* * Print time of day. */ if (strftime(buf, sizeof(buf), use_ampm ? "%l:%M%p" : "%k:%M", localtime(nowp)) != 0) xo_emit("{:time-of-day/%s} ", buf); /* * Print how long system has been up. */ if (clock_gettime(CLOCK_UPTIME, &tp) != -1) { uptime = tp.tv_sec; if (uptime > 60) uptime += 30; days = uptime / 86400; uptime %= 86400; hrs = uptime / 3600; uptime %= 3600; mins = uptime / 60; secs = uptime % 60; xo_emit(" up"); xo_emit("{e:uptime/%lu}", (unsigned long) tp.tv_sec); xo_emit("{e:days/%d}{e:hours/%d}{e:minutes/%d}{e:seconds/%d}", days, hrs, mins, secs); if (days > 0) sbuf_printf(upbuf, " %d day%s,", days, days > 1 ? "s" : ""); if (hrs > 0 && mins > 0) sbuf_printf(upbuf, " %2d:%02d,", hrs, mins); else if (hrs > 0) sbuf_printf(upbuf, " %d hr%s,", hrs, hrs > 1 ? "s" : ""); else if (mins > 0) sbuf_printf(upbuf, " %d min%s,", mins, mins > 1 ? "s" : ""); else sbuf_printf(upbuf, " %d sec%s,", secs, secs > 1 ? "s" : ""); if (sbuf_finish(upbuf) != 0) xo_err(1, "Could not generate output"); xo_emit("{:uptime-human/%s}", sbuf_data(upbuf)); sbuf_delete(upbuf); } /* Print number of users logged in to system */ xo_emit(" {:users/%d} {N:user%s}", nusers, nusers == 1 ? "" : "s"); /* * Print 1, 5, and 15 minute load averages. */ if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) == -1) xo_emit(", no load average information available\n"); else { static const char *format[] = { " {:load-average-1/%.2f}", " {:load-average-5/%.2f}", " {:load-average-15/%.2f}", }; xo_emit(", load averages:"); for (i = 0; i < (int)(sizeof(avenrun) / sizeof(avenrun[0])); i++) { if (use_comma && i > 0) xo_emit(","); xo_emit(format[i], avenrun[i]); } xo_emit("\n"); } }
int main (int argc, char **argv) { static char base_grocery[] = "GRO"; static char base_hardware[] = "HRD"; struct item { const char *i_title; int i_sold; int i_instock; int i_onorder; const char *i_sku_base; int i_sku_num; }; struct item list[] = { { "gum", 1412, 54, 10, base_grocery, 415 }, { "rope", 85, 4, 2, base_hardware, 212 }, { "ladder", 0, 2, 1, base_hardware, 517 }, { "bolt", 4123, 144, 42, base_hardware, 632 }, { "water", 17, 14, 2, base_grocery, 2331 }, { NULL, 0, 0, 0, NULL, 0 } }; struct item list2[] = { { "fish", 1321, 45, 1, base_grocery, 533 }, { NULL, 0, 0, 0, NULL, 0 } }; struct item *ip; xo_info_t info[] = { { "in-stock", "number", "Number of items in stock" }, { "name", "string", "Name of the item" }, { "on-order", "number", "Number of items on order" }, { "sku", "string", "Stock Keeping Unit" }, { "sold", "number", "Number of items sold" }, { NULL, NULL, NULL }, }; int info_count = (sizeof(info) / sizeof(info[0])) - 1; argc = xo_parse_args(argc, argv); if (argc < 0) return 1; for (argc = 1; argv[argc]; argc++) { if (strcmp(argv[argc], "xml") == 0) xo_set_style(NULL, XO_STYLE_XML); else if (strcmp(argv[argc], "json") == 0) xo_set_style(NULL, XO_STYLE_JSON); else if (strcmp(argv[argc], "text") == 0) xo_set_style(NULL, XO_STYLE_TEXT); else if (strcmp(argv[argc], "html") == 0) xo_set_style(NULL, XO_STYLE_HTML); else if (strcmp(argv[argc], "pretty") == 0) xo_set_flags(NULL, XOF_PRETTY); else if (strcmp(argv[argc], "xpath") == 0) xo_set_flags(NULL, XOF_XPATH); else if (strcmp(argv[argc], "info") == 0) xo_set_flags(NULL, XOF_INFO); else if (strcmp(argv[argc], "error") == 0) { close(-1); xo_err(1, "error detected"); } } xo_set_info(NULL, info, info_count); xo_set_flags(NULL, XOF_KEYS); xo_open_container_h(NULL, "top"); xo_attr("test", "value"); xo_open_container("data"); xo_open_list("item"); xo_attr("test2", "value2"); xo_emit("{T:Item/%-10s}{T:Total Sold/%12s}{T:In Stock/%12s}" "{T:On Order/%12s}{T:SKU/%5s}\n"); for (ip = list; ip->i_title; ip++) { xo_open_instance("item"); xo_attr("test3", "value3"); xo_emit("{keq:sku/%s-%u/%s-000-%u}" "{k:name/%-10s/%s}{n:sold/%12u/%u}{:in-stock/%12u/%u}" "{:on-order/%12u/%u}{qkd:sku/%5s-000-%u/%s-000-%u}\n", ip->i_sku_base, ip->i_sku_num, ip->i_title, ip->i_sold, ip->i_instock, ip->i_onorder, ip->i_sku_base, ip->i_sku_num); xo_close_instance("item"); } xo_close_list("item"); xo_close_container("data"); xo_emit("\n\n"); xo_open_container("data"); xo_open_list("item"); for (ip = list; ip->i_title; ip++) { xo_open_instance("item"); xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num); xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", ip->i_sold, ip->i_sold ? ".0" : ""); xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); xo_emit("{P: }{L:SKU}: {qkd:sku/%s-000-%u}\n", ip->i_sku_base, ip->i_sku_num); xo_close_instance("item"); } xo_close_list("item"); xo_close_container("data"); xo_open_container("data"); xo_open_list("item"); for (ip = list2; ip->i_title; ip++) { xo_open_instance("item"); xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num); xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", ip->i_sold, ip->i_sold ? ".0" : ""); xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); xo_emit("{P: }{L:SKU}: {qkd:sku/%s-000-%u}\n", ip->i_sku_base, ip->i_sku_num); xo_close_instance("item"); } xo_close_list("item"); xo_close_container("data"); xo_open_container("data"); xo_open_list("item"); for (ip = list; ip->i_title; ip++) { xo_attr("test4", "value4"); xo_emit("{Lwc:Item}{l:item}\n", ip->i_title); } xo_close_list("item"); xo_close_container("data"); xo_emit("X{P:}X", "epic fail"); xo_emit("X{T:}X", "epic fail"); xo_emit("X{N:}X", "epic fail"); xo_emit("X{L:}X\n", "epic fail"); xo_emit("X{P: }X{Lwc:Cost}{:cost/%u}\n", 425); xo_emit("X{P:/%30s}X{Lwc:Cost}{:cost/%u}\n", "", 455); xo_close_container_h(NULL, "top"); xo_finish(); return 0; }
static int add_param(const char *name, void *value, size_t valuelen, struct jailparam *source, unsigned flags) { struct jailparam *param, *tparams; int i, tnparams; static int paramlistsize; /* The pseudo-parameter "all" scans the list of available parameters. */ if (!strcmp(name, "all")) { tnparams = jailparam_all(&tparams); if (tnparams < 0) xo_errx(1, "%s", jail_errmsg); qsort(tparams, (size_t)tnparams, sizeof(struct jailparam), sort_param); for (i = 0; i < tnparams; i++) add_param(tparams[i].jp_name, NULL, (size_t)0, tparams + i, flags); free(tparams); return -1; } /* Check for repeat parameters. */ for (i = 0; i < nparams; i++) if (!strcmp(name, params[i].jp_name)) { if (value != NULL && jailparam_import_raw(params + i, value, valuelen) < 0) xo_errx(1, "%s", jail_errmsg); params[i].jp_flags |= flags; if (source != NULL) jailparam_free(source, 1); return i; } /* Make sure there is room for the new param record. */ if (!nparams) { paramlistsize = 32; params = malloc(paramlistsize * sizeof(*params)); param_parent = malloc(paramlistsize * sizeof(*param_parent)); if (params == NULL || param_parent == NULL) xo_err(1, "malloc"); } else if (nparams >= paramlistsize) { paramlistsize *= 2; params = realloc(params, paramlistsize * sizeof(*params)); param_parent = realloc(param_parent, paramlistsize * sizeof(*param_parent)); if (params == NULL || param_parent == NULL) xo_err(1, "realloc"); } /* Look up the parameter. */ param_parent[nparams] = -1; param = params + nparams++; if (source != NULL) { *param = *source; param->jp_flags |= flags; return param - params; } if (jailparam_init(param, name) < 0 || (value != NULL ? jailparam_import_raw(param, value, valuelen) : jailparam_import(param, value)) < 0) { if (flags & JP_OPT) { nparams--; return (-1); } xo_errx(1, "%s", jail_errmsg); } param->jp_flags = flags; return param - params; }
int main(int argc, char *argv[]) { int ch, func = 0; int rtn = 0; int aflag = 0; /* do it for all entries */ argc = xo_parse_args(argc, argv); if (argc < 0) exit(1); while ((ch = getopt(argc, argv, "andfsSi:")) != -1) switch(ch) { case 'a': aflag = 1; break; case 'd': SETFUNC(F_DELETE); break; case 'n': nflag = 1; break; case 'S': SETFUNC(F_REPLACE); break; case 's': SETFUNC(F_SET); break; case 'f' : SETFUNC(F_FILESET); break; case 'i': rifname = optarg; break; case '?': default: usage(); } argc -= optind; argv += optind; if (!func) func = F_GET; if (rifname) { if (func != F_GET && !(func == F_DELETE && aflag)) xo_errx(1, "-i not applicable to this operation"); if (if_nametoindex(rifname) == 0) { if (errno == ENXIO) xo_errx(1, "interface %s does not exist", rifname); else xo_err(1, "if_nametoindex(%s)", rifname); } } switch (func) { case F_GET: if (aflag) { if (argc != 0) usage(); xo_set_version(ARP_XO_VERSION); xo_open_container("arp"); xo_open_list("arp-cache"); search(0, print_entry); xo_close_list("arp-cache"); xo_close_container("arp"); xo_finish(); } else { if (argc != 1) usage(); rtn = get(argv[0]); } break; case F_SET: case F_REPLACE: if (argc < 2 || argc > 6) usage(); if (func == F_REPLACE) (void)delete(argv[0]); rtn = set(argc, argv) ? 1 : 0; break; case F_DELETE: if (aflag) { if (argc != 0) usage(); search(0, nuke_entry); } else { if (argc != 1) usage(); rtn = delete(argv[0]); } break; case F_FILESET: if (argc != 1) usage(); rtn = file(argv[0]); break; } if (ifnameindex != NULL) if_freenameindex(ifnameindex); return (rtn); }
/* * Traverse() walks the logical directory structure specified by the argv list * in the order specified by the mastercmp() comparison function. During the * traversal it passes linked lists of structures to display() which represent * a superset (may be exact set) of the files to be displayed. */ static void traverse(int argc, char *argv[], int options) { FTS *ftsp; FTSENT *p, *chp; int ch_options; int first = 1; if ((ftsp = fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL) xo_err(1, "fts_open"); /* * We ignore errors from fts_children here since they will be * replicated and signalled on the next call to fts_read() below. */ chp = fts_children(ftsp, 0); if (chp != NULL) display(NULL, chp, options); if (f_listdir) return; /* * If not recursing down this tree and don't need stat info, just get * the names. */ ch_options = !f_recursive && !f_label && options & FTS_NOSTAT ? FTS_NAMEONLY : 0; while ((p = fts_read(ftsp)) != NULL) switch (p->fts_info) { case FTS_DC: xo_warnx("%s: directory causes a cycle", p->fts_name); break; case FTS_DNR: case FTS_ERR: xo_warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; case FTS_D: if (p->fts_level != FTS_ROOTLEVEL && p->fts_name[0] == '.' && !f_listdot) break; if (first) { first = 0; xo_open_list("directory"); } xo_open_instance("directory"); /* * If already output something, put out a newline as * a separator. If multiple arguments, precede each * directory with its name. */ if (output) { xo_emit("\n"); (void)printname("path", p->fts_path); xo_emit(":\n"); } else if (argc > 1) { (void)printname("path", p->fts_path); xo_emit(":\n"); output = 1; } chp = fts_children(ftsp, ch_options); display(p, chp, options); xo_close_instance("directory"); if (!f_recursive && chp != NULL) (void)fts_set(ftsp, p, FTS_SKIP); break; default: break; } if (!first) xo_close_list("directory"); if (errno) xo_err(1, "fts_read"); }
void procstat_cs(struct procstat *procstat, struct kinfo_proc *kipp) { cpusetid_t cs; cpuset_t mask; struct kinfo_proc *kip; struct sbuf *cpusetbuf; unsigned int count, i; int once, twice, lastcpu, cpu; if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %6s %-19s %-19s %2s %4s %-7s}\n", "PID", "TID", "COMM", "TDNAME", "CPU", "CSID", "CPU MASK"); kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD, kipp->ki_pid, &count); if (kip == NULL) return; kinfo_proc_sort(kip, count); for (i = 0; i < count; i++) { kipp = &kip[i]; xo_emit("{k:process_id/%5d/%d} ", kipp->ki_pid); xo_emit("{:thread_id/%6d/%d} ", kipp->ki_tid); xo_emit("{:command/%-19s/%s} ", strlen(kipp->ki_comm) ? kipp->ki_comm : "-"); xo_emit("{:thread_name/%-19s/%s} ", kinfo_proc_thread_name(kipp)); if (kipp->ki_oncpu != 255) xo_emit("{:cpu/%3d/%d} ", kipp->ki_oncpu); else if (kipp->ki_lastcpu != 255) xo_emit("{:cpu/%3d/%d} ", kipp->ki_lastcpu); else xo_emit("{:cpu/%3s/%s} ", "-"); if (cpuset_getid(CPU_LEVEL_CPUSET, CPU_WHICH_TID, kipp->ki_tid, &cs) != 0) { cs = CPUSET_INVALID; } xo_emit("{:cpu_set_id/%4d/%d} ", cs); if ((cs != CPUSET_INVALID) && (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, kipp->ki_tid, sizeof(mask), &mask) == 0)) { lastcpu = -1; once = 0; twice = 0; cpusetbuf = sbuf_new_auto(); for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { if (CPU_ISSET(cpu, &mask)) { if (once == 0) { sbuf_printf(cpusetbuf, "%d", cpu); once = 1; } else if (cpu == lastcpu + 1) { twice = 1; } else if (twice == 1) { sbuf_printf(cpusetbuf, "-%d,%d", lastcpu, cpu); twice = 0; } else sbuf_printf(cpusetbuf, ",%d", cpu); lastcpu = cpu; } } if (once && twice) sbuf_printf(cpusetbuf, "-%d", lastcpu); if (sbuf_finish(cpusetbuf) != 0) xo_err(1, "Could not generate output"); xo_emit("{:cpu_set/%s}", sbuf_data(cpusetbuf)); sbuf_delete(cpusetbuf); } xo_emit("\n"); } procstat_freeprocs(procstat, kip); }
int main(int argc, char *argv[]) { struct protox *tp = NULL; /* for printing cblocks & stats */ int ch; int fib = -1; char *endptr; bool first = true; af = AF_UNSPEC; argc = xo_parse_args(argc, argv); while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:RrSTsuWw:xz")) != -1) switch(ch) { case '4': #ifdef INET af = AF_INET; #else errx(1, "IPv4 support is not compiled in"); #endif break; case '6': #ifdef INET6 af = AF_INET6; #else errx(1, "IPv6 support is not compiled in"); #endif break; case 'A': Aflag = 1; break; case 'a': aflag = 1; break; case 'B': Bflag = 1; break; case 'b': bflag = 1; break; case 'd': dflag = 1; break; case 'F': fib = strtol(optarg, &endptr, 0); if (*endptr != '\0' || (fib == 0 && (errno == EINVAL || errno == ERANGE))) xo_errx(1, "%s: invalid fib", optarg); break; case 'f': if (strcmp(optarg, "inet") == 0) af = AF_INET; #ifdef INET6 else if (strcmp(optarg, "inet6") == 0) af = AF_INET6; #endif #ifdef IPSEC else if (strcmp(optarg, "pfkey") == 0) af = PF_KEY; #endif else if (strcmp(optarg, "unix") == 0 || strcmp(optarg, "local") == 0) af = AF_UNIX; #ifdef NETGRAPH else if (strcmp(optarg, "ng") == 0 || strcmp(optarg, "netgraph") == 0) af = AF_NETGRAPH; #endif else if (strcmp(optarg, "link") == 0) af = AF_LINK; else { xo_errx(1, "%s: unknown address family", optarg); } break; case 'g': gflag = 1; break; case 'h': hflag = 1; break; case 'I': { char *cp; iflag = 1; for (cp = interface = optarg; isalpha(*cp); cp++) continue; unit = atoi(cp); break; } case 'i': iflag = 1; break; case 'L': Lflag = 1; break; case 'M': memf = optarg; break; case 'm': mflag = 1; break; case 'N': nlistf = optarg; break; case 'n': numeric_addr = numeric_port = 1; break; case 'p': if ((tp = name2protox(optarg)) == NULL) { xo_errx(1, "%s: unknown or uninstrumented " "protocol", optarg); } pflag = 1; break; case 'Q': Qflag = 1; break; case 'q': noutputs = atoi(optarg); if (noutputs != 0) noutputs++; break; case 'r': rflag = 1; break; case 'R': Rflag = 1; break; case 's': ++sflag; break; case 'S': numeric_addr = 1; break; case 'u': af = AF_UNIX; break; case 'W': case 'l': Wflag = 1; break; case 'w': interval = atoi(optarg); iflag = 1; break; case 'T': Tflag = 1; break; case 'x': xflag = 1; break; case 'z': zflag = 1; break; case '?': default: usage(); } argv += optind; argc -= optind; #define BACKWARD_COMPATIBILITY #ifdef BACKWARD_COMPATIBILITY if (*argv) { if (isdigit(**argv)) { interval = atoi(*argv); if (interval <= 0) usage(); ++argv; iflag = 1; } if (*argv) { nlistf = *argv; if (*++argv) memf = *argv; } } #endif /* * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. */ live = (nlistf == NULL && memf == NULL); if (!live) { if (setgid(getgid()) != 0) xo_err(-1, "setgid"); } if (xflag && Tflag) xo_errx(1, "-x and -T are incompatible, pick one."); if (Bflag) { if (!live) usage(); bpf_stats(interface); xo_finish(); exit(0); } if (mflag) { if (!live) { if (kread(0, NULL, 0) == 0) mbpr(kvmd, nl[N_SFSTAT].n_value); } else mbpr(NULL, 0); xo_finish(); exit(0); } if (Qflag) { if (!live) { if (kread(0, NULL, 0) == 0) netisr_stats(); } else netisr_stats(); xo_finish(); exit(0); } #if 0 /* * Keep file descriptors open to avoid overhead * of open/close on each call to get* routines. */ sethostent(1); setnetent(1); #else /* * This does not make sense any more with DNS being default over * the files. Doing a setXXXXent(1) causes a tcp connection to be * used for the queries, which is slower. */ #endif if (iflag && !sflag) { xo_open_container("statistics"); intpr(NULL, af); xo_close_container("statistics"); xo_finish(); exit(0); } if (rflag) { xo_open_container("statistics"); if (sflag) { rt_stats(); flowtable_stats(); } else routepr(fib, af); xo_close_container("statistics"); xo_finish(); exit(0); } if (gflag) { xo_open_container("statistics"); if (sflag) { if (af == AF_INET || af == AF_UNSPEC) mrt_stats(); #ifdef INET6 if (af == AF_INET6 || af == AF_UNSPEC) mrt6_stats(); #endif } else { if (af == AF_INET || af == AF_UNSPEC) mroutepr(); #ifdef INET6 if (af == AF_INET6 || af == AF_UNSPEC) mroute6pr(); #endif } xo_close_container("statistics"); xo_finish(); exit(0); } /* Load all necessary kvm symbols */ kresolve_list(nl); if (tp) { xo_open_container("statistics"); printproto(tp, tp->pr_name, &first); if (!first) xo_close_list("socket"); xo_close_container("statistics"); xo_finish(); exit(0); } xo_open_container("statistics"); if (af == AF_INET || af == AF_UNSPEC) for (tp = protox; tp->pr_name; tp++) printproto(tp, tp->pr_name, &first); #ifdef INET6 if (af == AF_INET6 || af == AF_UNSPEC) for (tp = ip6protox; tp->pr_name; tp++) printproto(tp, tp->pr_name, &first); #endif /*INET6*/ #ifdef IPSEC if (af == PF_KEY || af == AF_UNSPEC) for (tp = pfkeyprotox; tp->pr_name; tp++) printproto(tp, tp->pr_name, &first); #endif /*IPSEC*/ #ifdef NETGRAPH if (af == AF_NETGRAPH || af == AF_UNSPEC) for (tp = netgraphprotox; tp->pr_name; tp++) printproto(tp, tp->pr_name, &first); #endif /* NETGRAPH */ if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value, nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value, nl[N_UNP_SPHEAD].n_value, &first); if (!first) xo_close_list("socket"); xo_close_container("statistics"); xo_finish(); exit(0); }
/* * Set an individual arp entry */ static int set(int argc, char **argv) { struct sockaddr_in *addr; struct sockaddr_in *dst; /* what are we looking for */ struct sockaddr_dl *sdl; struct rt_msghdr *rtm; struct ether_addr *ea; char *host = argv[0], *eaddr = argv[1]; struct sockaddr_dl sdl_m; argc -= 2; argv += 2; bzero(&sdl_m, sizeof(sdl_m)); sdl_m.sdl_len = sizeof(sdl_m); sdl_m.sdl_family = AF_LINK; dst = getaddr(host); if (dst == NULL) return (1); doing_proxy = flags = expire_time = 0; while (argc-- > 0) { if (strcmp(argv[0], "temp") == 0) { struct timespec tp; int max_age; size_t len = sizeof(max_age); clock_gettime(CLOCK_MONOTONIC, &tp); if (sysctlbyname("net.link.ether.inet.max_age", &max_age, &len, NULL, 0) != 0) xo_err(1, "sysctlbyname"); expire_time = tp.tv_sec + max_age; } else if (strcmp(argv[0], "pub") == 0) { flags |= RTF_ANNOUNCE; doing_proxy = 1; if (argc && strcmp(argv[1], "only") == 0) { /* * Compatibility: in pre FreeBSD 8 times * the "only" keyword used to mean that * an ARP entry should be announced, but * not installed into routing table. */ argc--; argv++; } } else if (strcmp(argv[0], "blackhole") == 0) { if (flags & RTF_REJECT) { xo_errx(1, "Choose one of blackhole or reject, " "not both."); } flags |= RTF_BLACKHOLE; } else if (strcmp(argv[0], "reject") == 0) { if (flags & RTF_BLACKHOLE) { xo_errx(1, "Choose one of blackhole or reject, " "not both."); } flags |= RTF_REJECT; } else { xo_warnx("Invalid parameter '%s'", argv[0]); usage(); } argv++; } ea = (struct ether_addr *)LLADDR(&sdl_m); if (doing_proxy && !strcmp(eaddr, "auto")) { if (!get_ether_addr(dst->sin_addr.s_addr, ea)) { xo_warnx("no interface found for %s", inet_ntoa(dst->sin_addr)); return (1); } sdl_m.sdl_alen = ETHER_ADDR_LEN; } else { struct ether_addr *ea1 = ether_aton(eaddr); if (ea1 == NULL) { xo_warnx("invalid Ethernet address '%s'", eaddr); return (1); } else { *ea = *ea1; sdl_m.sdl_alen = ETHER_ADDR_LEN; } } /* * In the case a proxy-arp entry is being added for * a remote end point, the RTF_ANNOUNCE flag in the * RTM_GET command is an indication to the kernel * routing code that the interface associated with * the prefix route covering the local end of the * PPP link should be returned, on which ARP applies. */ rtm = rtmsg(RTM_GET, dst, NULL); if (rtm == NULL) { xo_warn("%s", host); return (1); } addr = (struct sockaddr_in *)(rtm + 1); sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr); if ((sdl->sdl_family != AF_LINK) || (rtm->rtm_flags & RTF_GATEWAY) || !valid_type(sdl->sdl_type)) { xo_warnx("cannot intuit interface index and type for %s", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return (rtmsg(RTM_ADD, dst, &sdl_m) == NULL); }
/* * Print a description of the nfs stats. */ static void intpr(int clientOnly, int serverOnly) { int nfssvc_flag; nfssvc_flag = NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT; if (zflag != 0) { if (clientOnly != 0) nfssvc_flag |= NFSSVC_ZEROCLTSTATS; if (serverOnly != 0) nfssvc_flag |= NFSSVC_ZEROSRVSTATS; } ext_nfsstats.vers = NFSSTATS_V1; if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0) xo_err(1, "Can't get stats"); if (clientOnly) { xo_open_container("clientstats"); if (printtitle) xo_emit("{T:Client Info:\n"); xo_open_container("operations"); xo_emit("{T:Rpc Counts:}\n"); xo_emit("{T:Getattr/%13.13s}{T:Setattr/%13.13s}" "{T:Lookup/%13.13s}{T:Readlink/%13.13s}" "{T:Read/%13.13s}{T:Write/%13.13s}" "{T:Create/%13.13s}{T:Remove/%13.13s}\n"); xo_emit("{:getattr/%13ju}{:setattr/%13ju}" "{:lookup/%13ju}{:readlink/%13ju}" "{:read/%13ju}{:write/%13ju}" "{:create/%13ju}{:remove/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETATTR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETATTR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOOKUP], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READLINK], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READ], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITE], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATE], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_REMOVE]); xo_emit("{T:Rename/%13.13s}{T:Link/%13.13s}" "{T:Symlink/%13.13s}{T:Mkdir/%13.13s}" "{T:Rmdir/%13.13s}{T:Readdir/%13.13s}" "{T:RdirPlus/%13.13s}{T:Access/%13.13s}\n"); xo_emit("{:rename/%13ju}{:link/%13ju}" "{:symlink/%13ju}{:mkdir/%13ju}" "{:rmdir/%13ju}{:readdir/%13ju}" "{:rdirplus/%13ju}{:access/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RENAME], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LINK], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SYMLINK], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKDIR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RMDIR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_ACCESS]); xo_emit("{T:Mknod/%13.13s}{T:Fsstat/%13.13s}" "{T:Fsinfo/%13.13s}{T:PathConf/%13.13s}" "{T:Commit/%13.13s}\n"); xo_emit("{:mknod/%13ju}{:fsstat/%13ju}" "{:fsinfo/%13ju}{:pathconf/%13ju}" "{:commit/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKNOD], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSSTAT], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSINFO], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PATHCONF], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMIT]); xo_close_container("operations"); xo_open_container("rpcs"); xo_emit("{T:Rpc Info:}\n"); xo_emit("{T:TimedOut/%13.13s}{T:Invalid/%13.13s}" "{T:X Replies/%13.13s}{T:Retries/%13.13s}" "{T:Requests/%13.13s}\n"); xo_emit("{:timedout/%13ju}{:invalid/%13ju}" "{:xreplies/%13ju}{:retries/%13ju}" "{:requests/%13ju}\n", (uintmax_t)ext_nfsstats.rpctimeouts, (uintmax_t)ext_nfsstats.rpcinvalid, (uintmax_t)ext_nfsstats.rpcunexpected, (uintmax_t)ext_nfsstats.rpcretries, (uintmax_t)ext_nfsstats.rpcrequests); xo_close_container("rpcs"); xo_open_container("cache"); xo_emit("{T:Cache Info:}\n"); xo_emit("{T:Attr Hits/%13.13s}{T:Attr Misses/%13.13s}" "{T:Lkup Hits/%13.13s}{T:Lkup Misses/%13.13s}" "{T:BioR Hits/%13.13s}{T:BioR Misses/%13.13s}" "{T:BioW Hits/%13.13s}{T:BioW Misses/%13.13s}\n"); xo_emit("{:attrhits/%13ju}{:attrmisses/%13ju}" "{:lkuphits/%13ju}{:lkupmisses/%13ju}" "{:biorhits/%13ju}{:biormisses/%13ju}" "{:biowhits/%13ju}{:biowmisses/%13ju}\n", (uintmax_t)ext_nfsstats.attrcache_hits, (uintmax_t)ext_nfsstats.attrcache_misses, (uintmax_t)ext_nfsstats.lookupcache_hits, (uintmax_t)ext_nfsstats.lookupcache_misses, (uintmax_t)(ext_nfsstats.biocache_reads - ext_nfsstats.read_bios), (uintmax_t)ext_nfsstats.read_bios, (uintmax_t)(ext_nfsstats.biocache_writes - ext_nfsstats.write_bios), (uintmax_t)ext_nfsstats.write_bios); xo_emit("{T:BioRL Hits/%13.13s}{T:BioRL Misses/%13.13s}" "{T:BioD Hits/%13.13s}{T:BioD Misses/%13.13s}" "{T:DirE Hits/%13.13s}{T:DirE Misses/%13.13s}" "{T:Accs Hits/%13.13s}{T:Accs Misses/%13.13s}\n"); xo_emit("{:biosrlhits/%13ju}{:biorlmisses/%13ju}" "{:biodhits/%13ju}{:biodmisses/%13ju}" "{:direhits/%13ju}{:diremisses/%13ju}" "{:accshits/%13ju}{:accsmisses/%13ju}\n", (uintmax_t)(ext_nfsstats.biocache_readlinks - ext_nfsstats.readlink_bios), (uintmax_t)ext_nfsstats.readlink_bios, (uintmax_t)(ext_nfsstats.biocache_readdirs - ext_nfsstats.readdir_bios), (uintmax_t)ext_nfsstats.readdir_bios, (uintmax_t)ext_nfsstats.direofcache_hits, (uintmax_t)ext_nfsstats.direofcache_misses, (uintmax_t)ext_nfsstats.accesscache_hits, (uintmax_t)ext_nfsstats.accesscache_misses); xo_close_container("cache"); xo_close_container("clientstats"); } if (serverOnly) { xo_open_container("serverstats"); xo_emit("{T:Server Info:}\n"); xo_open_container("operations"); xo_emit("{T:Getattr/%13.13s}{T:Setattr/%13.13s}" "{T:Lookup/%13.13s}{T:Readlink/%13.13s}" "{T:Read/%13.13s}{T:Write/%13.13s}" "{T:Create/%13.13s}{T:Remove/%13.13s}\n"); xo_emit("{:getattr/%13ju}{:setattr/%13ju}" "{:lookup/%13ju}{:readlink/%13ju}" "{:read/%13ju}{:write/%13ju}" "{:create/%13ju}{:remove/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READLINK], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READ], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]); xo_emit("{T:Rename/%13.13s}{T:Link/%13.13s}" "{T:Symlink/%13.13s}{T:Mkdir/%13.13s}" "{T:Rmdir/%13.13s}{T:Readdir/%13.13s}" "{T:RdirPlus/%13.13s}{T:Access/%13.13s}\n"); xo_emit("{:rename/%13ju}{:link/%13ju}" "{:symlink/%13ju}{:mkdir/%13ju}" "{:rmdir/%13ju}{:readdir/%13ju}" "{:rdirplus/%13ju}{:access/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENAME], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LINK], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]); xo_emit("{T:Mknod/%13.13s}{T:Fsstat/%13.13s}" "{T:Fsinfo/%13.13s}{T:PathConf/%13.13s}" "{T:Commit/%13.13s}\n"); xo_emit("{:mknod/%13ju}{:fsstat/%13ju}" "{:fsinfo/%13ju}{:pathconf/%13ju}" "{:commit/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]); xo_close_container("operations"); xo_open_container("server"); xo_emit("{T:Server Re-Failed:}\n"); xo_emit("{T:retfailed/%17ju}\n", (uintmax_t)ext_nfsstats.srvrpc_errs); xo_emit("{T:Server Faults:}\n"); xo_emit("{T:faults/%13ju}\n", (uintmax_t)ext_nfsstats.srv_errs); xo_emit("{T:Server Write Gathering:/%13.13s}\n"); xo_emit("{T:WriteOps/%13.13s}{T:WriteRPC/%13.13s}" "{T:Opsaved/%13.13s}\n"); xo_emit("{:writeops/%13ju}{:writerpc/%13ju}" "{:opsaved/%13ju}\n", /* * The new client doesn't do write gathering. It was * only useful for NFSv2. */ (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0); xo_close_container("server"); xo_open_container("cache"); xo_emit("{T:Server Cache Stats:/%13.13s}\n"); xo_emit("{T:Inprog/%13.13s}{T:Idem/%13.13s}" "{T:Non-Idem/%13.13s}{T:Misses/%13.13s}\n"); xo_emit("{:inprog/%13ju}{:idem/%13ju}" "{:nonidem/%13ju}{:misses/%13ju}\n", (uintmax_t)ext_nfsstats.srvcache_inproghits, (uintmax_t)ext_nfsstats.srvcache_idemdonehits, (uintmax_t)ext_nfsstats.srvcache_nonidemdonehits, (uintmax_t)ext_nfsstats.srvcache_misses); xo_close_container("cache"); xo_close_container("serverstats"); } }
/* * Display() takes a linked list of FTSENT structures and passes the list * along with any other necessary information to the print function. P * points to the parent directory of the display list. */ static void display(const FTSENT *p, FTSENT *list, int options) { struct stat *sp; DISPLAY d; FTSENT *cur; NAMES *np; off_t maxsize; long maxblock; uintmax_t maxinode; u_long btotal, labelstrlen, maxlen, maxnlink; u_long maxlabelstr; u_int sizelen; int maxflags; gid_t maxgroup; uid_t maxuser; size_t flen, ulen, glen; char *initmax; int entries, needstats; const char *user, *group; char *flags, *labelstr = NULL; char ngroup[STRBUF_SIZEOF(uid_t) + 1]; char nuser[STRBUF_SIZEOF(gid_t) + 1]; needstats = f_inode || f_longform || f_size; flen = 0; btotal = 0; initmax = getenv("LS_COLWIDTHS"); /* Fields match -lios order. New ones should be added at the end. */ maxlabelstr = maxblock = maxlen = maxnlink = 0; maxuser = maxgroup = maxflags = maxsize = 0; maxinode = 0; if (initmax != NULL && *initmax != '\0') { char *initmax2, *jinitmax; int ninitmax; /* Fill-in "::" as "0:0:0" for the sake of scanf. */ jinitmax = malloc(strlen(initmax) * 2 + 2); if (jinitmax == NULL) xo_err(1, "malloc"); initmax2 = jinitmax; if (*initmax == ':') strcpy(initmax2, "0:"), initmax2 += 2; else *initmax2++ = *initmax, *initmax2 = '\0'; for (initmax++; *initmax != '\0'; initmax++) { if (initmax[-1] == ':' && initmax[0] == ':') { *initmax2++ = '0'; *initmax2++ = initmax[0]; initmax2[1] = '\0'; } else { *initmax2++ = initmax[0]; initmax2[1] = '\0'; } } if (initmax2[-1] == ':') strcpy(initmax2, "0"); ninitmax = sscanf(jinitmax, " %ju : %ld : %lu : %u : %u : %i : %jd : %lu : %lu ", &maxinode, &maxblock, &maxnlink, &maxuser, &maxgroup, &maxflags, &maxsize, &maxlen, &maxlabelstr); f_notabs = 1; switch (ninitmax) { case 0: maxinode = 0; /* FALLTHROUGH */ case 1: maxblock = 0; /* FALLTHROUGH */ case 2: maxnlink = 0; /* FALLTHROUGH */ case 3: maxuser = 0; /* FALLTHROUGH */ case 4: maxgroup = 0; /* FALLTHROUGH */ case 5: maxflags = 0; /* FALLTHROUGH */ case 6: maxsize = 0; /* FALLTHROUGH */ case 7: maxlen = 0; /* FALLTHROUGH */ case 8: maxlabelstr = 0; /* FALLTHROUGH */ #ifdef COLORLS if (!f_color) #endif f_notabs = 0; /* FALLTHROUGH */ default: break; } MAKENINES(maxinode); MAKENINES(maxblock); MAKENINES(maxnlink); MAKENINES(maxsize); free(jinitmax); } d.s_size = 0; sizelen = 0; flags = NULL; for (cur = list, entries = 0; cur; cur = cur->fts_link) { if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) { xo_warnx("%s: %s", cur->fts_name, strerror(cur->fts_errno)); cur->fts_number = NO_PRINT; rval = 1; continue; } /* * P is NULL if list is the argv list, to which different rules * apply. */ if (p == NULL) { /* Directories will be displayed later. */ if (cur->fts_info == FTS_D && !f_listdir) { cur->fts_number = NO_PRINT; continue; } } else { /* Only display dot file if -a/-A set. */ if (cur->fts_name[0] == '.' && !f_listdot) { cur->fts_number = NO_PRINT; continue; } } if (cur->fts_namelen > maxlen) maxlen = cur->fts_namelen; if (f_octal || f_octal_escape) { u_long t = len_octal(cur->fts_name, cur->fts_namelen); if (t > maxlen) maxlen = t; } if (needstats) { sp = cur->fts_statp; if (sp->st_blocks > maxblock) maxblock = sp->st_blocks; if (sp->st_ino > maxinode) maxinode = sp->st_ino; if (sp->st_nlink > maxnlink) maxnlink = sp->st_nlink; if (sp->st_size > maxsize) maxsize = sp->st_size; btotal += sp->st_blocks; if (f_longform) { if (f_numericonly) { (void)snprintf(nuser, sizeof(nuser), "%u", sp->st_uid); (void)snprintf(ngroup, sizeof(ngroup), "%u", sp->st_gid); user = nuser; group = ngroup; } else { user = user_from_uid(sp->st_uid, 0); group = group_from_gid(sp->st_gid, 0); } if ((ulen = strlen(user)) > maxuser) maxuser = ulen; if ((glen = strlen(group)) > maxgroup) maxgroup = glen; if (f_flags) { flags = fflagstostr(sp->st_flags); if (flags != NULL && *flags == '\0') { free(flags); flags = strdup("-"); } if (flags == NULL) xo_err(1, "fflagstostr"); flen = strlen(flags); if (flen > (size_t)maxflags) maxflags = flen; } else flen = 0; labelstr = NULL; if (f_label) { char name[PATH_MAX + 1]; mac_t label; int error; error = mac_prepare_file_label(&label); if (error == -1) { xo_warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); goto label_out; } if (cur->fts_level == FTS_ROOTLEVEL) snprintf(name, sizeof(name), "%s", cur->fts_name); else snprintf(name, sizeof(name), "%s/%s", cur->fts_parent-> fts_accpath, cur->fts_name); if (options & FTS_LOGICAL) error = mac_get_file(name, label); else error = mac_get_link(name, label); if (error == -1) { xo_warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); mac_free(label); goto label_out; } error = mac_to_text(label, &labelstr); if (error == -1) { xo_warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); mac_free(label); goto label_out; } mac_free(label); label_out: if (labelstr == NULL) labelstr = strdup("-"); labelstrlen = strlen(labelstr); if (labelstrlen > maxlabelstr) maxlabelstr = labelstrlen; } else labelstrlen = 0; if ((np = malloc(sizeof(NAMES) + labelstrlen + ulen + glen + flen + 4)) == NULL) xo_err(1, "malloc"); np->user = &np->data[0]; (void)strcpy(np->user, user); np->group = &np->data[ulen + 1]; (void)strcpy(np->group, group); if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) { sizelen = snprintf(NULL, 0, "%#jx", (uintmax_t)sp->st_rdev); if (d.s_size < sizelen) d.s_size = sizelen; } if (f_flags) { np->flags = &np->data[ulen + glen + 2]; (void)strcpy(np->flags, flags); free(flags); } if (f_label) { np->label = &np->data[ulen + glen + 2 + (f_flags ? flen + 1 : 0)]; (void)strcpy(np->label, labelstr); free(labelstr); } cur->fts_pointer = np; } } ++entries; } /* * If there are no entries to display, we normally stop right * here. However, we must continue if we have to display the * total block count. In this case, we display the total only * on the second (p != NULL) pass. */ if (!entries && (!(f_longform || f_size) || p == NULL)) return; d.list = list; d.entries = entries; d.maxlen = maxlen; if (needstats) { d.btotal = btotal; d.s_block = snprintf(NULL, 0, "%lu", howmany(maxblock, blocksize)); d.s_flags = maxflags; d.s_label = maxlabelstr; d.s_group = maxgroup; d.s_inode = snprintf(NULL, 0, "%ju", maxinode); d.s_nlink = snprintf(NULL, 0, "%lu", maxnlink); sizelen = f_humanval ? HUMANVALSTR_LEN : snprintf(NULL, 0, "%ju", maxsize); if (d.s_size < sizelen) d.s_size = sizelen; d.s_user = maxuser; } if (f_thousands) /* make space for commas */ d.s_size += (d.s_size - 1) / 3; printfcn(&d); output = 1; if (f_longform) for (cur = list; cur; cur = cur->fts_link) free(cur->fts_pointer); }
/* * Print a description of the nfs stats for the client/server, * including NFSv4.1. */ static void exp_intpr(int clientOnly, int serverOnly, int nfs41) { int nfssvc_flag; xo_open_container("nfsv4"); nfssvc_flag = NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT; if (zflag != 0) { if (clientOnly != 0) nfssvc_flag |= NFSSVC_ZEROCLTSTATS; if (serverOnly != 0) nfssvc_flag |= NFSSVC_ZEROSRVSTATS; } ext_nfsstats.vers = NFSSTATS_V1; if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0) xo_err(1, "Can't get stats"); if (clientOnly != 0) { xo_open_container("clientstats"); xo_open_container("operations"); if (printtitle) { xo_emit("{T:Client Info:}\n"); xo_emit("{T:RPC Counts:}\n"); } xo_emit("{T:Getattr/%13.13s}{T:Setattr/%13.13s}" "{T:Lookup/%13.13s}{T:Readlink/%13.13s}" "{T:Read/%13.13s}{T:Write/%13.13s}\n"); xo_emit("{:getattr/%13ju}{:setattr/%13ju}{:lookup/%13ju}" "{:readlink/%13ju}{:read/%13ju}{:write/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETATTR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETATTR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOOKUP], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READLINK], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READ], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITE]); xo_emit("{T:Create/%13.13s}{T:Remove/%13.13s}" "{T:Rename/%13.13s}{T:Link/%13.13s}" "{T:Symlink/%13.13s}{T:Mkdir/%13.13s}\n"); xo_emit("{:create/%13ju}{:remove/%13ju}{:rename/%13ju}" "{:link/%13ju}{:symlink/%13ju}{:mkdir/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATE], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_REMOVE], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RENAME], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LINK], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SYMLINK], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKDIR]); xo_emit("{T:Rmdir/%13.13s}{T:Readdir/%13.13s}" "{T:RdirPlus/%13.13s}{T:Access/%13.13s}" "{T:Mknod/%13.13s}{T:Fsstat/%13.13s}\n"); xo_emit("{:rmdir/%13ju}{:readdir/%13ju}{:rdirplus/%13ju}" "{:access/%13ju}{:mknod/%13ju}{:fsstat/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RMDIR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIR], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_ACCESS], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKNOD], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSSTAT]); xo_emit("{T:FSinfo/%13.13s}{T:pathConf/%13.13s}" "{T:Commit/%13.13s}{T:SetClId/%13.13s}" "{T:SetClIdCf/%13.13s}{T:Lock/%13.13s}\n"); xo_emit("{:fsinfo/%13ju}{:pathconf/%13ju}{:commit/%13ju}" "{:setclientid/%13ju}{:setclientidcf/%13ju}{:lock/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSINFO], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PATHCONF], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMIT], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCK]); xo_emit("{T:LockT/%13.13s}{T:LockU/%13.13s}" "{T:Open/%13.13s}{T:OpenCfr/%13.13s}\n"); xo_emit("{:lockt/%13ju}{:locku/%13ju}" "{:open/%13ju}{:opencfr/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCKT], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCKU], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPEN], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]); if (nfs41) { xo_open_container("nfsv41"); xo_emit("{T:OpenDownGr/%13.13s}{T:Close/%13.13s}\n"); xo_emit("{:opendowngr/%13ju}{:close/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPENDOWNGRADE], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CLOSE]); xo_emit("{T:RelLckOwn/%13.13s}{T:FreeStateID/%13.13s}" "{T:PutRootFH/%13.13s}{T:DelegRet/%13.13s}" "{T:GetAcl/%13.13s}{T:SetAcl/%13.13s}\n"); xo_emit("{:rellckown/%13ju}{:freestateid/%13ju}" "{:getacl/%13ju}{:delegret/%13ju}" "{:getacl/%13ju}{:setacl/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RELEASELCKOWN], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FREESTATEID], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PUTROOTFH], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_DELEGRETURN], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETACL], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETACL]); xo_emit("{T:ExchangeId/%13.13s}{T:CreateSess/%13.13s}" "{T:DestroySess/%13.13s}{T:DestroyClId/%13.13s}" "{T:LayoutGet/%13.13s}{T:GetDevInfo/%13.13s}\n"); xo_emit("{:exchangeid/%13ju}{:createsess/%13ju}" "{:destroysess/%13ju}{:destroyclid/%13ju}" "{:layoutget/%13ju}{:getdevinfo/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_EXCHANGEID], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATESESSION], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_DESTROYSESSION], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_DESTROYCLIENT], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LAYOUTGET], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETDEVICEINFO]); xo_emit("{T:LayoutCommit/%13.13s}{T:LayoutReturn/%13.13s}" "{T:ReclaimCompl/%13.13s}{T:ReadDataS/%13.13s}" "{T:WriteDataS/%13.13s}{T:CommitDataS/%13.13s}\n"); xo_emit("{:layoutcomit/%13ju}{:layoutreturn/%13ju}" "{:reclaimcompl/%13ju}{:readdatas/%13ju}" "{:writedatas/%13ju}{:commitdatas/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LAYOUTCOMMIT], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LAYOUTRETURN], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RECLAIMCOMPL], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDS], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITEDS], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMITDS]); xo_emit("{T:OpenLayout/%13.13s}{T:CreateLayout/%13.13s}\n"); xo_emit("{:openlayout/%13ju}{:createlayout/%13ju}\n", (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPENLAYGET], (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATELAYGET]); xo_close_container("nfsv41"); } xo_close_container("operations"); xo_open_container("client"); xo_emit("{T:OpenOwner/%13.13s}{T:Opens/%13.13s}" "{T:LockOwner/%13.13s}{T:Locks/%13.13s}" "{T:Delegs/%13.13s}{T:LocalOwn/%13.13s}\n"); xo_emit("{:openowner/%13ju}{:opens/%13ju}" "{:lockowner/%13ju}{:locks/%13ju}" "{:delegs/%13ju}{:localown/%13ju}\n", (uintmax_t)ext_nfsstats.clopenowners, (uintmax_t)ext_nfsstats.clopens, (uintmax_t)ext_nfsstats.cllockowners, (uintmax_t)ext_nfsstats.cllocks, (uintmax_t)ext_nfsstats.cldelegates, (uintmax_t)ext_nfsstats.cllocalopenowners); xo_emit("{T:LocalOpen/%13.13s}{T:LocalLown/%13.13s}" "{T:LocalLock/%13.13s}\n"); xo_emit("{:localopen/%13ju}{:locallown/%13ju}" "{:locallock/%13ju}\n", (uintmax_t)ext_nfsstats.cllocalopens, (uintmax_t)ext_nfsstats.cllocallockowners, (uintmax_t)ext_nfsstats.cllocallocks); xo_close_container("client"); xo_open_container("rpc"); if (printtitle) xo_emit("{T:Rpc Info:}\n"); xo_emit("{T:TimedOut/%13.13s}{T:Invalid/%13.13s}" "{T:X Replies/%13.13s}{T:Retries/%13.13s}" "{T:Requests/%13.13s}\n"); xo_emit("{:timedout/%13ju}{:invalid/%13ju}" "{:xreplies/%13ju}{:retries/%13ju}" "{:requests/%13ju}\n", (uintmax_t)ext_nfsstats.rpctimeouts, (uintmax_t)ext_nfsstats.rpcinvalid, (uintmax_t)ext_nfsstats.rpcunexpected, (uintmax_t)ext_nfsstats.rpcretries, (uintmax_t)ext_nfsstats.rpcrequests); xo_close_container("rpc"); xo_open_container("cache"); if (printtitle) xo_emit("{T:Cache Info:}\n"); xo_emit("{T:Attr Hits/%13.13s}{T:Attr Misses/%13.13s}" "{T:Lkup Hits/%13.13s}{T:Lkup Misses/%13.13s}\n"); xo_emit("{:attrhits/%13ju}{:attrmisses/%13ju}" "{:lkuphits/%13ju}{:lkupmisses/%13ju}\n", (uintmax_t)ext_nfsstats.attrcache_hits, (uintmax_t)ext_nfsstats.attrcache_misses, (uintmax_t)ext_nfsstats.lookupcache_hits, (uintmax_t)ext_nfsstats.lookupcache_misses); xo_emit("{T:BioR Hits/%13.13s}{T:BioR Misses/%13.13s}" "{T:BioW Hits/%13.13s}{T:BioW Misses/%13.13s}\n"); xo_emit("{:biorhits/%13ju}{:biormisses/%13ju}" "{:biowhits/%13ju}{:biowmisses/%13ju}\n", (uintmax_t)(ext_nfsstats.biocache_reads - ext_nfsstats.read_bios), (uintmax_t)ext_nfsstats.read_bios, (uintmax_t)(ext_nfsstats.biocache_writes - ext_nfsstats.write_bios), (uintmax_t)ext_nfsstats.write_bios); xo_emit("{T:BioRL Hits/%13.13s}{T:BioRL Misses/%13.13s}" "{T:BioD Hits/%13.13s}{T:BioD Misses/%13.13s}\n"); xo_emit("{:biorlhits/%13ju}{:biorlmisses/%13ju}" "{:biodhits/%13ju}{:biodmisses/%13ju}\n", (uintmax_t)(ext_nfsstats.biocache_readlinks - ext_nfsstats.readlink_bios), (uintmax_t)ext_nfsstats.readlink_bios, (uintmax_t)(ext_nfsstats.biocache_readdirs - ext_nfsstats.readdir_bios), (uintmax_t)ext_nfsstats.readdir_bios); xo_emit("{T:DirE Hits/%13.13s}{T:DirE Misses/%13.13s}\n"); xo_emit("{:direhits/%13ju}{:diremisses/%13ju}\n", (uintmax_t)ext_nfsstats.direofcache_hits, (uintmax_t)ext_nfsstats.direofcache_misses); xo_open_container("cache"); xo_close_container("clientstats"); } if (serverOnly != 0) { xo_open_container("serverstats"); xo_open_container("operations"); if (printtitle) xo_emit("{T:Server Info:}\n"); xo_emit("{T:Getattr/%13.13s}{T:Setattr/%13.13s}" "{T:Lookup/%13.13s}{T:Readlink/%13.13s}" "{T:Read/%13.13s}{T:Write/%13.13s}\n"); xo_emit("{:getattr/%13ju}{:setattr/%13ju}{:lookup/%13ju}" "{:readlink/%13ju}{:read/%13ju}{:write/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READLINK], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READ], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE]); xo_emit("{T:Create/%13.13s}{T:Remove/%13.13s}" "{T:Rename/%13.13s}{T:Link/%13.13s}" "{T:Symlink/%13.13s}{T:Mkdir/%13.13s}\n"); xo_emit("{:create/%13ju}{:remove/%13ju}{:rename/%13ju}" "{:link/%13ju}{:symlink/%13ju}{:mkdir/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENAME], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LINK], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR]); xo_emit("{T:Rmdir/%13.13s}{T:Readdir/%13.13s}" "{T:RdirPlus/%13.13s}{T:Access/%13.13s}" "{T:Mknod/%13.13s}{T:Fsstat/%13.13s}\n"); xo_emit("{:rmdir/%13ju}{:readdir/%13ju}{:rdirplus/%13ju}" "{:access/%13ju}{:mknod/%13ju}{:fsstat/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT]); xo_emit("{T:FSinfo/%13.13s}{T:pathConf/%13.13s}" "{T:Commit/%13.13s}{T:LookupP/%13.13s}" "{T:SetClId/%13.13s}{T:SetClIdCf/%13.13s}\n"); xo_emit("{:fsinfo/%13ju}{:pathconf/%13ju}{:commit/%13ju}" "{:lookupp/%13ju}{:setclientid/%13ju}{:setclientidcfrm/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]); xo_emit("{T:Open/%13.13s}{T:OpenAttr/%13.13s}" "{T:OpenDwnGr/%13.13s}{T:OpenCfrm/%13.13s}" "{T:DelePurge/%13.13s}{T:DelRet/%13.13s}\n"); xo_emit("{:open/%13ju}{:openattr/%13ju}{:opendwgr/%13ju}" "{:opencfrm/%13ju}{:delepurge/%13ju}{:delreg/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPEN], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN]); xo_emit("{T:GetFH/%13.13s}{T:Lock/%13.13s}" "{T:LockT/%13.13s}{T:LockU/%13.13s}" "{T:Close/%13.13s}{T:Verify/%13.13s}\n"); xo_emit("{:getfh/%13ju}{:lock/%13ju}{:lockt/%13ju}" "{:locku/%13ju}{:close/%13ju}{:verify/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETFH], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCK], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY]); xo_emit("{T:NVerify/%13.13s}{T:PutFH/%13.13s}" "{T:PutPubFH/%13.13s}{T:PutRootFH/%13.13s}" "{T:Renew/%13.13s}{T:RestoreFH/%13.13s}\n"); xo_emit("{:nverify/%13ju}{:putfh/%13ju}{:putpubfh/%13ju}" "{:putrootfh/%13ju}{:renew/%13ju}{:restore/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENEW], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH]); xo_emit("{T:SaveFH/%13.13s}{T:Secinfo/%13.13s}" "{T:RelLockOwn/%13.13s}{T:V4Create/%13.13s}\n"); xo_emit("{:savefh/%13ju}{:secinfo/%13ju}{:rellockown/%13ju}" "{:v4create/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]); if (nfs41) { xo_open_container("nfsv41"); xo_emit("{T:BackChannelCtrl/%13.13s}{T:BindConnToSess/%13.13s}" "{T:ExchangeID/%13.13s}{T:CreateSess/%13.13s}" "{T:DestroySess/%13.13s}{T:FreeStateID/%13.13s}\n"); xo_emit("{:backchannelctrl/%13ju}{:bindconntosess/%13ju}" "{:exchangeid/%13ju}{:createsess/%13ju}" "{:destroysess/%13ju}{:freestateid/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_BACKCHANNELCTL], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_BINDCONNTOSESS], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_EXCHANGEID], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATESESSION], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DESTROYSESSION], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FREESTATEID]), xo_emit("{T:GetDirDeleg/%13.13s}{T:GetDevInfo/%13.13s}" "{T:GetDevList/%13.13s}{T:layoutCommit/%13.13s}" "{T:LayoutGet/%13.13s}{T:LayoutReturn/%13.13s}\n"); xo_emit("{:getdirdeleg/%13ju}{:getdevinfo/%13ju}" "{:getdevlist/%13ju}{:layoutcommit/%13ju}" "{:layoutget/%13ju}{:layoutreturn/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETDIRDELEG], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETDEVINFO], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETDEVLIST], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LAYOUTCOMMIT], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LAYOUTGET], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LAYOUTRETURN]); xo_emit("{T:SecInfNoName/%13.13s}{T:Sequence/%13.13s}" "{T:SetSSV/%13.13s}{T:TestStateID/%13.13s}" "{T:WantDeleg/%13.13s}{T:DestroyClId/%13.13s}\n"); xo_emit("{:secinfnoname/%13ju}{:sequence/%13ju}" "{:setssv/%13ju}{:teststateid/%13ju}{:wantdeleg/%13ju}" "{:destroyclid/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SECINFONONAME], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SEQUENCE], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETSSV], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_TESTSTATEID], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WANTDELEG], (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DESTROYCLIENTID]); xo_emit("{T:ReclaimCompl/%13.13s}\n"); xo_emit("{:reclaimcompl/%13ju}\n", (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RECLAIMCOMPL]); xo_close_container("nfsv41"); } xo_close_container("operations"); if (printtitle) xo_emit("{T:Server:}\n"); xo_open_container("server"); xo_emit("{T:Retfailed/%13.13s}{T:Faults/%13.13s}" "{T:Clients/%13.13s}\n"); xo_emit("{:retfailed/%13ju}{:faults/%13ju}{:clients/%13ju}\n", (uintmax_t)ext_nfsstats.srv_errs, (uintmax_t)ext_nfsstats.srvrpc_errs, (uintmax_t)ext_nfsstats.srvclients); xo_emit("{T:OpenOwner/%13.13s}{T:Opens/%13.13s}" "{T:LockOwner/%13.13s}{T:Locks/%13.13s}" "{T:Delegs/%13.13s}\n"); xo_emit("{:openowner/%13ju}{:opens/%13ju}{:lockowner/%13ju}" "{:locks/%13ju}{:delegs/%13ju}\n", (uintmax_t)ext_nfsstats.srvopenowners, (uintmax_t)ext_nfsstats.srvopens, (uintmax_t)ext_nfsstats.srvlockowners, (uintmax_t)ext_nfsstats.srvlocks, (uintmax_t)ext_nfsstats.srvdelegates); xo_close_container("server"); if (printtitle) xo_emit("{T:Server Cache Stats:}\n"); xo_open_container("cache"); xo_emit("{T:Inprog/%13.13s}{T:Idem/%13.13s}" "{T:Non-idem/%13.13s}{T:Misses/%13.13s}" "{T:CacheSize/%13.13s}{T:TCPPeak/%13.13s}\n"); xo_emit("{:inprog/%13ju}{:idem/%13ju}{:nonidem/%13ju}" "{:misses/%13ju}{:cachesize/%13ju}{:tcppeak/%13ju}\n", (uintmax_t)ext_nfsstats.srvcache_inproghits, (uintmax_t)ext_nfsstats.srvcache_idemdonehits, (uintmax_t)ext_nfsstats.srvcache_nonidemdonehits, (uintmax_t)ext_nfsstats.srvcache_misses, (uintmax_t)ext_nfsstats.srvcache_size, (uintmax_t)ext_nfsstats.srvcache_tcppeak); xo_close_container("cache"); xo_close_container("serverstats"); } xo_close_container("nfsv4"); }
int main(int argc, char *argv[]) { struct stat stbuf; struct statfs statfsbuf, totalbuf; struct maxwidths maxwidths; struct statfs *mntbuf; #ifdef MOUNT_CHAR_DEVS struct iovec *iov = NULL; #endif const char *fstype; #ifdef MOUNT_CHAR_DEVS char *mntpath; char errmsg[255] = {0}; #endif char *mntpt; const char **vfslist; int i, mntsize; int ch, rv; #ifdef MOUNT_CHAR_DEVS int iovlen = 0; #endif fstype = "ufs"; (void)setlocale(LC_ALL, ""); memset(&maxwidths, 0, sizeof(maxwidths)); memset(&totalbuf, 0, sizeof(totalbuf)); totalbuf.f_bsize = DEV_BSIZE; strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN); vfslist = NULL; argc = xo_parse_args(argc, argv); if (argc < 0) exit(1); while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T,")) != -1) switch (ch) { case 'a': aflag = 1; break; case 'b': /* FALLTHROUGH */ case 'P': /* * POSIX specifically discusses the behavior of * both -k and -P. It states that the blocksize should * be set to 1024. Thus, if this occurs, simply break * rather than clobbering the old blocksize. */ if (kflag) break; setenv("BLOCKSIZE", "512", 1); hflag = 0; break; case 'c': cflag = 1; break; case 'g': setenv("BLOCKSIZE", "1g", 1); hflag = 0; break; case 'H': hflag = UNITS_SI; break; case 'h': hflag = UNITS_2; break; case 'i': iflag = 1; break; case 'k': kflag++; setenv("BLOCKSIZE", "1024", 1); hflag = 0; break; case 'l': /* Ignore duplicate -l */ if (lflag) break; if (vfslist != NULL) xo_errx(1, "-l and -t are mutually exclusive."); vfslist = makevfslist(makenetvfslist()); lflag = 1; break; case 'm': setenv("BLOCKSIZE", "1m", 1); hflag = 0; break; case 'n': nflag = 1; break; case 't': if (lflag) xo_errx(1, "-l and -t are mutually exclusive."); if (vfslist != NULL) xo_errx(1, "only one -t option may be specified"); fstype = optarg; vfslist = makevfslist(optarg); break; case 'T': Tflag = 1; break; case ',': thousands = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; rv = 0; if (!*argv) { /* everything (modulo -t) */ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); mntsize = regetmntinfo(&mntbuf, mntsize, vfslist); } else { /* just the filesystems specified on the command line */ mntbuf = malloc(argc * sizeof(*mntbuf)); if (mntbuf == NULL) xo_err(1, "malloc()"); mntsize = 0; /* continued in for loop below */ } xo_open_container("storage-system-information"); xo_open_list("filesystem"); /* iterate through specified filesystems */ for (; *argv; argv++) { if (stat(*argv, &stbuf) < 0) { if ((mntpt = getmntpt(*argv)) == NULL) { xo_warn("%s", *argv); rv = 1; continue; } #ifdef MOUNT_CHAR_DEVS } else if (S_ISCHR(stbuf.st_mode)) { if ((mntpt = getmntpt(*argv)) == NULL) { mdev.fspec = *argv; mntpath = strdup("/tmp/df.XXXXXX"); if (mntpath == NULL) { xo_warn("strdup failed"); rv = 1; continue; } mntpt = mkdtemp(mntpath); if (mntpt == NULL) { xo_warn("mkdtemp(\"%s\") failed", mntpath); rv = 1; free(mntpath); continue; } if (iov != NULL) free_iovec(&iov, &iovlen); build_iovec_argf(&iov, &iovlen, "fstype", "%s", fstype); build_iovec_argf(&iov, &iovlen, "fspath", "%s", mntpath); build_iovec_argf(&iov, &iovlen, "from", "%s", *argv); build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg)); if (nmount(iov, iovlen, MNT_RDONLY|MNT_NOEXEC) < 0) { if (errmsg[0]) xo_warn("%s: %s", *argv, errmsg); else xo_warn("%s", *argv); rv = 1; (void)rmdir(mntpt); free(mntpath); continue; } else if (statfs(mntpt, &statfsbuf) == 0) { statfsbuf.f_mntonname[0] = '\0'; prtstat(&statfsbuf, &maxwidths); if (cflag) addstat(&totalbuf, &statfsbuf); } else { xo_warn("%s", *argv); rv = 1; } (void)unmount(mntpt, 0); (void)rmdir(mntpt); free(mntpath); continue; } #endif } else mntpt = *argv; /* * Statfs does not take a `wait' flag, so we cannot * implement nflag here. */ if (statfs(mntpt, &statfsbuf) < 0) { xo_warn("%s", mntpt); rv = 1; continue; } /* * Check to make sure the arguments we've been given are * satisfied. Return an error if we have been asked to * list a mount point that does not match the other args * we've been given (-l, -t, etc.). */ if (checkvfsname(statfsbuf.f_fstypename, vfslist)) { rv = 1; continue; } /* the user asked for it, so ignore the ignore flag */ statfsbuf.f_flags &= ~MNT_IGNORE; /* add to list */ mntbuf[mntsize++] = statfsbuf; } memset(&maxwidths, 0, sizeof(maxwidths)); for (i = 0; i < mntsize; i++) { if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) { update_maxwidths(&maxwidths, &mntbuf[i]); if (cflag) addstat(&totalbuf, &mntbuf[i]); } } for (i = 0; i < mntsize; i++) if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) prtstat(&mntbuf[i], &maxwidths); xo_close_list("filesystem"); if (cflag) prtstat(&totalbuf, &maxwidths); xo_close_container("storage-system-information"); xo_finish(); exit(rv); }