17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
519f92332Sml93401 * Common Development and Distribution License (the "License").
619f92332Sml93401 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate
22*23a1cceaSRoger A. Faulkner /*
23*23a1cceaSRoger A. Faulkner * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24*23a1cceaSRoger A. Faulkner */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <sys/rctl_impl.h>
277c478bd9Sstevel@tonic-gate #include <sys/types.h>
287c478bd9Sstevel@tonic-gate #include <sys/stat.h>
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate #include <errno.h>
317c478bd9Sstevel@tonic-gate #include <libintl.h>
327c478bd9Sstevel@tonic-gate #include <locale.h>
337c478bd9Sstevel@tonic-gate #include <rctl.h>
347c478bd9Sstevel@tonic-gate #include <stdio.h>
357c478bd9Sstevel@tonic-gate #include <stdlib.h>
367c478bd9Sstevel@tonic-gate #include <string.h>
377c478bd9Sstevel@tonic-gate #include <syslog.h>
387c478bd9Sstevel@tonic-gate #include <unistd.h>
397c478bd9Sstevel@tonic-gate #include <fcntl.h>
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate #include "utils.h"
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate #define ENABLE 1
447c478bd9Sstevel@tonic-gate #define DISABLE 0
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate #define CONFIGPATH "/etc/rctladm.conf"
477c478bd9Sstevel@tonic-gate #define CONFIGOWNER 0 /* uid 0 (root) */
487c478bd9Sstevel@tonic-gate #define CONFIGGROUP 1 /* gid 1 (other) */
497c478bd9Sstevel@tonic-gate #define CONFIGPERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /* 0644 */
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate /*
527c478bd9Sstevel@tonic-gate * Macros to produce a quoted string containing the value of a
537c478bd9Sstevel@tonic-gate * preprocessor macro. For example, if SIZE is defined to be 256,
547c478bd9Sstevel@tonic-gate * VAL2STR(SIZE) is "256". This is used to construct format
557c478bd9Sstevel@tonic-gate * strings for scanf-family functions below.
567c478bd9Sstevel@tonic-gate */
577c478bd9Sstevel@tonic-gate #define QUOTE(x) #x
587c478bd9Sstevel@tonic-gate #define VAL2STR(x) QUOTE(x)
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate static const char USAGE[] =
617c478bd9Sstevel@tonic-gate "Usage:\trctladm -l\n"
627c478bd9Sstevel@tonic-gate "\trctladm -u\n"
637c478bd9Sstevel@tonic-gate "\trctladm -e actions -d actions rctl_name\n";
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate static const char OPTS[] = "d:e:lu";
667c478bd9Sstevel@tonic-gate static int dflg, eflg, lflg, uflg;
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate static uint_t op_failures;
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate static void rctladm_enable(const char *, char *);
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate #define BUFSIZE 256
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate static void
usage()757c478bd9Sstevel@tonic-gate usage()
767c478bd9Sstevel@tonic-gate {
777c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(USAGE));
787c478bd9Sstevel@tonic-gate exit(E_USAGE);
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate #define LOG_HIGHEST LOG_DEBUG
827c478bd9Sstevel@tonic-gate static const char *syslog_priorities[] = {
837c478bd9Sstevel@tonic-gate "emerg", /* LOG_EMERG */
847c478bd9Sstevel@tonic-gate "alert", /* LOG_ALERT */
857c478bd9Sstevel@tonic-gate "crit", /* LOG_CRIT */
867c478bd9Sstevel@tonic-gate "err", /* LOG_ERR */
877c478bd9Sstevel@tonic-gate "warning", /* LOG_WARNING */
887c478bd9Sstevel@tonic-gate "notice", /* LOG_NOTICE */
897c478bd9Sstevel@tonic-gate "info", /* LOG_INFO */
907c478bd9Sstevel@tonic-gate "debug" /* LOG_DEBUG */
917c478bd9Sstevel@tonic-gate };
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate static int
rctladm_syslog_prio(const char * priority)947c478bd9Sstevel@tonic-gate rctladm_syslog_prio(const char *priority)
957c478bd9Sstevel@tonic-gate {
967c478bd9Sstevel@tonic-gate uint_t i;
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate for (i = 0; i < LOG_HIGHEST + 1; i++) {
997c478bd9Sstevel@tonic-gate if ((strcasecmp(priority, syslog_priorities[i]) == 0))
1007c478bd9Sstevel@tonic-gate return (i);
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate die(gettext("unknown syslog priority \"%s\"\n"), priority);
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate /*NOTREACHED*/
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1097c478bd9Sstevel@tonic-gate static int
rctl_save_walk_cb(const char * rctl_name,void * file)1107c478bd9Sstevel@tonic-gate rctl_save_walk_cb(const char *rctl_name, void *file)
1117c478bd9Sstevel@tonic-gate {
1127c478bd9Sstevel@tonic-gate FILE *fp = file;
1137c478bd9Sstevel@tonic-gate rctlblk_t *gblk;
1147c478bd9Sstevel@tonic-gate uint_t action;
1157c478bd9Sstevel@tonic-gate rctl_opaque_t *gopq;
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate if ((gblk = malloc(rctlblk_size())) == NULL)
1187c478bd9Sstevel@tonic-gate die(gettext("unable to allocate control block"));
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate if (rctlctl(rctl_name, gblk, RCTLCTL_GET) == -1) {
1227c478bd9Sstevel@tonic-gate warn(gettext("unable to obtain control block contents for %s"),
1237c478bd9Sstevel@tonic-gate rctl_name);
1247c478bd9Sstevel@tonic-gate } else {
1257c478bd9Sstevel@tonic-gate action = rctlblk_get_global_action(gblk);
1267c478bd9Sstevel@tonic-gate gopq = (rctl_opaque_t *)gblk;
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s=", rctl_name);
1297c478bd9Sstevel@tonic-gate if (action & RCTL_GLOBAL_SYSLOG)
1307c478bd9Sstevel@tonic-gate (void) fprintf(fp, "syslog=%s\n",
1317c478bd9Sstevel@tonic-gate syslog_priorities[gopq->rcq_global_syslog_level]);
1327c478bd9Sstevel@tonic-gate else
1337c478bd9Sstevel@tonic-gate (void) fprintf(fp, "none\n");
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate free(gblk);
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate return (0);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate static void
rctladm_save_config()1427c478bd9Sstevel@tonic-gate rctladm_save_config()
1437c478bd9Sstevel@tonic-gate {
1447c478bd9Sstevel@tonic-gate int fd;
1457c478bd9Sstevel@tonic-gate FILE *fp;
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate /*
1487c478bd9Sstevel@tonic-gate * Non-root users shouldn't update the configuration file.
1497c478bd9Sstevel@tonic-gate */
1507c478bd9Sstevel@tonic-gate if (geteuid() != 0)
1517c478bd9Sstevel@tonic-gate return;
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate if ((fd = open(CONFIGPATH, O_WRONLY|O_CREAT|O_TRUNC, CONFIGPERM)) == -1)
1547c478bd9Sstevel@tonic-gate die(gettext("failed to open %s"), CONFIGPATH);
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate if ((fp = fdopen(fd, "w")) == NULL)
1577c478bd9Sstevel@tonic-gate die(gettext("failed to open stream for %s"), CONFIGPATH);
1587c478bd9Sstevel@tonic-gate
1597c478bd9Sstevel@tonic-gate (void) fputs(
1607c478bd9Sstevel@tonic-gate "#\n"
1617c478bd9Sstevel@tonic-gate "# rctladm.conf\n"
1627c478bd9Sstevel@tonic-gate "#\n"
1637c478bd9Sstevel@tonic-gate "# Parameters for resource controls configuration.\n"
1647c478bd9Sstevel@tonic-gate "# Do NOT edit this file by hand -- use rctladm(1m) instead.\n"
1657c478bd9Sstevel@tonic-gate "#\n",
1667c478bd9Sstevel@tonic-gate fp);
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate (void) rctl_walk(rctl_save_walk_cb, fp);
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate (void) fflush(fp);
1717c478bd9Sstevel@tonic-gate (void) fsync(fd);
1727c478bd9Sstevel@tonic-gate (void) fchmod(fd, CONFIGPERM);
1737c478bd9Sstevel@tonic-gate (void) fchown(fd, CONFIGOWNER, CONFIGGROUP);
1747c478bd9Sstevel@tonic-gate (void) fclose(fp);
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate static void
rctladm_setup_action(char * name,char * action,int line)1787c478bd9Sstevel@tonic-gate rctladm_setup_action(char *name, char *action, int line)
1797c478bd9Sstevel@tonic-gate {
1807c478bd9Sstevel@tonic-gate if (action[0] == '\0') {
1817c478bd9Sstevel@tonic-gate warn(gettext("\"%s\", line %d, syntax error\n"), CONFIGPATH,
1827c478bd9Sstevel@tonic-gate line);
1837c478bd9Sstevel@tonic-gate return;
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate rctladm_enable(name, action);
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate static void
rctladm_read_config()1897c478bd9Sstevel@tonic-gate rctladm_read_config()
1907c478bd9Sstevel@tonic-gate {
1917c478bd9Sstevel@tonic-gate int fd;
1927c478bd9Sstevel@tonic-gate FILE *fp;
1937c478bd9Sstevel@tonic-gate char buf[BUFSIZE];
1947c478bd9Sstevel@tonic-gate char name[BUFSIZE+1], actions[BUFSIZE+1];
1957c478bd9Sstevel@tonic-gate char *action;
1967c478bd9Sstevel@tonic-gate int line, len, n;
1977c478bd9Sstevel@tonic-gate rctl_opaque_t *gblk;
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate /*
2007c478bd9Sstevel@tonic-gate * Non-root users shouldn't do this.
2017c478bd9Sstevel@tonic-gate */
2027c478bd9Sstevel@tonic-gate if (geteuid() != 0)
2037c478bd9Sstevel@tonic-gate die(gettext("you must be root to use this option\n"));
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate if ((fd = open(CONFIGPATH, O_RDONLY, CONFIGPERM)) == -1)
2067c478bd9Sstevel@tonic-gate die(gettext("failed to open %s"), CONFIGPATH);
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate if ((fp = fdopen(fd, "r")) == NULL)
2097c478bd9Sstevel@tonic-gate die(gettext("failed to open stream for %s"), CONFIGPATH);
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate if ((gblk = malloc(rctlblk_size())) == NULL)
2127c478bd9Sstevel@tonic-gate die(gettext("unable to allocate control block"));
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate for (line = 1; fgets(buf, BUFSIZE, fp) != NULL; line++) {
2157c478bd9Sstevel@tonic-gate /*
2167c478bd9Sstevel@tonic-gate * Skip comment lines and empty lines.
2177c478bd9Sstevel@tonic-gate */
2187c478bd9Sstevel@tonic-gate if (buf[0] == '#' || buf[0] == '\n')
2197c478bd9Sstevel@tonic-gate continue;
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate /*
2227c478bd9Sstevel@tonic-gate * Look for "rctl_name=action;action;...;action, with
2237c478bd9Sstevel@tonic-gate * optional whitespace on either side, terminated by a newline,
2247c478bd9Sstevel@tonic-gate * and consuming the whole line.
2257c478bd9Sstevel@tonic-gate */
2267c478bd9Sstevel@tonic-gate n = sscanf(buf,
2277c478bd9Sstevel@tonic-gate " %" VAL2STR(BUFSIZE) "[^=]=%" VAL2STR(BUFSIZE) "s \n%n",
2287c478bd9Sstevel@tonic-gate name, actions, &len);
2297c478bd9Sstevel@tonic-gate if (n >= 1 && name[0] != '\0' &&
2307c478bd9Sstevel@tonic-gate (n == 1 || len == strlen(buf))) {
2317c478bd9Sstevel@tonic-gate if (n == 1) {
2327c478bd9Sstevel@tonic-gate warn(gettext("\"%s\", line %d, syntax error\n"),
2337c478bd9Sstevel@tonic-gate CONFIGPATH, line);
2347c478bd9Sstevel@tonic-gate continue;
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate if (rctlctl(name, (rctlblk_t *)gblk,
2377c478bd9Sstevel@tonic-gate RCTLCTL_GET) == -1) {
2387c478bd9Sstevel@tonic-gate warn(gettext("\"%s\", line %d, unknown resource"
2397c478bd9Sstevel@tonic-gate " control: %s\n"), CONFIGPATH, line, name);
2407c478bd9Sstevel@tonic-gate continue;
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate if (actions[0] == ';') {
2437c478bd9Sstevel@tonic-gate warn(gettext("\"%s\", line %d, syntax error\n"),
2447c478bd9Sstevel@tonic-gate CONFIGPATH, line);
2457c478bd9Sstevel@tonic-gate continue;
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate action = strtok(actions, ";");
2487c478bd9Sstevel@tonic-gate rctladm_setup_action(name, action, line);
2497c478bd9Sstevel@tonic-gate while (action = strtok(NULL, ";"))
2507c478bd9Sstevel@tonic-gate rctladm_setup_action(name, action, line);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate }
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate if (line == 1)
2557c478bd9Sstevel@tonic-gate die(gettext("failed to read rctl configuration from \"%s\""),
2567c478bd9Sstevel@tonic-gate CONFIGPATH);
2577c478bd9Sstevel@tonic-gate free(gblk);
2587c478bd9Sstevel@tonic-gate (void) fclose(fp);
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate static void
rctladm_modify_action(const char * rctl_name,uint_t enable,uint_t action,int log_level)2627c478bd9Sstevel@tonic-gate rctladm_modify_action(const char *rctl_name, uint_t enable, uint_t action,
2637c478bd9Sstevel@tonic-gate int log_level)
2647c478bd9Sstevel@tonic-gate {
2657c478bd9Sstevel@tonic-gate rctl_opaque_t *gblk;
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate if ((gblk = malloc(rctlblk_size())) == NULL)
2687c478bd9Sstevel@tonic-gate die(gettext("unable to allocate control block"));
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate if (rctlctl(rctl_name, (rctlblk_t *)gblk, RCTLCTL_GET) == -1)
2717c478bd9Sstevel@tonic-gate die(gettext("unable to obtain resource control block"));
2727c478bd9Sstevel@tonic-gate
27372a7a5edSjj204856 if ((gblk->rcq_global_flagaction & RCTL_GLOBAL_SYSLOG_NEVER) &&
27472a7a5edSjj204856 (action == RCTL_GLOBAL_SYSLOG)) {
27519f92332Sml93401 warn(gettext("\"syslog\" action not valid for %s\n"),
27619f92332Sml93401 rctl_name);
27719f92332Sml93401 op_failures++;
27819f92332Sml93401 free(gblk);
27919f92332Sml93401 return;
28019f92332Sml93401 }
28119f92332Sml93401
2827c478bd9Sstevel@tonic-gate if (enable) {
2837c478bd9Sstevel@tonic-gate gblk->rcq_global_flagaction |= (action &
2847c478bd9Sstevel@tonic-gate ~RCTL_GLOBAL_ACTION_MASK);
2857c478bd9Sstevel@tonic-gate gblk->rcq_global_syslog_level = log_level;
2867c478bd9Sstevel@tonic-gate } else {
2877c478bd9Sstevel@tonic-gate gblk->rcq_global_flagaction &= ~(action &
2887c478bd9Sstevel@tonic-gate ~RCTL_GLOBAL_ACTION_MASK);
2897c478bd9Sstevel@tonic-gate gblk->rcq_global_syslog_level = LOG_NOTICE;
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate if (rctlctl(rctl_name, (rctlblk_t *)gblk, RCTLCTL_SET) == -1) {
2937c478bd9Sstevel@tonic-gate warn(gettext("unable to update control block contents"));
2947c478bd9Sstevel@tonic-gate op_failures++;
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate free(gblk);
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate
3007c478bd9Sstevel@tonic-gate static int
rctladm_get_log_level(char * action)3017c478bd9Sstevel@tonic-gate rctladm_get_log_level(char *action)
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate char *log_lvl_str;
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate /*
3067c478bd9Sstevel@tonic-gate * Our syslog priority defaults to LOG_NOTICE.
3077c478bd9Sstevel@tonic-gate */
3087c478bd9Sstevel@tonic-gate if (strcmp("syslog", action) == 0)
3097c478bd9Sstevel@tonic-gate return (LOG_NOTICE);
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate if (strncmp("syslog=", action, strlen("syslog=")) != 0)
3127c478bd9Sstevel@tonic-gate die(gettext("unknown action \"%s\"\n"), action);
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate log_lvl_str = action + strlen("syslog=");
3157c478bd9Sstevel@tonic-gate
3167c478bd9Sstevel@tonic-gate return (rctladm_syslog_prio(log_lvl_str));
3177c478bd9Sstevel@tonic-gate }
3187c478bd9Sstevel@tonic-gate
3197c478bd9Sstevel@tonic-gate
3207c478bd9Sstevel@tonic-gate static void
rctladm_enable(const char * rctl_name,char * action)3217c478bd9Sstevel@tonic-gate rctladm_enable(const char *rctl_name, char *action)
3227c478bd9Sstevel@tonic-gate {
3237c478bd9Sstevel@tonic-gate /*
3247c478bd9Sstevel@tonic-gate * Two valid values: "none" and "syslog[=level]".
3257c478bd9Sstevel@tonic-gate */
3267c478bd9Sstevel@tonic-gate if (strcmp("none", action) == 0) {
3277c478bd9Sstevel@tonic-gate rctladm_modify_action(rctl_name, DISABLE,
3287c478bd9Sstevel@tonic-gate ~RCTL_GLOBAL_ACTION_MASK, 0);
3297c478bd9Sstevel@tonic-gate return;
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate rctladm_modify_action(rctl_name, ENABLE, RCTL_GLOBAL_SYSLOG,
3337c478bd9Sstevel@tonic-gate rctladm_get_log_level(action));
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate
3367c478bd9Sstevel@tonic-gate static void
rctladm_disable(const char * rctl_name,char * action)3377c478bd9Sstevel@tonic-gate rctladm_disable(const char *rctl_name, char *action)
3387c478bd9Sstevel@tonic-gate {
3397c478bd9Sstevel@tonic-gate /*
3407c478bd9Sstevel@tonic-gate * Two valid values: "all" and "syslog".
3417c478bd9Sstevel@tonic-gate */
3427c478bd9Sstevel@tonic-gate if (strcmp("all", action) == 0) {
3437c478bd9Sstevel@tonic-gate rctladm_modify_action(rctl_name, DISABLE,
3447c478bd9Sstevel@tonic-gate ~RCTL_GLOBAL_ACTION_MASK, 0);
3457c478bd9Sstevel@tonic-gate return;
3467c478bd9Sstevel@tonic-gate } else if (strcmp("syslog", action) == 0) {
3477c478bd9Sstevel@tonic-gate rctladm_modify_action(rctl_name, DISABLE, RCTL_GLOBAL_SYSLOG,
3487c478bd9Sstevel@tonic-gate 0);
3497c478bd9Sstevel@tonic-gate return;
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate die(gettext("unknown action \"%s\"\n"), action);
3537c478bd9Sstevel@tonic-gate }
3547c478bd9Sstevel@tonic-gate
3557c478bd9Sstevel@tonic-gate static void
rctlblk_display(FILE * f,rctlblk_t * gblk)3567c478bd9Sstevel@tonic-gate rctlblk_display(FILE *f, rctlblk_t *gblk)
3577c478bd9Sstevel@tonic-gate {
3587c478bd9Sstevel@tonic-gate uint_t action = rctlblk_get_global_action(gblk);
3597c478bd9Sstevel@tonic-gate uint_t flags = rctlblk_get_global_flags(gblk);
3607c478bd9Sstevel@tonic-gate rctl_opaque_t *gopq = (rctl_opaque_t *)gblk;
3617c478bd9Sstevel@tonic-gate
36219f92332Sml93401 if (flags & RCTL_GLOBAL_SYSLOG_NEVER)
36319f92332Sml93401 (void) fprintf(f, "syslog=n/a ");
36419f92332Sml93401 else if (action & RCTL_GLOBAL_SYSLOG)
3657c478bd9Sstevel@tonic-gate (void) fprintf(f, "syslog=%-7s",
3667c478bd9Sstevel@tonic-gate syslog_priorities[gopq->rcq_global_syslog_level]);
3677c478bd9Sstevel@tonic-gate else
3687c478bd9Sstevel@tonic-gate (void) fprintf(f, "syslog=off ");
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_ACTION_MASK)
3717c478bd9Sstevel@tonic-gate (void) fprintf(f, " [");
3727c478bd9Sstevel@tonic-gate
3737c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_NOBASIC)
3747c478bd9Sstevel@tonic-gate (void) fprintf(f, " no-basic");
3757c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_LOWERABLE)
3767c478bd9Sstevel@tonic-gate (void) fprintf(f, " lowerable");
3777c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_DENY_ALWAYS)
3787c478bd9Sstevel@tonic-gate (void) fprintf(f, " deny");
3797c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_DENY_NEVER)
3807c478bd9Sstevel@tonic-gate (void) fprintf(f, " no-deny");
3817c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_CPU_TIME)
3827c478bd9Sstevel@tonic-gate (void) fprintf(f, " cpu-time");
3837c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_FILE_SIZE)
3847c478bd9Sstevel@tonic-gate (void) fprintf(f, " file-size");
3857c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_SIGNAL_NEVER)
3867c478bd9Sstevel@tonic-gate (void) fprintf(f, " no-signal");
3877c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_UNOBSERVABLE)
3887c478bd9Sstevel@tonic-gate (void) fprintf(f, " no-obs");
3897c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_INFINITE)
3907c478bd9Sstevel@tonic-gate (void) fprintf(f, " inf");
39119f92332Sml93401 if (flags & RCTL_GLOBAL_SYSLOG_NEVER)
39219f92332Sml93401 (void) fprintf(f, " no-syslog");
3937c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_SECONDS)
3947c478bd9Sstevel@tonic-gate (void) fprintf(f, " seconds");
3957c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_BYTES)
3967c478bd9Sstevel@tonic-gate (void) fprintf(f, " bytes");
3977c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_COUNT)
3987c478bd9Sstevel@tonic-gate (void) fprintf(f, " count");
3997c478bd9Sstevel@tonic-gate if (flags & RCTL_GLOBAL_ACTION_MASK)
4007c478bd9Sstevel@tonic-gate (void) fprintf(f, " ]");
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate (void) fprintf(f, "\n");
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate
4057c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4067c478bd9Sstevel@tonic-gate static int
rctl_walk_cb(const char * rctl_name,void * pvt)4077c478bd9Sstevel@tonic-gate rctl_walk_cb(const char *rctl_name, void *pvt)
4087c478bd9Sstevel@tonic-gate {
4097c478bd9Sstevel@tonic-gate rctlblk_t *gblk;
4107c478bd9Sstevel@tonic-gate
4117c478bd9Sstevel@tonic-gate if ((gblk = malloc(rctlblk_size())) == NULL)
4127c478bd9Sstevel@tonic-gate die(gettext("unable to allocate control block"));
4137c478bd9Sstevel@tonic-gate
4147c478bd9Sstevel@tonic-gate if (rctlctl(rctl_name, gblk, RCTLCTL_GET) == -1) {
4157c478bd9Sstevel@tonic-gate if (errno == ESRCH)
4167c478bd9Sstevel@tonic-gate warn(gettext("unknown resource control: %s\n"),
4177c478bd9Sstevel@tonic-gate rctl_name);
4187c478bd9Sstevel@tonic-gate else
4197c478bd9Sstevel@tonic-gate warn(gettext("unable to obtain %s properties"),
4207c478bd9Sstevel@tonic-gate rctl_name);
4217c478bd9Sstevel@tonic-gate op_failures++;
4227c478bd9Sstevel@tonic-gate } else {
4237c478bd9Sstevel@tonic-gate (void) printf("%-27s ", rctl_name);
4247c478bd9Sstevel@tonic-gate rctlblk_display(stdout, gblk);
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate free(gblk);
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate return (0);
4307c478bd9Sstevel@tonic-gate }
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate static void
rctladm_list_rctls(int optind,int argc,char * argv[])4337c478bd9Sstevel@tonic-gate rctladm_list_rctls(int optind, int argc, char *argv[])
4347c478bd9Sstevel@tonic-gate {
4357c478bd9Sstevel@tonic-gate if (optind >= argc) {
4367c478bd9Sstevel@tonic-gate (void) rctl_walk(rctl_walk_cb, NULL);
4377c478bd9Sstevel@tonic-gate return;
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate for (; optind < argc; optind++)
4417c478bd9Sstevel@tonic-gate (void) rctl_walk_cb(argv[optind], NULL);
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate
4447c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])4457c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
4467c478bd9Sstevel@tonic-gate {
4477c478bd9Sstevel@tonic-gate int c; /* options character */
4487c478bd9Sstevel@tonic-gate char *action;
4497c478bd9Sstevel@tonic-gate char *rctl;
4507c478bd9Sstevel@tonic-gate
4517c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
4527c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
453*23a1cceaSRoger A. Faulkner (void) setpname(argv[0]);
4547c478bd9Sstevel@tonic-gate
4557c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, OPTS)) != EOF) {
4567c478bd9Sstevel@tonic-gate switch (c) {
4577c478bd9Sstevel@tonic-gate case 'd':
4587c478bd9Sstevel@tonic-gate dflg++;
4597c478bd9Sstevel@tonic-gate action = optarg;
4607c478bd9Sstevel@tonic-gate break;
4617c478bd9Sstevel@tonic-gate case 'e':
4627c478bd9Sstevel@tonic-gate eflg++;
4637c478bd9Sstevel@tonic-gate action = optarg;
4647c478bd9Sstevel@tonic-gate break;
4657c478bd9Sstevel@tonic-gate case 'l':
4667c478bd9Sstevel@tonic-gate lflg = 1;
4677c478bd9Sstevel@tonic-gate break;
4687c478bd9Sstevel@tonic-gate case 'u':
4697c478bd9Sstevel@tonic-gate uflg = 1;
4707c478bd9Sstevel@tonic-gate break;
4717c478bd9Sstevel@tonic-gate case '?':
4727c478bd9Sstevel@tonic-gate default:
4737c478bd9Sstevel@tonic-gate usage();
4747c478bd9Sstevel@tonic-gate }
4757c478bd9Sstevel@tonic-gate }
4767c478bd9Sstevel@tonic-gate
4777c478bd9Sstevel@tonic-gate if (uflg) {
4787c478bd9Sstevel@tonic-gate rctladm_read_config();
4797c478bd9Sstevel@tonic-gate return (E_SUCCESS);
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate if (lflg && (dflg || eflg)) {
4837c478bd9Sstevel@tonic-gate warn(gettext("-l, -d, and -e flags are exclusive\n"));
4847c478bd9Sstevel@tonic-gate usage();
4857c478bd9Sstevel@tonic-gate }
4867c478bd9Sstevel@tonic-gate
4877c478bd9Sstevel@tonic-gate if (dflg && eflg) {
4887c478bd9Sstevel@tonic-gate warn(gettext("-d and -e flags are exclusive\n"));
4897c478bd9Sstevel@tonic-gate usage();
4907c478bd9Sstevel@tonic-gate }
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate if (dflg > 1 || eflg > 1) {
4937c478bd9Sstevel@tonic-gate warn(gettext("only one -d or -e flag per line\n"));
4947c478bd9Sstevel@tonic-gate usage();
4957c478bd9Sstevel@tonic-gate }
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate if (lflg || !(dflg || eflg)) {
4987c478bd9Sstevel@tonic-gate rctladm_list_rctls(optind, argc, argv);
4997c478bd9Sstevel@tonic-gate rctladm_save_config();
5007c478bd9Sstevel@tonic-gate
5017c478bd9Sstevel@tonic-gate return (op_failures ? E_ERROR : E_SUCCESS);
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate if (optind >= argc) {
5057c478bd9Sstevel@tonic-gate warn(gettext("must specify one or more "
5067c478bd9Sstevel@tonic-gate "resource control names\n"));
5077c478bd9Sstevel@tonic-gate usage();
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate for (; optind < argc; optind++) {
5117c478bd9Sstevel@tonic-gate rctl = argv[optind];
5127c478bd9Sstevel@tonic-gate
5137c478bd9Sstevel@tonic-gate if (eflg) {
5147c478bd9Sstevel@tonic-gate rctladm_enable(rctl, action);
5157c478bd9Sstevel@tonic-gate rctladm_save_config();
5167c478bd9Sstevel@tonic-gate } else if (dflg) {
5177c478bd9Sstevel@tonic-gate rctladm_disable(rctl, action);
5187c478bd9Sstevel@tonic-gate rctladm_save_config();
5197c478bd9Sstevel@tonic-gate } else {
5207c478bd9Sstevel@tonic-gate usage();
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate }
5237c478bd9Sstevel@tonic-gate
5247c478bd9Sstevel@tonic-gate return (op_failures ? E_ERROR : E_SUCCESS);
5257c478bd9Sstevel@tonic-gate }
526