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