summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2008-07-25 19:58:14 +0000
committerbrooks <brooks@FreeBSD.org>2008-07-25 19:58:14 +0000
commit8330af909ca941f7f0083761fdafe90a332e74de (patch)
tree62fd98a560aa70ad64312a864e5064cbfbef32da
parentfb5f9ab862007c3c81c74a45467be20efed0b373 (diff)
downloadFreeBSD-src-8330af909ca941f7f0083761fdafe90a332e74de.zip
FreeBSD-src-8330af909ca941f7f0083761fdafe90a332e74de.tar.gz
Add support for a new login capability, cpumask which allows login
sessions to be pinned to cpus by login class.
-rw-r--r--lib/libutil/login.conf.59
-rw-r--r--lib/libutil/login_cap.h3
-rw-r--r--lib/libutil/login_class.314
-rw-r--r--lib/libutil/login_class.c107
4 files changed, 132 insertions, 1 deletions
diff --git a/lib/libutil/login.conf.5 b/lib/libutil/login.conf.5
index b4c96f2..863aa06 100644
--- a/lib/libutil/login.conf.5
+++ b/lib/libutil/login.conf.5
@@ -203,6 +203,15 @@ The maximum and current limits may be specified individually by appending a
.It Sy "Name Type Notes Description
.It "charset string Set $MM_CHARSET environment variable to the specified
value.
+.It "cpumask string List of cpus to bind the user to.
+The syntax is the same as for the
+.Fl l
+argument of
+.Xr cpuset 1 or the word
+.Ql default .
+If set to
+.Ql default
+no action is taken.
.It "hushlogin bool false Same as having a ~/.hushlogin file.
.It "ignorenologin bool false Login not prevented by nologin.
.It "ftp-chroot bool false Limit FTP access with
diff --git a/lib/libutil/login_cap.h b/lib/libutil/login_cap.h
index a7cb4c6..c98e7fd 100644
--- a/lib/libutil/login_cap.h
+++ b/lib/libutil/login_cap.h
@@ -48,7 +48,8 @@
#define LOGIN_SETUSER 0x0040 /* set user (via setuid) */
#define LOGIN_SETENV 0x0080 /* set user environment */
#define LOGIN_SETMAC 0x0100 /* set user default MAC label */
-#define LOGIN_SETALL 0x01ff /* set everything */
+#define LOGIN_SETCPUMASK 0x0200 /* set user cpumask */
+#define LOGIN_SETALL 0x03ff /* set everything */
#define BI_AUTH "authorize" /* accepted authentication */
#define BI_REJECT "reject" /* rejected authentication */
diff --git a/lib/libutil/login_class.3 b/lib/libutil/login_class.3
index ca5b2ce..c91f9a9 100644
--- a/lib/libutil/login_class.3
+++ b/lib/libutil/login_class.3
@@ -155,6 +155,18 @@ capability "setenv=var1 val1,var2 val2..,varN valN".
Set the MAC label for the current process to the label specified
in system login class database.
.Pp
+.It LOGIN_SETCPUMASK
+Create a new
+.Xr cpuset 2
+and set the cpu affinity to the specified mask.
+The string may contain a comma separated list of numbers and/or number
+ranges as handled by the
+.Xr cpuset 1
+utility or the case-insensitive string
+.Ql default .
+If the string is
+.Ql default
+no action will be taken.
.It LOGIN_SETALL
Enables all of the above settings.
.El
@@ -186,6 +198,8 @@ or resources, a message is reported to
.Xr syslog 3 ,
with LOG_ERR priority and directed to the currently active facility.
.Sh SEE ALSO
+.Xr cpuset 1 ,
+.Xr cpuset 2 ,
.Xr setgid 2 ,
.Xr setlogin 2 ,
.Xr setuid 2 ,
diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c
index 39f114f..c18d46a 100644
--- a/lib/libutil/login_class.c
+++ b/lib/libutil/login_class.c
@@ -26,9 +26,11 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <sys/cpuset.h>
#include <sys/mac.h>
#include <sys/rtprio.h>
#include <errno.h>
@@ -239,6 +241,108 @@ setclassenvironment(login_cap_t *lc, const struct passwd * pwd, int paths)
}
+static int
+list2cpuset(const char *list, cpuset_t *mask)
+{
+ enum { NONE, NUM, DASH } state;
+ int lastnum;
+ int curnum;
+ const char *l;
+
+ state = NONE;
+ curnum = lastnum = 0;
+ for (l = list; *l != '\0';) {
+ if (isdigit(*l)) {
+ curnum = atoi(l);
+ if (curnum > CPU_SETSIZE)
+ errx(EXIT_FAILURE,
+ "Only %d cpus supported", CPU_SETSIZE);
+ while (isdigit(*l))
+ l++;
+ switch (state) {
+ case NONE:
+ lastnum = curnum;
+ state = NUM;
+ break;
+ case DASH:
+ for (; lastnum <= curnum; lastnum++)
+ CPU_SET(lastnum, mask);
+ state = NONE;
+ break;
+ case NUM:
+ default:
+ return (0);
+ }
+ continue;
+ }
+ switch (*l) {
+ case ',':
+ switch (state) {
+ case NONE:
+ break;
+ case NUM:
+ CPU_SET(curnum, mask);
+ state = NONE;
+ break;
+ case DASH:
+ return (0);
+ break;
+ }
+ break;
+ case '-':
+ if (state != NUM)
+ return (0);
+ state = DASH;
+ break;
+ default:
+ return (0);
+ }
+ l++;
+ }
+ switch (state) {
+ case NONE:
+ break;
+ case NUM:
+ CPU_SET(curnum, mask);
+ break;
+ case DASH:
+ return (0);
+ }
+ return 1;
+}
+
+
+void
+setclasscpumask(login_cap_t *lc)
+{
+ const char *maskstr;
+ cpuset_t maskset;
+ cpusetid_t setid;
+
+ maskstr = login_getcapstr(lc, "cpumask", NULL, NULL);
+ CPU_ZERO(&maskset);
+ if (maskstr == NULL)
+ return;
+ if (strcasecmp("default", maskstr) == 0)
+ return;
+ if (!list2cpuset(maskstr, &maskset)) {
+ syslog(LOG_WARNING,
+ "list2cpuset(%s) invalid mask specification", maskstr);
+ return;
+ }
+
+ if (cpuset(&setid) != 0) {
+ syslog(LOG_ERR, "cpuset(): %s", strerror(errno));
+ return;
+ }
+
+ if (cpuset_setaffinity(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1,
+ sizeof(maskset), &maskset) != 0)
+ syslog(LOG_ERR, "cpuset_setaffinity(%s): %s", maskstr,
+ strerror(errno));
+}
+
+
/*
* setclasscontext()
*
@@ -289,6 +393,9 @@ setlogincontext(login_cap_t *lc, const struct passwd *pwd,
/* Set environment */
if (flags & LOGIN_SETENV)
setclassenvironment(lc, pwd, 0);
+ /* Set cpu affinity */
+ if (flags & LOGIN_SETCPUMASK)
+ setclasscpumask(lc);
}
return mymask;
}
OpenPOWER on IntegriCloud