==== //depot/projects/usb/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c#9 - /home/some_dir/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c ==== @@ -3058,7 +3058,6 @@ destroy_dev(zfsdev); } -static struct root_hold_token *zfs_root_token; struct proc *zfsproc; uint_t zfs_fsyncer_key; @@ -3071,8 +3070,6 @@ switch (type) { case MOD_LOAD: - zfs_root_token = root_mount_hold("ZFS"); - mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL); spa_init(FREAD | FWRITE); @@ -3083,7 +3080,6 @@ tsd_create(&rrw_tsd_key, NULL); printf("ZFS storage pool version " SPA_VERSION_STRING "\n"); - root_mount_rel(zfs_root_token); zfsdev_init(); break; ==== //depot/projects/usb/src/sys/dev/pccbb/pccbb.c#14 - /home/some_dir/src/sys/dev/pccbb/pccbb.c ==== @@ -500,15 +500,6 @@ mtx_unlock(&Giant); /* - * First time through we need to tell mountroot that we're - * done. - */ - if (sc->sc_root_token) { - root_mount_rel(sc->sc_root_token); - sc->sc_root_token = NULL; - } - - /* * Wait until it has been 250ms since the last time we * get an interrupt. We handle the rest of the interrupt * at the top of the loop. Although we clear the bit in the ==== //depot/projects/usb/src/sys/dev/pccbb/pccbb_pci.c#11 - /home/some_dir/src/sys/dev/pccbb/pccbb_pci.c ==== @@ -439,7 +439,6 @@ device_printf(brdev, "unable to create event thread.\n"); panic("cbb_create_event_thread"); } - sc->sc_root_token = root_mount_hold(device_get_nameunit(sc->dev)); return (0); err: if (sc->irq_res) ==== //depot/projects/usb/src/sys/dev/pccbb/pccbbvar.h#8 - /home/some_dir/src/sys/dev/pccbb/pccbbvar.h ==== @@ -88,7 +88,6 @@ struct proc *event_thread; void (*chipinit)(struct cbb_softc *); int powerintr; - struct root_hold_token *sc_root_token; }; /* result of detect_card */ ==== //depot/projects/usb/src/sys/dev/usb/controller/usb_controller.c#32 - /home/some_dir/src/sys/dev/usb/controller/usb_controller.c ==== @@ -78,11 +78,6 @@ "Debug level"); #endif -static int usb_no_boot_wait = 0; -TUNABLE_INT("hw.usb.no_boot_wait", &usb_no_boot_wait); -SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RDTUN, &usb_no_boot_wait, 0, - "No device enumerate waiting at boot."); - static devclass_t usb_devclass; static device_method_t usb_methods[] = { @@ -134,11 +129,6 @@ return (ENXIO); } - if (usb_no_boot_wait == 0) { - /* delay vfs_mountroot until the bus is explored */ - bus->bus_roothold = root_mount_hold(device_get_nameunit(dev)); - } - usb_attach_sub(dev, bus); return (0); /* return success */ @@ -161,12 +151,6 @@ /* Stop power watchdog */ usb_callout_drain(&bus->power_wdog); - /* Let the USB explore process detach all devices. */ - if (bus->bus_roothold != NULL) { - root_mount_rel(bus->bus_roothold); - bus->bus_roothold = NULL; - } - USB_BUS_LOCK(bus); if (usb_proc_msignal(&bus->explore_proc, &bus->detach_msg[0], &bus->detach_msg[1])) { @@ -239,10 +223,6 @@ (udev->hub->explore) (udev); USB_BUS_LOCK(bus); } - if (bus->bus_roothold != NULL) { - root_mount_rel(bus->bus_roothold); - bus->bus_roothold = NULL; - } } /*------------------------------------------------------------------------* ==== //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#32 - /home/some_dir/src/sys/dev/usb/input/ukbd.c ==== @@ -67,6 +67,7 @@ #include #include #include +#include #include #include @@ -328,6 +329,9 @@ { DPRINTFN(2, "polling\n"); + if (kdb_active == 0) + return; /* Only poll if KDB is active */ + while (sc->sc_inputs == 0) { usbd_transfer_poll(sc->sc_xfer, UKBD_N_TRANSFER); ==== //depot/projects/usb/src/sys/dev/usb/usb_bus.h#15 - /home/some_dir/src/sys/dev/usb/usb_bus.h ==== @@ -51,7 +51,6 @@ struct usb_bus { struct usb_bus_stat stats_err; struct usb_bus_stat stats_ok; - struct root_hold_token *bus_roothold; /* * There are two callback processes. One for Giant locked * callbacks. One for non-Giant locked callbacks. This should ==== //depot/projects/usb/src/sys/geom/journal/g_journal.c#12 - /home/some_dir/src/sys/geom/journal/g_journal.c ==== @@ -2108,12 +2108,6 @@ g_topology_unlock(); last_write = time_second; - if (sc->sc_rootmount != NULL) { - GJ_DEBUG(1, "root_mount_rel %p", sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; - } - for (;;) { /* Get first request from the queue. */ mtx_lock(&sc->sc_mtx); @@ -2311,9 +2305,6 @@ sc->sc_inactive.jj_queue = NULL; sc->sc_active.jj_queue = NULL; - sc->sc_rootmount = root_mount_hold("GJOURNAL"); - GJ_DEBUG(1, "root_mount_hold %p", sc->sc_rootmount); - callout_init(&sc->sc_callout, CALLOUT_MPSAFE); if (md->md_type != GJ_TYPE_COMPLETE) { /* @@ -2445,12 +2436,6 @@ g_topology_unlock(); - if (sc->sc_rootmount != NULL) { - GJ_DEBUG(1, "root_mount_rel %p", sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; - } - callout_drain(&sc->sc_callout); mtx_lock(&sc->sc_mtx); wakeup(sc); ==== //depot/projects/usb/src/sys/geom/journal/g_journal.h#2 - /home/some_dir/src/sys/geom/journal/g_journal.h ==== @@ -163,8 +163,6 @@ struct callout sc_callout; struct proc *sc_worker; - - struct root_hold_token *sc_rootmount; }; #define sc_dprovider sc_dconsumer->provider #define sc_jprovider sc_jconsumer->provider ==== //depot/projects/usb/src/sys/geom/mirror/g_mirror.c#7 - /home/some_dir/src/sys/geom/mirror/g_mirror.c ==== @@ -1726,13 +1726,6 @@ static int g_mirror_try_destroy(struct g_mirror_softc *sc) { - - if (sc->sc_rootmount != NULL) { - G_MIRROR_DEBUG(1, "root_mount_rel[%u] %p", __LINE__, - sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; - } g_topology_lock(); if (!g_mirror_can_destroy(sc)) { g_topology_unlock(); @@ -2190,10 +2183,6 @@ */ callout_drain(&sc->sc_callout); sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROY; - G_MIRROR_DEBUG(1, "root_mount_rel[%u] %p", __LINE__, - sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; return; } else { return; @@ -2217,10 +2206,6 @@ if (ndisks == 0) { /* No valid disks found, destroy device. */ sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROY; - G_MIRROR_DEBUG(1, "root_mount_rel[%u] %p", - __LINE__, sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; return; } } else { @@ -2374,12 +2359,6 @@ */ if (sc->sc_provider == NULL) g_mirror_launch_provider(sc); - if (sc->sc_rootmount != NULL) { - G_MIRROR_DEBUG(1, "root_mount_rel[%u] %p", - __LINE__, sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; - } } /* * Genid should be bumped immediately, so do it here. @@ -2907,8 +2886,6 @@ G_MIRROR_DEBUG(1, "Device %s created (%u components, id=%u).", sc->sc_name, sc->sc_ndisks, sc->sc_id); - sc->sc_rootmount = root_mount_hold("GMIRROR"); - G_MIRROR_DEBUG(1, "root_mount_hold %p", sc->sc_rootmount); /* * Run timeout. */ ==== //depot/projects/usb/src/sys/geom/mirror/g_mirror.h#2 - /home/some_dir/src/sys/geom/mirror/g_mirror.h ==== @@ -207,8 +207,6 @@ struct mtx sc_events_mtx; struct callout sc_callout; - - struct root_hold_token *sc_rootmount; }; #define sc_name sc_geom->name ==== //depot/projects/usb/src/sys/geom/part/g_part.c#19 - /home/some_dir/src/sys/geom/part/g_part.c ==== @@ -1448,7 +1448,6 @@ struct g_geom *gp; struct g_part_entry *entry; struct g_part_table *table; - struct root_hold_token *rht; int attr, depth; int error; @@ -1470,7 +1469,6 @@ return (NULL); } - rht = root_mount_hold(mp->name); g_topology_unlock(); /* @@ -1515,13 +1513,11 @@ g_part_new_provider(gp, table, entry); } - root_mount_rel(rht); g_access(cp, -1, 0, 0); return (gp); fail: g_topology_lock(); - root_mount_rel(rht); g_access(cp, -1, 0, 0); g_part_wither(gp, error); return (NULL); ==== //depot/projects/usb/src/sys/geom/raid3/g_raid3.c#7 - /home/some_dir/src/sys/geom/raid3/g_raid3.c ==== @@ -1974,13 +1974,6 @@ g_topology_assert_not(); sx_assert(&sc->sc_lock, SX_XLOCKED); - if (sc->sc_rootmount != NULL) { - G_RAID3_DEBUG(1, "root_mount_rel[%u] %p", __LINE__, - sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; - } - g_topology_lock(); if (!g_raid3_can_destroy(sc)) { g_topology_unlock(); @@ -2464,10 +2457,6 @@ * Timeout expired, so destroy device. */ sc->sc_flags |= G_RAID3_DEVICE_FLAG_DESTROY; - G_RAID3_DEBUG(1, "root_mount_rel[%u] %p", - __LINE__, sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; } return; } @@ -2610,12 +2599,6 @@ } if (sc->sc_provider == NULL) g_raid3_launch_provider(sc); - if (sc->sc_rootmount != NULL) { - G_RAID3_DEBUG(1, "root_mount_rel[%u] %p", __LINE__, - sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; - } break; case G_RAID3_DEVICE_STATE_COMPLETE: /* @@ -2643,12 +2626,6 @@ } if (sc->sc_provider == NULL) g_raid3_launch_provider(sc); - if (sc->sc_rootmount != NULL) { - G_RAID3_DEBUG(1, "root_mount_rel[%u] %p", __LINE__, - sc->sc_rootmount); - root_mount_rel(sc->sc_rootmount); - sc->sc_rootmount = NULL; - } break; default: KASSERT(1 == 0, ("Wrong device state (%s, %s).", sc->sc_name, @@ -3193,9 +3170,6 @@ G_RAID3_DEBUG(1, "Device %s created (%u components, id=%u).", sc->sc_name, sc->sc_ndisks, sc->sc_id); - sc->sc_rootmount = root_mount_hold("GRAID3"); - G_RAID3_DEBUG(1, "root_mount_hold %p", sc->sc_rootmount); - /* * Run timeout. */ ==== //depot/projects/usb/src/sys/geom/raid3/g_raid3.h#2 - /home/some_dir/src/sys/geom/raid3/g_raid3.h ==== @@ -240,8 +240,6 @@ struct mtx sc_events_mtx; struct callout sc_callout; - - struct root_hold_token *sc_rootmount; }; #define sc_name sc_geom->name ==== //depot/projects/usb/src/sys/kern/kern_cons.c#3 - /home/some_dir/src/sys/kern/kern_cons.c ==== @@ -353,8 +353,10 @@ if (cn_mute) return (-1); - while ((c = cncheckc()) == -1) - ; + while ((c = cncheckc()) == -1) { + if (!kdb_active) + pause("WKEY", hz / 100); /* give USB a chance */ + } if (c == '\r') c = '\n'; /* console input is always ICRNL */ return (c); ==== //depot/projects/usb/src/sys/kern/vfs_mount.c#29 - /home/some_dir/src/sys/kern/vfs_mount.c ==== @@ -1344,82 +1344,9 @@ * */ -struct root_hold_token { - const char *who; - LIST_ENTRY(root_hold_token) list; -}; - -static LIST_HEAD(, root_hold_token) root_holds = - LIST_HEAD_INITIALIZER(&root_holds); - static int root_mount_complete; /* - * Hold root mount. - */ -struct root_hold_token * -root_mount_hold(const char *identifier) -{ - struct root_hold_token *h; - - if (root_mounted()) - return (NULL); - - h = malloc(sizeof *h, M_DEVBUF, M_ZERO | M_WAITOK); - h->who = identifier; - mtx_lock(&mountlist_mtx); - LIST_INSERT_HEAD(&root_holds, h, list); - mtx_unlock(&mountlist_mtx); - return (h); -} - -/* - * Release root mount. - */ -void -root_mount_rel(struct root_hold_token *h) -{ - - if (h == NULL) - return; - mtx_lock(&mountlist_mtx); - LIST_REMOVE(h, list); - wakeup(&root_holds); - mtx_unlock(&mountlist_mtx); - free(h, M_DEVBUF); -} - -/* - * Wait for all subsystems to release root mount. - */ -static void -root_mount_prepare(void) -{ - struct root_hold_token *h; - struct timeval lastfail; - int curfail = 0; - - for (;;) { - DROP_GIANT(); - g_waitidle(); - PICKUP_GIANT(); - mtx_lock(&mountlist_mtx); - if (LIST_EMPTY(&root_holds)) { - mtx_unlock(&mountlist_mtx); - break; - } - if (ppsratecheck(&lastfail, &curfail, 1)) { - printf("Root mount waiting for:"); - LIST_FOREACH(h, &root_holds, list) - printf(" %s", h->who); - printf("\n"); - } - msleep(&root_holds, &mountlist_mtx, PZERO | PDROP, "roothold", - hz); - } -} - -/* * Root was mounted, share the good news. */ static void @@ -1452,27 +1379,6 @@ return (root_mount_complete); } -/* - * Wait until root is mounted. - */ -void -root_mount_wait(void) -{ - - /* - * Panic on an obvious deadlock - the function can't be called from - * a thread which is doing the whole SYSINIT stuff. - */ - KASSERT(curthread->td_proc->p_pid != 0, - ("root_mount_wait: cannot be called from the swapper thread")); - mtx_lock(&mountlist_mtx); - while (!root_mount_complete) { - msleep(&root_mount_complete, &mountlist_mtx, PZERO, "rootwait", - hz); - } - mtx_unlock(&mountlist_mtx); -} - static void set_rootvnode() { @@ -1644,24 +1550,24 @@ vfs_mountroot(void) { char *cp, *options; - int error, i, asked = 0; + int error, i, t, asked = 0; options = NULL; - root_mount_prepare(); - mount_zone = uma_zcreate("Mountpoints", sizeof(struct mount), NULL, NULL, mount_init, mount_fini, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); devfs_first(); +repeat: + /* * We are booted with instructions to prompt for the root filesystem. */ if (boothowto & RB_ASKNAME) { if (!vfs_mountroot_ask()) goto mounted; - asked = 1; + asked++; } options = getenv("vfs.root.mountfrom.options"); @@ -1715,14 +1621,35 @@ if (ctrootdevname != NULL) if (!vfs_mountroot_try(ctrootdevname, options)) goto mounted; + + if (!asked) { + printf("\nWaiting for boot disk to appear. " + "Press CTRL+C to abort.\n"); + } + + asked ++; + + t = 16; + i = -1; + while (t-- && (i == -1)) { + pause("WKEY", hz / 16); /* give USB a chance */ + i = cncheckc(); + } + + if (i != -1) + printf("Got key: %d, %c\n", i, i); + /* * Everything so far has failed, prompt on the console if we haven't * already tried that. */ - if (!asked) + if (i == 'c') if (!vfs_mountroot_ask()) goto mounted; + if (asked < (3 * 60)) /* Wait a maximum of 3 minutes */ + goto repeat; + panic("Root mount failed, startup aborted."); mounted: @@ -1875,6 +1802,7 @@ char *options; for(;;) { + printf("\n"); printf("Loader variables:\n"); printf("vfs.root.mountfrom="); mountfrom = getenv("vfs.root.mountfrom"); ==== //depot/projects/usb/src/sys/sys/systm.h#19 - /home/some_dir/src/sys/sys/systm.h ==== @@ -333,15 +333,8 @@ /* XXX: Should be void nanodelay(u_int nsec); */ void DELAY(int usec); -/* Root mount holdback API */ -struct root_hold_token; - -struct root_hold_token *root_mount_hold(const char *identifier); -void root_mount_rel(struct root_hold_token *h); -void root_mount_wait(void); int root_mounted(void); - /* * Unit number allocation API. (kern/subr_unit.c) */