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
This commit is contained in:
Colin Percival 2009-06-24 23:17:00 +00:00
parent 6882bf4d92
commit 2245fa69bb
8 changed files with 180 additions and 2 deletions

View File

@ -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

View File

@ -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 @@ deviceGetAll(void)
}
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 */

View File

@ -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");

View File

@ -220,6 +220,52 @@ mediaSetFloppy(dialogMenuItem *self)
return (mediaDevice ? DITEM_LEAVE_MENU : DITEM_FAILURE);
}
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)
{

View File

@ -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 } },
};

View File

@ -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";

View File

@ -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);

88
usr.sbin/sysinstall/usb.c Normal file
View File

@ -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;
}