kernel: make noswap flag exclude processes from killbig() if not eve, reset noswap flag on exec

This commit is contained in:
cinap_lenrek 2014-08-17 00:50:20 +02:00
parent 0bc51a90b0
commit 3b661a96ef
7 changed files with 68 additions and 65 deletions

View file

@ -301,6 +301,32 @@ This bit is inherited across
and
.IR exec (2).
.TP 10n
.B nohang
Clear the hang bit.
.TP 10n
.B private
Make it impossible to read the process's user memory.
This property is inherited on
.IR fork (2),
cleared on
.IR exec (2),
and is not otherwise resettable.
.TP 10n
.B noswap
Don't allow this process to be swapped out. This should
be used carefully and sparingly or the system could run
out of memory. It is meant for processes that can't be
swapped, like the local fileserver implementing the swap
device and for processes containing sensitive data.
This property is inherited on
.IR fork (2),
cleared on
.IR exec (2),
and is not otherwise resettable.
.TP 10n
.B kill
Kill the process the next time it crosses the user/kernel boundary.
.TP 10n
.B "close\ \fIn
Close file descriptor
.I n
@ -309,25 +335,6 @@ in the process.
.B closefiles
Close all open file descriptors in the process.
.TP 10n
.B nohang
Clear the hang bit.
.TP 10n
.B noswap
Don't allow this process to be swapped out. This should
be used carefully and sparingly or the system could run
out of memory. It is meant for processes that can't be
swapped, like the ones implementing the swap device and for
processes containing sensitive data.
.TP 10n
.B kill
Kill the process the next time it crosses the user/kernel boundary.
.TP 10n
.B private
Make it impossible to read the process's user memory.
This property is inherited on fork, cleared on
.IR exec (2),
and is not otherwise resettable.
.TP 10n
.B "pri\ \fIn
Set the base priority for the process to the integer
.IR n .

View file

@ -492,7 +492,7 @@ procwstat(Chan *c, uchar *db, int n)
if(p->pid != PID(c->qid))
error(Eprocdied);
if(strcmp(up->user, p->user) != 0 && strcmp(up->user, eve) != 0)
if(strcmp(up->user, p->user) != 0 && !iseve())
error(Eperm);
d = smalloc(sizeof(Dir)+n);
@ -500,10 +500,9 @@ procwstat(Chan *c, uchar *db, int n)
if(n == 0)
error(Eshortstat);
if(!emptystr(d->uid) && strcmp(d->uid, p->user) != 0){
if(strcmp(up->user, eve) != 0)
if(!iseve())
error(Eperm);
else
kstrdup(&p->user, d->uid);
kstrdup(&p->user, d->uid);
}
/* p->procmode determines default mode for files in /proc */
if(d->mode != ~0UL)
@ -1530,32 +1529,6 @@ procstopped(void *a)
return ((Proc*)a)->state == Stopped;
}
ulong
procpagecount(Proc *p)
{
Segment *s;
ulong pages;
int i;
eqlock(&p->seglock);
if(waserror()){
qunlock(&p->seglock);
nexterror();
}
pages = 0;
for(i=0; i<NSEG; i++){
if((s = p->seg[i]) != nil){
eqlock(s);
pages += mcountseg(s);
qunlock(s);
}
}
qunlock(&p->seglock);
poperror();
return pages;
}
int
procctlmemio(Proc *p, uintptr offset, int n, void *va, int read)
{

View file

@ -37,7 +37,6 @@ extern char Econrefused[]; /* connection refused */
extern char Econinuse[]; /* connection in use */
extern char Eintr[]; /* interrupted */
extern char Enomem[]; /* kernel allocate failed */
extern char Enoswap[]; /* swap space full */
extern char Esoverlap[]; /* segments overlap */
extern char Emouseset[]; /* mouse type already set */
extern char Eshort[]; /* i/o count too small */

View file

@ -667,7 +667,7 @@ struct Proc
QLock debug; /* to access debugging elements of User */
Proc *pdbg; /* the debugging process */
ulong procmode; /* proc device default file mode */
ulong privatemem; /* proc does not let anyone read mem */
int privatemem; /* proc does not let anyone read mem */
int hang; /* hang at next exec for debug */
int procctl; /* Control for /proc debugging */
uintptr pc; /* DEBUG only */

View file

@ -225,9 +225,10 @@ ulong procalarm(ulong);
void procctl(Proc*);
void procdump(void);
int procfdprint(Chan*, int, int, char*, int);
void procflushseg(Segment*);
int procindex(ulong);
void procinit0(void);
void procflushseg(Segment*);
ulong procpagecount(Proc*);
void procpriority(Proc*, int, int);
Proc* proctab(int);
extern void (*proctrace)(Proc*, int, vlong);

View file

@ -1491,6 +1491,32 @@ exhausted(char *resource)
error(buf);
}
ulong
procpagecount(Proc *p)
{
Segment *s;
ulong pages;
int i;
eqlock(&p->seglock);
if(waserror()){
qunlock(&p->seglock);
nexterror();
}
pages = 0;
for(i=0; i<NSEG; i++){
if((s = p->seg[i]) != nil){
eqlock(s);
pages += mcountseg(s);
qunlock(s);
}
}
qunlock(&p->seglock);
poperror();
return pages;
}
void
killbig(char *why)
{
@ -1503,25 +1529,20 @@ killbig(char *why)
kp = nil;
ep = procalloc.arena+conf.nproc;
for(p = procalloc.arena; p < ep; p++) {
if(p->state == Dead || p->kp || !canqlock(&p->seglock))
if(p->state == Dead || p->kp)
continue;
l = 0;
for(i=1; i<NSEG; i++) {
s = p->seg[i];
if(s == nil || !canqlock(s))
continue;
l += mcountseg(s);
qunlock(s);
}
qunlock(&p->seglock);
if(l > max && ((p->procmode&0222) || strcmp(eve, p->user)!=0)) {
if((p->noswap || (p->procmode & 0222) == 0) && strcmp(eve, p->user) == 0)
continue;
l = procpagecount(p);
if(l > max){
kp = p;
max = l;
}
}
if(kp == nil || !canqlock(&kp->seglock))
if(kp == nil)
return;
print("%lud: %s killed: %s\n", kp->pid, kp->text, why);
qlock(&kp->seglock);
for(p = procalloc.arena; p < ep; p++) {
if(p->state == Dead || p->kp)
continue;
@ -1531,7 +1552,8 @@ killbig(char *why)
kp->procctl = Proc_exitbig;
for(i = 0; i < NSEG; i++) {
s = kp->seg[i];
if(s != nil && canqlock(s)) {
if(s != nil) {
qlock(s);
mfreeseg(s, s->base, (s->top - s->base)/BY2PG);
qunlock(s);
}

View file

@ -512,6 +512,7 @@ sysexec(va_list list)
up->notify = 0;
up->notified = 0;
up->privatemem = 0;
up->noswap = 0;
procsetup(up);
qunlock(&up->debug);