rcapadm.c revision d75e6a5d480f559280524b60d52730c76a25524f
/*
* 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
* 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 <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <libscf.h>
#include <libscf_priv.h>
#include <libintl.h>
#include <locale.h>
#include <zone.h>
#include <libzonecfg.h>
#include "utils.h"
#include "rcapd.h"
#include "rcapd_conf.h"
#include "rcapd_stat.h"
static void
usage()
{
gettext("usage: rcapadm\n"
" [-E|-D] "
" [-n] "
" [-i <scan|sample|report|config>=value] "
"# set intervals\n"
" [-c <percent>] "
"# set memory cap\n"
" "
"# enforcement threshold\n"
" [-z <zonename> -m <max-rss>] "
"# update zone memory cap\n"));
}
static int enable = -1;
static int disable = -1;
static int pressure = -1;
static int no_starting_stopping = -1;
static int scan_interval = -1;
static int report_interval = -1;
static int config_interval = -1;
static int sample_interval = -1;
static char *subopt_v[] = {
"scan",
"sample",
"report",
"config",
};
typedef enum {
OPT_SCAN = 0,
} subopt_idx_t;
static void
print_state(void)
{
scf_handle_t *h;
/* LINTED: conditionally assigned and used in function */
scf_handle_bind(h) != 0)
goto out;
out:
if (!persistent)
"state: unknown"));
"state: %s (%s at next boot)\n"), *temporary ?
else
gettext("disabled"));
}
/*
* Update the in-kernel memory cap for the specified zone.
*/
static int
{
return (E_SUCCESS);
/* get the running zone from the kernel */
zonename);
return (E_ERROR);
}
return (E_ERROR);
}
"cap for zone '%s'\n"), zonename);
return (E_ERROR);
}
return (E_SUCCESS);
}
int
{
int modified = 0;
int opt;
char *zonename;
(void) setprogname("rcapadm");
(void) textdomain(TEXT_DOMAIN);
switch (opt) {
case 'n':
no_starting_stopping = 1;
break;
case 'c':
pressure > 100 ||
usage();
modified++;
break;
case 'E':
enable = 1;
disable = 0;
break;
case 'D':
disable = 1;
enable = 0;
break;
case 'i':
while (*subopts != '\0') {
&optval)) {
case OPT_SCAN:
usage();
break;
case OPT_SAMPLE:
usage();
break;
case OPT_REPORT:
usage();
break;
case OPT_CONFIG:
usage();
break;
default:
usage();
}
}
modified++;
break;
case 'm':
break;
case 'z':
break;
default:
usage();
}
}
/* the -z & -m options must be used together */
usage();
usage();
/*
*/
if (disable > 0) {
? SMF_AT_NEXT_BOOT : 0) != 0)
scf_strerror(scf_error()));
}
if (enable > 0) {
? SMF_AT_NEXT_BOOT : 0) != 0)
scf_strerror(scf_error()));
}
/*
* If instance is enabled, put it in maintenance since we
* failed to read configuration from the repository or
* create statistics file.
*/
SCF_STATE_STRING_DISABLED) != 0)
(void) smf_maintain_instance(RCAP_FMRI, 0);
} else {
/* Done reading configuration */
}
}
if (refresh)
if (modified) {
if (pressure >= 0)
if (config_interval >= 0)
if (scan_interval >= 0)
if (report_interval >= 0)
if (sample_interval >= 0)
/*
* Modify configuration with the new parameter(s). The
* function will exit if it fails.
*/
if ((modify_config(&conf)) != 0)
if (smf_refresh_instance(RCAP_FMRI) != 0)
scf_strerror(scf_error()));
}
/*
* Display current configuration
*/
print_state();
return (E_SUCCESS);
}