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