init(8) is wanted to have process ID 1. It's also the only process
which is assigned non-random PID (well, there's also swapper as PID
0).
This patch renames fork1() to fork1_to_pid() and introduces new
argument "pid" which can be used to select PID for new process. When
pid is 0, random PID is assigned. fork1() is then wrapper to
fork1_to_pid() with pid argument being 0. No functional change in
fork1().
Only caller (outside fork1()) for fork1_to_pid() should be in kernel
main() to start the init(8) process.
With above changes it's possible to remove global variable "randompid"
which only purpose was to assign PID 1 to init(8). It's also possible
to remove static variable "lastpid" from allocpid().
Tested in amd64 by building the base and kernel, and run some of the
regress test set.
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index e21a8306854..20f92752921 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -437,14 +437,12 @@ main(void *framep)
{
struct proc *initproc;
- if (fork1(p, FORK_FORK, NULL, 0, start_init, NULL, NULL,
- &initproc))
+ if (fork1_to_pid(p, 1, FORK_FORK, NULL, 0, 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 3ff2085f732..b1d1d249ca7 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 *);
@@ -80,7 +79,7 @@ pid_t alloctid(void);
pid_t allocpid(void);
int ispidtaken(pid_t);
-void process_new(struct proc *, struct process *, int);
+void process_new(struct proc *, struct process *, pid_t, int);
void
fork_return(void *arg)
@@ -176,7 +175,7 @@ process_initialize(struct process *pr, struct proc *p)
* Allocate and initialize a new process.
*/
void
-process_new(struct proc *p, struct process *parent, int flags)
+process_new(struct proc *p, struct process *parent, pid_t pid, int flags)
{
struct process *pr;
@@ -193,7 +192,7 @@ 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();
+ pr->ps_pid = pid ? pid : allocpid();
/* post-copy fixups */
pr->ps_pptr = parent;
@@ -256,6 +255,15 @@ fork1(struct proc *curp, int flags, void *stack, pid_t
*tidptr,
void (*func)(void *), void *arg, register_t *retval,
struct proc **rnewprocp)
{
+ return (fork1_to_pid(curp, 0, flags, stack, tidptr, func, arg, retval,
+ rnewprocp));
+}
+
+int
+fork1_to_pid(struct proc *curp, pid_t pid, int flags, void *stack,
+ pid_t *tidptr, void (*func)(void *), void *arg, register_t *retval,
+ struct proc **rnewprocp)
+{
struct process *curpr = curp->p_p;
struct process *pr;
struct proc *p;
@@ -270,7 +278,8 @@ fork1(struct proc *curp, int flags, void *stack, pid_t
*tidptr,
if (flags & FORK_THREAD) {
if ((flags & FORK_SHAREFILES) == 0 ||
(flags & FORK_SIGHAND) == 0 ||
- (flags & FORK_SYSTEM) != 0)
+ (flags & FORK_SYSTEM) != 0 ||
+ pid != 0)
return (EINVAL);
}
if (flags & FORK_SIGHAND && (flags & FORK_SHAREVM) == 0)
@@ -362,7 +371,7 @@ fork1(struct proc *curp, int flags, void *stack, pid_t
*tidptr,
p->p_p = pr = curpr;
pr->ps_refcnt++;
} else {
- process_new(p, curpr, flags);
+ process_new(p, curpr, pid, flags);
pr = p->p_p;
}
p->p_fd = pr->ps_fd;
@@ -590,19 +599,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 1a1f0966518..c2163e1ac27 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -525,6 +525,8 @@ int dowait4(struct proc *, pid_t, int *, int, struct rusage
*,
register_t *);
void cpu_exit(struct proc *);
void process_initialize(struct process *, struct proc *);
+int fork1_to_pid(struct proc *, pid_t, int, void *, pid_t *,
+ void (*)(void *), void *, register_t *, struct proc **);
int fork1(struct proc *, int, void *, pid_t *, void (*)(void *),
void *, register_t *, struct proc **);
int groupmember(gid_t, struct ucred *);
--
Ossi Herrala