summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bsdconfig/share/device.subr
diff options
context:
space:
mode:
authordteske <dteske@FreeBSD.org>2014-05-17 03:28:43 +0000
committerdteske <dteske@FreeBSD.org>2014-05-17 03:28:43 +0000
commit5dd59bc6ac2020fbc6c987fd0b4fb2bb70daa35b (patch)
treeae02a3cfcc3e67aa5b92565199400cd2cfc2879a /usr.sbin/bsdconfig/share/device.subr
parent0f7f48b5f92ced3835af73951a1c1d6a463829e4 (diff)
downloadFreeBSD-src-5dd59bc6ac2020fbc6c987fd0b4fb2bb70daa35b.zip
FreeBSD-src-5dd59bc6ac2020fbc6c987fd0b4fb2bb70daa35b.tar.gz
MFC r264840: Implement GEOM based media device classification.
Diffstat (limited to 'usr.sbin/bsdconfig/share/device.subr')
-rw-r--r--usr.sbin/bsdconfig/share/device.subr1522
1 files changed, 946 insertions, 576 deletions
diff --git a/usr.sbin/bsdconfig/share/device.subr b/usr.sbin/bsdconfig/share/device.subr
index 9201b95..d93cd9b 100644
--- a/usr.sbin/bsdconfig/share/device.subr
+++ b/usr.sbin/bsdconfig/share/device.subr
@@ -32,6 +32,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
. $BSDCFG_SHARE/common.subr || exit 1
f_dprintf "%s: loading includes..." device.subr
f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/geom.subr
f_include $BSDCFG_SHARE/strings.subr
f_include $BSDCFG_SHARE/struct.subr
@@ -40,42 +41,53 @@ f_include_lang $BSDCFG_LIBE/include/messages.subr
############################################################ GLOBALS
-DEVICES=
-DEVICE_NAMES=
-NDEVICES=0
+NDEVICES=0 # Set by f_device_register(), used by f_device_*()
-# A "device" from sysinstall's point of view
+#
+# A "device" from legacy sysinstall's point of view (mostly)
+#
+# NB: Disk devices have their `private' property set to GEOM ident
+# NB: USB devices have their `private' property set to USB disk device name
+#
f_struct_define DEVICE \
- name \
+ capacity \
desc \
devname \
- type \
- capacity \
enabled \
- init \
- get \
- shutdown \
flags \
+ get \
+ init \
+ name \
private \
+ shutdown \
+ type \
volume
# Network devices have their `private' property set to this
f_struct_define DEVICE_INFO \
- use_rtsol use_dhcp ipaddr ipv6addr netmask extras
-
-setvar DEVICE_TYPE_NONE 1
-setvar DEVICE_TYPE_DISK 2
-setvar DEVICE_TYPE_FLOPPY 3
-setvar DEVICE_TYPE_FTP 4
-setvar DEVICE_TYPE_NETWORK 5
-setvar DEVICE_TYPE_CDROM 6
-setvar DEVICE_TYPE_USB 7
-setvar DEVICE_TYPE_DOS 8
-setvar DEVICE_TYPE_UFS 9
-setvar DEVICE_TYPE_NFS 10
-setvar DEVICE_TYPE_ANY 11
-setvar DEVICE_TYPE_HTTP_PROXY 12
-setvar DEVICE_TYPE_HTTP 13
+ extras \
+ ipaddr \
+ ipv6addr \
+ netmask \
+ use_dhcp \
+ use_rtsol
+
+#
+# Device types for f_device_register(), f_device_find(), et al.
+#
+setvar DEVICE_TYPE_ANY "any" # Any
+setvar DEVICE_TYPE_NONE "NONE" # Unknown
+setvar DEVICE_TYPE_DISK "DISK" # GEOM `DISK'
+setvar DEVICE_TYPE_FLOPPY "FD" # GEOM `FD'
+setvar DEVICE_TYPE_FTP "FTP" # Dynamic network device
+setvar DEVICE_TYPE_NETWORK "NETWORK" # See f_device_get_all_network
+setvar DEVICE_TYPE_CDROM "CDROM" # GEOM `DISK'
+setvar DEVICE_TYPE_USB "USB" # GEOM `PART'
+setvar DEVICE_TYPE_DOS "DOS" # GEOM `DISK' `PART' or `LABEL'
+setvar DEVICE_TYPE_UFS "UFS" # GEOM `DISK' `PART' or `LABEL'
+setvar DEVICE_TYPE_NFS "NFS" # Dynamic network device
+setvar DEVICE_TYPE_HTTP_PROXY "HTTP_PROXY" # Dynamic network device
+setvar DEVICE_TYPE_HTTP "HTTP" # Dynamic network device
# Network devices have the following flags available
setvar IF_ETHERNET 1
@@ -87,76 +99,70 @@ setvar IF_ACTIVE 4
#
: ${DEVICE_SELF_SCAN_ALL=1}
-############################################################ FUNCTIONS
-
-# f_device_try $name [$i [$var_path]]
#
-# Test a particular device. If $i is given, then $name is expected to contain a
-# single "%d" where $i will be inserted using printf. If $var_path is given,
-# it is used as a variable name to provide the caller the device pathname.
+# Device Catalog variables
#
-# Returns success if the device path exists and is a cdev.
+DEVICE_CATALOG_APPEND_ONLY= # Used by f_device_catalog_set()
+NCATALOG_DEVICES=0 # Used by f_device_catalog_*() and MAIN
+
#
-f_device_try()
-{
- local name="$1" i="$2" var_path="$3" unit
- if [ "$i" ]; then
- f_sprintf unit "$name" "$i"
- else
- unit="$name"
- fi
- case "$unit" in
- /dev/*) : good ;; # already qualified
- *) unit="/dev/$unit" ;;
- esac
- [ "$var_path" ] && setvar "$var_path" "$unit"
- f_dprintf "f_device_try: making sure %s is a device node" "$unit"
- if [ -c "$unit" ]; then
- f_dprintf "f_device_try: %s is a cdev [good]" "$unit"
- return $SUCCESS
- else
- f_dprintf "f_device_try: %s is not a cdev [skip]" "$unit"
- return $FAILURE
- fi
-}
+# A ``catalog'' device is for mapping GEOM devices to media devices (for
+# example, determining if a $GEOM_CLASS_DISK geom is $DEVICE_TYPE_CDROM or
+# $DEVICE_TYPE_DISK) and also getting default descriptions for devices that
+# either lack a GEOM provided description or lack a presence in GEOM)
+#
+f_struct_define CATALOG_DEVICE \
+ desc \
+ name \
+ type
+
+############################################################ FUNCTIONS
-# f_device_register $name $desc $devname $type $enabled $init_function \
-# $get_function $shutdown_function $private $capacity
+# f_device_register $var_to_set $name $desc $devname $type $enabled
+# $init_function $get_function $shutdown_function
+# $private $capacity
#
-# Register a device. A `structure' (see struct.subr) is created with the name
-# device_$name (so make sure $name contains only alpha-numeric characters or
-# the underscore, `_'). The remaining arguments after $name correspond to the
-# properties of the `DEVICE' structure-type (defined above).
+# Register a device. A `structure' (see struct.subr) is created and if
+# $var_to_set is non-NULL, upon success holds the name of the struct created.
+# The remaining positional arguments correspond to the properties of the
+# `DEVICE' structure-type to be assigned (defined above).
#
-# If not already registered, the device is then appended to the DEVICES
-# environment variable, a space-separated list of all registered devices.
+# If not already registered (based on $name and $type), a new device is created
+# and $NDEVICES is incremented.
#
f_device_register()
{
- local name="$1" desc="$2" devname="$3" type="$4" enabled="$5"
- local init_func="$6" get_func="$7" shutdown_func="$8" private="$9"
- local capacity="${10}"
-
- f_struct_new DEVICE "device_$name" || return $FAILURE
- device_$name set name "$name"
- device_$name set desc "$desc"
- device_$name set devname "$devname"
- device_$name set type "$type"
- device_$name set enabled "$enabled"
- device_$name set init "$init_func"
- device_$name set get "$get_func"
- device_$name set shutdown "$shutdown_func"
- device_$name set private "$private"
- device_$name set capacity "$capacity"
-
- # Scan our global register to see if it needs ammending
- local dev found=
- for dev in $DEVICES; do
- [ "$dev" = "$name" ] || continue
- found=1 && break
- done
- [ "$found" ] || DEVICES="$DEVICES $name"
+ local __var_to_set="$1" __name="$2" __desc="$3" __devname="$4"
+ local __type="$5" __enabled="$6" __init_func="$7" __get_func="$8"
+ local __shutdown_func="$9" __private="${10}" __capacity="${11}"
+
+ # Required parameter(s)
+ [ "$__name" ] || return $FAILURE
+ if [ "$__var_to_set" ]; then
+ setvar "$__var_to_set" "" || return $FAILURE
+ fi
+ local __device
+ if f_device_find -1 "$__name" "$__type" __device; then
+ f_struct_free "$__device"
+ f_struct_new DEVICE "$__device" || return $FAILURE
+ else
+ __device=device_$(( NDEVICES + 1 ))
+ f_struct_new DEVICE "$__device" || return $FAILURE
+ NDEVICES=$(( $NDEVICES + 1 ))
+ fi
+ $__device set name "$__name"
+ $__device set desc "$__desc"
+ $__device set devname "$__devname"
+ $__device set type "$__type"
+ $__device set enabled "$__enabled"
+ $__device set init "$__init_func"
+ $__device set get "$__get_func"
+ $__device set shutdown "$__shutdown_func"
+ $__device set private "$__private"
+ $__device set capacity "$__capacity"
+
+ [ "$__var_to_set" ] && setvar "$__var_to_set" "$__device"
return $SUCCESS
}
@@ -166,18 +172,21 @@ f_device_register()
#
f_device_reset()
{
- local dev
- for dev in $DEVICES; do
- f_device_shutdown $dev
+ local n=1
+ while [ $n -le $NDEVICES ]; do
+ f_device_shutdown device_$n
+ #
# XXX This potentially leaks $dev->private if it's being
# used to point to something dynamic, but you're not supposed
# to call this routine at such times that some open instance
# has its private member pointing somewhere anyway.
#
- f_struct_free device_$dev
+ f_struct_free device_$n
+
+ n=$(( $n + 1 ))
done
- DEVICES=
+ NDEVICES=0
}
# f_device_reset_network
@@ -186,34 +195,45 @@ f_device_reset()
#
f_device_reset_network()
{
- local dev type private pruned_list=
- for dev in $DEVICES; do
- device_$dev get type type
- if [ "$type" != "$DEVICE_TYPE_NETWORK" ]; then
- pruned_list="$pruned_list $dev"
- continue
- fi
+ local n=1 device type private i
+ while [ $n -le $NDEVICES ]; do
+ device=device_$n
+ f_struct $device || continue
+ $device get type type
+ [ "$type" = "$DEVICE_TYPE_NETWORK" ] || continue
#
# Leave the device up (don't call shutdown routine)
#
# Network devices may have DEVICE_INFO private member
- device_$dev get private private
+ $device get private private
[ "$private" ] && f_struct_free "$private"
- f_struct_free device_$dev
+ # Free the network device
+ f_struct_free $device
+
+ # Fill the gap we just created
+ i=$n
+ while [ $i -lt $NDEVICES ]; do
+ f_struct_copy device_$(( $i + 1 )) device_$i
+ done
+ f_struct_free device_$NDEVICES
+
+ # Finally decrement the number of devices
+ NDEVICES=$(( $NDEVICES - 1 ))
+
+ n=$(( $n + 1 ))
done
- DEVICES="${pruned_list# }"
}
# f_device_get_all
#
-# Get all device information for devices we have attached.
+# Get all device information for all devices.
#
f_device_get_all()
{
- local devname desc capacity
+ local devname type desc capacity
f_dprintf "f_device_get_all: Probing devices..."
f_dialog_info "$msg_probing_devices_please_wait_this_can_take_a_while"
@@ -221,180 +241,16 @@ f_device_get_all()
# First go for the network interfaces
f_device_get_all_network
- # Next, try to find all the types of devices one might use
- # as a media source for content
- #
-
- local dev type max n=0
- for dev in $DEVICE_NAMES; do
- n=$(( $n + 1 ))
- # Get the desc, type, and max (with debugging disabled)
- # NOTE: Bypassing f_device_name_get() for efficiency
- # ASIDE: This would be equivalent to the following:
- # debug= f_device_name_get $dev desc
- # debug= f_device_name_get $dev type
- # debug= f_device_name_get $dev max
- debug= f_getvar _device_desc$n desc
- debug= f_getvar _device_type$n type
- debug= f_getvar _device_max$n max
-
- local k=0
- while [ $k -lt ${max:-0} ]; do
- i=$k k=$(( $k + 1 ))
- devname=""
- case "$type" in
- $DEVICE_TYPE_CDROM)
- f_device_try "$dev" "$i" devname || continue
- f_device_capacity "$devname" capacity
- f_device_register "${devname##*/}" "$desc" \
- "$devname" $DEVICE_TYPE_CDROM 1 \
- f_media_init_cdrom f_media_get_cdrom \
- f_media_shutdown_cdrom "" "$capacity"
- f_dprintf "Found a CDROM device for %s" \
- "$devname"
- ;;
- $DEVICE_TYPE_FLOPPY)
- f_device_try "$dev" "$i" devname || continue
- f_device_capacity "$devname" capacity
- f_device_register "${devname##*/}" "$desc" \
- "$devname" $DEVICE_TYPE_FLOPPY 1 \
- f_media_init_floppy \
- f_media_get_floppy \
- f_media_shutdown_floppy "" "$capacity"
- f_dprintf "Found a floppy device for %s" \
- "$devname"
- ;;
- $DEVICE_TYPE_USB)
- f_device_try "$dev" "$i" devname || continue
- f_device_capacity "$devname" capacity
- f_device_register "${devname##*/}" "$desc" \
- "$devname" $DEVICE_TYPE_USB 1 \
- f_media_init_usb f_media_get_usb \
- f_media_shutdown_usb "" "$capacity"
- f_dprintf "Found a USB disk for %s" "$devname"
- ;;
- esac
- done
- done
-
- # Register ISO9660 providers as CDROM devices
- for devname in /dev/iso9660/*; do
- f_device_try "$devname" || continue
- f_device_capacity "$devname" capacity
- f_device_register "${devname##*/}" "ISO9660 file system" \
- "$devname" $DEVICE_TYPE_CDROM 1 \
- f_media_init_cdrom f_media_get_cdrom \
- f_media_shutdown_cdrom "" "$capacity"
- f_dprintf "Found a CDROM device for %s" "$devname"
- done
-
- # Scan for mdconfig(8)-created md(4) devices
- local filename
- for devname in /dev/md[0-9] /dev/md[0-9][0-9]; do
- f_device_try "$devname" || continue
-
- # See if the md(4) device is a vnode type backed by a file
- filename=$( sysctl kern.geom.conftxt |
- awk -v devname="${devname##*/}" \
- '
- ( $2 == "MD" ) && \
- ( $3 == devname ) && \
- ( $(NF-2) == "vnode" ) && \
- ( $(NF-1) == "file" ) \
- {
- print $NF
- }
- ' )
- case "$filename" in
- *.iso) # Register the device as an ISO9660 provider
- f_device_capacity "$devname" capacity
- f_device_register "${devname##*/}" \
- "md(4) vnode file system" \
- "$devname" $DEVICE_TYPE_CDROM 1 \
- f_media_init_cdrom f_media_get_cdrom \
- f_media_shutdown_cdrom "" "$capacity"
- f_dprintf "Found a CDROM device for %s" "$devname"
- ;;
- esac
- done
-
- # Finally go get the disks and look for partitions to register
- local diskname slices index type rest slice part
- for diskname in $( sysctl -n kern.disks ); do
-
- case "$diskname" in
- cd*)
- # XXX Due to unknown reasons, kern.disks returns SCSI
- # CDROM as a valid disk. This will prevent bsdconfig
- # from presenting SCSI CDROMs as available disks in
- # various menus. Why GEOM treats SCSI CDROM as a disk
- # is beyond me and that should be investigated.
- # For temporary workaround, ignore SCSI CDROM device.
- #
- continue ;;
- esac
-
- # Try to create a list of partitions and their types,
- # consisting of "N,typeN ..." (e.g., "1,0xa5 2,0x06").
- if ! slices=$( fdisk -p "$diskname" 2> /dev/null |
- awk '( $1 == "p" ) { print $2","$3 }' )
- then
- f_dprintf "Unable to open disk %s" "$diskname"
- continue
+ # Next, go for the GEOM devices we might want to use as media
+ local geom geoms geom_name
+ debug= f_geom_find "" $GEOM_CLASS_DEV geoms
+ for geom in $geoms; do
+ if ! f_device_probe_geom $geom; then
+ debug= $geom get name geom_name
+ f_dprintf "WARNING! Unable to classify %s as %s" \
+ "GEOM device $geom_name" "media source"
fi
-
- # Try and find its description
- f_device_desc "$diskname" $DEVICE_TYPE_DISK desc
-
- f_device_capacity "$diskname" capacity
- f_device_register "$diskname" "$desc" \
- "/dev/$diskname" $DEVICE_TYPE_DISK 0 \
- "" "" "" "" "$capacity"
- f_dprintf "Found a disk device named %s" "$diskname"
-
- # Look for existing partitions to register
- for slice in $slices; do
- index="${slice%%,*}" type="${slice#*,}"
- slice=${diskname}s$index
- case "$type" in
- 0x01|0x04|0x06|0x0b|0x0c|0x0e|0xef)
- # DOS partitions to add as "DOS media devices"
- f_device_capacity "/dev/$slice" capacity
- f_device_register "$slice" "" \
- "/dev/$slice" $DEVICE_TYPE_DOS 1 \
- f_media_init_dos f_media_get_dos \
- f_media_shutdown_dos "" "$capacity"
- f_dprintf "Found a DOS partition %s" "$slice"
- ;;
- 0xa5) # FreeBSD partition
- for part in $(
- bsdlabel -r $slice 2> /dev/null |
- awk -v slice="$slice" '
- ( $1 ~ /[abdefgh]:/ ) {
- printf "%s%s\n",
- slice,
- substr($1,1,1)
- }'
- ); do
- f_quietly dumpfs -m /dev/$part ||
- continue
- f_device_capacity \
- "$/dev/$part" capacity
- f_device_register \
- "$part" "" "/dev/$part" \
- $DEVICE_TYPE_UFS 1 \
- f_media_init_ufs \
- f_media_get_ufs \
- f_media_shutdown_ufs "" \
- "$capacity"
- f_dprintf "Found a UFS partition %s" \
- "$part"
- done # parts
- ;;
- esac
- done # slices
-
- done # disks
+ done
}
# f_device_get_all_network
@@ -403,7 +259,7 @@ f_device_get_all()
#
f_device_get_all_network()
{
- local devname desc flags
+ local devname desc device flags
for devname in $( ifconfig -l ); do
# Eliminate network devices that don't make sense
case "$devname" in
@@ -413,9 +269,9 @@ f_device_get_all_network()
# Try and find its description
f_device_desc "$devname" $DEVICE_TYPE_NETWORK desc
- f_dprintf "Found a network device named %s" "$devname"
- f_device_register $devname \
- "$desc" "$devname" $DEVICE_TYPE_NETWORK 1 \
+ f_dprintf "Found network device named %s" "$devname"
+ debug= f_device_register device $devname "$desc" \
+ "$devname" $DEVICE_TYPE_NETWORK 1 \
f_media_init_network "" f_media_shutdown_network "" -1
# Set flags based on media and status
@@ -435,37 +291,532 @@ f_device_get_all_network()
if (value ~ /^active/) _or(var, "IF_ACTIVE")
}
}' )"
- device_$devname set flags $flags
+ $device set flags $flags
done
}
-# f_device_name_get $type $name type|desc|max [$var_to_set]
+# f_device_rescan
+#
+# Rescan all devices, after closing previous set - convenience function.
+#
+f_device_rescan()
+{
+ f_device_reset
+ f_geom_rescan
+ f_device_get_all
+}
+
+# f_device_rescan_network
+#
+# Rescan all network devices, after closing previous set - for convenience.
+#
+f_device_rescan_network()
+{
+ f_device_reset_network
+ f_device_get_all_network
+}
+
+# f_device_probe_geom $geom
+#
+# Probe a single GEOM device and if it can be classified as a media source,
+# register it using f_device_register() with known type-specific arguments.
+#
+f_device_probe_geom()
+{
+ local geom="$1"
+
+ f_struct "$geom" || return $FAILURE
+
+ # geom associated variables
+ local geom_name geom_consumer provider_ref geom_provider=
+ local provider_geom provider_config provider_class=
+ local provider_config_type catalog_struct catalog_type
+ local disk_ident
+
+ # gnop(8)/geli(8) associated variables (p for `parent device')
+ local p_devname p_geom p_consumer p_provider_ref p_provider
+ local p_provider_config p_provider_geom p_provider_class
+
+ # md(4) associated variables
+ local config config_type config_file magic=
+
+ # Temporarily disable debugging to keep debug output light
+ local old_debug="$debug" debug=
+
+ #
+ # Get the GEOM name (for use below in device registration)
+ #
+ $geom get name devname || continue
+
+ #
+ # Attempt to get the consumer, provider, provider config, and
+ # provider class for this geom (errors ignored).
+ #
+ # NB: Each GEOM in the `DEV' class should have one consumer.
+ # That consumer should have a reference to its provider.
+ #
+ $geom get consumer1 geom_consumer
+ f_struct "$geom_consumer" get provider_ref provider_ref &&
+ f_geom_find_by id "$provider_ref" provider geom_provider
+ if f_struct "$geom_provider"; then
+ $geom_provider get config provider_config
+ f_geom_parent $geom_provider provider_geom &&
+ f_geom_parent $provider_geom provider_class
+ fi
+
+ #
+ # Get values for device registration (errors ignored)
+ #
+ f_struct "$provider_class" get name type
+ f_struct "$geom_provider" get mediasize capacity
+ f_struct "$provider_config" get descr desc
+
+ #
+ # For gnop(8), geli(8), or combination thereof, change device type to
+ # that of the consumer
+ #
+ p_devname= p_geom= p_provider= p_provider_config=
+ case "$devname" in
+ *.nop.eli) p_devname="${devname%.nop.eli}" ;;
+ *.eli.nop) p_devname="${devname%.eli.nop}" ;;
+ *.eli) p_devname="${devname%.eli}" ;;
+ *.nop) p_devname="${devname%.nop}" ;;
+ esac
+ [ "$p_devname" ] && f_geom_find "$p_devname" $GEOM_CLASS_DEV p_geom
+ if [ "${p_geom:-$geom}" != "$geom" ]; then
+ f_struct "$p_geom" get consumer1 p_consumer
+ f_struct "$p_consumer" get provider_ref p_provider_ref &&
+ f_geom_find_by id "$p_provider_ref" provider p_provider
+ if f_struct "$p_provider"; then
+ $p_provider get config p_provider_config
+ f_geom_parent $p_provider p_provider_geom &&
+ f_geom_parent $p_provider_geom p_provider_class
+ fi
+ f_struct "$p_provider_class" get name type
+ fi
+
+ # Look up geom device in device catalog for default description
+ f_device_catalog_get \
+ $DEVICE_TYPE_ANY "${p_devname:-$devname}" catalog_struct
+ [ "$desc" ] || f_struct "catalog_device_$catalog_struct" get desc desc
+
+ # Use device catalog entry for potential re-classification(s)
+ f_struct "catalog_device_$catalog_struct" get type catalog_type
+
+ # Restore debugging for this next part (device registration)
+ debug="$old_debug"
+
+ #
+ # Register the device
+ #
+ local retval device
+ case "$type" in
+ $GEOM_CLASS_DISK)
+ # First attempt to classify by device catalog (see MAIN)
+ case "$catalog_type" in
+ $DEVICE_TYPE_CDROM)
+ f_dprintf "Found CDROM device for disk %s" "$devname"
+ debug= f_device_register device "$devname" "$desc" \
+ "/dev/$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom "" "$capacity" &&
+ return $SUCCESS
+ ;;
+ esac
+
+ # Fall back to register label device as a disk and taste it
+ f_dprintf "Found disk device named %s" "$devname"
+ debug= f_struct "$p_provider_config" get \
+ ident disk_ident ||
+ debug= f_struct "$provider_config" get \
+ ident disk_ident
+ debug= f_device_register device "$devname" "$desc" \
+ "/dev/$devname" $DEVICE_TYPE_DISK 1 \
+ "" "" "" "$disk_ident" "$capacity"
+ retval=$?
+
+ # Detect ``dangerously dedicated'' filesystems (errors ignored)
+ f_device_probe_disk_fs device "$devname" "$capacity" &&
+ retval=$SUCCESS
+
+ return $retval
+ ;;
+ $GEOM_CLASS_FD)
+ f_dprintf "Found floppy device named %s" "$devname"
+ debug= f_device_register device "$devname" "$desc" \
+ "/dev/$devname" $DEVICE_TYPE_FLOPPY 1 \
+ f_media_init_floppy f_media_get_floppy \
+ f_media_shutdown_floppy "" "$capacity"
+ return $?
+ ;;
+ $GEOM_CLASS_LABEL)
+ : fall through to below section # reduces indentation level
+ ;;
+ $GEOM_CLASS_MD)
+ f_dprintf "Found disk device named %s" "$devname"
+ debug= f_device_register device "$devname" "$desc" \
+ "/dev/$devname" $DEVICE_TYPE_DISK 1 \
+ "" "" "" "" "$capacity"
+ retval=$?
+
+ #
+ # Attempt to get file(1) magic to potentially classify as
+ # alternate media type. If unable to get magic, fall back to
+ # md(4) characteristics (such as vnode filename).
+ #
+ [ -r "/dev/$devname" ] &&
+ magic=$( file -bs "/dev/$devname" 2> /dev/null )
+ if [ ! "$magic" ]; then
+ # Fall back to md(4) characteristics
+ if f_struct "$p_provider_config"; then
+ config="$p_provider_config"
+ else
+ config="$provider_config"
+ fi
+ debug= f_struct "$config" get type config_type
+ debug= f_struct "$config" get file config_file
+
+ # Substitute magic for below based on type and file
+ case "$config_type=$config_file" in
+ vnode=*.iso) magic="ISO 9660" ;;
+ esac
+ fi
+ f_device_probe_disk_fs device \
+ "$devname" "$capacity" "$magic" &&
+ retval=$SUCCESS # Errors ignored
+
+ return $retval
+ ;;
+ $GEOM_CLASS_PART)
+ if f_struct "$p_provider_config"; then
+ config="$p_provider_config"
+ else
+ config="$provider_config"
+ fi
+ debug= f_struct "$config" get type provider_config_type
+ f_device_probe_geom_part device \
+ "$provider_config_type" "$devname" "$capacity"
+ retval=$?
+ device_type=$DEVICE_TYPE_NONE
+ [ $retval -eq $SUCCESS ] &&
+ debug= f_struct "$device" get type device_type
+
+ # Potentially re-classify as USB device
+ if [ "$device_type" = "$DEVICE_TYPE_UFS" -a \
+ "$catalog_type" = "$DEVICE_TYPE_USB" ]
+ then
+ f_dprintf "Found USB device for partition %s" \
+ "$devname"
+ debug= f_struct "$p_provider_geom" get \
+ name disk_name ||
+ debug= f_struct "$provider_geom" get \
+ name disk_name
+ debug= f_device_register device "$devname" "$desc" \
+ "/dev/$devname" $DEVICE_TYPE_USB 1 \
+ f_media_init_usb f_media_get_usb \
+ f_media_shutdown_usb "$disk_name" "$capacity"
+ retval=$?
+ fi
+
+ return $retval
+ ;;
+ $GEOM_CLASS_RAID)
+ # Use the provider geom name as the description
+ if [ ! "$desc" ]; then
+ f_struct "$p_provider_geom" get name desc ||
+ f_struct "$provider_geom" get name desc
+ fi
+
+ f_dprintf "Found disk device named %s" "$devname"
+ debug= f_device_register device \
+ "$devname" "${desc:-GEOM RAID device}" \
+ "/dev/$devname" $DEVICE_TYPE_DISK 1 \
+ "" "" "" "" "$capacity"
+ retval=$?
+
+ # Detect ``dangerously dedicated'' filesystems
+ f_device_probe_disk_fs device "$devname" "$capacity" &&
+ retval=$SUCCESS # Errors ignored
+
+ return $retval
+ ;;
+ $GEOM_CLASS_ZFS_ZVOL)
+ f_dprintf "Found disk device named %s" "$devname"
+ debug= f_device_register device \
+ "$devname" "${desc:-GEOM ZFS::ZVOL device}" \
+ "/dev/$devname" $DEVICE_TYPE_DISK 1 \
+ "" "" "" "" "$capacity"
+ retval=$?
+
+ # Detect ``dangerously dedicated'' filesystems
+ f_device_probe_disk_fs device "$devname" "$capacity" &&
+ retval=$SUCCESS # Errors ignored
+
+ return $retval
+ ;;
+ *)
+ return $FAILURE # Unknown GEOM class
+ esac
+
+ #
+ # Still here? Must be $GEOM_CLASS_LABEL
+ #
+
+ local label_geom label_devname label_devgeom= label_devconsumer
+ local label_devprovider= label_devprovider_ref label_devprovider_config
+ local label_gpart_type
+
+ if f_struct "$p_provider"; then
+ label_geom="$p_provider_geom"
+ else
+ label_geom="$provider_geom"
+ fi
+
+ case "$devname" in
+ gpt/*|gptid/*)
+ #
+ # Attempt to get the partition type by getting the `config'
+ # member of the provider for our device (which is named in the
+ # parent geom of our current provider).
+ #
+ debug= f_struct "$label_geom" get name label_devname &&
+ debug= f_geom_find "$label_devname" $GEOM_CLASS_DEV \
+ label_devgeom
+ debug= f_struct "$label_devgeom" get \
+ consumer1 label_devconsumer
+ debug= f_struct "$label_devconsumer" get \
+ provider_ref label_devprovider_ref &&
+ debug= f_geom_find_by id "$label_devprovider_ref" \
+ provider label_devprovider
+ debug= f_struct "$label_devprovider" get \
+ config label_devprovider_config
+ debug= f_struct "$label_devprovider_config" get \
+ type label_gpart_type
+
+ #
+ # Register device label based on partition type
+ #
+ f_device_probe_geom_part device \
+ "$label_gpart_type" "$devname" "$capacity"
+ return $?
+ ;;
+ iso9660/*)
+ f_dprintf "Found CDROM device labeled %s" "$devname"
+ debug= f_device_register device \
+ "$devname" "ISO9660 file system" \
+ "/dev/$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom "" "$capacity"
+ return $?
+ ;;
+ label/*)
+ # For generic labels, use provider geom name as real device
+ debug= f_struct "$label_geom" get name label_devname
+
+ # Look up label geom device in device catalog for default desc
+ debug= f_device_catalog_get \
+ $DEVICE_TYPE_ANY "$label_devname" catalog_struct
+ [ "$desc" ] || debug= f_struct \
+ "catalog_device_$catalog_struct" get desc desc
+
+ # Use device catalog entry for potential re-classification(s)
+ debug= f_struct "catalog_device_$catalog_struct" get \
+ type catalog_type
+
+ # First attempt to classify by device catalog (see MAIN)
+ case "$catalog_type" in
+ $DEVICE_TYPE_CDROM)
+ f_dprintf "Found CDROM device for disk %s" "$devname"
+ debug= f_device_register device "$devname" "$desc" \
+ "/dev/$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom "" "$capacity" &&
+ return $SUCCESS
+ ;;
+ esac
+
+ # Fall back to register label device as a disk and taste it
+ f_dprintf "Found disk device labeled %s" "$devname"
+ debug= f_device_register device \
+ "$devname" "GEOM LABEL device" \
+ "/dev/$devname" $DEVICE_TYPE_DISK 1 \
+ "" "" "" "" "$capacity"
+ retval=$?
+
+ # Detect ``dangerously dedicated'' filesystems (errors ignored)
+ f_device_probe_disk_fs device "$devname" "$capacity" &&
+ retval=$SUCCESS
+
+ return $retval
+ ;;
+ msdosfs/*)
+ f_dprintf "Found DOS partition labeled %s" "$devname"
+ debug= f_device_register device "$devname" "DOS file system" \
+ "/dev/$devname" $DEVICE_TYPE_DOS 1 \
+ f_media_init_dos f_media_get_dos \
+ f_media_shutdown_dos "" "$capacity"
+ return $?
+ ;;
+ ufs/*|ufsid/*)
+ f_dprintf "Found UFS partition labeled %s" "$devname"
+ debug= f_device_register device "$devname" "UFS file system" \
+ "/dev/$devname" $DEVICE_TYPE_UFS 1 \
+ f_media_init_ufs f_media_get_ufs \
+ f_media_shutdown_ufs "" "$capacity"
+ return $?
+ ;;
+ ext2fs/*|ntfs/*|reiserfs/*)
+ return $FAILURE # No media device handlers for these labels
+ ;;
+ esac
+
+ # Unable to classify GEOM label
+ return $FAILURE
+}
+
+# f_device_probe_geom_part $var_to_set $gpart_type $devname $capacity [$magic]
+#
+# Given a gpart(8) partition type and a device name, register the device if it
+# is a known partition type that we can handle. If $var_to_set is non-NULL,
+# upon success holds the DEVICE struct name of the registered device.
+#
+# Returns success if the device was successfully registered, failure otherwise.
+#
+f_device_probe_geom_part()
+{
+ local __var_to_set="$1" __gpart_type="$2" __devname="$3"
+ local __capacity="${4:--1}" __magic="$5"
+
+ #
+ # Register device based on partition type
+ # NB: !0 equates to `unused' bsdlabel
+ #
+ case "$__gpart_type" in
+ fat16|fat32)
+ f_dprintf "Found DOS partition named %s" "$__devname"
+ debug= f_device_register "$__var_to_set" \
+ "$__devname" "DOS file system" \
+ "/dev/$__devname" $DEVICE_TYPE_DOS 1 \
+ f_media_init_dos f_media_get_dos \
+ f_media_shutdown_dos "" "$__capacity"
+ return $?
+ ;;
+ freebsd|!0) # Commonly used inappropriately, taste for FreeBSD
+ [ -r "/dev/$__devname" -a ! "$__magic" ] &&
+ __magic=$( file -bs "/dev/$__devname" 2> /dev/null )
+ case "$__magic" in
+ *"Unix Fast File system"*)
+ f_dprintf "Found UFS partition named %s" "$__devname"
+ debug= f_device_register "$__var_to_set" \
+ "$__devname" "UFS file system" \
+ "/dev/$__devname" $DEVICE_TYPE_UFS 1 \
+ f_media_init_ufs f_media_get_ufs \
+ f_media_shutdown_ufs "" "$__capacity"
+ return $?
+ esac
+ return $FAILURE
+ ;;
+ freebsd-ufs)
+ f_dprintf "Found UFS partition named %s" "$__devname"
+ debug= f_device_register "$__var_to_set" \
+ "$__devname" "UFS file system" \
+ "/dev/$__devname" $DEVICE_TYPE_UFS 1 \
+ f_media_init_ufs f_media_get_ufs \
+ f_media_shutdown_ufs "" "$__capacity"
+ return $?
+ ;;
+ apple-*|linux-*|ms-*|netbsd-*|ntfs|vmware-*)
+ return $FAILURE # No device types for these
+ ;;
+ bios-*|ebr|efi|mbr|freebsd-boot|freebsd-swap)
+ return $FAILURE # Not a source for media
+ ;;
+ freebsd-nandfs|freebsd-vinum|freebsd-zfs)
+ return $FAILURE # Unsupported as media source
+ ;;
+ esac
+
+ return $FAILURE # Unknown partition type
+}
+
+# f_device_probe_disk_fs $var_to_set $devname [$capacity [$magic]]
+#
+# Given a device name, taste it and register the device if it is a so-called
+# ``dangerously dedicated'' file system written without a partition table.
+# Tasting is done using file(1) (specifically `file -bs') but if $magic is
+# present and non-NULL it is used instead. If $var_to_set is non-NULL, upon
+# success holds the DEVICE struct name of the registered device.
#
-# Fetch the device type (type), description (desc), or maximum number of
-# devices to scan for (max) associated with device $name and $type. If $type is
-# either NULL, missing, or set to $DEVICE_TYPE_ANY then only $name is used.
+# Returns success if the device was successfully registered, failure otherwise.
+#
+f_device_probe_disk_fs()
+{
+ local __var_to_set="$1" __devname="$2" __capacity="${3:--1}"
+ local __magic="$4"
+
+ [ -r "/dev/${__devname#/dev/}" -a ! "$__magic" ] &&
+ __magic=$( file -bs "/dev/$__devname" 2> /dev/null )
+
+ case "$__magic" in
+ *"ISO 9660"*)
+ f_dprintf "Found CDROM device for disk %s" "$__devname"
+ debug= f_device_register "$__var_to_set" \
+ "$__devname" "ISO9660 file system" \
+ "/dev/$__devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom "" "$__capacity"
+ return $?
+ ;;
+ *"Unix Fast File system"*)
+ f_dprintf "Found UFS device for disk %s" "$__devname"
+ debug= f_device_register "$__var_to_set" \
+ "$__devname" "UFS file system" \
+ "/dev/$__devname" $DEVICE_TYPE_UFS 1 \
+ f_media_init_ufs f_media_get_ufs \
+ f_media_shutdown_ufs "" "$__capacity"
+ return $?
+ ;;
+ *"FAT (12 bit)"*|*"FAT (16 bit)"*|*"FAT (32 bit)"*)
+ f_dprintf "Found DOS device for disk %s" "$__devname"
+ debug= f_device_register "$__var_to_set" \
+ "$__devname" "DOS file system" \
+ "/dev/$__devname" $DEVICE_TYPE_DOS 1 \
+ f_media_init_dos f_media_get_dos \
+ f_media_shutdown_dos "" "$__capacity"
+ return $?
+ ;;
+ esac
+
+ return $FAILURE # Unknown file system type
+}
+
+# f_device_catalog_get $type $name [$var_to_set]
+#
+# Fetch the struct name of the catalog device matching device $name. If $type
+# is either NULL, missing, or set to $DEVICE_TYPE_ANY then only $name is used.
# Returns success if a match was found, otherwise failure.
#
-# If $var_to_set is missing or NULL, the device name is printed to standard out
+# If $var_to_set is missing or NULL, the struct name is printed to standard out
# for capturing in a sub-shell (which is less-recommended because of
# performance degredation; for example, when called in a loop).
#
-f_device_name_get()
+f_device_catalog_get()
{
- local __type="$1" __name="$2" __prop="$3" __var_to_set="$4"
- local __dev __devtype __n=0
+ local __type="$1" __name="$2" __var_to_set="$3"
+ local __dname=
- # Return failure if no $name or $prop is an unknown property
+ # Return failure if no $name
[ "$__name" ] || return $FAILURE
- case "$__prop" in type|desc|max) : good ;;
- *) return $FAILURE; esac
+
+ # Disable debugging to keep debug output light
+ local debug=
#
# Attempt to create an alternate-form of $__name that contains the
# first contiguous string of numbers replaced with `%d' for comparison
# against stored pattern names (see MAIN).
#
- local __left="${__name%%[0-9]*}" __right="${__name#*[0-9]}" __dname=
+ local __left="${__name%%[0-9]*}" __right="${__name#*[0-9]}"
if [ "$__left" != "$__name" ]; then
# Chop leading digits from right 'til we hit first non-digit
while :; do
@@ -478,45 +829,58 @@ f_device_name_get()
fi
[ "$__type" = "$DEVICE_TYPE_ANY" ] && __type=
- for __dev in $DEVICE_NAMES; do
- __n=$(( $__n + 1 ))
- [ "$__dev" = "$__name" -o "$__dev" = "$__dname" ] || continue
- f_getvar _device_type$__n __devtype
- [ "${__type:-$__devtype}" = "$__devtype" ] || continue
- f_getvar _device_$__prop$__n $__var_to_set
+ local __dev __dev_name __dev_type
+ for __dev in $DEVICE_CATALOG; do
+ catalog_device_$__dev get name __dev_name
+ [ "$__dev_name" = "$__name" -o "$__dev_name" = "$__dname" ] ||
+ continue
+ catalog_device_$__dev get type __dev_type
+ [ "${__type:-$__dev_type}" = "$__dev_type" ] || continue
+ if [ "$__var_to_set" ]; then
+ setvar "$__var_to_set" $__dev
+ else
+ echo $__dev
+ fi
return $?
done
+
+ [ "$__var_to_set" ] && setvar "$__var_to_set" ""
return $FAILURE
}
-# f_device_name_set $type $name $desc [$max]
+# f_device_catalog_set $type $name $desc
#
-# Store a description (desc) and [optionally] maximum number of devices to scan
-# for (max) in-association with device $type and $name. Returns success unless
-# $name is NULL or missing. Use the f_device_name_get() routine with the same
-# $name and optionally $type to retrieve one of type, desc, or max properties.
+# Store a description (desc) in-association with device $type and $name.
+# Returns success unless $name is NULL or missing. Use f_device_catalog_get()
+# routine with the same $name and optionally $type to retrieve catalog device
+# structure (see CATALOG_DEVICE struct definition in GLOBALS section).
#
-f_device_name_set()
+f_device_catalog_set()
{
- local type="$1" name="$2" desc="$3" max="$4"
- local dev devtype n=0 found=
+ local type="$1" name="$2" desc="$3"
+ local struct dev dev_type found=
+
[ "$name" ] || return $FAILURE
- for dev in $DEVICE_NAMES; do
- n=$(( $n + 1 ))
- [ "$dev" = "$name" ] || continue
- if f_getvar _device_type$n devtype; then
- # Allow multiple entries with same name but diff type
- [ "$devtype" = "$type" ] || continue
- fi
- found=1 && break
- done
- if [ ! "$found" ]; then
- DEVICE_NAMES="$DEVICE_NAMES $name"
- n=$(( $n + 1 ))
+
+ # Disable debugging to keep debug output light
+ local debug=
+
+ f_str2varname "$name" struct
+ if [ ! "$DEVICE_CATALOG_APPEND_ONLY" ]; then
+ for dev in $DEVICE_CATALOG; do
+ [ "$dev" = "$struct" ] || continue
+ found=1 break
+ done
fi
- setvar _device_type$n "$type"
- setvar _device_desc$n "$desc"
- [ "${4+set}" ] && setvar _device_max$n "$max"
+ if [ "$found" ]; then
+ f_struct_free "catalog_device_$struct"
+ else
+ DEVICE_CATALOG="$DEVICE_CATALOG $struct"
+ fi
+ f_struct_new CATALOG_DEVICE "catalog_device_$struct" || return $FAILURE
+ catalog_device_$struct set type "$type"
+ catalog_device_$struct set name "$name"
+ catalog_device_$struct set desc "$desc"
return $SUCCESS
}
@@ -540,8 +904,8 @@ f_device_desc()
[ "$__var_to_set" ] && { setvar "$__var_to_set" "" || return; }
#
- # Return sysctl MIB dev.NAME.UNIT.%desc if it exists,
- # otherwise fall through to below static list.
+ # Return sysctl MIB dev.NAME.UNIT.%desc if it exists, otherwise fall
+ # through to further alternate methods.
#
if f_have sysctl; then
__devname="${__name%%[0-9]*}"
@@ -561,54 +925,11 @@ f_device_desc()
fi
fi
- #
- # For disks, attempt to return camcontrol(8) descriptions.
- # Otherwise fall through to below static list.
- #
- f_have camcontrol &&
- [ "${__type:-$DEVICE_TYPE_DISK}" = "$DEVICE_TYPE_DISK" ] &&
- __cp=$( camcontrol devlist 2> /dev/null | awk -v disk="$__name" '
- $0~"(\\(|,)"disk"(,|\\))" {
- if (!match($0, "<[^>]+>")) next
- print substr($0, RSTART+1, RLENGTH-2)
- found = 1
- exit
- }
- END { exit ! found }
- ' ) && setvar "$__var_to_set" "$__cp" && return $SUCCESS
-
- #
- # Attempt to create an alternate-form of $__name that contains the
- # first contiguous string of numbers replaced with `%d' for comparison
- # against stored pattern names (see MAIN).
- #
- local __left="${__name%%[0-9]*}" __right="${__name#*[0-9]}" __dname=
- if [ "$__left" != "$__name" ]; then
- # Chop leading digits from right 'til we hit first non-digit
- while :; do
- case "$__right" in
- [0-9]*) __right="${__right#[0-9]}" ;;
- *) break
- esac
- done
- __dname="${__left}%d$__right"
- fi
-
- local __dev __devtype __n=0
- for __dev in $DEVICE_NAMES; do
- __n=$(( $__n + 1 ))
- debug= f_getvar _device_type$__n __devtype
- [ "${__type:-$__devtype}" = "$__devtype" ] || continue
- if [ "$__devtype" = "$DEVICE_TYPE_NETWORK" ]; then
- __devname=$( f_substr "$__name" 0 ${#__dev} )
- [ "$__devname" = "$__dev" ] || continue
- else
- [ "$__dev" = "$__name" -o "$__dev" = "$__dname" ] ||
- continue
- fi
- debug= f_getvar _device_desc$__n $__var_to_set
- return $?
- done
+ # Look up device in catalog for default description
+ local __catalog_struct
+ debug= f_device_catalog_get "$__type" "$__name" __catalog_struct
+ debug= f_struct "catalog_device_$__catalog_struct" get \
+ desc "$__var_to_set" && return $SUCCESS
#
# Sensible fall-backs for specific types
@@ -617,7 +938,7 @@ f_device_desc()
$DEVICE_TYPE_CDROM) __cp="<unknown cdrom device type>" ;;
$DEVICE_TYPE_DISK) __cp="<unknown disk device type>" ;;
$DEVICE_TYPE_FLOPPY) __cp="<unknown floppy device type>" ;;
- $DEVICE_TYPE_USB) __cp="<unknown usb storage device type>" ;;
+ $DEVICE_TYPE_USB) __cp="<unknown USB storage device type>" ;;
$DEVICE_TYPE_NETWORK) __cp="<unknown network interface type>" ;;
*)
__cp="<unknown device type>"
@@ -642,14 +963,14 @@ f_device_is_ethernet()
local dev="$1" type flags
# Make sure we have an actual device by that name
- f_struct "device_$dev" || return $FAILURE
+ f_struct "$dev" || return $FAILURE
# Make sure that the device is a network device
- device_$dev get type type
+ $dev get type type
[ "$type" = "$DEVICE_TYPE_NETWORK" ] || return $FAILURE
# Make sure that the media flags indicate that it is Ethernet
- device_$dev get flags flags
+ $dev get flags flags
[ $(( ${flags:-0} & $IF_ETHERNET )) -eq $IF_ETHERNET ]
}
@@ -663,14 +984,14 @@ f_device_is_wireless()
local dev="$1" type flags
# Make sure we have an actual device by that name
- f_struct "device_$dev" || return $FAILURE
+ f_struct "$dev" || return $FAILURE
# Make sure that the device is a network device
- device_$dev get type type
+ $dev get type type
[ "$type" = "$DEVICE_TYPE_NETWORK" ] || return $FAILURE
- # Make sure that the media flags indicate that it is Ethernet
- device_$dev get flags flags
+ # Make sure that the media flags indicate that it is 802.11 wireless
+ $dev get flags flags
[ $(( ${flags:-0} & $IF_WIRELESS )) -eq $IF_WIRELESS ]
}
@@ -684,13 +1005,13 @@ f_device_is_active()
local dev="$1" type flags=0
# Make sure we have an actual device by that name
- f_struct "device_$dev" || return $FAILURE
+ f_struct "$dev" || return $FAILURE
- device_$dev get type type
+ $dev get type type
case "$type" in
$DEVICE_TYPE_NETWORK)
# Make sure that the media flags indicate that it is active
- device_$dev get flags flags
+ $dev get flags flags
[ $(( ${flags:-0} & $IF_ACTIVE )) -eq $IF_ACTIVE ]
;;
*)
@@ -698,49 +1019,42 @@ f_device_is_active()
esac
}
-# f_device_rescan
-#
-# Rescan all devices, after closing previous set - convenience function.
-#
-f_device_rescan()
-{
- f_device_reset
- f_device_get_all
-}
-
-# f_device_rescan_network
-#
-# Rescan all network devices, after closing previous set - for convenience.
-#
-f_device_rescan_network()
-{
- f_device_reset_network
- f_device_get_all_network
-}
-
-# f_device_find $name [$type [$var_to_set]]
+# f_device_find [-1] $name [$type [$var_to_set]]
#
# Find one or more registered devices by name, type, or both. Returns a space-
# separated list of devices matching the search criterion.
#
+# If `-1' option flag is given, only the first matching device is returned.
+#
# If $var_to_set is missing or NULL, the device name(s) are printed to standard
# out for capturing in a sub-shell (which is less-recommended because of
# performance degredation; for example, when called in a loop).
#
f_device_find()
{
+ local OPTIND OPTARG flag only_one=
+ while getopts 1 flag; do
+ case "$flag" in
+ 1) only_one=1 ;;
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+
local __name="$1" __type="${2:-$DEVICE_TYPE_ANY}" __var_to_set="$3"
- local __dev __devname __devtype __found=
- for __dev in $DEVICES; do
- device_$__dev get name __devname
- device_$__dev get type __devtype
+ local __n=1 __devname __devtype __found=
+ while [ $__n -le $NDEVICES ]; do
+ device_$__n get name __devname
+ device_$__n get type __devtype
if [ "$__name" = "$__devname" -o ! "$__name" ] &&
[ "$__type" = "$DEVICE_TYPE_ANY" -o \
"$__type" = "$__devtype" ]
then
- __found="$__found $__dev"
+ __found="$__found device_$__n"
+ [ "$only_one" ] && break
fi
+ __n=$(( $__n + 1 ))
done
+
if [ "$__var_to_set" ]; then
setvar "$__var_to_set" "${__found# }"
else
@@ -749,38 +1063,100 @@ f_device_find()
[ "$__found" ] # Return status
}
-# f_device_init $name
+# f_device_init $device
#
-# Initialize a device by evaluating its `init' function.
+# Initialize a device by evaluating its `init' function. The $device argument
+# is a DEVICE struct name.
#
f_device_init()
{
- local name="$1" init_func
- device_$name get init init_func || return $?
- ${init_func:-:} $name
+ local device="$1" init_func
+ f_struct "$device" || return $?
+ $device get init init_func
+ ${init_func:-:} "$device"
}
-# f_device_get $name $file [$probe]
+# f_device_get $device $file [$probe]
#
# Read $file by evaluating the device's `get' function. The file is commonly
# produced on standard output (but it truly depends on the function called).
+# The $device argument is a DEVICE struct name.
#
f_device_get()
{
- local name="$1" file="$2" probe="$3" get_func
- device_$name get get get_func || return $?
- ${get_func:-:} $name "$file" ${3+"$probe"}
+ local device="$1" file="$2" probe="$3" get_func
+ f_struct "$device" || return $?
+ $device get get get_func
+ ${get_func:-:} "$device" "$file" ${3+"$probe"}
}
-# f_device_shutdown $name
+# f_device_shutdown $device
#
-# Shutdown a device by evaluating its `shutdown' function.
+# Shutdown a device by evaluating its `shutdown' function. The $device argument
+# is a DEVICE struct name.
#
f_device_shutdown()
{
- local name="$1" shutdown_func
- device_$name get shutdown shutdown_func || return $?
- ${shutdown_func:-:} $name
+ local device="$1" shutdown_func
+ f_struct "$device" || return $?
+ $device get shutdown shutdown_func
+ ${shutdown_func:-:} "$device"
+}
+
+# f_devices_sort_by $property $var_to_get [$var_to_set]
+#
+# Take list of devices from $var_to_get (separated by whitespace, newline
+# included) and sort them by $property (e.g., `name'). The sorted list of
+# DEVICE struct names is returned on standard output separated by whitespace
+# (newline to be specific) unless $var_to_set is present and non-NULL.
+#
+# This function is a two-parter. Below is the awk(1) portion of the function,
+# afterward is the sh(1) function which utilizes the below awk script.
+#
+f_device_sort_by_awk='
+# Variables that should be defined on the invocation line:
+# -v prop="property"
+function asorti(src, dest)
+{
+ for (i in src) dest[++nitems] = i
+ for (i = 1; i <= nitems; k = i++) {
+ idx = dest[i]
+ while ((k > 0) && (dest[k] > idx)) {
+ dest[k+1] = dest[k]; k--
+ }
+ dest[k+1] = idx
+ }
+ return nitems
+}
+{
+ split($0, devs, FS)
+ for (d in devs) {
+ name = ENVIRON["_struct_value_" devs[d] "_" prop]
+ devices[name] = devs[d]
+ }
+}
+END {
+ nitems = asorti(devices, devices_sorted)
+ for (i = 1; i <= nitems; i++) print devices[devices_sorted[i]]
+}
+'
+f_device_sort_by()
+{
+ local __property="${1:-name}" __var_to_get="$2" __var_to_set="$3"
+
+ f_isset "$__var_to_get" || return $FAILURE
+
+ local __dev
+ for __dev in $( f_getvar "$__var_to_get" ); do
+ export _struct_value_${__dev}_$__property
+ done
+
+ local __cp
+ setvar "${__var_to_set:-__cp}" "$(
+ f_getvar "$__var_to_get" |
+ awk -v prop="$__property" "$f_device_sort_by_awk"
+ )"
+ [ "$__var_to_set" ] || echo "$__cp"
}
# f_device_menu $title $prompt $hline $device_type [$helpfile]
@@ -795,20 +1171,20 @@ f_device_menu()
local prompt="$2" hline="$3" type="$4" helpfile="$5"
- local dev devtype devs=
- for dev in $DEVICES; do
- device_$dev get type devtype || continue
- [ "$devtype" = "$type" ] || continue
- devs="$devs $dev"
- done
- [ "$devs" ] || return $DIALOG_CANCEL
+ local devs
+ f_device_find "" "$type" devs || return $DIALOG_CANCEL
- local desc menu_list=
+ local name desc menu_list=
+ f_device_sort_by name devs devs
for dev in $devs; do
- device_$dev get desc desc
+ $dev get name name
+ $dev get desc desc
+ f_shell_escape "$name" name
f_shell_escape "$desc" desc
- menu_list="$menu_list '$dev' '$desc'"
+ menu_list="$menu_list
+ '$name' '$desc'" # END-QUOTE
done
+ menu_list="${menu_list#$NL}"
local height width rows
eval f_dialog_menu_size height width rows \
@@ -827,6 +1203,7 @@ f_device_menu()
mtag=$( eval $DIALOG \
--title \"\$title\" \
--backtitle \"\$btitle\" \
+ --hline \"\$hline\" \
--ok-label \"\$msg_ok\" \
--cancel-label \"\$msg_cancel\" \
${helpfile:+ \
@@ -851,165 +1228,158 @@ f_device_menu()
[ "$errexit" ] && set -e
if [ $retval -eq $DIALOG_OK ]; then
- # Clean up the output of [X]dialog(1) and return it
+ # Clean up the output of [X]dialog(1)
f_dialog_data_sanitize mtag
- echo "$mtag" >&2
+
+ # Map the user's choice back to a struct name
+ local index device
+ index=$( eval f_dialog_menutag2index \"\$mtag\" $menu_list )
+ device=$( set -- $devs; eval echo \${$index} )
+
+ echo "$device" >&2
fi
return $retval
}
-# f_device_capacity $device [$var_to_set]
#
-# Return the capacity of $device in bytes.
+# Short-hand
#
-f_device_capacity()
-{
- local __dev="$1" __var_to_set="$2"
- local __bytes
-
- __bytes=$( diskinfo -v "$__dev" 2> /dev/null |
- awk '/# mediasize in bytes/{print $1}' ) || __bytes=-1
+f_cdrom() { f_device_catalog_set $DEVICE_TYPE_CDROM "$1" "$2"; }
+f_disk() { f_device_catalog_set $DEVICE_TYPE_DISK "$1" "$2"; }
+f_floppy() { f_device_catalog_set $DEVICE_TYPE_FLOPPY "$1" "$2"; }
+f_usb() { f_device_catalog_set $DEVICE_TYPE_USB "$1" "$2"; }
+f_network() { f_device_catalog_set $DEVICE_TYPE_NETWORK "$1" "$2"; }
- if [ "$__var_to_set" ]; then
- setvar "$__var_to_set" "$__bytes"
- else
- echo "$__bytes"
- fi
-}
+############################################################ MAIN
#
-# Short-hand
+# The below classifications allow us to re-group the GEOM devices from the
+# `DEV' GEOM class appropriately while providing fall-back descriptions both
+# for making the below code more maintainable and handling the rare case the
+# GEOM device lacks a description.
#
-f_cdrom() { f_device_name_set $DEVICE_TYPE_CDROM "$1" "$2" "$3"; }
-f_disk() { f_device_name_set $DEVICE_TYPE_DISK "$1" "$2" "$3"; }
-f_floppy() { f_device_name_set $DEVICE_TYPE_FLOPPY "$1" "$2" "$3"; }
-f_serial() { f_device_name_set $DEVICE_TYPE_NETWORK "$1" "$2" "$3"; }
-f_usb() { f_device_name_set $DEVICE_TYPE_USB "$1" "$2" "$3"; }
-f_network() { f_device_name_set $DEVICE_TYPE_NETWORK "$1" "$2"; }
-
-############################################################ MAIN
-# CDROM, Disk, Floppy, Serial, and USB devices/names
-f_cdrom "cd%d" "SCSI CDROM drive" 4
-f_cdrom "mcd%d" "Mitsumi (old model) CDROM drive" 4
-f_cdrom "scd%d" "Sony CDROM drive - CDU31/33A type" 4
-f_disk "aacd%d" "Adaptec FSA RAID array" 4
-f_disk "ada%d" "ATA/SATA disk device" 16
-f_disk "amrd%d" "AMI MegaRAID drive" 4
-f_disk "da%d" "SCSI disk device" 16
-f_disk "idad%d" "Compaq RAID array" 4
-f_disk "ipsd%d" "IBM ServeRAID RAID array" 4
-f_disk "mfid%d" "LSI MegaRAID SAS array" 4
-f_disk "mlxd%d" "Mylex RAID disk" 4
-f_disk "twed%d" "3ware ATA RAID array" 4
-f_disk "vtbd%d" "VirtIO Block Device" 16
-f_floppy "fd%d" "Floppy Drive unit A" 4
-f_serial "cuau%d" "%s on device %s (COM%d)" 16
-f_usb "da%da" "USB Mass Storage Device" 16
+DEVICE_CATALOG_APPEND_ONLY=1 # Make initial loading faster
+
+# CDROM, Disk, Floppy, and USB devices/names
+f_cdrom "cd%d" "SCSI CDROM drive"
+f_cdrom "mcd%d" "Mitsumi (old model) CDROM drive"
+f_cdrom "scd%d" "Sony CDROM drive - CDU31/33A type"
+f_disk "aacd%d" "Adaptec FSA RAID array"
+f_disk "ada%d" "ATA/SATA disk device"
+f_disk "amrd%d" "AMI MegaRAID drive"
+f_disk "da%d" "SCSI disk device"
+f_disk "idad%d" "Compaq RAID array"
+f_disk "ipsd%d" "IBM ServeRAID RAID array"
+f_disk "md%d" "md(4) disk device"
+f_disk "mfid%d" "LSI MegaRAID SAS array"
+f_disk "mlxd%d" "Mylex RAID disk"
+f_disk "twed%d" "3ware ATA RAID array"
+f_disk "vtbd%d" "VirtIO Block Device"
+f_floppy "fd%d" "Floppy Drive unit A"
+f_usb "da%da" "USB Mass Storage Device"
# Network interfaces/names
-f_network "ae" "Attansic/Atheros L2 Fast Ethernet"
-f_network "age" "Attansic/Atheros L1 Gigabit Ethernet"
-f_network "alc" "Atheros AR8131/AR8132 PCIe Ethernet"
-f_network "ale" "Atheros AR8121/AR8113/AR8114 PCIe Ethernet"
-f_network "an" "Aironet 4500/4800 802.11 wireless adapter"
-f_network "ath" "Atheros IEEE 802.11 wireless adapter"
-f_network "aue" "ADMtek USB Ethernet adapter"
-f_network "axe" "ASIX Electronics USB Ethernet adapter"
-f_network "bce" "Broadcom NetXtreme II Gigabit Ethernet card"
-f_network "bfe" "Broadcom BCM440x PCI Ethernet card"
-f_network "bge" "Broadcom BCM570x PCI Gigabit Ethernet card"
-f_network "bm" "Apple BMAC Built-in Ethernet"
-f_network "bwn" "Broadcom BCM43xx IEEE 802.11 wireless adapter"
-f_network "cas" "Sun Cassini/Cassini+ or NS DP83065 Saturn Ethernet"
-f_network "cc3i" "SDL HSSI sync serial PCI card"
-f_network "cue" "CATC USB Ethernet adapter"
-f_network "cxgb" "Chelsio T3 10Gb Ethernet card"
-f_network "dc" "DEC/Intel 21143 (and clones) PCI Fast Ethernet card"
-f_network "de" "DEC DE435 PCI NIC or other DC21040-AA based card"
-f_network "disc" "Software discard network interface"
-f_network "ed" "Novell NE1000/2000; 3C503; NE2000-compatible PCMCIA"
-f_network "el" "3Com 3C501 Ethernet card"
-f_network "em" "Intel(R) PRO/1000 Ethernet card"
-f_network "en" "Efficient Networks ATM PCI card"
-f_network "ep" "3Com 3C509 Ethernet card/3C589 PCMCIA"
-f_network "et" "Agere ET1310 based PCI Express Gigabit Ethernet card"
-f_network "ex" "Intel EtherExpress Pro/10 Ethernet card"
-f_network "fe" "Fujitsu MB86960A/MB86965A Ethernet card"
-f_network "fpa" "DEC DEFPA PCI FDDI card"
-f_network "fwe" "FireWire Ethernet emulation"
-f_network "fwip" "IP over FireWire"
-f_network "fxp" "Intel EtherExpress Pro/100B PCI Fast Ethernet card"
-f_network "gem" "Apple GMAC or Sun ERI/GEM Ethernet adapter"
-f_network "hme" "Sun HME (Happy Meal Ethernet) Ethernet adapter"
-f_network "ie" "AT&T StarLAN 10 and EN100; 3Com 3C507; NI5210"
-f_network "igb" "Intel(R) PRO/1000 PCI Express Gigabit Ethernet card"
-f_network "ipw" "Intel PRO/Wireless 2100 IEEE 802.11 adapter"
-f_network "iwi" "Intel PRO/Wireless 2200BG/2225BG/2915ABG adapter"
-f_network "iwn" "Intel Wireless WiFi Link 4965AGN IEEE 802.11n adapter"
-f_network "ixgbe" "Intel(R) PRO/10Gb Ethernet card"
-f_network "ixgb" "Intel(R) PRO/10Gb Ethernet card"
-f_network "ix" "Intel Etherexpress Ethernet card"
- # Maintain sequential order of above(3): ixgbe ixgb ix
-f_network "jme" "JMicron JMC250 Gigabit/JMC260 Fast Ethernet"
-f_network "kue" "Kawasaki LSI USB Ethernet adapter"
-f_network "le" "AMD Am7900 LANCE or Am79C9xx PCnet Ethernet adapter"
-f_network "lge" "Level 1 LXT1001 Gigabit Ethernet card"
-f_network "lnc" "Lance/PCnet (Isolan/Novell NE2100/NE32-VL) Ethernet"
-f_network "lo" "Loop-back (local) network interface"
-f_network "lp" "Parallel Port IP (PLIP) peer connection"
-f_network "malo" "Marvell Libertas 88W8335 802.11 wireless adapter"
-f_network "msk" "Marvell/SysKonnect Yukon II Gigabit Ethernet"
-f_network "mxge" "Myricom Myri10GE 10Gb Ethernet card"
-f_network "nfe" "NVIDIA nForce MCP Ethernet"
-f_network "nge" "NatSemi PCI Gigabit Ethernet card"
-f_network "ng" "Vimage netgraph(4) bridged Ethernet device"
- # Maintain sequential order of above(2): nge ng
-f_network "nve" "NVIDIA nForce MCP Ethernet"
-f_network "nxge" "Neterion Xframe 10GbE Server/Storage adapter"
-f_network "pcn" "AMD Am79c79x PCI Ethernet card"
-f_network "plip" "Parallel Port IP (PLIP) peer connection"
-f_network "ral" "Ralink Technology IEEE 802.11 wireless adapter"
-f_network "ray" "Raytheon Raylink 802.11 wireless adapter"
-f_network "re" "RealTek 8139C+/8169/8169S/8110S PCI Ethernet adapter"
-f_network "rl" "RealTek 8129/8139 PCI Ethernet card"
-f_network "rue" "RealTek USB Ethernet card"
-f_network "rum" "Ralink Technology USB IEEE 802.11 wireless adapter"
-f_network "sf" "Adaptec AIC-6915 PCI Ethernet card"
-f_network "sge" "Silicon Integrated Systems SiS190/191 Ethernet"
-f_network "sis" "SiS 900/SiS 7016 PCI Ethernet card"
-f_network "sk" "SysKonnect PCI Gigabit Ethernet card"
-f_network "snc" "SONIC Ethernet card"
-f_network "sn" "SMC/Megahertz Ethernet card"
- # Maintain sequential order of above(2): snc sn
-f_network "sr" "SDL T1/E1 sync serial PCI card"
-f_network "ste" "Sundance ST201 PCI Ethernet card"
-f_network "stge" "Sundance/Tamarack TC9021 Gigabit Ethernet"
-f_network "ti" "Alteon Networks PCI Gigabit Ethernet card"
-f_network "tl" "Texas Instruments ThunderLAN PCI Ethernet card"
-f_network "txp" "3Com 3cR990 Ethernet card"
-f_network "tx" "SMC 9432TX Ethernet card"
- # Maintain sequential order of above(2): txp tx
-f_network "uath" "Atheros AR5005UG and AR5005UX USB wireless adapter"
-f_network "upgt" "Conexant/Intersil PrismGT USB wireless adapter"
-f_network "ural" "Ralink Technology RT2500USB 802.11 wireless adapter"
-f_network "urtw" "Realtek 8187L USB wireless adapter"
-f_network "vge" "VIA VT612x PCI Gigabit Ethernet card"
-f_network "vlan" "IEEE 802.1Q VLAN network interface"
-f_network "vr" "VIA VT3043/VT86C100A Rhine PCI Ethernet card"
-f_network "vx" "3COM 3c590 / 3c595 Ethernet card"
-f_network "wb" "Winbond W89C840F PCI Ethernet card"
-f_network "wi" "Lucent WaveLAN/IEEE 802.11 wireless adapter"
-f_network "wpi" "Intel 3945ABG IEEE 802.11 wireless adapter"
-f_network "wx" "Intel Gigabit Ethernet (82452) card"
-f_network "xe" "Xircom/Intel EtherExpress Pro100/16 Ethernet card"
-f_network "xl" "3COM 3c90x / 3c90xB PCI Ethernet card"
-f_network "zyd" "ZyDAS ZD1211/ZD1211B USB 802.11 wireless adapter"
-
-f_count NDEVICES $DEVICE_NAMES
-f_dprintf "%s: Initialized %u known device names/descriptions." device.subr \
- $NDEVICES
+f_network "ae%d" "Attansic/Atheros L2 Fast Ethernet"
+f_network "age%d" "Attansic/Atheros L1 Gigabit Ethernet"
+f_network "alc%d" "Atheros AR8131/AR8132 PCIe Ethernet"
+f_network "ale%d" "Atheros AR8121/AR8113/AR8114 PCIe Ethernet"
+f_network "an%d" "Aironet 4500/4800 802.11 wireless adapter"
+f_network "ath%d" "Atheros IEEE 802.11 wireless adapter"
+f_network "aue%d" "ADMtek USB Ethernet adapter"
+f_network "axe%d" "ASIX Electronics USB Ethernet adapter"
+f_network "bce%d" "Broadcom NetXtreme II Gigabit Ethernet card"
+f_network "bfe%d" "Broadcom BCM440x PCI Ethernet card"
+f_network "bge%d" "Broadcom BCM570x PCI Gigabit Ethernet card"
+f_network "bm%d" "Apple BMAC Built-in Ethernet"
+f_network "bwn%d" "Broadcom BCM43xx IEEE 802.11 wireless adapter"
+f_network "cas%d" "Sun Cassini/Cassini+ or NS DP83065 Saturn Ethernet"
+f_network "cc3i%d" "SDL HSSI sync serial PCI card"
+f_network "cue%d" "CATC USB Ethernet adapter"
+f_network "cxgb%d" "Chelsio T3 10Gb Ethernet card"
+f_network "dc%d" "DEC/Intel 21143 (and clones) PCI Fast Ethernet card"
+f_network "de%d" "DEC DE435 PCI NIC or other DC21040-AA based card"
+f_network "disc%d" "Software discard network interface"
+f_network "ed%d" "Novell NE1000/2000; 3C503; NE2000-compatible PCMCIA"
+f_network "el%d" "3Com 3C501 Ethernet card"
+f_network "em%d" "Intel(R) PRO/1000 Ethernet card"
+f_network "en%d" "Efficient Networks ATM PCI card"
+f_network "ep%d" "3Com 3C509 Ethernet card/3C589 PCMCIA"
+f_network "et%d" "Agere ET1310 based PCI Express Gigabit Ethernet card"
+f_network "ex%d" "Intel EtherExpress Pro/10 Ethernet card"
+f_network "fe%d" "Fujitsu MB86960A/MB86965A Ethernet card"
+f_network "fpa%d" "DEC DEFPA PCI FDDI card"
+f_network "fwe%d" "FireWire Ethernet emulation"
+f_network "fwip%d" "IP over FireWire"
+f_network "fxp%d" "Intel EtherExpress Pro/100B PCI Fast Ethernet card"
+f_network "gem%d" "Apple GMAC or Sun ERI/GEM Ethernet adapter"
+f_network "hme%d" "Sun HME (Happy Meal Ethernet) Ethernet adapter"
+f_network "ie%d" "AT&T StarLAN 10 and EN100; 3Com 3C507; NI5210"
+f_network "igb%d" "Intel(R) PRO/1000 PCI Express Gigabit Ethernet card"
+f_network "ipw%d" "Intel PRO/Wireless 2100 IEEE 802.11 adapter"
+f_network "iwi%d" "Intel PRO/Wireless 2200BG/2225BG/2915ABG adapter"
+f_network "iwn%d" "Intel Wireless WiFi Link 4965AGN IEEE 802.11n adapter"
+f_network "ix%d" "Intel Etherexpress Ethernet card"
+f_network "ixgb%d" "Intel(R) PRO/10Gb Ethernet card"
+f_network "ixgbe%d" "Intel(R) PRO/10Gb Ethernet card"
+f_network "jme%d" "JMicron JMC250 Gigabit/JMC260 Fast Ethernet"
+f_network "kue%d" "Kawasaki LSI USB Ethernet adapter"
+f_network "le%d" "AMD Am7900 LANCE or Am79C9xx PCnet Ethernet adapter"
+f_network "lge%d" "Level 1 LXT1001 Gigabit Ethernet card"
+f_network "lnc%d" "Lance/PCnet (Isolan/Novell NE2100/NE32-VL) Ethernet"
+f_network "lo%d" "Loop-back (local) network interface"
+f_network "lp%d" "Parallel Port IP (PLIP) peer connection"
+f_network "malo%d" "Marvell Libertas 88W8335 802.11 wireless adapter"
+f_network "msk%d" "Marvell/SysKonnect Yukon II Gigabit Ethernet"
+f_network "mxge%d" "Myricom Myri10GE 10Gb Ethernet card"
+f_network "nfe%d" "NVIDIA nForce MCP Ethernet"
+f_network "ng%d" "Vimage netgraph(4) bridged Ethernet device"
+f_network "nge%d" "NatSemi PCI Gigabit Ethernet card"
+f_network "nve%d" "NVIDIA nForce MCP Ethernet"
+f_network "nxge%d" "Neterion Xframe 10GbE Server/Storage adapter"
+f_network "pcn%d" "AMD Am79c79x PCI Ethernet card"
+f_network "plip%d" "Parallel Port IP (PLIP) peer connection"
+f_network "ral%d" "Ralink Technology IEEE 802.11 wireless adapter"
+f_network "ray%d" "Raytheon Raylink 802.11 wireless adapter"
+f_network "re%d" "RealTek 8139C+/8169/8169S/8110S PCI Ethernet adapter"
+f_network "rl%d" "RealTek 8129/8139 PCI Ethernet card"
+f_network "rue%d" "RealTek USB Ethernet card"
+f_network "rum%d" "Ralink Technology USB IEEE 802.11 wireless adapter"
+f_network "sf%d" "Adaptec AIC-6915 PCI Ethernet card"
+f_network "sge%d" "Silicon Integrated Systems SiS190/191 Ethernet"
+f_network "sis%d" "SiS 900/SiS 7016 PCI Ethernet card"
+f_network "sk%d" "SysKonnect PCI Gigabit Ethernet card"
+f_network "sn%d" "SMC/Megahertz Ethernet card"
+f_network "snc%d" "SONIC Ethernet card"
+f_network "sr%d" "SDL T1/E1 sync serial PCI card"
+f_network "ste%d" "Sundance ST201 PCI Ethernet card"
+f_network "stge%d" "Sundance/Tamarack TC9021 Gigabit Ethernet"
+f_network "ti%d" "Alteon Networks PCI Gigabit Ethernet card"
+f_network "tl%d" "Texas Instruments ThunderLAN PCI Ethernet card"
+f_network "tx%d" "SMC 9432TX Ethernet card"
+f_network "txp%d" "3Com 3cR990 Ethernet card"
+f_network "uath%d" "Atheros AR5005UG and AR5005UX USB wireless adapter"
+f_network "upgt%d" "Conexant/Intersil PrismGT USB wireless adapter"
+f_network "ural%d" "Ralink Technology RT2500USB 802.11 wireless adapter"
+f_network "urtw%d" "Realtek 8187L USB wireless adapter"
+f_network "vge%d" "VIA VT612x PCI Gigabit Ethernet card"
+f_network "vlan%d" "IEEE 802.1Q VLAN network interface"
+f_network "vr%d" "VIA VT3043/VT86C100A Rhine PCI Ethernet card"
+f_network "vx%d" "3COM 3c590 / 3c595 Ethernet card"
+f_network "wb%d" "Winbond W89C840F PCI Ethernet card"
+f_network "wi%d" "Lucent WaveLAN/IEEE 802.11 wireless adapter"
+f_network "wpi%d" "Intel 3945ABG IEEE 802.11 wireless adapter"
+f_network "wx%d" "Intel Gigabit Ethernet (82452) card"
+f_network "xe%d" "Xircom/Intel EtherExpress Pro100/16 Ethernet card"
+f_network "xl%d" "3COM 3c90x / 3c90xB PCI Ethernet card"
+f_network "zyd%d" "ZyDAS ZD1211/ZD1211B USB 802.11 wireless adapter"
+
+DEVICE_CATALOG_APPEND_ONLY= # Additional loading modifies existing devices
+
+f_count NCATALOG_DEVICES $DEVICE_CATALOG
+f_dprintf "%s: Initialized device catalog with %u names/descriptions." \
+ device.subr $NCATALOG_DEVICES
#
# Scan for the above devices unless requeted otherwise
OpenPOWER on IntegriCloud