From owner-freebsd-current@FreeBSD.ORG Sat Oct 3 17:30:41 2009 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A6B49106566B for ; Sat, 3 Oct 2009 17:30:41 +0000 (UTC) (envelope-from hselasky@c2i.net) Received: from swip.net (mailfe14.tele2.se [212.247.155.161]) by mx1.freebsd.org (Postfix) with ESMTP id C2E6A8FC19 for ; Sat, 3 Oct 2009 17:30:40 +0000 (UTC) X-Cloudmark-Score: 0.000000 [] X-Cloudmark-Analysis: v=1.0 c=1 a=aQey1_VUwUUA:10 a=RERtC8nhXGhYvIZhK0yWrQ==:17 a=QM9bZEqh-AD268miR9YA:9 a=dziWhO2-t5NtCJMW5JlWEyWviJ4A:4 a=yDsR5o4TGx5hdJQgHXoA:9 a=Gwy5qfOPNbwUCF4hmu8A:7 a=mqmwgKMJpqpOiXYO1Q4eFkBNcy4A:4 Received: from [90.149.203.35] (account mc467741@c2i.net HELO laptop.adsl.tele2.no) by mailfe14.swip.net (CommuniGate Pro SMTP 5.2.16) with ESMTPA id 570040641; Sat, 03 Oct 2009 19:30:38 +0200 From: Hans Petter Selasky To: freebsd-current@freebsd.org Date: Sat, 3 Oct 2009 19:31:22 +0200 User-Agent: KMail/1.11.4 (FreeBSD/9.0-CURRENT; KDE/4.2.4; i386; ; ) References: <20091002150931.K35591@pooker.samsco.org> <200910031800.24896.hselasky@c2i.net> In-Reply-To: X-Face: (%:6u[ldzJ`0qjD7sCkfdMmD*RxpO< =?iso-8859-1?q?Q0yAl=7E=3F=60=27F=3FjDVb=5DE6TQ7=27=23h-VlLs=7Dk/=0A=09?=(yxg(p!IL.`#ng"%`BMrham7%UK,}VH\wUOm=^>wEEQ+KWt[{J#x6ow~JO:,zwp.(t; @ =?iso-8859-1?q?Aq=0A=09=3A4=3A=26nFCgDb8=5B3oIeTb=5E=27?=",; u{5{}C9>"PuY\)!=#\u9SSM-nz8+SR~B\!qBv MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_sp4xKvPSgaU5kXU" Message-Id: <200910031931.24600.hselasky@c2i.net> Cc: Subject: Re: [PATCH] Fix for USB media not found at boot X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 03 Oct 2009 17:30:41 -0000 --Boundary-00=_sp4xKvPSgaU5kXU Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Saturday 03 October 2009 18:05:32 Scott Long wrote: > That's an interesting idea. If you can make this work, go for it. > Meanwhile, I'm going to continue to look at the usb enumeration code. Please find attached an outline. I need one more hour to finalize the patch. All existing mount root features have been kept. The only difference is that the system will not panic before 3 minutes, if no root disk is present. I think that is acceptable. --HPS --Boundary-00=_sp4xKvPSgaU5kXU Content-Type: text/x-patch; charset="iso-8859-1"; name="mount_root_outline.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mount_root_outline.diff" ==== //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) */ --Boundary-00=_sp4xKvPSgaU5kXU--