summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2009-06-24 23:17:00 +0000
committercperciva <cperciva@FreeBSD.org>2009-06-24 23:17:00 +0000
commit8f1962d8fc528050e30fea347d88c0f96b905608 (patch)
treecb558ef8f9bf60cb354f08b5cefbf7d7686ceabd /usr.sbin
parent11197296caae985dd245decd98433d199f255d12 (diff)
downloadFreeBSD-src-8f1962d8fc528050e30fea347d88c0f96b905608.zip
FreeBSD-src-8f1962d8fc528050e30fea347d88c0f96b905608.tar.gz
Make sysinstall search for /dev/daXa and register such devices as USB disks.
This covers the common case of unsliced USB drives, and makes it possible to select them as installation source media. PR: 61152, 115197, 135016 Submitted by: randi MFC after: 1 month
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/sysinstall/Makefile2
-rw-r--r--usr.sbin/sysinstall/devices.c19
-rw-r--r--usr.sbin/sysinstall/dispatch.c4
-rw-r--r--usr.sbin/sysinstall/media.c46
-rw-r--r--usr.sbin/sysinstall/menus.c12
-rw-r--r--usr.sbin/sysinstall/options.c3
-rw-r--r--usr.sbin/sysinstall/sysinstall.h8
-rw-r--r--usr.sbin/sysinstall/usb.c88
8 files changed, 180 insertions, 2 deletions
diff --git a/usr.sbin/sysinstall/Makefile b/usr.sbin/sysinstall/Makefile
index 5cbd2e5..3f2b758 100644
--- a/usr.sbin/sysinstall/Makefile
+++ b/usr.sbin/sysinstall/Makefile
@@ -11,7 +11,7 @@ SRCS= anonFTP.c cdrom.c command.c config.c devices.c dhcp.c \
ftp.c globals.c http.c index.c install.c installUpgrade.c keymap.c \
label.c main.c makedevs.c media.c menus.c misc.c modules.c \
mouse.c msg.c network.c nfs.c options.c package.c \
- system.c tcpip.c termcap.c ttys.c ufs.c user.c \
+ system.c tcpip.c termcap.c ttys.c ufs.c usb.c user.c \
variable.c ${_wizard} keymap.h countries.h
CFLAGS+= -DUSE_GZIP=1
diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c
index e78c268..3ba8732 100644
--- a/usr.sbin/sysinstall/devices.c
+++ b/usr.sbin/sysinstall/devices.c
@@ -65,6 +65,8 @@ static int numDevs;
DEVICE_ENTRY(DEVICE_TYPE_NETWORK, name, descr, 0)
#define SERIAL(name, descr, max) \
DEVICE_ENTRY(DEVICE_TYPE_NETWORK, name, descr, max)
+#define USB(name, descr, max) \
+ DEVICE_ENTRY(DEVICE_TYPE_USB, name, descr, max)
static struct _devname {
DeviceType type;
@@ -89,6 +91,7 @@ static struct _devname {
DISK("mfid%d", "LSI MegaRAID SAS array", 4),
FLOPPY("fd%d", "floppy drive unit A", 4),
SERIAL("cuad%d", "%s on device %s (COM%d)", 16),
+ USB("da%da", "USB Mass Storage Device", 16),
NETWORK("ae", "Attansic/Atheros L2 Fast Ethernet"),
NETWORK("age", "Attansic/Atheros L1 Gigabit Ethernet"),
NETWORK("alc", "Atheros AR8131/AR8132 PCIe Ethernet"),
@@ -392,6 +395,22 @@ skipif:
}
break;
+ case DEVICE_TYPE_USB:
+ fd = deviceTry(device_names[i], try, j);
+ if (fd >= 0) {
+ char n[BUFSIZ];
+
+ close(fd);
+ snprintf(n, sizeof(n), device_names[i].name, j);
+ deviceRegister(strdup(n), device_names[i].description,
+ strdup(try), DEVICE_TYPE_USB, TRUE, mediaInitUSB,
+ mediaGetUSB, mediaShutdownUSB, NULL);
+
+ if (isDebug())
+ msgDebug("Found a USB disk for %s\n", try);
+ }
+ break;
+
case DEVICE_TYPE_NETWORK:
fd = deviceTry(device_names[i], try, j);
/* The only network devices that you can open this way are serial ones */
diff --git a/usr.sbin/sysinstall/dispatch.c b/usr.sbin/sysinstall/dispatch.c
index 79d9cf3..bd22afd 100644
--- a/usr.sbin/sysinstall/dispatch.c
+++ b/usr.sbin/sysinstall/dispatch.c
@@ -96,6 +96,7 @@ static struct _word {
{ "mediaClose", dispatch_mediaClose },
{ "mediaSetCDROM", mediaSetCDROM },
{ "mediaSetFloppy", mediaSetFloppy },
+ { "mediaSetUSB", mediaSetUSB },
{ "mediaSetDOS", mediaSetDOS },
{ "mediaSetFTP", mediaSetFTP },
{ "mediaSetFTPActive", mediaSetFTPActive },
@@ -511,7 +512,8 @@ dispatch_load_menu(dialogMenuItem *self)
Device **devlist;
char *err;
int what, i, j, msize, count;
- DeviceType dtypes[] = {DEVICE_TYPE_FLOPPY, DEVICE_TYPE_CDROM, DEVICE_TYPE_DOS, DEVICE_TYPE_UFS};
+ DeviceType dtypes[] = {DEVICE_TYPE_FLOPPY, DEVICE_TYPE_CDROM,
+ DEVICE_TYPE_DOS, DEVICE_TYPE_UFS, DEVICE_TYPE_USB};
fprintf(stderr, "dispatch_load_menu called\n");
diff --git a/usr.sbin/sysinstall/media.c b/usr.sbin/sysinstall/media.c
index 643f28b..e50b47c 100644
--- a/usr.sbin/sysinstall/media.c
+++ b/usr.sbin/sysinstall/media.c
@@ -221,6 +221,52 @@ mediaSetFloppy(dialogMenuItem *self)
}
static int
+USBHook(dialogMenuItem *self)
+{
+ return genericHook(self, DEVICE_TYPE_USB);
+}
+
+
+/*
+ * Attempt to use USB as the installation media type.
+ */
+int
+mediaSetUSB(dialogMenuItem *self)
+{
+ Device **devs;
+ int cnt;
+
+ mediaClose();
+ devs = deviceFind(NULL, DEVICE_TYPE_USB);
+ cnt = deviceCount(devs);
+
+ if (!cnt) {
+ msgConfirm("No USB devices found!");
+ return DITEM_FAILURE | DITEM_CONTINUE;
+ }
+ else if (cnt > 1) {
+ DMenu *menu;
+ int status;
+
+ menu = deviceCreateMenu(&MenuMediaUSB, DEVICE_TYPE_USB, USBHook,
+ NULL);
+ if (!menu)
+ msgFatal("Unable to create USB menu! Something is " \
+ "seriously wrong.");
+ status = dmenuOpenSimple(menu, FALSE);
+ free(menu);
+ if (!status)
+ return DITEM_FAILURE;
+ }
+ else
+ mediaDevice = devs[0];
+ if (mediaDevice)
+ mediaDevice->private = NULL;
+ msgConfirm("Using USB device: %s", mediaDevice->name);
+ return (mediaDevice ? DITEM_LEAVE_MENU : DITEM_FAILURE);
+}
+
+static int
DOSHook(dialogMenuItem *self)
{
return genericHook(self, DEVICE_TYPE_DOS);
diff --git a/usr.sbin/sysinstall/menus.c b/usr.sbin/sysinstall/menus.c
index 7d1210b..152ad32 100644
--- a/usr.sbin/sysinstall/menus.c
+++ b/usr.sbin/sysinstall/menus.c
@@ -191,6 +191,7 @@ DMenu MenuIndex = {
{ " Media, NFS", "Select NFS installation media.", NULL, mediaSetNFS },
{ " Media, Floppy", "Select floppy installation media.", NULL, mediaSetFloppy },
{ " Media, CDROM/DVD", "Select CDROM/DVD installation media.", NULL, mediaSetCDROM },
+ { " Media, USB", "Select USB installation media.", NULL, mediaSetUSB },
{ " Media, DOS", "Select DOS installation media.", NULL, mediaSetDOS },
{ " Media, UFS", "Select UFS installation media.", NULL, mediaSetUFS },
{ " Media, FTP", "Select FTP installation media.", NULL, mediaSetFTP },
@@ -428,6 +429,16 @@ DMenu MenuMediaFloppy = {
{ { NULL } },
};
+DMenu MenuMediaUSB = {
+ DMENU_NORMAL_TYPE | DMENU_SELECTION_RETURNS,
+ "Choose a USB drive",
+ "You have more than one USB drive. Please choose which drive\n"
+ "you would like to use.",
+ NULL,
+ NULL,
+ { { NULL } },
+};
+
DMenu MenuMediaDOS = {
DMENU_NORMAL_TYPE | DMENU_SELECTION_RETURNS,
"Choose a DOS partition",
@@ -850,6 +861,7 @@ DMenu MenuMedia = {
{ "6 NFS", "Install over NFS", NULL, mediaSetNFS },
{ "7 File System", "Install from an existing filesystem", NULL, mediaSetUFS },
{ "8 Floppy", "Install from a floppy disk set", NULL, mediaSetFloppy },
+ { "9 USB", "Install from a USB drive", NULL, mediaSetUSB },
{ "X Options", "Go to the Options screen", NULL, optionsEditor },
{ NULL } },
};
diff --git a/usr.sbin/sysinstall/options.c b/usr.sbin/sysinstall/options.c
index 714ff4d..33b5031 100644
--- a/usr.sbin/sysinstall/options.c
+++ b/usr.sbin/sysinstall/options.c
@@ -78,6 +78,9 @@ mediaCheck(Option *opt)
case DEVICE_TYPE_CDROM:
return "CDROM";
+ case DEVICE_TYPE_USB:
+ return "USB";
+
case DEVICE_TYPE_DOS:
return "DOS";
diff --git a/usr.sbin/sysinstall/sysinstall.h b/usr.sbin/sysinstall/sysinstall.h
index 6f860f5..89827b1 100644
--- a/usr.sbin/sysinstall/sysinstall.h
+++ b/usr.sbin/sysinstall/sysinstall.h
@@ -271,6 +271,7 @@ typedef enum {
DEVICE_TYPE_FTP,
DEVICE_TYPE_NETWORK,
DEVICE_TYPE_CDROM,
+ DEVICE_TYPE_USB,
DEVICE_TYPE_DOS,
DEVICE_TYPE_UFS,
DEVICE_TYPE_NFS,
@@ -440,6 +441,7 @@ extern DMenu MenuMedia; /* Media type menu */
extern DMenu MenuMouse; /* Mouse type menu */
#endif
extern DMenu MenuMediaCDROM; /* CDROM media menu */
+extern DMenu MenuMediaUSB; /* USB media menu */
extern DMenu MenuMediaDOS; /* DOS media menu */
extern DMenu MenuMediaFloppy; /* Floppy media menu */
extern DMenu MenuMediaFTP; /* FTP media menu */
@@ -717,6 +719,7 @@ extern void mediaClose(void);
extern int mediaTimeout(void);
extern int mediaSetCDROM(dialogMenuItem *self);
extern int mediaSetFloppy(dialogMenuItem *self);
+extern int mediaSetUSB(dialogMenuItem *self);
extern int mediaSetDOS(dialogMenuItem *self);
extern int mediaSetFTP(dialogMenuItem *self);
extern int mediaSetFTPActive(dialogMenuItem *self);
@@ -848,6 +851,11 @@ extern void mediaShutdownUFS(Device *dev);
extern Boolean mediaInitUFS(Device *dev);
extern FILE *mediaGetUFS(Device *dev, char *file, Boolean probe);
+/* usb.c */
+extern Boolean mediaInitUSB(Device *dev);
+extern FILE *mediaGetUSB(Device *dev, char *file, Boolean probe);
+extern void mediaShutdownUSB(Device *dev);
+
/* user.c */
extern int userAddGroup(dialogMenuItem *self);
extern int userAddUser(dialogMenuItem *self);
diff --git a/usr.sbin/sysinstall/usb.c b/usr.sbin/sysinstall/usb.c
new file mode 100644
index 0000000..5be8ac1
--- /dev/null
+++ b/usr.sbin/sysinstall/usb.c
@@ -0,0 +1,88 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * verbatim and that no modifications are made prior to this
+ * point in the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * used floppy.c and cdrom.c as templates, edited as necessary.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/fcntl.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#include <ufs/ufs/ufsmount.h>
+
+#include "sysinstall.h"
+
+static Boolean USBMounted;
+static char mountpoint[] = "/dist";
+
+Boolean
+mediaInitUSB(Device *dev)
+{
+ struct ufs_args ufsargs;
+
+ if (USBMounted)
+ return TRUE;
+
+ Mkdir(mountpoint);
+
+ memset(&ufsargs, 0, sizeof(ufsargs));
+ ufsargs.fspec = dev->devname;
+
+ if (mount("ufs", mountpoint, MNT_RDONLY, (caddr_t)&ufsargs) != -1) {
+ USBMounted = TRUE;
+ return TRUE;
+ }
+
+ msgConfirm("Error mounting USB drive %s (%s) on %s : %s",
+ dev->name, dev->devname, mountpoint, strerror(errno));
+ return FALSE;
+}
+
+
+FILE *
+mediaGetUSB(Device *dev, char *file, Boolean probe)
+{
+ return mediaGenericGet(mountpoint, file);
+}
+
+
+/*
+ * When sysinstall terminates, all USB drives handled by deviceRegister will
+ * be checked and unmounted if necessary.
+ */
+void
+mediaShutdownUSB(Device *dev)
+{
+ if (!USBMounted)
+ return;
+
+ if (unmount(mountpoint, MNT_FORCE) != 0)
+ msgConfirm("Could not unmount the USB drive from %s: %s",
+ mountpoint, strerror(errno));
+ else
+ USBMounted = FALSE;
+
+}
OpenPOWER on IntegriCloud