diff options
| author | nf202958 <none@none> | 2006-07-26 16:31:57 -0700 |
|---|---|---|
| committer | nf202958 <none@none> | 2006-07-26 16:31:57 -0700 |
| commit | aa4a4f3b6a666da60ab2a89e6fd7e25157931a06 (patch) | |
| tree | d7a4c9beb91fbc817fe57969190851abec0d615b /usr/src | |
| parent | 43ecc7ea8dbfb25feb5543dc932bd952eaab3816 (diff) | |
| download | illumos-joyent-aa4a4f3b6a666da60ab2a89e6fd7e25157931a06.tar.gz | |
6201153 rctl exceeded message should include zonename
6340634 truss should decode rctls
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/cmd/truss/Makefile.com | 4 | ||||
| -rw-r--r-- | usr/src/cmd/truss/codes.c | 71 | ||||
| -rw-r--r-- | usr/src/cmd/truss/expound.c | 138 | ||||
| -rw-r--r-- | usr/src/cmd/truss/print.c | 97 | ||||
| -rw-r--r-- | usr/src/cmd/truss/print.h | 6 | ||||
| -rw-r--r-- | usr/src/cmd/truss/proto.h | 10 | ||||
| -rw-r--r-- | usr/src/cmd/truss/systable.c | 24 | ||||
| -rw-r--r-- | usr/src/uts/common/os/rctl.c | 52 |
8 files changed, 382 insertions, 20 deletions
diff --git a/usr/src/cmd/truss/Makefile.com b/usr/src/cmd/truss/Makefile.com index b849ad1866..34f54cbcff 100644 --- a/usr/src/cmd/truss/Makefile.com +++ b/usr/src/cmd/truss/Makefile.com @@ -39,8 +39,8 @@ include ../../Makefile.cmd CFLAGS += $(CCVERBOSE) CFLAGS64 += $(CCVERBOSE) -LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD) -lint := LAZYLIBS = -ltsol +LAZYLIBS = $(ZLAZYLOAD) -ltsol -lnvpair $(ZNOLAZYLOAD) +lint := LAZYLIBS = -ltsol -lnvpair LDLIBS += -lproc -lrtld_db -lc_db -lnsl -lsocket $(LAZYLIBS) CPPFLAGS += -D_REENTRANT -D_LARGEFILE64_SOURCE=1 diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c index f95c90b174..66f9a00daa 100644 --- a/usr/src/cmd/truss/codes.c +++ b/usr/src/cmd/truss/codes.c @@ -1146,6 +1146,77 @@ utscode(int code) } const char * +rctlsyscode(int code) +{ + const char *str = NULL; + switch (code) { + case 0: str = "GETRCTL"; break; + case 1: str = "SETRCTL"; break; + case 2: str = "RCTLSYS_LST"; break; + case 3: str = "RCTLSYS_CTL"; break; + default: str = "UNKNOWN"; break; + } + return (str); +} + +const char * +rctl_local_action(private_t *pri, uint_t val) +{ + uint_t action = val & (~RCTL_LOCAL_ACTION_MASK); + + char *s = pri->code_buf; + + *s = '\0'; + + if (action & RCTL_LOCAL_NOACTION) { + action ^= RCTL_LOCAL_NOACTION; + (void) strlcat(s, "|RCTL_LOCAL_NOACTION", + sizeof (pri->code_buf)); + } + if (action & RCTL_LOCAL_SIGNAL) { + action ^= RCTL_LOCAL_SIGNAL; + (void) strlcat(s, "|RCTL_LOCAL_SIGNAL", + sizeof (pri->code_buf)); + } + if (action & RCTL_LOCAL_DENY) { + action ^= RCTL_LOCAL_DENY; + (void) strlcat(s, "|RCTL_LOCAL_DENY", + sizeof (pri->code_buf)); + } + + if ((action & (~RCTL_LOCAL_ACTION_MASK)) != 0) + return (NULL); + else if (*s != '\0') + return (s+1); + else + return (NULL); +} + + +const char * +rctl_local_flags(private_t *pri, uint_t val) +{ + uint_t pval = val & RCTL_LOCAL_ACTION_MASK; + char *s = pri->code_buf; + + *s = '\0'; + + if (pval & RCTL_LOCAL_MAXIMAL) { + pval ^= RCTL_LOCAL_MAXIMAL; + (void) strlcat(s, "|RCTL_LOCAL_MAXIMAL", + sizeof (pri->code_buf)); + } + + if ((pval & RCTL_LOCAL_ACTION_MASK) != 0) + return (NULL); + else if (*s != '\0') + return (s+1); + else + return (NULL); +} + + +const char * sconfname(int code) { const char *str = NULL; diff --git a/usr/src/cmd/truss/expound.c b/usr/src/cmd/truss/expound.c index cb64154f41..e5213b88d5 100644 --- a/usr/src/cmd/truss/expound.c +++ b/usr/src/cmd/truss/expound.c @@ -91,6 +91,8 @@ #include <sys/priv_impl.h> #include <sys/priv.h> #include <tsol/label.h> +#include <sys/nvpair.h> +#include <libnvpair.h> #include "ramdata.h" #include "systable.h" @@ -4394,6 +4396,41 @@ show_getrusage32(long offset) } #endif +/* + * Utility function to print a packed nvlist by unpacking + * and calling the libnvpair pretty printer. Frees all + * allocated memory internally. + */ +static void +show_packed_nvlist(private_t *pri, uintptr_t offset, size_t size) +{ + nvlist_t *nvl = NULL; + size_t readsize; + char *buf; + + if ((offset == 0) || (size == 0)) { + return; + } + + buf = my_malloc(size, "nvlist decode buffer"); + readsize = Pread(Proc, buf, size, offset); + if (readsize != size) { + (void) printf("%s\t<?>", pri->pname); + } else { + int result; + + result = nvlist_unpack(buf, size, &nvl, 0); + if (result == 0) { + nvlist_print(stdout, nvl); + nvlist_free(nvl); + } else { + (void) printf("%s\tunpack of nvlist" + " failed: %d\n", pri->pname, result); + } + } + free(buf); +} + static void show_zone_create_args(private_t *pri, long offset) { @@ -4436,6 +4473,9 @@ show_zone_create_args(private_t *pri, long offset) (void) printf("%s\t rctlbufsz: %lu\n", pri->pname, (ulong_t)args.rctlbufsz); + show_packed_nvlist(pri, (uintptr_t)args.rctlbuf, + args.rctlbufsz); + (void) printf("%s\t zfs: %s\n", pri->pname, zone_zfs); (void) printf("%s\textended_error: 0x%p\n", pri->pname, @@ -4518,6 +4558,9 @@ show_zone_create_args32(private_t *pri, long offset) (void) printf("%s\t rctlbufsz: %lu\n", pri->pname, (ulong_t)args.rctlbufsz); + show_packed_nvlist(pri, (uintptr_t)args.rctlbuf, + args.rctlbufsz); + (void) printf("%s\t zfs: %s\n", pri->pname, zone_zfs); (void) printf("%s\textended_error: 0x%x\n", pri->pname, @@ -4573,6 +4616,97 @@ show_zones(private_t *pri) } } +static void +show_rctlblk(private_t *pri, long _rctlblk) +{ + rctlblk_t *blk; + int size = rctlblk_size(); + size_t readsize; + const char *s; + + blk = my_malloc(size, "rctlblk decode buffer"); + readsize = Pread(Proc, blk, size, _rctlblk); + if (readsize != size) { + (void) printf("%s\t\t<?>", pri->pname); + } else { + (void) printf("%s\t\t Privilege: 0x%x\n", + pri->pname, + rctlblk_get_privilege(blk)); + (void) printf("%s\t\t Value: %lld\n", + pri->pname, + rctlblk_get_value(blk)); + (void) printf("%s\t\tEnforced Value: %lld\n", + pri->pname, + rctlblk_get_enforced_value(blk)); + + { + int sig, act; + act = rctlblk_get_local_action(blk, &sig); + + s = rctl_local_action(pri, act); + if (s == NULL) { + (void) printf("%s\t\t Local action: 0x%x\n", + pri->pname, act); + } else { + (void) printf("%s\t\t Local action: %s\n", + pri->pname, s); + } + + if (act & RCTL_LOCAL_SIGNAL) { + (void) printf("%s\t\t " + "For signal %s\n", + pri->pname, signame(pri, sig)); + } + } + + s = rctl_local_flags(pri, rctlblk_get_local_flags(blk)); + if (s == NULL) { + (void) printf("%s\t\t Local flags: 0x%x\n", + pri->pname, rctlblk_get_local_flags(blk)); + } else { + (void) printf("%s\t\t Local flags: %s\n", + pri->pname, s); + } + +#ifdef _LP64 + (void) printf("%s\t\t Recipient PID: %d\n", + pri->pname, + rctlblk_get_recipient_pid(blk)); +#else + (void) printf("%s\t\t Recipient PID: %ld\n", + pri->pname, + rctlblk_get_recipient_pid(blk)); +#endif + (void) printf("%s\t\t Firing Time: %lld\n", + pri->pname, + rctlblk_get_firing_time(blk)); + } + free(blk); +} + +static void +show_rctls(private_t *pri) +{ + switch (pri->sys_args[0]) { + case 0: /* getrctl */ + case 1: /* setrctl */ + /* + * If these offsets look a little odd, remember that they're + * into the _raw_ system call + */ + (void) printf("%s\tOld rctlblk: 0x%lx\n", pri->pname, + pri->sys_args[2]); + if (pri->sys_args[2] != NULL) { + show_rctlblk(pri, pri->sys_args[2]); + } + (void) printf("%s\tNew rctlblk: 0x%lx\n", pri->pname, + pri->sys_args[3]); + if (pri->sys_args[3] != NULL) { + show_rctlblk(pri, pri->sys_args[3]); + } + break; + } +} /* expound verbosely upon syscall arguments */ /*ARGSUSED*/ @@ -5054,5 +5188,9 @@ expound(private_t *pri, long r0, int raw) case SYS_zone: show_zones(pri); break; + + case SYS_rctlsys: + show_rctls(pri); + break; } } diff --git a/usr/src/cmd/truss/print.c b/usr/src/cmd/truss/print.c index 2438bf3ec7..d063081e5e 100644 --- a/usr/src/cmd/truss/print.c +++ b/usr/src/cmd/truss/print.c @@ -77,6 +77,8 @@ #include <sys/lgrp_user.h> #include <sys/door.h> #include <sys/tsol/tndb.h> +#include <sys/rctl.h> +#include <sys/rctl_impl.h> #include "ramdata.h" #include "print.h" #include "proto.h" @@ -2439,6 +2441,97 @@ prt_dpm(private_t *pri, int raw, long val) } /* + * Print rctlsys subcodes + */ +void +prt_rsc(private_t *pri, int raw, long val) /* print utssys code */ +{ + const char *s = raw? NULL : rctlsyscode(val); + + if (s == NULL) + prt_dec(pri, 0, val); + else + outstring(pri, s); +} + +/* + * Print getrctl flags + */ +void +prt_rgf(private_t *pri, int raw, long val) +{ + long action = val & (~RCTLSYS_ACTION_MASK); + + if (raw) + prt_hex(pri, 0, val); + else if (action == RCTL_FIRST) + outstring(pri, "RCTL_FIRST"); + else if (action == RCTL_NEXT) + outstring(pri, "RCTL_NEXT"); + else if (action == RCTL_USAGE) + outstring(pri, "RCTL_USAGE"); + else + prt_hex(pri, 0, val); +} + +/* + * Print setrctl flags + */ +void +prt_rsf(private_t *pri, int raw, long val) +{ + long action = val & (~RCTLSYS_ACTION_MASK); + long pval = val & RCTL_LOCAL_ACTION_MASK; + char *s = pri->code_buf; + + if (raw) { + prt_hex(pri, 0, val); + return; + } else if (action == RCTL_INSERT) + (void) strcpy(s, "RCTL_INSERT"); + else if (action == RCTL_DELETE) + (void) strcpy(s, "RCTL_DELETE"); + else if (action == RCTL_REPLACE) + (void) strcpy(s, "RCTL_REPLACE"); + else { + prt_hex(pri, 0, val); + return; + } + + if (pval & RCTL_USE_RECIPIENT_PID) { + pval ^= RCTL_USE_RECIPIENT_PID; + (void) strlcat(s, "|RCTL_USE_RECIPIENT_PID", + sizeof (pri->code_buf)); + } + + if ((pval & RCTLSYS_ACTION_MASK) != 0) + prt_hex(pri, 0, val); + else if (*s != '\0') + outstring(pri, s); + else + prt_hex(pri, 0, val); +} + +/* + * Print rctlctl flags + */ +void +prt_rcf(private_t *pri, int raw, long val) +{ + long action = val & (~RCTLSYS_ACTION_MASK); + + if (raw) + prt_hex(pri, 0, val); + else if (action == RCTLCTL_GET) + outstring(pri, "RCTLCTL_GET"); + else if (action == RCTLCTL_SET) + outstring(pri, "RCTLCTL_SET"); + else + prt_hex(pri, 0, val); +} + + +/* * Array of pointers to print functions, one for each format. */ void (* const Print[])() = { @@ -2531,5 +2624,9 @@ void (* const Print[])() = { prt_dfl, /* DFL -- print door_create() flags */ prt_dpm, /* DPM -- print DOOR_PARAM_XX flags */ prt_tnd, /* TND -- print trusted network data base opcode */ + prt_rsc, /* RSC -- print rctlsys() subcodes */ + prt_rgf, /* RGF -- print getrctl() flags */ + prt_rsf, /* RSF -- print setrctl() flags */ + prt_rcf, /* RCF -- print rctlsys_ctl() flags */ prt_dec, /* HID -- hidden argument, make this the last one */ }; diff --git a/usr/src/cmd/truss/print.h b/usr/src/cmd/truss/print.h index 7714525875..3819c4c01e 100644 --- a/usr/src/cmd/truss/print.h +++ b/usr/src/cmd/truss/print.h @@ -128,7 +128,11 @@ extern "C" { #define DFL 86 /* print door_create() flags */ #define DPM 87 /* print DOOR_PARAM_XX flags */ #define TND 88 /* print trusted network data base opcode */ -#define HID 89 /* hidden argument, don't print */ +#define RSC 89 /* print rctlsys subcode */ +#define RGF 90 /* print rctlsys_get flags */ +#define RSF 91 /* print rctlsys_set flags */ +#define RCF 92 /* print rctlsys_ctl flags */ +#define HID 93 /* hidden argument, don't print */ /* make sure HID is always the last member */ /* diff --git a/usr/src/cmd/truss/proto.h b/usr/src/cmd/truss/proto.h index cd1627699c..7565bd8aa1 100644 --- a/usr/src/cmd/truss/proto.h +++ b/usr/src/cmd/truss/proto.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -92,6 +91,9 @@ extern const char *pathconfname(int); extern const char *fuiname(int); extern const char *fuflags(private_t *, int); extern const char *ipprotos(int); +extern const char *rctlsyscode(int); +extern const char *rctl_local_flags(private_t *, uint_t val); +extern const char *rctl_local_action(private_t *, uint_t val); extern void expound(private_t *, long, int); extern void prtimestruc(private_t *, const char *, timestruc_t *); diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c index 13860bc560..ee8b7f0233 100644 --- a/usr/src/cmd/truss/systable.c +++ b/usr/src/cmd/truss/systable.c @@ -300,7 +300,7 @@ const struct systable systable[] = { {"acctctl", 3, DEC, NOV, HEX, HEX, UNS}, /* 71 */ {"exacctsys", 6, DEC, NOV, DEC, IDT, DEC, HEX, DEC, HEX}, /* 72 */ {"getpagesizes", 2, DEC, NOV, HEX, DEC}, /* 73 */ -{"rctlsys", 6, DEC, NOV, DEC, STG, HEX, HEX, DEC, DEC}, /* 74 */ +{"rctlsys", 6, DEC, NOV, RSC, STG, HEX, HEX, DEC, DEC}, /* 74 */ {"issetugid", 0, DEC, NOV}, /* 75 */ {"fsat", 6, DEC, NOV, HEX, HEX, HEX, HEX, HEX, HEX}, /* 76 */ {"lwp_park", 3, DEC, NOV, DEC, HEX, DEC}, /* 77 */ @@ -576,6 +576,14 @@ const struct systable utstable[] = { }; #define NUTSCODE (sizeof (utstable) / sizeof (struct systable)) +const struct systable rctltable[] = { +{"getrctl", 6, DEC, NOV, HID, STG, HEX, HEX, HID, RGF}, /* 0 */ +{"setrctl", 6, DEC, NOV, HID, STG, HEX, HEX, HID, RSF}, /* 1 */ +{"rctlsys_lst", 6, DEC, NOV, HID, HID, HEX, HID, HEX, HID}, /* 2 */ +{"rctlsys_ctl", 6, DEC, NOV, HID, STG, HEX, HID, HID, RCF}, /* 3 */ +}; +#define NRCTLCODE (sizeof (rctltable) / sizeof (struct systable)) + const struct systable sgptable[] = { {"sigpendsys", 2, DEC, NOV, DEC, HEX}, /* err */ {"sigpending", 2, DEC, NOV, HID, HEX}, /* 1 */ @@ -946,6 +954,10 @@ const struct sysalias sysalias[] = { { "tnmlp", SYS_labelsys }, { "getlabel", SYS_labelsys }, { "fgetlabel", SYS_labelsys }, + { "getrctl", SYS_rctlsys }, + { "setrctl", SYS_rctlsys }, + { "rctlsys_lst", SYS_rctlsys }, + { "rctlsys_ctl", SYS_rctlsys }, { NULL, 0 } /* end-of-list */ }; @@ -1083,6 +1095,10 @@ subsys(int syscall, int subcode) if ((unsigned)subcode < NLABELCODE) stp = &labeltable[subcode]; break; + case SYS_rctlsys: /* rctl family */ + if ((unsigned)subcode < NRCTLCODE) + stp = &rctltable[subcode]; + break; } } @@ -1233,6 +1249,7 @@ getsubcode(private_t *pri) case SYS_ucredsys: /* ucredsys */ case SYS_zone: /* zone */ case SYS_labelsys: /* labelsys */ + case SYS_rctlsys: /* rctlsys */ subcode = arg0; break; case SYS_fcntl: /* fcntl() */ @@ -1293,7 +1310,8 @@ maxsyscalls() + NUCREDSYSCODE - 1 + NPORTCODE - 1 + NZONECODE - 1 - + NLABELCODE - 1); + + NLABELCODE - 1 + + NRCTLCODE - 1); } /* @@ -1365,6 +1383,8 @@ nsubcodes(int syscall) return (NZONECODE); case SYS_labelsys: return (NLABELCODE); + case SYS_rctlsys: + return (NRCTLCODE); default: return (1); } diff --git a/usr/src/uts/common/os/rctl.c b/usr/src/uts/common/os/rctl.c index d4f7316bb4..dd6230ad7b 100644 --- a/usr/src/uts/common/os/rctl.c +++ b/usr/src/uts/common/os/rctl.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -2152,8 +2151,13 @@ static int rctl_global_action(rctl_t *r, rctl_set_t *rset, struct proc *p, rctl_val_t *v) { rctl_dict_entry_t *rde = r->rc_dict_entry; - const char *pr, *en; + const char *pr, *en, *idstr; id_t id; + enum { + SUFFIX_NONE, /* id consumed directly */ + SUFFIX_NUMERIC, /* id consumed in suffix */ + SUFFIX_STRING /* idstr consumed in suffix */ + } suffix = SUFFIX_NONE; int ret = 0; v->rcv_firing_time = gethrtime(); @@ -2177,30 +2181,56 @@ rctl_global_action(rctl_t *r, rctl_set_t *rset, struct proc *p, rctl_val_t *v) case RCENTITY_PROCESS: en = "process"; id = p->p_pid; + suffix = SUFFIX_NONE; break; case RCENTITY_TASK: en = "task"; id = p->p_task->tk_tkid; + suffix = SUFFIX_NUMERIC; break; case RCENTITY_PROJECT: en = "project"; id = p->p_task->tk_proj->kpj_id; + suffix = SUFFIX_NUMERIC; break; case RCENTITY_ZONE: en = "zone"; - id = p->p_zone->zone_id; + idstr = p->p_zone->zone_name; + suffix = SUFFIX_STRING; break; default: - en = "unknown entity associated with pid"; + en = "unknown entity associated with process"; id = p->p_pid; + suffix = SUFFIX_NONE; break; } if (rde->rcd_flagaction & RCTL_GLOBAL_SYSLOG) { - (void) strlog(0, 0, 0, - rde->rcd_strlog_flags | log_global.lz_active, - "%s rctl %s (value %llu) exceeded by %s %d", pr, - rde->rcd_name, v->rcv_value, en, id); + switch (suffix) { + default: + case SUFFIX_NONE: + (void) strlog(0, 0, 0, + rde->rcd_strlog_flags | log_global.lz_active, + "%s rctl %s (value %llu) exceeded by %s %d.", + pr, rde->rcd_name, v->rcv_value, en, id); + break; + case SUFFIX_NUMERIC: + (void) strlog(0, 0, 0, + rde->rcd_strlog_flags | log_global.lz_active, + "%s rctl %s (value %llu) exceeded by process %d" + " in %s %d.", + pr, rde->rcd_name, v->rcv_value, p->p_pid, + en, id); + break; + case SUFFIX_STRING: + (void) strlog(0, 0, 0, + rde->rcd_strlog_flags | log_global.lz_active, + "%s rctl %s (value %llu) exceeded by process %d" + " in %s %s.", + pr, rde->rcd_name, v->rcv_value, p->p_pid, + en, idstr); + break; + } } if (rde->rcd_flagaction & RCTL_GLOBAL_DENY_ALWAYS) |
