summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/madvise.29
-rw-r--r--sys/sys/mman.h1
-rw-r--r--sys/sys/proc.h1
-rw-r--r--sys/vm/vm_mmap.c15
-rw-r--r--sys/vm/vm_pageout.c3
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;
OpenPOWER on IntegriCloud