Add support for a new login capability, cpumask which allows login
sessions to be pinned to cpus by login class.
This commit is contained in:
parent
32c5ce374b
commit
d84c42924c
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 ,
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user