diff options
Diffstat (limited to 'usr/src/cmd/rcap')
| -rw-r--r-- | usr/src/cmd/rcap/Makefile.com | 27 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/common/rcapd.h | 10 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/common/rcapd_conf.c | 244 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/common/rcapd_conf.h | 6 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/common/rcapd_conf.l | 347 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/rcapadm/Makefile | 4 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/rcapadm/rcapadm.c | 87 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/rcapd/Makefile.rcapd | 4 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/rcapd/rcap.xml | 24 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/rcapd/rcapd_main.c | 78 | ||||
| -rw-r--r-- | usr/src/cmd/rcap/rcapstat/Makefile | 4 |
11 files changed, 363 insertions, 472 deletions
diff --git a/usr/src/cmd/rcap/Makefile.com b/usr/src/cmd/rcap/Makefile.com index deb938a28e..c39ee2a6fd 100644 --- a/usr/src/cmd/rcap/Makefile.com +++ b/usr/src/cmd/rcap/Makefile.com @@ -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 2003 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -31,26 +30,6 @@ # COMMON_DIR. # -LFLAGS= -t -v -YFLAGS= -d -v - -rcapd_conf.o := CFLAGS += -erroff=E_STATEMENT_NOT_REACHED -rcapd_conf.o := CFLAGS64 += -erroff=E_STATEMENT_NOT_REACHED - -rcapd_conf.c: $(COMMON_DIR)/rcapd_conf.l - $(RM) rcapd_conf.c - $(LEX) $(LFLAGS) $(COMMON_DIR)/rcapd_conf.l > $@ - -rcapd_conf.o: rcapd_conf.c - -# -# Switching the order of these would have the undesired effect of having -# the .c.l rule be used to build $(COMMON_DIR)/rcapd_conf.c from -# $(COMMON_DIR)/rcapd_conf.l, instead of building ./rcapd_conf.c. -# -%.o: %.c - $(COMPILE.c) $< - %.o: $(COMMON_DIR)/%.c $(COMPILE.c) $< %.po: $(COMMON_DIR)/%.c diff --git a/usr/src/cmd/rcap/common/rcapd.h b/usr/src/cmd/rcap/common/rcapd.h index 7a554c213b..4dc6116adc 100644 --- a/usr/src/cmd/rcap/common/rcapd.h +++ b/usr/src/cmd/rcap/common/rcapd.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,7 +37,13 @@ extern "C" { #include "rcapd_conf.h" #define LC_NAME_LEN 32 -#define RCAPD_DEFAULT_CONF_FILE "/etc/rcap.conf" +#define RCAP_FMRI "svc:/system/rcap:default" +#define CONFIG_PG "config" +#define PRESSURE "pressure" +#define RECONFIG_INT "reconfig_interval" +#define REPORT_INT "report_interval" +#define RSS_SAMPLE_INT "rss_sample_interval" +#define WALK_INT "walk_interval" #define RCAPD_IGNORED_SET_FLUSH_IVAL 10 /* number of scans between */ /* flushes of the ignored set */ diff --git a/usr/src/cmd/rcap/common/rcapd_conf.c b/usr/src/cmd/rcap/common/rcapd_conf.c new file mode 100644 index 0000000000..63daa38564 --- /dev/null +++ b/usr/src/cmd/rcap/common/rcapd_conf.c @@ -0,0 +1,244 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * 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. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <strings.h> +#include <fcntl.h> +#include <unistd.h> +#include <libscf.h> +#include <libscf_priv.h> +#include <libuutil.h> +#include "rcapd.h" +#include "rcapd_conf.h" +#include "rcapd_stat.h" +#include "utils.h" + +/* + * Read configuration and set the fields of an rcfg_t correspondingly. + * Verify that the statistics file is writable, with the optional + * verify_stat_file_creation() callback. + */ +int +rcfg_read(rcfg_t *_rcfg, int(*verify_stat_file_creation)(void)) +{ + scf_simple_handle_t *simple_h; + uint64_t count_val; + int ret = E_ERROR; + + rcfg_init(_rcfg); + + if ((simple_h = scf_general_pg_setup(RCAP_FMRI, CONFIG_PG)) + == NULL) { + warn(gettext("SMF initialization problem: %s\n"), + scf_strerror(scf_error())); + goto err; + } + + if (scf_read_count_property(simple_h, PRESSURE, &count_val) + == SCF_FAILED) { + warn(gettext("Configuration property '%s' " + "not found. \n"), PRESSURE); + goto err; + } else { + if (count_val > 100) + _rcfg->rcfg_memory_cap_enforcement_pressure = 100; + else + _rcfg->rcfg_memory_cap_enforcement_pressure + = count_val; + + debug("cap max pressure: %d%%\n", + _rcfg->rcfg_memory_cap_enforcement_pressure); + } + + if (scf_read_count_property(simple_h, RECONFIG_INT, &count_val) + == SCF_FAILED) { + warn(gettext("Configuration property '%s' " + "not found. \n"), RECONFIG_INT); + goto err; + } else { + _rcfg->rcfg_reconfiguration_interval = count_val; + debug("reconfiguration interval: %d seconds\n", + _rcfg->rcfg_reconfiguration_interval); + } + + if (scf_read_count_property(simple_h, REPORT_INT, &count_val) + == SCF_FAILED) { + warn(gettext("Configuration property '%s' " + "not found. \n"), REPORT_INT); + goto err; + } else { + _rcfg->rcfg_report_interval = count_val; + debug("report interval: %d seconds\n", + _rcfg->rcfg_report_interval); + } + + if (scf_read_count_property(simple_h, RSS_SAMPLE_INT, &count_val) + == SCF_FAILED) { + warn(gettext("Configuration property '%s' " + "not found. \n"), RSS_SAMPLE_INT); + goto err; + } else { + _rcfg->rcfg_rss_sample_interval = count_val; + debug("RSS sample interval: %d seconds\n", + _rcfg->rcfg_rss_sample_interval); + } + + if (scf_read_count_property(simple_h, WALK_INT, &count_val) + == SCF_FAILED) { + warn(gettext("Configuration property '%s' " + "not found. \n"), WALK_INT); + goto err; + } else { + _rcfg->rcfg_proc_walk_interval = count_val; + debug("proc_walk interval: %d seconds\n", + _rcfg->rcfg_proc_walk_interval); + } + + if (_rcfg->rcfg_mode_name == NULL) { + /* + * Set project mode, by default. + */ + _rcfg->rcfg_mode = rctype_project; + _rcfg->rcfg_mode_name = "project"; + debug("mode: %s\n", _rcfg->rcfg_mode_name); + } + + if (verify_stat_file_creation != 0 && verify_stat_file_creation() + != 0) { + warn(gettext("cannot create statistics file, " "%s"), + _rcfg->rcfg_stat_file); + goto err; + } + + debug("done parsing\n"); + ret = E_SUCCESS; + goto out; + +err: + if (scf_error() != SCF_ERROR_NONE) { + warn(gettext("Unexpected libscf error: %s. \n"), + scf_strerror(scf_error())); + } + +out: + scf_simple_handle_destroy(simple_h); + return (ret); +} + +void +rcfg_init(rcfg_t *rcfg) +{ + bzero(rcfg, sizeof (*rcfg)); + (void) strcpy(rcfg->rcfg_stat_file, STAT_FILE_DEFAULT); +} + +/* + * Modify configuration in repository given the rcfg_t structure. + */ +int +modify_config(rcfg_t *conf) +{ + scf_simple_handle_t *simple_h; + scf_transaction_t *tx = NULL; + int rval, ret = E_ERROR; + + if ((simple_h = scf_general_pg_setup(RCAP_FMRI, CONFIG_PG)) + == NULL) { + warn(gettext("SMF initialization problem: %s\n"), + scf_strerror(scf_error())); + goto out; + } + + if ((tx = scf_transaction_setup(simple_h)) == NULL) { + warn(gettext("SMF initialization problem: %s\n"), + scf_strerror(scf_error())); + goto out; + } + + do { + if (scf_set_count_property(tx, PRESSURE, + conf->rcfg_memory_cap_enforcement_pressure, 0) + != SCF_SUCCESS) { + warn(gettext("Couldn't set '%s' property. \n"), + PRESSURE); + goto out; + } + + if (scf_set_count_property(tx, RECONFIG_INT, + conf->rcfg_reconfiguration_interval, 0) != SCF_SUCCESS) { + warn(gettext("Couldn't set '%s' property. \n"), + RECONFIG_INT); + goto out; + } + + if (scf_set_count_property(tx, RSS_SAMPLE_INT, + conf->rcfg_rss_sample_interval, 0) != SCF_SUCCESS) { + warn(gettext("Couldn't set '%s' property. \n"), + RSS_SAMPLE_INT); + goto out; + } + + if (scf_set_count_property(tx, REPORT_INT, + conf->rcfg_report_interval, 0) != SCF_SUCCESS) { + warn(gettext("Couldn't set '%s' property. \n"), + REPORT_INT); + goto out; + } + + if (scf_set_count_property(tx, WALK_INT, + conf->rcfg_proc_walk_interval, 0) != SCF_SUCCESS) { + warn(gettext("Couldn't set '%s' property. \n"), + WALK_INT); + goto out; + } + + if ((rval = scf_transaction_commit(tx)) == -1) + goto out; + + if (rval == 0) { + if (scf_transaction_restart(simple_h, tx) + != SCF_SUCCESS) { + warn(gettext("SMF initialization problem: " + "%s\n"), scf_strerror(scf_error())); + goto out; + } + } + } while (rval == 0); + + ret = E_SUCCESS; + +out: + if (tx != NULL) { + scf_transaction_destroy_children(tx); + scf_transaction_destroy(tx); + } + scf_simple_handle_destroy(simple_h); + return (ret); +} diff --git a/usr/src/cmd/rcap/common/rcapd_conf.h b/usr/src/cmd/rcap/common/rcapd_conf.h index 3b12d8cab9..f648a05782 100644 --- a/usr/src/cmd/rcap/common/rcapd_conf.h +++ b/usr/src/cmd/rcap/common/rcapd_conf.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -85,9 +85,9 @@ typedef enum { RCT_INVALID } rctoken_t; -extern int rcfg_read(char *, int, rcfg_t *, int(*)(void)); +extern int rcfg_read(rcfg_t *, int(*)(void)); extern void rcfg_init(rcfg_t *); -extern void create_config_file(rcfg_t *); +extern int modify_config(rcfg_t *); #ifdef __cplusplus } diff --git a/usr/src/cmd/rcap/common/rcapd_conf.l b/usr/src/cmd/rcap/common/rcapd_conf.l deleted file mode 100644 index e990a58e19..0000000000 --- a/usr/src/cmd/rcap/common/rcapd_conf.l +++ /dev/null @@ -1,347 +0,0 @@ -%{ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * 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. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <strings.h> -#include <fcntl.h> -#include <unistd.h> -#include "rcapd.h" -#include "rcapd_conf.h" -#include "rcapd_stat.h" -#include "utils.h" - -#define LINELEN 256 - -/*PRINTFLIKE1*/ -static void -parse_err(char *filename, char *str, ...) -{ - va_list alist; - char buf[LINELEN]; - - (void) snprintf(buf, LINELEN - 1, "%s: line %d: ", filename, yylineno); - va_start(alist, str); - (void) vsnprintf(buf + strlen(buf), LINELEN - 1 - strlen(buf), str, - alist); - va_end(alist); - dprintfe(RCM_ERR, buf); - - exit(E_ERROR); - /*NOTREACHED*/ -} - -#define CFG_EXPECT(ttype, context) { \ - if (yylex() != ttype) { \ - parse_err(name, context); \ - } \ - } - -#define YYSTYPE yystype_t - -typedef union { - int id; -} yystype_t; - -extern yystype_t yylval; -%} - -%x fn - -%% - -<fn>\= { return (RCT_EQUALS); } -<fn>[ \t] { break; } -<fn>[^ \t\n]+ { BEGIN(INITIAL); return (RCT_FILENAME); } - -"RCAPD_MODE" { return (RCT_MODE_VAR); } -"RCAPD_STATE" { return (RCT_STATE); } -"RCAPD_PROC_WALK_INTERVAL" { return (RCT_PROC_WALK_INTERVAL_VAR); } - -"RCAPD_RECONFIGURATION_INTERVAL" { return - (RCT_RECONFIGURATION_INTERVAL_VAR); - } -"RCAPD_REPORT_INTERVAL" \ - { return (RCT_REPORT_INTERVAL_VAR); } -"RCAPD_RSS_SAMPLE_INTERVAL" \ - { return (RCT_RSS_SAMPLE_INTERVAL_VAR); } -"RCAPD_MEMORY_CAP_ENFORCEMENT_PRESSURE" \ - { return (RCT_MEMORY_CAP_ENFORCEMENT_PRESSURE_VAR); } -"RCAPD_STATISTICS_FILE" { BEGIN(fn); return (RCT_STAT_FILE_VAR); } -\= { return (RCT_EQUALS); } -[0-9]+ { return (RCT_NUMBER); } -"project" { return (RCT_PROJECT); } -"lnode" { return (RCT_LNODE); } -"on" { return (RCT_ON); } -"off" { return (RCT_OFF); } - -[ \t] { break; } -\#.* { break; } -\n { break; } -[^ \t\n]* { return (RCT_INVALID); } - -%% - -/* - * Read the supplied configuration file and set the fields of an rcfg_t - * correspondingly. Verify that the statistics file is writable, with the - * optional verify_stat_file_creation() callback. - * - * fd should be the number of a low-numbered (<256) file descriptor on 32-bit - * processes, as stdio requires them to be in that range. The actual - * descriptor will be recorded in rcfg and left open, and may be supplied in - * future calls to rcfg_read(), simplifying descriptor distribution. - */ -int -rcfg_read(char *name, int fd, rcfg_t *_rcfg, - int(*verify_stat_file_creation)(void)) -{ - rctoken_t l; - FILE *f; - struct stat stat; - - if (fd >= 0) - (void) close(fd); - if ((fd = open(name, O_RDONLY)) < 0) - return (-1); - if ((f = fdopen(fd, "r")) == NULL) - return (-1); - if (strlen(name) >= sizeof (_rcfg->rcfg_filename)) { - errno = EINVAL; - return (-1); - } - - rcfg_init(_rcfg); - (void) strcpy(_rcfg->rcfg_filename, name); - _rcfg->rcfg_fd = fd; - if (fstat(fd, &stat) == 0) - _rcfg->rcfg_last_modification = stat.st_mtime; - - yyin = f; - l = 0; - for (; (l = yylex()) != 0; ) { - switch (l) { - case RCT_MODE_VAR: - if (_rcfg->rcfg_mode_name != NULL) - parse_err(name, "RCAPD_MODE already set\n"); - CFG_EXPECT(RCT_EQUALS, "Expecting '='\n"); - l = yylex(); - if (l == RCT_PROJECT) { - _rcfg->rcfg_mode = rctype_project; - _rcfg->rcfg_mode_name = "project"; - } else if (l == RCT_LNODE) { - /* - * Provided for compatibility with old - * configuration files. The consumer is - * expected to warn that the mode setting is - * ineffective when anything other than - * "project" is specified. - */ - _rcfg->rcfg_mode_name = "lnode"; - } else - parse_err(name, "RCAPD_MODE must be " - "\"project\", and is unused.\n"); - debug("%s: mode: %s\n", name, - _rcfg->rcfg_mode_name); - break; - case RCT_STATE: - /* legacy variable is ignored */ - CFG_EXPECT(RCT_EQUALS, "Expecting '='\n"); - l = yylex(); - debug("%s: state ignored\n", name); - break; - case RCT_REPORT_INTERVAL_VAR: - CFG_EXPECT(RCT_EQUALS, "Expecting '='\n"); - CFG_EXPECT(RCT_NUMBER, "Expecting time value " - "(seconds)\n"); - _rcfg->rcfg_report_interval = atoi(yytext); - debug("%s: report interval: %d seconds\n", name, - _rcfg->rcfg_report_interval); - break; - case RCT_RSS_SAMPLE_INTERVAL_VAR: - CFG_EXPECT(RCT_EQUALS, "Expecting '='\n"); - CFG_EXPECT(RCT_NUMBER, "Expecting time value " - "(seconds)\n"); - _rcfg->rcfg_rss_sample_interval = atoi(yytext); - debug("%s: RSS sample interval: %d seconds\n", name, - _rcfg->rcfg_rss_sample_interval); - break; - case RCT_STAT_FILE_VAR: - CFG_EXPECT(RCT_EQUALS, "Expecting '='\n"); - CFG_EXPECT(RCT_FILENAME, "Expecting filename\n"); - if (strlen(yytext) >= sizeof (_rcfg->rcfg_stat_file)) - parse_err(name, "Path too long"); - if (yytext[0] != '/') - parse_err(name, "Path not absolute"); - (void) strcpy(_rcfg->rcfg_stat_file, yytext); - debug("%s: statistics file: %s\n", name, _rcfg->rcfg_stat_file); - break; - case RCT_RECONFIGURATION_INTERVAL_VAR: - CFG_EXPECT(RCT_EQUALS, "Expecting '='\n"); - CFG_EXPECT(RCT_NUMBER, "Expecting time value " - "(seconds)\n"); - _rcfg->rcfg_reconfiguration_interval = atoi(yytext); - debug("%s: reconfiguration interval: %d seconds\n", - name, _rcfg->rcfg_reconfiguration_interval); - break; - case RCT_PROC_WALK_INTERVAL_VAR: - CFG_EXPECT(RCT_EQUALS, "Expecting '='\n"); - CFG_EXPECT(RCT_NUMBER, "Expecting time value " - "(seconds)\n"); - _rcfg->rcfg_proc_walk_interval = atoi(yytext); - debug("%s: proc_walk interval: %d seconds\n", - name, _rcfg->rcfg_proc_walk_interval); - break; - case RCT_MEMORY_CAP_ENFORCEMENT_PRESSURE_VAR: - CFG_EXPECT(RCT_EQUALS, "Expecting '='\n"); - CFG_EXPECT(RCT_NUMBER, "Expecting integer value (%)\n"); - if ((_rcfg->rcfg_memory_cap_enforcement_pressure = - atoi(yytext)) < 0) - _rcfg->rcfg_memory_cap_enforcement_pressure = 0; - debug("%s: cap max pressure: %d%%\n", name, - _rcfg->rcfg_memory_cap_enforcement_pressure); - break; - default: - parse_err(name, "Unexpected input: %s\n", yytext); - } - } - if (_rcfg->rcfg_mode_name == NULL) { - /* - * Set project mode, by default. - */ - _rcfg->rcfg_mode = rctype_project; - _rcfg->rcfg_mode_name = "project"; - debug("%s: mode: %s\n", name, _rcfg->rcfg_mode_name); - } - if (verify_stat_file_creation != 0 && verify_stat_file_creation() != 0) - die(gettext("cannot create statistics file, " "%s"), - _rcfg->rcfg_stat_file); - debug("%s: done parsing\n", name); - - return (0); -} - -void -rcfg_init(rcfg_t *rcfg) -{ - bzero(rcfg, sizeof (*rcfg)); - rcfg->rcfg_proc_walk_interval = 15; - rcfg->rcfg_reconfiguration_interval = 60; - rcfg->rcfg_report_interval = 5; - rcfg->rcfg_rss_sample_interval = 5; - rcfg->rcfg_memory_cap_enforcement_pressure = 0; - (void) strcpy(rcfg->rcfg_stat_file, STAT_FILE_DEFAULT); -} - -/* - * Create the configuration file given the rcfg_t structure. If a rcfg_t - * structure is NULL, create the configuration file with default parameters. - */ -void -create_config_file(rcfg_t *conf) -{ - char *fname = RCAPD_DEFAULT_CONF_FILE; - char *template; - FILE *fp; - mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; - int fd, olderrno, create_default = 0; - - if (conf == NULL) { - create_default = 1; - if ((conf = malloc(sizeof (*conf))) == NULL) - die(gettext("memory allocation failure")); - - /* Initialize config file with default parameters */ - rcfg_init(conf); - conf->rcfg_mode_name = "project"; - } - - if ((template = malloc(strlen(fname) + - strlen(CFG_TEMPLATE_SUFFIX) + 1)) == NULL) - die(gettext("memory allocation failure")); - - (void) strcpy(template, fname); - (void) strcat(template, CFG_TEMPLATE_SUFFIX); - - if ((fd = mkstemp(template)) < 0) - die(gettext("failed to create a temporary file %s"), - template); - - if ((fp = fdopen(fd, "w")) == NULL) { - olderrno = errno; - (void) close(fd); - if (unlink(template) < 0) - warn(gettext("could not unlink temp file %s"), - template); - errno = olderrno; - die(gettext("Failed to open output file %s"), template); - } - - (void) fputs("#\n# rcap.conf\n#\n" - "# Configuration parameters for resource capping daemon.\n" - "# Do NOT edit by hand -- use rcapadm(1m) instead.\n" - "#\n", fp); - (void) fprintf(fp, "RCAPD_MEMORY_CAP_ENFORCEMENT_PRESSURE " - "= %d\n", conf->rcfg_memory_cap_enforcement_pressure); - (void) fprintf(fp, "RCAPD_RECONFIGURATION_INTERVAL " - "= %d\n", conf->rcfg_reconfiguration_interval); - (void) fprintf(fp, "RCAPD_PROC_WALK_INTERVAL " - "= %d\n", conf->rcfg_proc_walk_interval); - (void) fprintf(fp, "RCAPD_REPORT_INTERVAL " - "= %d\n", conf->rcfg_report_interval); - (void) fprintf(fp, "RCAPD_RSS_SAMPLE_INTERVAL " - "= %d\n", conf->rcfg_rss_sample_interval); - - if (fchmod(fd, mode) != 0) { - olderrno = errno; - (void) fclose(fp); - if (unlink(template) < 0) - warn(gettext("could not unlink temp file %s"), - template); - errno = olderrno; - die(gettext("failed to fchmod %s to %o"), template, mode); - } - - if (rename(template, fname) != 0) { - olderrno = errno; - (void) fclose(fp); - if (unlink(template) < 0) - warn(gettext("could not unlink temp file %s"), - template); - errno = olderrno; - die(gettext("could not rename temporary file to %s"), fname); - } - - (void) fclose(fp); - free(template); - - if (create_default == 1) - free(conf); -} diff --git a/usr/src/cmd/rcap/rcapadm/Makefile b/usr/src/cmd/rcap/rcapadm/Makefile index 3b4de32953..e88a65ecdf 100644 --- a/usr/src/cmd/rcap/rcapadm/Makefile +++ b/usr/src/cmd/rcap/rcapadm/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -40,7 +40,7 @@ LINTSRCS = $(COMMON_DIR)/utils.c \ $(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG CPPFLAGS += -I$(COMMON_DIR) -LDLIBS += -lumem -ll -lscf -lzonecfg +LDLIBS += -lumem -lscf -lzonecfg LINTFLAGS += $(LDLIBS) -mnu diff --git a/usr/src/cmd/rcap/rcapadm/rcapadm.c b/usr/src/cmd/rcap/rcapadm/rcapadm.c index 1951682283..f8e6269221 100644 --- a/usr/src/cmd/rcap/rcapadm/rcapadm.c +++ b/usr/src/cmd/rcap/rcapadm/rcapadm.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -47,8 +47,6 @@ #include "rcapd_conf.h" #include "rcapd_stat.h" -#define RCAP_FMRI "system/rcap:default" - static void usage() { @@ -78,7 +76,6 @@ static int scan_interval = -1; static int report_interval = -1; static int config_interval = -1; static int sample_interval = -1; -static char *fname = RCAPD_DEFAULT_CONF_FILE; static char *subopt_v[] = { "scan", @@ -134,6 +131,17 @@ out: "state: %s\n"), *persistent ? gettext("enabled") : gettext("disabled")); + (void) printf(gettext(" memory cap enforcement" + " threshold: %d%%\n"), conf.rcfg_memory_cap_enforcement_pressure); + (void) printf(gettext(" process scan rate" + " (sec): %d\n"), conf.rcfg_proc_walk_interval); + (void) printf(gettext(" reconfiguration rate" + " (sec): %d\n"), conf.rcfg_reconfiguration_interval); + (void) printf(gettext(" report rate" + " (sec): %d\n"), conf.rcfg_report_interval); + (void) printf(gettext(" RSS sampling rate" + " (sec): %d\n"), conf.rcfg_rss_sample_interval); + scf_simple_prop_free(temporary_prop); scf_simple_prop_free(persistent_prop); scf_handle_destroy(h); @@ -201,12 +209,10 @@ main(int argc, char *argv[]) case 'E': enable = 1; disable = 0; - modified++; break; case 'D': disable = 1; enable = 0; - modified++; break; case 'i': subopts = optarg; @@ -263,19 +269,37 @@ main(int argc, char *argv[]) if (refresh && (no_starting_stopping > 0 || modified)) usage(); - if (rcfg_read(fname, -1, &conf, NULL) < 0) { - if (!(errno == ENOENT && modified)) { - die(gettext("resource caps not configured\n")); - return (E_ERROR); - } - rcfg_init(&conf); - conf.rcfg_mode_name = "project"; - } else { + /* + * disable/enable before reading configuration from the repository + * which may fail and prevents the disabling/enabling to complete. + */ + if (disable > 0) { + if (smf_disable_instance(RCAP_FMRI, no_starting_stopping > 0 + ? SMF_AT_NEXT_BOOT : 0) != 0) + die(gettext("cannot disable service: %s\n"), + scf_strerror(scf_error())); + } + + if (enable > 0) { + if (smf_enable_instance(RCAP_FMRI, no_starting_stopping > 0 + ? SMF_AT_NEXT_BOOT : 0) != 0) + die(gettext("cannot enable service: %s\n"), + scf_strerror(scf_error())); + } + + if (rcfg_read(&conf, NULL) != E_SUCCESS) { /* - * The configuration file has been read. Warn that any lnode - * (or non-project) mode specification (by an SRM - * 1.3 configuration file, for example) is ignored. + * If instance is enabled, put it in maintenance since we + * failed to read configuration from the repository or + * create statistics file. */ + if (strcmp(smf_get_state(RCAP_FMRI), + SCF_STATE_STRING_DISABLED) != 0) + (void) smf_maintain_instance(RCAP_FMRI, 0); + + die(gettext("resource caps not configured\n")); + } else { + /* Done reading configuration */ if (strcmp(conf.rcfg_mode_name, "project") != 0) { warn(gettext("%s mode specification ignored -- using" " project mode\n"), conf.rcfg_mode_name); @@ -300,37 +324,20 @@ main(int argc, char *argv[]) conf.rcfg_rss_sample_interval = sample_interval; /* - * Create config file with the new parameter(s). The - * create_config_file will exit if it fails. + * Modify configuration with the new parameter(s). The + * function will exit if it fails. */ - create_config_file(&conf); + if ((modify_config(&conf)) != 0) + die(gettext("Error updating repository \n")); - if (enable > 0 && smf_enable_instance(RCAP_FMRI, - no_starting_stopping > 0 ? SMF_AT_NEXT_BOOT : 0) != 0) - die(gettext("cannot enable service: %s\n"), - scf_strerror(scf_error())); - else if (disable > 0 && smf_disable_instance(RCAP_FMRI, - no_starting_stopping > 0 ? SMF_AT_NEXT_BOOT : 0) != 0) - die(gettext("cannot disable service: %s\n"), + if (smf_refresh_instance(RCAP_FMRI) != 0) + die(gettext("cannot refresh service: %s\n"), scf_strerror(scf_error())); - - return (E_SUCCESS); } /* * Display current configuration */ print_state(); - (void) printf(gettext(" memory cap enforcement" - " threshold: %d%%\n"), conf.rcfg_memory_cap_enforcement_pressure); - (void) printf(gettext(" process scan rate" - " (sec): %d\n"), conf.rcfg_proc_walk_interval); - (void) printf(gettext(" reconfiguration rate" - " (sec): %d\n"), conf.rcfg_reconfiguration_interval); - (void) printf(gettext(" report rate" - " (sec): %d\n"), conf.rcfg_report_interval); - (void) printf(gettext(" RSS sampling rate" - " (sec): %d\n"), conf.rcfg_rss_sample_interval); - return (E_SUCCESS); } diff --git a/usr/src/cmd/rcap/rcapd/Makefile.rcapd b/usr/src/cmd/rcap/rcapd/Makefile.rcapd index 716ea41e38..f0ff0e0669 100644 --- a/usr/src/cmd/rcap/rcapd/Makefile.rcapd +++ b/usr/src/cmd/rcap/rcapd/Makefile.rcapd @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -55,7 +55,7 @@ LINTSRCS = ../rcapd_main.c \ $(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG CPPFLAGS += -DDEBUG_MSG CPPFLAGS += -I$(COMMON_DIR) -LDLIBS += -lkstat -ll -lproc -lproject -lzonecfg -lumem +LDLIBS += -lkstat -lproc -lproject -lzonecfg -lumem -lscf LDLIBS += $(EXTRA_LDLIBS) LINTFLAGS += -u diff --git a/usr/src/cmd/rcap/rcapd/rcap.xml b/usr/src/cmd/rcap/rcapd/rcap.xml index 957643a361..41fae6decf 100644 --- a/usr/src/cmd/rcap/rcapd/rcap.xml +++ b/usr/src/cmd/rcap/rcapd/rcap.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> <!-- - Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Copyright 2007 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. CDDL HEADER START @@ -38,8 +38,6 @@ type='service' version='1'> - <create_default_instance enabled='false' /> - <single_instance /> <dependency @@ -50,6 +48,14 @@ <service_fmri value='svc:/system/filesystem/minimal' /> </dependency> + <dependency + name='manifest' + type='service' + grouping='optional_all' + restart_on='none'> + <service_fmri value='svc:/system/manifest-import' /> + </dependency> + <dependent name='rcap_multi-user' grouping='optional_all' @@ -57,6 +63,8 @@ <service_fmri value='svc:/milestone/multi-user' /> </dependent> + <instance name='default' enabled='false'> + <exec_method type='method' name='start' @@ -79,6 +87,16 @@ exec=':kill' timeout_seconds='60' /> + <property_group name='config' type='application'> + <propval name='pressure' type='count' value='0' /> + <propval name='reconfig_interval' type='count' value='60' /> + <propval name='walk_interval' type='count' value='15' /> + <propval name='report_interval' type='count' value='5' /> + <propval name='rss_sample_interval' type='count' value='5' /> + </property_group> + + </instance> + <stability value='Unstable' /> <template> diff --git a/usr/src/cmd/rcap/rcapd/rcapd_main.c b/usr/src/cmd/rcap/rcapd/rcapd_main.c index 960065826e..bb0a13f129 100644 --- a/usr/src/cmd/rcap/rcapd/rcapd_main.c +++ b/usr/src/cmd/rcap/rcapd/rcapd_main.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -56,6 +56,7 @@ #include <stdio.h> #include <stdio_ext.h> #include <stdlib.h> +#include <libscf.h> #include <strings.h> #include <time.h> #include <unistd.h> @@ -937,24 +938,19 @@ finish_configuration(void) } /* - * Cause the configuration file to be reread and applied. + * Cause the configuration to be reread and applied. */ static void -reread_configuration_file(void) +reread_configuration(void) { rcfg_t rcfg_new; - struct stat st; - if (stat(rcfg.rcfg_filename, &st) == 0 && st.st_mtime == - rcfg.rcfg_last_modification) - return; - - if (rcfg_read(rcfg.rcfg_filename, rcfg.rcfg_fd, &rcfg_new, - update_statistics) != 0) - warn(gettext("can't reread configuration")); - else { + if (rcfg_read(&rcfg_new, update_statistics) != E_SUCCESS) { + warn(gettext("can't reread configuration \n")); + exit(SMF_EXIT_ERR_CONFIG); + } else { /* - * The configuration file has been read. Remove existing + * Done reading configuration. Remove existing * collections in case there is a change in collection type. */ if (rcfg.rcfg_mode != rcfg_new.rcfg_mode) { @@ -972,8 +968,8 @@ reread_configuration_file(void) } /* - * Reread the configuration filex, then examine changes, additions, and - * deletions to cap definitions. + * First, examine changes, additions, and deletions to cap definitions. + * Then, set the next event time. */ static void reconfigure(hrtime_t now, hrtime_t *next_configuration, @@ -982,11 +978,6 @@ reconfigure(hrtime_t now, hrtime_t *next_configuration, debug("reconfigure...\n"); /* - * Reread the configuration data. - */ - reread_configuration_file(); - - /* * Walk the lcollection, marking active collections so inactive ones * can be freed. */ @@ -1021,7 +1012,7 @@ reconfigure(hrtime_t now, hrtime_t *next_configuration, } /* - * Respond to SIGHUP by triggering the rereading the configuration file and cap + * Respond to SIGHUP by triggering the rereading the configuration and cap * definitions. */ /*ARGSUSED*/ @@ -1488,6 +1479,14 @@ main(int argc, char *argv[]) } /* + * Read the configuration. + */ + if (rcfg_read(&rcfg, verify_statistics) != E_SUCCESS) { + warn(gettext("resource caps not configured\n")); + return (SMF_EXIT_ERR_CONFIG); + } + + /* * If not debugging, fork and continue operating, changing the * destination of messages to syslog(). */ @@ -1514,27 +1513,6 @@ main(int argc, char *argv[]) "terminal")); } - /* - * Read the configuration file. - */ - if (rcfg_read(RCAPD_DEFAULT_CONF_FILE, -1, &rcfg, verify_statistics) - != 0) { - /* - * A configuration file may not exist if rcapd is started - * by enabling the smf rcap service, so attempt to create - * a default file. - */ - create_config_file(NULL); - - /* - * A real failure if still can't read the - * configuration file - */ - if (rcfg_read(RCAPD_DEFAULT_CONF_FILE, -1, &rcfg, - verify_statistics) != 0) - die(gettext("resource caps not configured %s"), - RCAPD_DEFAULT_CONF_FILE); - } finish_configuration(); should_reconfigure = 0; @@ -1636,14 +1614,20 @@ main(int argc, char *argv[]) now = gethrtime(); /* - * Detect configuration and cap changes at every - * reconfiguration_interval, or when SIGHUP has been received. + * Detect configuration and cap changes only when SIGHUP + * is received. Call reconfigure to apply new configuration + * parameters. */ - if (EVENT_TIME(now, next_configuration) || - should_reconfigure == 1) { + if (should_reconfigure == 1) { + reread_configuration(); + should_reconfigure = 0; + reconfigure(now, &next_configuration, &next_proc_walk, + &next_rss_sample); + } + + if (EVENT_TIME(now, next_configuration)) { reconfigure(now, &next_configuration, &next_proc_walk, &next_rss_sample); - should_reconfigure = 0; } /* diff --git a/usr/src/cmd/rcap/rcapstat/Makefile b/usr/src/cmd/rcap/rcapstat/Makefile index fb436f5684..e9959c4ef7 100644 --- a/usr/src/cmd/rcap/rcapstat/Makefile +++ b/usr/src/cmd/rcap/rcapstat/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -38,7 +38,7 @@ LINTSRCS = $(COMMON_DIR)/utils.c \ $(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG CPPFLAGS += -I$(COMMON_DIR) -LDLIBS += -lumem -ll -lzonecfg +LDLIBS += -lumem -lzonecfg -lscf LINTFLAGS += $(LDLIBS) -mnu |
