diff options
Diffstat (limited to 'usr/src/cmd/rcap')
-rw-r--r-- | usr/src/cmd/rcap/common/utils.c | 75 | ||||
-rw-r--r-- | usr/src/cmd/rcap/common/utils.h | 2 | ||||
-rw-r--r-- | usr/src/cmd/rcap/rcapadm/rcapadm.c | 16 | ||||
-rw-r--r-- | usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c | 141 | ||||
-rw-r--r-- | usr/src/cmd/rcap/rcapd/rcapd_scanner.c | 3 | ||||
-rw-r--r-- | usr/src/cmd/rcap/rcapstat/rcapstat.c | 7 |
6 files changed, 121 insertions, 123 deletions
diff --git a/usr/src/cmd/rcap/common/utils.c b/usr/src/cmd/rcap/common/utils.c index 799fdcef23..dd511c7c50 100644 --- a/usr/src/cmd/rcap/common/utils.c +++ b/usr/src/cmd/rcap/common/utils.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #include <sys/param.h> @@ -257,77 +258,3 @@ xatoi(char *p) return (i); } } - -/* - * get_running_zones() calls zone_list(2) to find out how many zones are - * running. It then calls zone_list(2) again to fetch the list of running - * zones (stored in *zents). - */ -int -get_running_zones(uint_t *nzents, zone_entry_t **zents) -{ - zoneid_t *zids; - uint_t nzents_saved; - int i; - zone_entry_t *zentp; - zone_state_t zstate; - - *zents = NULL; - if (zone_list(NULL, nzents) != 0) { - warn(gettext("could not get zoneid list\n")); - return (E_ERROR); - } - -again: - if (*nzents == 0) - return (E_SUCCESS); - - if ((zids = (zoneid_t *)calloc(*nzents, sizeof (zoneid_t))) == NULL) { - warn(gettext("out of memory: zones will not be capped\n")); - return (E_ERROR); - } - - nzents_saved = *nzents; - - if (zone_list(zids, nzents) != 0) { - warn(gettext("could not get zone list\n")); - free(zids); - return (E_ERROR); - } - if (*nzents != nzents_saved) { - /* list changed, try again */ - free(zids); - goto again; - } - - *zents = calloc(*nzents, sizeof (zone_entry_t)); - if (*zents == NULL) { - warn(gettext("out of memory: zones will not be capped\n")); - free(zids); - return (E_ERROR); - } - - zentp = *zents; - for (i = 0; i < *nzents; i++) { - char name[ZONENAME_MAX]; - - if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) { - warn(gettext("could not get name for " - "zoneid %d\n"), zids[i]); - continue; - } - - (void) strlcpy(zentp->zname, name, sizeof (zentp->zname)); - zentp->zid = zids[i]; - if (zone_get_state(name, &zstate) != Z_OK || - zstate != ZONE_STATE_RUNNING) - continue; - - - zentp++; - } - *nzents = zentp - *zents; - - free(zids); - return (E_SUCCESS); -} diff --git a/usr/src/cmd/rcap/common/utils.h b/usr/src/cmd/rcap/common/utils.h index 7196cfb4ce..cf2e17c080 100644 --- a/usr/src/cmd/rcap/common/utils.h +++ b/usr/src/cmd/rcap/common/utils.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #ifndef _UTILS_H @@ -98,7 +99,6 @@ extern void vdprintfe(int, const char *, va_list); extern void dprintfe(int, char *, ...); extern void hrt2ts(hrtime_t, timestruc_t *); extern int xatoi(char *); -extern int get_running_zones(uint_t *, zone_entry_t **); #ifdef __cplusplus } diff --git a/usr/src/cmd/rcap/rcapadm/rcapadm.c b/usr/src/cmd/rcap/rcapadm/rcapadm.c index 92888b2071..b92115469a 100644 --- a/usr/src/cmd/rcap/rcapadm/rcapadm.c +++ b/usr/src/cmd/rcap/rcapadm/rcapadm.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -145,20 +146,29 @@ out: scf_handle_destroy(h); } +static int +set_zone_cap(char *zonename, uint64_t mcap) +{ + char cmd[128 + ZONENAME_MAX]; + + (void) snprintf(cmd, sizeof (cmd), "/usr/bin/prctl -r " + "-n zone.max-physical-memory -v %llu -i zone %s", mcap, zonename); + return (system(cmd)); +} + /* * Update the in-kernel memory cap for the specified zone. */ static int update_zone_mcap(char *zonename, char *maxrss) { - zoneid_t zone_id; uint64_t num; if (getzoneid() != GLOBAL_ZONEID || zonecfg_in_alt_root()) return (E_SUCCESS); /* get the running zone from the kernel */ - if ((zone_id = getzoneidbyname(zonename)) == -1) { + if (getzoneidbyname(zonename) == -1) { (void) fprintf(stderr, gettext("zone '%s' must be running\n"), zonename); return (E_ERROR); @@ -169,7 +179,7 @@ update_zone_mcap(char *zonename, char *maxrss) return (E_ERROR); } - if (zone_setattr(zone_id, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) { + if (set_zone_cap(zonename, num) == -1) { (void) fprintf(stderr, gettext("could not set memory " "cap for zone '%s'\n"), zonename); return (E_ERROR); diff --git a/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c b/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c index db86aa6276..88403dda37 100644 --- a/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c +++ b/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c @@ -21,16 +21,17 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2011 Joyent, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <procfs.h> #include <project.h> #include <stdlib.h> #include <strings.h> #include <zone.h> #include <libzonecfg.h> +#include <dirent.h> +#include <libproc.h> #include "rcapd.h" #include "utils.h" @@ -39,61 +40,117 @@ extern boolean_t gz_capped; /* round up to next y = 2^n */ #define ROUNDUP(x, y) (((x) + ((y) - 1)) & ~((y) - 1)) -static void -update_zone(zone_entry_t *zent, void *walk_data) +static struct ps_prochandle * +grab_zone_proc(zoneid_t zid) { - void(*update_notification_cb)(char *, char *, int, uint64_t, int) = - (void(*)(char *, char *, int, uint64_t, int))walk_data; - int changes; - int64_t max_rss; + DIR *dirp; + struct dirent *dentp; + int pid, pid_self, tmp; + psinfo_t psinfo; + struct ps_prochandle *pr = NULL; + + pid_self = getpid(); + + if ((dirp = opendir("/proc")) == NULL) + return (NULL); + + while (dentp = readdir(dirp)) { + pid = atoi(dentp->d_name); + + /* Skip self */ + if (pid == pid_self) + continue; + + if (proc_get_psinfo(pid, &psinfo) != 0) + continue; + + if (psinfo.pr_zoneid != zid) + continue; + + /* attempt to grab process */ + if ((pr = Pgrab(pid, 0, &tmp)) != NULL) { + if (Psetflags(pr, PR_RLC) != 0) { + Prelease(pr, 0); + } + if (Pcreate_agent(pr) == 0) { + if (pr_getzoneid(pr) != zid) { + Prelease(pr, 0); + continue; + } + + (void) closedir(dirp); + return (pr); + } else { + Prelease(pr, 0); + } + } + } + + (void) closedir(dirp); + return (NULL); +} + +static uint64_t +get_zone_cap(zoneid_t zid) +{ + rctlblk_t *rblk; uint64_t mcap; - lcollection_t *lcol; - rcid_t colid; + struct ps_prochandle *pr; - if (zone_getattr(zent->zid, ZONE_ATTR_PHYS_MCAP, &mcap, - sizeof (mcap)) != -1 && mcap != 0) - max_rss = ROUNDUP(mcap, 1024) / 1024; - else - max_rss = 0; - - if (zent->zid == GLOBAL_ZONEID) { - if (max_rss > 0) - gz_capped = B_TRUE; - else - gz_capped = B_FALSE; + if ((rblk = (rctlblk_t *)malloc(rctlblk_size())) == NULL) + return (UINT64_MAX); + + if ((pr = grab_zone_proc(zid)) == NULL) { + free(rblk); + return (UINT64_MAX); } + if (pr_getrctl(pr, "zone.max-physical-memory", NULL, rblk, + RCTL_FIRST)) { + Pdestroy_agent(pr); + Prelease(pr, 0); + free(rblk); + return (UINT64_MAX); + } - colid.rcid_type = RCIDT_ZONE; - colid.rcid_val = zent->zid; + Pdestroy_agent(pr); + Prelease(pr, 0); - lcol = lcollection_insert_update(&colid, max_rss, zent->zname, - &changes); - if (update_notification_cb != NULL) - update_notification_cb("zone", zent->zname, changes, max_rss, - (lcol != NULL) ? lcol->lcol_mark : 0); + mcap = rctlblk_get_value(rblk); + free(rblk); + return (mcap); } - +/* + * For zones, rcapd only caps the global zone, since each non-global zone + * caps itself. + */ /* ARGSUSED */ void lcollection_update_zone(lcollection_update_type_t ut, void(*update_notification_cb)(char *, char *, int, uint64_t, int)) { - int i; - uint_t nzents; - zone_entry_t *zents; - - /* - * Enumerate running zones. - */ - if (get_running_zones(&nzents, &zents) != 0) - return; - - for (i = 0; i < nzents; i++) { - update_zone(&zents[i], (void *)update_notification_cb); + int changes; + int64_t max_rss; + uint64_t mcap; + lcollection_t *lcol; + rcid_t colid; + mcap = get_zone_cap(GLOBAL_ZONEID); + if (mcap != 0 && mcap != UINT64_MAX) { + max_rss = ROUNDUP(mcap, 1024) / 1024; + gz_capped = B_TRUE; + } else { + max_rss = UINT64_MAX / 1024; + gz_capped = B_FALSE; } - free(zents); + colid.rcid_type = RCIDT_ZONE; + colid.rcid_val = GLOBAL_ZONEID; + + lcol = lcollection_insert_update(&colid, max_rss, GLOBAL_ZONENAME, + &changes); + if (update_notification_cb != NULL) + update_notification_cb("zone", GLOBAL_ZONENAME, changes, + max_rss, (lcol != NULL) ? lcol->lcol_mark : 0); } diff --git a/usr/src/cmd/rcap/rcapd/rcapd_scanner.c b/usr/src/cmd/rcap/rcapd/rcapd_scanner.c index b39811b552..254bb9e922 100644 --- a/usr/src/cmd/rcap/rcapd/rcapd_scanner.c +++ b/usr/src/cmd/rcap/rcapd/rcapd_scanner.c @@ -21,6 +21,7 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Joyent, Inc. All rights reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -551,7 +552,7 @@ pageout(pid_t pid, struct ps_prochandle *Pr, caddr_t start, caddr_t end) errno = 0; res = pr_memcntl(Pr, start, (end - start), MC_SYNC, - (caddr_t)(MS_ASYNC | MS_INVALIDATE), 0, 0); + (caddr_t)(MS_ASYNC | MS_INVALCURPROC), 0, 0); debug_high("pr_memcntl [%p-%p): %d", (void *)start, (void *)end, res); /* diff --git a/usr/src/cmd/rcap/rcapstat/rcapstat.c b/usr/src/cmd/rcap/rcapstat/rcapstat.c index 0632250fed..2838c6e5d5 100644 --- a/usr/src/cmd/rcap/rcapstat/rcapstat.c +++ b/usr/src/cmd/rcap/rcapstat/rcapstat.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -72,6 +73,8 @@ typedef struct col { static col_t *col_head; static int ncol; +#define RCAPD_NA "rcapd is not active (try zonememstat)\n" + static col_t * col_find(rcid_t id) { @@ -152,7 +155,7 @@ read_stats(rcid_type_t stat_type) struct stat st; if ((fd = open(STAT_FILE_DEFAULT, O_RDONLY)) < 0) { - warn(gettext("rcapd is not active\n")); + warn(gettext(RCAPD_NA)); return (E_ERROR); } @@ -173,7 +176,7 @@ read_stats(rcid_type_t stat_type) pid = hdr.rs_pid; (void) snprintf(procfile, 20, "/proc/%lld/psinfo", pid); if ((proc_fd = open(procfile, O_RDONLY)) < 0) { - warn(gettext("rcapd is not active\n")); + warn(gettext(RCAPD_NA)); (void) close(fd); return (E_ERROR); } |