summaryrefslogtreecommitdiff
path: root/usr/src/lib/libcmd/common/vmstate.c
diff options
context:
space:
mode:
authorRoger A. Faulkner <Roger.Faulkner@Oracle.COM>2010-04-03 09:48:44 -0700
committerRoger A. Faulkner <Roger.Faulkner@Oracle.COM>2010-04-03 09:48:44 -0700
commit3e14f97f673e8a630f076077de35afdd43dc1587 (patch)
tree9828b6b676f58d7b27dd28e00202d3f3461a5cd8 /usr/src/lib/libcmd/common/vmstate.c
parent4f60987df4dcaa54a88b596f861fbf4f3382c65e (diff)
downloadillumos-joyent-3e14f97f673e8a630f076077de35afdd43dc1587.tar.gz
6939349 RFE: Update ksh93 to ast-ksh.2010-03-09
6877392 ksh93 regresses 'uniq -c' performance 6887363 Korn shell 93 sometimes mishandles return value of its child process 6900314 (while true ; do true|true ; done) hang in ioctl() with SIGTTOU 6904557 wc no longer counts number of bytes correctly 6904575 cut -d with multibyte character no longer works 6904597 paste -d no longer works with multibyte characters 6904780 /usr/bin/cksum changed output in snv_128 6904870 uniq -s does not skip multibyte characters correctly 6904878 join -t no longer works with multibyte char separator 6907460 EXIT trap handlers are sometimes executed twice 6909579 libast getopt solaris compatibility broken 6920072 ksh93 tail -f, with unconditional .25s sleep and line parsing, about 37x slower than cat 6932124 mktemp in ksh93 is broken Contributed by Olga Kryzhanovska <olga.kryzhanovska@gmail.com>
Diffstat (limited to 'usr/src/lib/libcmd/common/vmstate.c')
-rw-r--r--usr/src/lib/libcmd/common/vmstate.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/usr/src/lib/libcmd/common/vmstate.c b/usr/src/lib/libcmd/common/vmstate.c
new file mode 100644
index 0000000000..79722972d2
--- /dev/null
+++ b/usr/src/lib/libcmd/common/vmstate.c
@@ -0,0 +1,163 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1992-2010 AT&T Intellectual Property *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.opensource.org/licenses/cpl1.0.txt *
+* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#define FORMAT "region=%(region)p size=%(size)d segments=%(segments)d busy=(%(busy_size)d,%(busy_blocks)d,%(busy_max)d) free=(%(free_size)d,%(free_blocks)d,%(free_max)d)"
+
+static const char usage[] =
+"[-?\n@(#)$Id: vmstate (AT&T Research) 2010-03-05 $\n]"
+USAGE_LICENSE
+"[+NAME?vmstate - list the calling process vmalloc region state]"
+"[+DESCRIPTION?When invoked as a shell builtin, \bvmstate\b lists the "
+ "calling process \bvmalloc\b(3) state for all regions.]"
+"[f:format?List the ids specified by \aformat\a. \aformat\a follows "
+ "\bprintf\b(3) conventions, except that \bsfio\b(3) inline ids are used "
+ "instead of arguments: "
+ "%[-+]][\awidth\a[.\aprecis\a[.\abase\a]]]]]](\aid\a)\achar\a. The "
+ "supported \aid\as are:]:[format:=" FORMAT "]"
+ "{"
+ "[+size?The total region size.]"
+ "[+segments?The number of segments in the region.]"
+ "[+busy_size?The total busy block size.]"
+ "[+busy_blocks?The number of busy blocks.]"
+ "[+busy_max?The maximum busy block size.]"
+ "[+free_size?The total free block size.]"
+ "[+free_blocks?The number of free blocks.]"
+ "[+free_max?The maximum free block size.]"
+ "}"
+"[+SEE ALSO?\bvmalloc\b(3)]"
+;
+
+#include <cmd.h>
+#include <vmalloc.h>
+
+typedef struct State_s
+{
+ char* format;
+ Vmalloc_t* vm;
+ Vmstat_t vs;
+ unsigned int regions;
+ Vmalloc_t* region[256];
+} State_t;
+
+/*
+ * sfkeyprintf() lookup
+ * handle==0 for heading
+ */
+
+static int
+key(void* handle, Sffmt_t* fp, const char* arg, char** ps, Sflong_t* pn)
+{
+ register State_t* state = (State_t*)handle;
+ register char* s;
+
+ if (!(s = fp->t_str) || streq(s, "size"))
+ *pn = state->vs.extent;
+ else if (streq(s, "region"))
+ *pn = integralof(state->vm);
+ else if (streq(s, "segments"))
+ *pn = state->vs.n_seg;
+ else if (streq(s, "busy_size"))
+ *pn = state->vs.s_busy;
+ else if (streq(s, "busy_blocks"))
+ *pn = state->vs.n_busy;
+ else if (streq(s, "busy_max"))
+ *pn = state->vs.m_busy;
+ else if (streq(s, "free_size"))
+ *pn = state->vs.s_free;
+ else if (streq(s, "free_blocks"))
+ *pn = state->vs.n_free;
+ else if (streq(s, "free_max"))
+ *pn = state->vs.m_free;
+ else if (streq(s, "format"))
+ *ps = (char*)state->format;
+ else
+ {
+ error(2, "%s: unknown format identifier", s);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+visit(Vmalloc_t* vm, void* addr, size_t size, Vmdisc_t* disc, void* handle)
+{
+ State_t* state = (State_t*)handle;
+ Vmstat_t vs;
+
+ if (vm != state->vm)
+ {
+ state->vm = vm;
+ if (state->regions < elementsof(state->region))
+ state->region[state->regions++] = vm;
+ }
+ return 0;
+}
+
+int
+b_vmstate(int argc, char** argv, void* context)
+{
+ register int i;
+ State_t state;
+
+ memset(&state, 0, sizeof(state));
+ cmdinit(argc, argv, context, ERROR_CATALOG, 0);
+ for (;;)
+ {
+ switch (optget(argv, usage))
+ {
+ case 'f':
+ state.format = opt_info.arg;
+ continue;
+ case '?':
+ error(ERROR_USAGE|4, "%s", opt_info.arg);
+ continue;
+ case ':':
+ error(2, "%s", opt_info.arg);
+ continue;
+ }
+ break;
+ }
+ argv += opt_info.index;
+ if (error_info.errors || *argv)
+ error(ERROR_USAGE|4, "%s", optusage(NiL));
+ if (!state.format)
+ state.format = FORMAT;
+
+ /*
+ * the walk must do no allocations because it locks the regions
+ */
+
+ vmwalk(NiL, visit, &state);
+
+ /*
+ * now we can compute and list the state of each region
+ */
+
+ for (i = 0; i < state.regions; i++)
+ {
+ state.vm = state.region[i];
+ vmstat(state.vm, &state.vs);
+ sfkeyprintf(sfstdout, &state, state.format, key, NiL);
+ sfprintf(sfstdout, "\n");
+ }
+ return 0;
+}