Print this page
XXX zone aliases in "prstat -ZA"
@@ -22,27 +22,29 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Portions Copyright 2009 Chad Mynhier
- * Copyright 2012 Joyent, Inc. All rights reserved.
+ * Copyright 2013 Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/loadavg.h>
#include <sys/time.h>
#include <sys/pset.h>
#include <sys/vm_usage.h>
+#include <sys/queue.h>
#include <zone.h>
#include <libzonecfg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
+#include <strings.h>
#include <errno.h>
#include <poll.h>
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
@@ -52,10 +54,12 @@
#include <langinfo.h>
#include <libintl.h>
#include <locale.h>
+#include <sasl/saslutil.h>
+
#include "prstat.h"
#include "prutil.h"
#include "prtable.h"
#include "prsort.h"
#include "prfile.h"
@@ -116,11 +120,11 @@
#define TASK_LINE \
"%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
#define PROJECT_LINE \
"%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
#define ZONE_LINE \
-"%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
+"%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %-28s"
#define TOTAL_LINE \
"Total: %d processes, %d lwps, load averages: %3.2f, %3.2f, %3.2f"
/* global variables */
@@ -163,10 +167,27 @@
static volatile uint_t sigtstp = 0;
static volatile uint_t sigterm = 0;
static long pagesize;
+/*
+ * Cache for mapping 'alias' names (an attribute of the zone configuration) to
+ * zone names, for use in -Z output.
+ */
+static uint_t enable_alias_cache = FALSE;
+static SLIST_HEAD(alias_cache_head, alias_cache_entry) alias_cache =
+ SLIST_HEAD_INITIALIZER(alias_cache);
+
+typedef struct alias_cache_entry {
+ char *ace_zonename;
+ char *ace_alias;
+
+ SLIST_ENTRY(alias_cache_entry) ace_linkage;
+} alias_cache_entry_t;
+
+static const char *lookup_zone_alias(const char *);
+
/* default settings */
static optdesc_t opts = {
5, /* interval between updates, seconds */
15, /* number of lines in top part */
@@ -481,11 +502,11 @@
id->id_nproc, psize, prssize, pmem, ptime,
pcpu, projname);
else if (list->l_type == LT_ZONES)
(void) printf(ZONE_LINE, (int)id->id_zoneid,
id->id_nproc, psize, prssize, pmem, ptime,
- pcpu, zonename);
+ pcpu, lookup_zone_alias(zonename));
else
(void) printf(USER_LINE, id->id_nproc, pname,
psize, prssize, pmem, ptime, pcpu);
(void) putp(t_eol);
(void) putchar('\n');
@@ -833,10 +854,108 @@
lwp->li_sig = usage->pr_sigs - lwp->li_usage.pr_sigs;
(void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t));
}
}
+static alias_cache_entry_t *
+fetch_zone_alias(const char *zonen)
+{
+ zone_dochandle_t zch;
+ alias_cache_entry_t *ace;
+ struct zone_attrtab attrtab;
+ char out[4 * sizeof (attrtab.zone_attr_value)];
+ unsigned outlen = 0;
+ int err;
+
+ /*
+ * Get handle to zone configuration:
+ */
+ if ((zch = zonecfg_init_handle()) == NULL)
+ return (NULL);
+ if (zonecfg_get_handle(zonen, zch) != Z_OK) {
+ zonecfg_fini_handle(zch);
+ return (NULL);
+ }
+
+ /*
+ * Lookup the 'alias' attribute:
+ */
+ bzero(&attrtab, sizeof (attrtab));
+ (void) strlcpy(attrtab.zone_attr_name, "alias",
+ sizeof (attrtab.zone_attr_name));
+ if ((zonecfg_lookup_attr(zch, &attrtab)) != Z_OK) {
+ zonecfg_fini_handle(zch);
+ return (NULL);
+ }
+ zonecfg_fini_handle(zch);
+
+ /*
+ * Attempt to base64 decode the 'alias' attribute value:
+ */
+ if ((err = sasl_decode64(attrtab.zone_attr_value,
+ strlen(attrtab.zone_attr_value), out, sizeof (out), &outlen)) !=
+ SASL_OK) {
+ if (err == SASL_BADPROT) {
+ /*
+ * If it was invalid base64, hand the raw value on:
+ */
+ (void) strlcpy(out, attrtab.zone_attr_value,
+ sizeof (out));
+ } else {
+ /*
+ * If we failed for any other reason, error out:
+ */
+ return (NULL);
+ }
+ }
+
+ /*
+ * Store it in the cache:
+ */
+ if ((ace = calloc(1, sizeof (*ace))) == NULL) {
+ return (NULL);
+ }
+ if ((ace->ace_zonename = strdup(zonen)) == NULL) {
+ free(ace);
+ return (NULL);
+ }
+ if ((ace->ace_alias = strdup(out)) == NULL) {
+ free(ace->ace_zonename);
+ free(ace);
+ return (NULL);
+ }
+
+ SLIST_INSERT_HEAD(&alias_cache, ace, ace_linkage);
+
+ return (ace);
+}
+
+static const char *
+lookup_zone_alias(const char *zonen)
+{
+ alias_cache_entry_t *ace;
+
+ if (enable_alias_cache != TRUE)
+ return (zonen);
+
+ /*
+ * Check if we have a value cached:
+ */
+ SLIST_FOREACH(ace, &alias_cache, ace_linkage) {
+ if (strcmp(ace->ace_zonename, zonen) == 0)
+ return (ace->ace_alias);
+ }
+
+ /*
+ * If not, try and fetch it from libzonecfg:
+ */
+ if ((ace = fetch_zone_alias(zonen)) != NULL)
+ return (ace->ace_alias);
+
+ return (zonen);
+}
+
static int
read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize)
{
char procfile[MAX_PROCFS_PATH];
@@ -1374,12 +1493,15 @@
fd_init(Setrlimit());
pagesize = sysconf(_SC_PAGESIZE);
while ((opt = getopt(argc, argv,
- "vVcd:HmarRLtu:U:n:p:C:P:h:s:S:j:k:TJz:Z")) != (int)EOF) {
+ "vVcd:HmAarRLtu:U:n:p:C:P:h:s:S:j:k:TJz:Z")) != (int)EOF) {
switch (opt) {
+ case 'A':
+ enable_alias_cache = TRUE;
+ break;
case 'r':
opts.o_outpmode |= OPT_NORESOLVE;
break;
case 'R':
opts.o_outpmode |= OPT_REALTIME;