summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/compat/linux/linux_sched.c5
-rw-r--r--sys/compat/netbsd/netbsd_misc.c4
-rw-r--r--sys/dev/usb/usb_port.h5
-rw-r--r--sys/kern/init_main.c88
-rw-r--r--sys/kern/kern_fork.c25
-rw-r--r--sys/kern/kern_kthread.c9
-rw-r--r--sys/kern/subr_autoconf.c30
-rw-r--r--sys/sys/device.h5
-rw-r--r--sys/sys/proc.h4
9 files changed, 128 insertions, 47 deletions
diff --git a/sys/compat/linux/linux_sched.c b/sys/compat/linux/linux_sched.c
index c5b1b008db9..4521fee96e6 100644
--- a/sys/compat/linux/linux_sched.c
+++ b/sys/compat/linux/linux_sched.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_sched.c,v 1.4 2004/06/13 21:49:23 niklas Exp $ */
+/* $OpenBSD: linux_sched.c,v 1.5 2004/11/23 19:08:52 miod Exp $ */
/* $NetBSD: linux_sched.c,v 1.6 2000/05/28 05:49:05 thorpej Exp $ */
/*-
@@ -96,7 +96,8 @@ linux_sys_clone(p, v, retval)
* or down. So, we pass a stack size of 0, so that the code
* that makes this adjustment is a noop.
*/
- return (fork1(p, sig, flags, SCARG(uap, stack), 0, NULL, NULL, retval));
+ return (fork1(p, sig, flags, SCARG(uap, stack), 0, NULL, NULL, retval,
+ NULL));
}
int
diff --git a/sys/compat/netbsd/netbsd_misc.c b/sys/compat/netbsd/netbsd_misc.c
index b8a7b984103..627c5cb1d83 100644
--- a/sys/compat/netbsd/netbsd_misc.c
+++ b/sys/compat/netbsd/netbsd_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netbsd_misc.c,v 1.13 2003/06/02 23:28:00 millert Exp $ */
+/* $OpenBSD: netbsd_misc.c,v 1.14 2004/11/23 19:08:54 miod Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -57,7 +57,7 @@ netbsd_sys___vfork14(p, v, retval)
register_t *retval;
{
return (fork1(p, SIGCHLD, FORK_PPWAIT|FORK_SHAREVM, NULL, 0, NULL,
- NULL, retval));
+ NULL, retval, NULL));
}
/* XXX syncs whole file */
diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h
index c830e6e1820..dab4ad72e3a 100644
--- a/sys/dev/usb/usb_port.h
+++ b/sys/dev/usb/usb_port.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usb_port.h,v 1.52 2004/11/08 22:01:02 dlg Exp $ */
+/* $OpenBSD: usb_port.h,v 1.53 2004/11/23 19:08:54 miod Exp $ */
/* $NetBSD: usb_port.h,v 1.62 2003/02/15 18:33:30 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_port.h,v 1.21 1999/11/17 22:33:47 n_hibma Exp $ */
@@ -279,9 +279,6 @@ typedef struct proc *usb_proc_ptr;
#define usb_kthread_create1 kthread_create
#define usb_kthread_create kthread_create_deferred
-#define config_pending_incr()
-#define config_pending_decr()
-
typedef int usb_malloc_type;
#define Ether_ifattach(ifp, eaddr) ether_ifattach(ifp)
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 196065727d4..119bcecce17 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.119 2004/07/28 17:15:12 tholo Exp $ */
+/* $OpenBSD: init_main.c,v 1.120 2004/11/23 19:08:55 miod Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -126,6 +126,7 @@ struct timeval boottime;
struct timeval runtime;
#endif
int ncpus = 1;
+__volatile int start_init_exec; /* semaphore for start_init() */
#if !defined(NO_PROPOLICE)
long __guard[8];
@@ -185,7 +186,6 @@ main(framep)
struct timeval rtv;
quad_t lim;
int s, i;
- register_t rval[2];
extern struct pdevinit pdevinit[];
extern void scheduler_start(void);
extern void disk_init(void);
@@ -399,6 +399,34 @@ main(framep)
/* Start the scheduler */
scheduler_start();
+ /*
+ * Create process 1 (init(8)). We do this now, as Unix has
+ * historically had init be process 1, and changing this would
+ * probably upset a lot of people.
+ *
+ * Note that process 1 won't immediately exec init(8), but will
+ * wait for us to inform it that the root file system has been
+ * mounted.
+ */
+ if (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, start_init, NULL, NULL,
+ &initproc))
+ panic("fork init");
+
+ /*
+ * Create any kernel threads who's creation was deferred because
+ * initproc had not yet been created.
+ */
+ kthread_run_deferred_queue();
+
+ /*
+ * Now that device driver threads have been created, wait for
+ * them to finish any deferred autoconfiguration. Note we don't
+ * need to lock this semaphore, since we haven't booted any
+ * secondary processors, yet.
+ */
+ while (config_pending)
+ (void) tsleep((void *)&config_pending, PWAIT, "cfpend", 0);
+
dostartuphooks();
/* Configure root/swap devices */
@@ -419,6 +447,15 @@ main(framep)
p->p_fd->fd_rdir = NULL;
/*
+ * Now that root is mounted, we can fixup initproc's CWD
+ * info. All other processes are kthreads, which merely
+ * share proc0's CWD info.
+ */
+ initproc->p_fd->fd_cdir = rootvnode;
+ VREF(initproc->p_fd->fd_cdir);
+ initproc->p_fd->fd_rdir = NULL;
+
+ /*
* Now can look at time, having had a chance to verify the time
* from the file system. Reset p->p_rtime as it may have been
* munched in mi_switch() after the time got set.
@@ -428,49 +465,45 @@ main(framep)
#else
boottime = mono_time = time;
#endif
- p->p_stats->p_start = boottime;
-#ifdef __HAVE_CPUINFO
- microuptime(&p->p_cpu->ci_schedstate.spc_runtime);
-#else
+#ifndef __HAVE_CPUINFO
microuptime(&runtime);
#endif
- p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
+ LIST_FOREACH(p, &allproc, p_list) {
+ p->p_stats->p_start = boottime;
+#ifdef __HAVE_CPUINFO
+ microuptime(&p->p_cpu->ci_schedstate.spc_runtime);
+#endif
+ p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
+ }
uvm_swap_init();
- /* Create process 1 (init(8)). */
- if (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, start_init, NULL, rval))
- panic("fork init");
-
- /* Create process 2, the pageout daemon kernel thread. */
+ /* Create the pageout daemon kernel thread. */
if (kthread_create(uvm_pageout, NULL, NULL, "pagedaemon"))
panic("fork pagedaemon");
- /* Create process 3, the reaper daemon kernel thread. */
+ /* Create the reaper daemon kernel thread. */
if (kthread_create(start_reaper, NULL, NULL, "reaper"))
panic("fork reaper");
- /* Create process 4, the cleaner daemon kernel thread. */
+ /* Create the cleaner daemon kernel thread. */
if (kthread_create(start_cleaner, NULL, NULL, "cleaner"))
panic("fork cleaner");
- /* Create process 5, the update daemon kernel thread. */
+ /* Create the update daemon kernel thread. */
if (kthread_create(start_update, NULL, NULL, "update"))
panic("fork update");
- /* Create process 6, the aiodone daemon kernel thread. */
+ /* Create the aiodone daemon kernel thread. */
if (kthread_create(uvm_aiodone_daemon, NULL, NULL, "aiodoned"))
panic("fork aiodoned");
#ifdef CRYPTO
- /* Create process 7, the crypto kernel thread. */
+ /* Create the crypto kernel thread. */
if (kthread_create(start_crypto, NULL, NULL, "crypto"))
panic("crypto thread");
#endif /* CRYPTO */
- /* Create any other deferred kernel threads. */
- kthread_run_deferred_queue();
-
microtime(&rtv);
srandom((u_long)(rtv.tv_sec ^ rtv.tv_usec));
@@ -481,6 +514,12 @@ main(framep)
cpu_boot_secondary_processors();
#endif
+ /*
+ * Okay, now we can let init(8) exec! It's off to userland!
+ */
+ start_init_exec = 1;
+ wakeup((void *)&start_init_exec);
+
/* The scheduler is an infinite loop. */
uvm_scheduler();
/* NOTREACHED */
@@ -535,11 +574,16 @@ start_init(arg)
char flags[4], *flagsp;
char **pathp, *path, *ucp, **uap, *arg0, *arg1 = NULL;
- initproc = p;
-
/*
* Now in process 1.
*/
+
+ /*
+ * Wait for main() to tell us that it's safe to exec.
+ */
+ while (start_init_exec == 0)
+ (void) tsleep((void *)&start_init_exec, PWAIT, "initexec", 0);
+
check_console(p);
/*
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 4fc2dd5c8f0..eee21a8231c 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.72 2004/08/06 22:31:30 mickey Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.73 2004/11/23 19:08:55 miod Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -75,7 +75,8 @@ int pidtaken(pid_t);
int
sys_fork(struct proc *p, void *v, register_t *retval)
{
- return (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, NULL, NULL, retval));
+ return (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, NULL,
+ NULL, retval, NULL));
}
/*ARGSUSED*/
@@ -83,7 +84,7 @@ int
sys_vfork(struct proc *p, void *v, register_t *retval)
{
return (fork1(p, SIGCHLD, FORK_VFORK|FORK_PPWAIT, NULL, 0, NULL,
- NULL, retval));
+ NULL, retval, NULL));
}
int
@@ -121,7 +122,7 @@ sys_rfork(struct proc *p, void *v, register_t *retval)
if (rforkflags & RFMEM)
flags |= FORK_SHAREVM;
- return (fork1(p, SIGCHLD, flags, NULL, 0, NULL, NULL, retval));
+ return (fork1(p, SIGCHLD, flags, NULL, 0, NULL, NULL, retval, NULL));
}
/* print the 'table full' message once per 10 seconds */
@@ -129,7 +130,8 @@ struct timeval fork_tfmrate = { 10, 0 };
int
fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
- void (*func)(void *), void *arg, register_t *retval)
+ void (*func)(void *), void *arg, register_t *retval,
+ struct proc **rnewprocp)
{
struct proc *p2;
uid_t uid;
@@ -354,6 +356,14 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
*/
PRELE(p1);
+ /*
+ * Notify any interested parties about the new process.
+ */
+ KNOTE(&p1->p_klist, NOTE_FORK | p2->p_pid);
+
+ /*
+ * Update stats now that we know the fork was successfull.
+ */
uvmexp.forks++;
if (flags & FORK_PPWAIT)
uvmexp.forks_ppwait++;
@@ -361,9 +371,10 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
uvmexp.forks_sharevm++;
/*
- * tell any interested parties about the new process
+ * Pass a pointer to the new process to the caller.
*/
- KNOTE(&p1->p_klist, NOTE_FORK | p2->p_pid);
+ if (rnewprocp != NULL)
+ *rnewprocp = p2;
/*
* Preserve synchronization semantics of vfork. If waiting for
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index 44c85d176a3..721c440c999 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_kthread.c,v 1.22 2004/05/04 16:59:32 grange Exp $ */
+/* $OpenBSD: kern_kthread.c,v 1.23 2004/11/23 19:08:55 miod Exp $ */
/* $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $ */
/*-
@@ -65,7 +65,6 @@ kthread_create(void (*func)(void *), void *arg,
struct proc **newpp, const char *fmt, ...)
{
struct proc *p2;
- register_t rv[2];
int error;
va_list ap;
@@ -74,13 +73,11 @@ kthread_create(void (*func)(void *), void *arg,
* descriptors and don't leave the exit status around for the
* parent to wait for.
*/
- error = fork1(&proc0, 0,
- FORK_SHAREVM|FORK_NOZOMBIE|FORK_SIGHAND, NULL, 0, func, arg, rv);
+ error = fork1(&proc0, 0, FORK_SHAREVM |FORK_NOZOMBIE |FORK_SIGHAND,
+ NULL, 0, func, arg, NULL, &p2);
if (error)
return (error);
- p2 = pfind(rv[0]);
-
/*
* Mark it as a system process and not a candidate for
* swapping.
diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c
index c378eac10e2..9cb03dbf82d 100644
--- a/sys/kern/subr_autoconf.c
+++ b/sys/kern/subr_autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_autoconf.c,v 1.38 2004/08/03 17:49:04 pefo Exp $ */
+/* $OpenBSD: subr_autoconf.c,v 1.39 2004/11/23 19:08:55 miod Exp $ */
/* $NetBSD: subr_autoconf.c,v 1.21 1996/04/04 06:06:18 cgd Exp $ */
/*
@@ -51,6 +51,7 @@
#include <sys/systm.h>
/* Extra stuff from Matthias Drochner <drochner@zelux6.zel.kfa-juelich.de> */
#include <sys/queue.h>
+#include <sys/proc.h>
#include "hotplug.h"
@@ -101,6 +102,8 @@ void config_process_deferred_children(struct device *);
struct devicelist alldevs; /* list of all devices */
struct evcntlist allevents; /* list of all event counters */
+__volatile int config_pending; /* semaphore for mountroot */
+
/*
* Initialize autoconfiguration data structures. This occurs before console
* initialization as that might require use of this subsystem. Furthermore
@@ -691,6 +694,7 @@ config_defer(dev, func)
dc->dc_dev = dev;
dc->dc_func = func;
TAILQ_INSERT_TAIL(&deferred_config_queue, dc, dc_queue);
+ config_pending_incr();
}
/*
@@ -709,10 +713,34 @@ config_process_deferred_children(parent)
TAILQ_REMOVE(&deferred_config_queue, dc, dc_queue);
(*dc->dc_func)(dc->dc_dev);
free(dc, M_DEVBUF);
+ config_pending_decr();
}
}
}
+/*
+ * Manipulate the config_pending semaphore.
+ */
+void
+config_pending_incr(void)
+{
+
+ config_pending++;
+}
+
+void
+config_pending_decr(void)
+{
+
+#ifdef DIAGNOSTIC
+ if (config_pending == 0)
+ panic("config_pending_decr: config_pending == 0");
+#endif
+ config_pending--;
+ if (config_pending == 0)
+ wakeup((void *)&config_pending);
+}
+
int
config_detach_children(parent, flags)
struct device *parent;
diff --git a/sys/sys/device.h b/sys/sys/device.h
index c06c4bc2831..95ea9f12939 100644
--- a/sys/sys/device.h
+++ b/sys/sys/device.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: device.h,v 1.28 2004/11/17 14:12:59 deraadt Exp $ */
+/* $OpenBSD: device.h,v 1.29 2004/11/23 19:08:55 miod Exp $ */
/* $NetBSD: device.h,v 1.15 1996/04/09 20:55:24 cgd Exp $ */
/*
@@ -185,6 +185,7 @@ extern struct devicelist alldevs; /* list of all devices */
extern struct evcntlist allevents; /* list of all event counters */
extern int autoconf_verbose;
+extern __volatile int config_pending; /* semaphore for mountroot */
void config_init(void);
void *config_search(cfmatch_t, struct device *, void *);
@@ -203,6 +204,8 @@ struct device *config_make_softc(struct device *parent,
struct cfdata *cf);
void config_defer(struct device *, void (*)(struct device *));
void evcnt_attach(struct device *, const char *, struct evcnt *);
+void config_pending_incr(void);
+void config_pending_decr(void);
struct device *device_lookup(struct cfdriver *, int unit);
void device_ref(struct device *);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 4ab6cfe9c9c..a8746d3eecf 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.75 2004/07/22 15:42:11 art Exp $ */
+/* $OpenBSD: proc.h,v 1.76 2004/11/23 19:08:55 miod Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -421,7 +421,7 @@ void reaper(void);
void exit1(struct proc *, int);
void exit2(struct proc *);
int fork1(struct proc *, int, int, void *, size_t, void (*)(void *),
- void *, register_t *);
+ void *, register_t *, struct proc **);
void rqinit(void);
int groupmember(gid_t, struct ucred *);
#if !defined(cpu_switch)