diff options
-rw-r--r-- | lib/libc/sys/madvise.2 | 9 | ||||
-rw-r--r-- | sys/sys/mman.h | 1 | ||||
-rw-r--r-- | sys/sys/proc.h | 1 | ||||
-rw-r--r-- | sys/vm/vm_mmap.c | 15 | ||||
-rw-r--r-- | sys/vm/vm_pageout.c | 3 |
5 files changed, 28 insertions, 1 deletions
diff --git a/lib/libc/sys/madvise.2 b/lib/libc/sys/madvise.2 index 27a032f..d783ea0 100644 --- a/lib/libc/sys/madvise.2 +++ b/lib/libc/sys/madvise.2 @@ -117,6 +117,12 @@ system calls. Region is not included in a core file. .It Dv MADV_CORE Include region in a core file. +.It Dv MADV_PROTECT +Informs the VM system this process should not be killed when the +swap space is exhausted. +The process must have superuser privileges. +This should be used judiciously in processes that must remain running +for the system to properly function. .El .Sh RETURN VALUES .Rv -std madvise @@ -131,6 +137,9 @@ The virtual address range specified by the and .Fa len arguments is not valid. +.It Bq Er EPERM +.Dv MADV_PROTECT +was specified and the process does not have superuser privileges. .El .Sh SEE ALSO .Xr mincore 2 , diff --git a/sys/sys/mman.h b/sys/sys/mman.h index 71ac90c..f8b94cc 100644 --- a/sys/sys/mman.h +++ b/sys/sys/mman.h @@ -124,6 +124,7 @@ #define MADV_AUTOSYNC 7 /* revert to default flushing strategy */ #define MADV_NOCORE 8 /* do not include these pages in a core file */ #define MADV_CORE 9 /* revert to including pages in a core file */ +#define MADV_PROTECT 10 /* protect process from pageout kill */ /* * Return bits from mincore diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 77464a0..8e25aa0 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -629,6 +629,7 @@ struct proc { #define P_EXEC 0x04000 /* Process called exec. */ #define P_THREADED 0x08000 /* Process is using threads. */ #define P_CONTINUED 0x10000 /* Proc has continued from a stopped state. */ +#define P_PROTECTED 0x20000 /* Do not kill on memory overcommit. */ /* flags that control how threads may be suspended for some reason */ #define P_STOPPED_SIG 0x20000 /* Stopped due to SIGSTOP/SIGTSTP */ diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 93c8524..d20756f 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -752,8 +752,23 @@ madvise(td, uap) { vm_offset_t start, end; vm_map_t map; + struct proc *p; + int error; /* + * Check for our special case, advising the swap pager we are + * "immortal." + */ + if (uap->behav == MADV_PROTECT) { + p = td->td_proc; + PROC_LOCK(p); + error = suser(td); + if (error == 0) + p->p_flag |= P_PROTECTED; + PROC_UNLOCK(p); + return (error); + } + /* * Check for illegal behavior */ if (uap->behav < 0 || uap->behav > MADV_CORE) diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index dab4ae2..8c07be2 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1184,9 +1184,10 @@ rescan0: if (PROC_TRYLOCK(p) == 0) continue; /* - * if this is a system process, skip it + * If this is a system or protected process, skip it. */ if ((p->p_flag & P_SYSTEM) || (p->p_pid == 1) || + (p->p_flag & P_PROTECTED) || ((p->p_pid < 48) && (vm_swap_size != 0))) { PROC_UNLOCK(p); continue; |