From owner-p4-projects@FreeBSD.ORG Mon Aug 21 07:11:38 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6A32E16A4E1; Mon, 21 Aug 2006 07:11:38 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2D8A116A4DE for ; Mon, 21 Aug 2006 07:11:38 +0000 (UTC) (envelope-from cdjones@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id B162D43D7F for ; Mon, 21 Aug 2006 07:11:26 +0000 (GMT) (envelope-from cdjones@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k7L7BO4j036200 for ; Mon, 21 Aug 2006 07:11:24 GMT (envelope-from cdjones@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k7L7BOQr036197 for perforce@freebsd.org; Mon, 21 Aug 2006 07:11:24 GMT (envelope-from cdjones@FreeBSD.org) Date: Mon, 21 Aug 2006 07:11:24 GMT Message-Id: <200608210711.k7L7BOQr036197@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to cdjones@FreeBSD.org using -f From: Chris Jones To: Perforce Change Reviews Cc: Subject: PERFORCE change 104655 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Aug 2006 07:11:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=104655 Change 104655 by cdjones@cdjones-impulse on 2006/08/21 07:10:35 Documentation update for jls and jail; adding flags to jail for cpu shares and memory limits; and getting jtune to set jail limits. Affected files ... .. //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jail/jail.8#5 edit .. //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jail/jail.c#8 edit .. //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jls/Makefile#1 branch .. //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jls/jls.8#1 add .. //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jls/jls.c#1 branch .. //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jtune/jtune.8#2 edit .. //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jtune/jtune.c#2 edit Differences ... ==== //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jail/jail.8#5 (text+ko) ==== @@ -45,6 +45,8 @@ .Op Fl J Ar jid_file .Op Fl s Ar securelevel .Op Fl l u Ar username | Fl U Ar username +.Op Fl S Ar cpu_shares +.Op Fl M Ar mem_limit .Ar path hostname ip-number command ... .Sh DESCRIPTION The @@ -86,6 +88,10 @@ The user name from jailed environment as whom the .Ar command should run. +.It Fl S Ar cpu_shares +CPU shares to assign to the prison. +.It Fl M Ar mem_limit +Amount of memory (in MB) to allow the prison to use. .It Ar path Directory which is to be the root of the prison. .It Ar hostname @@ -542,6 +548,17 @@ privileged, and may manipulate system file flags subject to the usual constraints on .Va kern.securelevel . +.It Va security.jail.limit_jail_memory, Va security.jail.jail_pager_interval +These MIB entries determine whether and how often (in seconds) a +jail's memory-limit monitoring daemon will run, and consequently the +period during which a jail can be overcommitted for resident memory. +.It Va kern.sched.limit_jail_cpu +This MIB entry sets whether CPU usage limits will be enforced +against processes in jails with CPU limits. +.It Va kern.sched.system_cpu_shares +Number of CPU usage shares to allocate to unjailed processes for the +purposes of determining CPU usage permitted for jailed processes. +Unjailed processes are not subject to CPU usage limits. .El .Pp The read-only ==== //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jail/jail.c#8 (text+ko) ==== @@ -56,7 +56,8 @@ struct in_addr in; gid_t groups[NGROUPS]; int ch, i, iflag, Jflag, lflag, ngroups, securelevel, uflag, Uflag; - unsigned int mem_limit, priority; + unsigned int mem_limit = 0; + unsigned int sched_shares = 0; char path[PATH_MAX], *ep, *username, *JidFile; static char *cleanenv; const char *shell, *p = NULL; @@ -64,13 +65,11 @@ FILE *fp; iflag = Jflag = lflag = uflag = Uflag = 0; - mem_limit = JAIL_DEFAULT_MEM_LIMIT; - priority = JAIL_DEFAULT_PRIORITY; securelevel = -1; username = JidFile = cleanenv = NULL; fp = NULL; - while ((ch = getopt(argc, argv, "ilp:m:s:u:U:J:")) != -1) { + while ((ch = getopt(argc, argv, "ilS:M:s:u:U:J:")) != -1) { switch (ch) { case 'i': iflag = 1; @@ -79,16 +78,12 @@ JidFile = optarg; Jflag = 1; break; - case 'm': - /* TODO --- should this be specified in MB? */ + case 'M': mem_limit = atoi(optarg); mem_limit *= 1024 * 1024; break; - case 'p': - priority = atoi(optarg); - if (priority < JAIL_MINIMUM_PRIORITY || - priority > JAIL_MAXIMUM_PRIORITY) - errx(1, "invalid priority: `%s'", optarg); + case 'S': + sched_shares = atoi(optarg); break; case 's': ltmp = strtol(optarg, &ep, 0); @@ -133,7 +128,7 @@ errx(1, "Could not make sense of ip-number: %s", argv[2]); j.ip_number = ntohl(in.s_addr); j.mem_limit = mem_limit; - j.priority = priority; + j.sched_shares = sched_shares; if (Jflag) { fp = fopen(JidFile, "w"); if (fp == NULL) @@ -199,8 +194,8 @@ { (void)fprintf(stderr, "%s%s%s%s%s\n", - "usage: jail [-i] [-J jid_file] [-m mem_limit] ", - "[-p priority] [-s securelevel]", + "usage: jail [-i] [-J jid_file] [-M mem_limit] ", + "[-S cpu_shares] [-s securelevel]", " [-l -u ", "username | -U username]", " path hostname ip-number command ..."); ==== //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jtune/jtune.8#2 (text+ko) ==== @@ -1,0 +1,75 @@ +.\" Copyright (c) 2006 Chris Jones +.\" All rights reserved. +.\" +.\" This software was developed for the FreeBSD Project by Chris Jones +.\" thanks to the support of Google's Summer of Code program and +.\" mentoring by Kip Macy. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 21, 2006 +.Dt JTUNE 8 +.Os +.Sh NAME +.Nm jtune +.Nd "modify jail resource limits" +.Sh SYNOPSIS +.Nm +.Fl j Ar jail_id +.Op Fl i +.Op Fl m Ar mem_limit +.Op Fl s Ar cpu_shares +.Sh DESCRIPTION +The +.Nm +utility modifies a jail's memory and CPU usage limits. +.Pp +The options are as follows: +.Bl -tag -width ".Fl u Ar cpu_shares" +.It Ar jail_id +Jail identifier (JID) of the jail whose limits are being tuned. +.It Fl i +Show jail's resource limits. +.It Fl m Ar mem_limit +Limit a jail's memory usage (resident set size) to +.Ar mem_limit +megabytes. +.It Fl s Ar cpu_shares +Set a jail's CPU shares to +.Ar cpu_shares +shares. +.Sh SEE ALSO +.Xr jail 2 , +.Xr jail 8 , +.Xr jexec 8 +.Xr jls 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx FIXME . +.Pp +.Nm +was written by Chris Jones through the 2006 Google Summer of Code +program. ==== //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jtune/jtune.c#2 (text+ko) ==== @@ -1,12 +1,41 @@ +/*- + * Copyright (c) 2006 Chris Jones + * All rights reserved. + * + * This software was developed for the FreeBSD Project by Chris Jones + * thanks to the support of Google's Summer of Code program and + * mentoring by Kip Macy. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + #include +__FBSDID("$FreeBSD"); #include #include #include -#include -#include - #include #include #include @@ -25,100 +54,135 @@ int main(int argc, char **argv) { - struct xprison *xp; - int jid = 0; - int memlimit = -1; - int shares = 0; - int ch; + struct xprison *xp; + int jid = 0; + int memlimit = -1; + int shares = -1; + int iflag = 0; + int retval; + int ch; + + while ((ch = getopt(argc, argv, "ij:m:s:")) != -1) { + switch (ch) { + case 'i': + iflag = 1; + break; + case 'j': + jid = atoi(optarg); + if (!jid && errno) + err(1, "invalid jail id '%s'", optarg); + break; + + case 'm': + memlimit = atoi(optarg); + if (!memlimit && errno) + err(1, "invalid memory limit '%s'", optarg); + if (memlimit < 0) + errx(1, "invalid memory limit '%s'", optarg); + memlimit *= 1024 * 1024; + break; + + case 's': + shares = atoi(optarg); + if (!shares && errno) + err(1, "invalid cpu share '%s'", optarg); + if (shares < 0) + errx(1, "invalid cpu share '%s'", optarg); + break; + + default: + usage(); + } + } + + argc -= optind; + argv += optind; - while ((ch = getopt(argc, argv, "j:m:s:")) != -1) { - switch (ch) { - case 'j': - jid = atoi(optarg); - if (jid < 1) - errx(1, "invalid jail id '%s'", optarg); - break; + if (!jid) + usage(); + + xp = getxprison(jid); + if (NULL == xp) + errx(1, "no jail with id %d", jid); - case 'm': - memlimit = atoi(optarg); - if (memlimit > 0 || -1 != memlimit) - errx(1, "invalid memory limit '%s'", optarg); - break; + if (iflag) { + char *memlimstr, *memusestr; - case 's': - shares = atoi(optarg); - if (shares < 1) - errx(1, "invalid cpu share '%s'", optarg); - break; + asprintf(&memusestr, "%d M", + xp->pr_mem_usage / (1024 * 1024)); + if (xp->pr_mem_limit) { + asprintf(&memlimstr, "%d M", + xp->pr_mem_limit / (1024 * 1024)); + } else { + asprintf(&memlimstr, "None"); + } - default: - usage(); - } - } + if (NULL == memusestr || NULL == memlimstr) + err(1, "couldn't allocate memory"); - argc -= optind; - argv += optind; + printf(" JID Hostname Memory Used / Limit CPU Shares\n"); + printf("%6d %-24.24s %6s / %-6.6s %-4d\n", + xp->pr_id, xp->pr_host, + memusestr, memlimstr, + xp->pr_sched_shares); + exit(0); + } - xp = getxprison(jid); - if (NULL == xp) - errx(1, "no jail with id %d", jid); - - /* - * TODO --- set memory or cpu here. Will need sysctl, presumably. - */ - - warnx("jail id %d, memory limit %d, cpu share %d", jid, memlimit, shares); - printf("Jail '%s' has %d shares (%d CPU) and memory limit %d (used %d)\n", - xp->pr_host, xp->pr_sched_shares, xp->pr_estcpu, - xp->pr_mem_limit, xp->pr_mem_usage); - exit(0); - + retval = jail_set_resource_limits(jid, shares, memlimit); + if (retval) { + errx(1, "jail_set_resource_limit(%d, %d, %d) failed", + jid, memlimit, shares); + } + exit(0); + } static void usage() { - exit(0); + (void)fprintf(stderr, "%s\n", + "usage: jtune -j jid_id [-m mem_limit] [-s cpu_shares]"); + exit(0); } static struct xprison * getxprison(int jid) { - size_t i, len; - struct xprison *xpl, *sxpl; - if (sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1) - err(1, "sysctlbyname(): security.jail.list"); + size_t i, len; + struct xprison *xpl, *sxpl; + if (sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1) + err(1, "sysctlbyname(): security.jail.list"); + + if (len <= 0) + errx(1, "sysctl security.jail.list has no entries for jid %d", jid); + + /* getxprison allocates the structure, caller frees */ + sxpl = xpl = malloc(len); + if (NULL == xpl) + err(1, "malloc()"); + + if (sysctlbyname("security.jail.list", xpl, &len, NULL, 0) == -1) { + free(xpl); + err(1, "sysctlbyname(): security.jail.list"); + } + + if (len < sizeof(*xpl) || len % sizeof(*xpl) || + xpl->pr_version != XPRISON_VERSION) + errx(1, "Kernel and userland out of sync"); + + for (i = 0; i < len / sizeof(*xpl); i++) { + if (jid == xpl->pr_id) { + struct xprison *xp; + xp = malloc(sizeof (struct xprison)); + if (NULL == xp) + err(1, "malloc()"); + memcpy(xp, xpl, sizeof (struct xprison)); + free(sxpl); + return xp; + } + xpl++; + } - if (len <= 0) - errx(1, "sysctl security.jail.list has no entries for jid %d", jid); - - /* getxprison allocates the structure, caller frees */ - sxpl = xpl = malloc(len); - if (NULL == xpl) - err(1, "malloc()"); - - if (sysctlbyname("security.jail.list", xpl, &len, NULL, 0) == -1) { - free(xpl); - err(1, "sysctlbyname(): security.jail.list"); - } - - if (len < sizeof(*xpl) || len % sizeof(*xpl) || - xpl->pr_version != XPRISON_VERSION) - errx(1, "Kernel and userland out of sync"); - - for (i = 0; i < len / sizeof(*xpl); i++) { - if (jid == xpl->pr_id) { - struct xprison *xp; - xp = malloc(sizeof (struct xprison)); - if (NULL == xp) - err(1, "malloc()"); - memcpy(xp, xpl, sizeof (struct xprison)); - free(sxpl); - return xp; - } - xpl++; - } - - free(sxpl); - return NULL; + free(sxpl); + return NULL; }