bin/135700: Add an ability to run inetd(8) with P_PROTECTED flag set

Dmitry Sivachenko mitya at yandex-team.ru
Thu Jun 18 12:50:02 UTC 2009


>Number:         135700
>Category:       bin
>Synopsis:       Add an ability to run inetd(8) with P_PROTECTED flag set
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jun 18 12:50:00 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Dmitry S. Sivachenko
>Release:        FreeBSD 4.11-STABLE i386
>Organization:
>Environment:
System: FreeBSD sinbin.demos.su 4.11-STABLE FreeBSD 4.11-STABLE #1: Tue Mar 6 12:43:07 MSK 2007 root at sinbin.demos.su:/mnt/backup/releng_4/obj/mnt/backup/releng_4/src/sys/SINBIN i386


	
>Description:
Sometimes when OS is running out of swap, swap pager can kill important
processes like inetd, sshd, etc.

This patch adds '-i' (means "immortal") option to inetd, which,
when specified, will set P_PROTECTED flag for inetd process, preventing
swap pager to kill inetd.

This will allow at least to login to the affected machine (via telnet or
ssh if sshd is started from inetd) and fix the issue.

This patch was made against inetd found in 7.2-STABLE.

>How-To-Repeat:
	
>Fix:


--- inetd.c.orig	2007-07-01 16:08:08.000000000 +0400
+++ inetd.c	2009-06-18 16:06:54.000000000 +0400
@@ -115,6 +115,7 @@ __FBSDID("$FreeBSD: src/usr.sbin/inetd/i
 #include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/un.h>
+#include <sys/mman.h>
 
 #include <netinet/in.h>
 #include <netinet/tcp.h>
@@ -244,6 +245,7 @@ int	wrap_ex = 0;
 int	wrap_bi = 0;
 int	debug = 0;
 int	dolog = 0;
+int	is_immortal = 0;
 int	maxsock;			/* highest-numbered descriptor */
 fd_set	allsock;
 int	options;
@@ -344,7 +346,7 @@ main(int argc, char **argv)
 
 	openlog("inetd", LOG_PID | LOG_NOWAIT | LOG_PERROR, LOG_DAEMON);
 
-	while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:s:")) != -1)
+	while ((ch = getopt(argc, argv, "dilwWR:a:c:C:p:s:")) != -1)
 		switch(ch) {
 		case 'd':
 			debug = 1;
@@ -353,6 +355,9 @@ main(int argc, char **argv)
 		case 'l':
 			dolog = 1;
 			break;
+		case 'i':
+			is_immortal = 1;
+			break;
 		case 'R':
 			getvalue(optarg, &toomany,
 				"-R %s: bad value for service invocation rate");
@@ -562,6 +567,12 @@ main(int argc, char **argv)
 	if (signalpipe[1] > maxsock)
 	    maxsock = signalpipe[1];
 
+	if (is_immortal)
+	    if (madvise(NULL, 0, MADV_PROTECT)) {
+		syslog(LOG_ERR, "Unable to set MADV_PROTECT flag: %s", strerror(error));
+		exit(EX_OSERR);
+	    }
+
 	for (;;) {
 	    int n, ctrl;
 	    fd_set readable;



--- inetd.8.orig	2008-01-22 12:46:00.000000000 +0300
+++ inetd.8	2009-06-18 15:12:52.000000000 +0400
@@ -38,6 +38,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl d
+.Op Fl i
 .Op Fl l
 .Op Fl w
 .Op Fl W
@@ -76,6 +77,9 @@ The following options are available:
 .Bl -tag -width indent
 .It Fl d
 Turn on debugging.
+.It Fl i
+Set P_PROTECTED flag for inetd process, advising the swap pager
+we are "immortal".
 .It Fl l
 Turn on logging of successful connections.
 .It Fl w
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list