On Sun, Feb 12, 2017 at 01:34:14AM +0200, Ossi Herrala wrote:

> After couple of private mails with guenther@ we came up with the
> following patch.
> 
> Introduce new flag FORK_PID1 for fork1(9).
> 
> This flag is special and only for forking init(8) which wants to be
> PID 1.
> 
> With this flag in place, it's possible to remove global randompid
> variable which was used to control if allocpid() returns random PIDs
> or PID 1 for init(8). Now allocpid() can also be simplified.
>

New patch which works with latest changes to fork1(9).

This version also documents FORK_PID1 flag in fork1(9) man page.


---
 share/man/man9/fork1.9 |  3 +++
 sys/kern/init_main.c   |  5 ++---
 sys/kern/kern_fork.c   | 24 ++++++++++--------------
 sys/sys/proc.h         |  2 +-
 4 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/share/man/man9/fork1.9 b/share/man/man9/fork1.9
index c22c9800aa4..21175416ed4 100644
--- a/share/man/man9/fork1.9
+++ b/share/man/man9/fork1.9
@@ -109,6 +109,9 @@ must also be set.
 .It Dv FORK_PTRACE
 The child will start with tracing enabled, as if
 ptrace(PT_TRACE_ME, 0, 0, 0) had been invoked in the child.
+.It Dv FORK_PID1
+Special flag to assign PID 1 for
+.Xr init 8 process.
 .El
 .Pp
 If
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index faa74aa4244..f1975a6aa89 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -437,13 +437,12 @@ main(void *framep)
        {
                struct proc *initproc;
 
-               if (fork1(p, FORK_FORK, start_init, NULL, NULL, &initproc))
+               if (fork1(p, FORK_FORK|FORK_PID1, start_init, NULL, NULL,
+                   &initproc))
                        panic("fork init");
                initprocess = initproc->p_p;
        }
 
-       randompid = 1;
-
        /*
         * Create any kernel threads whose creation was deferred because
         * initprocess had not yet been created.
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 38c1be4a981..b5f99d3c4dc 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -71,7 +71,6 @@
 
 int    nprocesses = 1;         /* process 0 */
 int    nthreads = 1;           /* proc 0 */
-int    randompid;              /* when set to 1, pid's go random */
 struct forkstat forkstat;
 
 void fork_return(void *);
@@ -220,7 +219,11 @@ process_new(struct proc *p, struct process *parent, int 
flags)
            (caddr_t)&pr->ps_endcopy - (caddr_t)&pr->ps_startcopy);
 
        process_initialize(pr, p);
-       pr->ps_pid = allocpid();
+
+       if (flags & FORK_PID1)
+               pr->ps_pid = 1;
+       else
+               pr->ps_pid = allocpid();
 
        /* post-copy fixups */
        pr->ps_pptr = parent;
@@ -332,7 +335,7 @@ fork1(struct proc *curp, int flags, void (*func)(void *), 
void *arg,
 
        KASSERT((flags & ~(FORK_FORK | FORK_VFORK | FORK_PPWAIT | FORK_PTRACE
            | FORK_IDLE | FORK_SHAREVM | FORK_SHAREFILES | FORK_NOZOMBIE
-           | FORK_SYSTEM | FORK_SIGHAND)) == 0);
+           | FORK_SYSTEM | FORK_SIGHAND | FORK_PID1)) == 0);
        KASSERT((flags & FORK_SIGHAND) == 0 || (flags & FORK_SHAREVM));
        KASSERT(func != NULL);
 
@@ -631,19 +634,12 @@ ispidtaken(pid_t pid)
 pid_t
 allocpid(void)
 {
-       static pid_t lastpid;
        pid_t pid;
 
-       if (!randompid) {
-               /* only used early on for system processes */
-               pid = ++lastpid;
-       } else {
-               /* Find an unused pid satisfying lastpid < pid <= PID_MAX */
-               do {
-                       pid = arc4random_uniform(PID_MAX - lastpid) + 1 +
-                           lastpid;
-               } while (ispidtaken(pid));
-       }
+       /* Find an unused pid satisfying 1 < pid <= PID_MAX */
+       do {
+               pid = 2 + arc4random_uniform(PID_MAX - 1);
+       } while (ispidtaken(pid));
 
        return pid;
 }
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 4f015f2eeb0..b3b3ac4bb0d 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -449,6 +449,7 @@ struct uidinfo *uid_find(uid_t);
 #define FORK_SHAREVM   0x00000080
 #define FORK_SIGHAND   0x00000200
 #define FORK_PTRACE    0x00000400
+#define FORK_PID1      0x00000800
 
 #define EXIT_NORMAL            0x00000001
 #define EXIT_THREAD            0x00000002
@@ -470,7 +471,6 @@ extern struct proc proc0;           /* Process slot for 
swapper. */
 extern struct process process0;                /* Process slot for kernel 
threads. */
 extern int nprocesses, maxprocess;     /* Cur and max number of processes. */
 extern int nthreads, maxthread;                /* Cur and max number of 
threads. */
-extern int randompid;                  /* fork() should create random pid's */
 
 LIST_HEAD(proclist, proc);
 LIST_HEAD(processlist, process);
-- 
2.11.1



-- 
Ossi Herrala

Reply via email to