devfs-enabled kernels and /proc/partitions
Currently, the boot-floppies can't deal with a kernel which has
CONFIG_DEVFS_FS=y, even if CONFIG_DEVFS_MOUNT is not set. I tracked
this down to libfdisk not liking the devfs /proc/partitions.
I started to write a little C function which translated the names,
and this is fairly trivial for IDE. However, it is not so trivial
for SCSI.
So, we could just try to ensure that b-f will never be booted with a
DevFS-enabled kernel, but I think this is a bad idea.
I found a function to do the conversion, but it is written in shell;
popening /bin/sh in the middle of libfdisk seems really gross to
me...does anyone know of a C function somewhere we could snarf? If
not, I guess I can just send a patch to do the former.
For reference, here's the shell function in question:
## convert devfs names into normal short ones, written by Tom Rini.
fixdevfs()
{
## get partition number, if any
local PARTNUM="${1##*[a-z]}"
## Find the bus type.
local TYPE="$(v=${1#/dev/} ; echo ${v%/host*})"
## Find the host number.
local HOST="$(v=${1#/dev/*/host} ; echo ${v%/bus*})"
## Find the bus number.
local BUS="$(v=${1#/dev/*/bus} ; echo ${v%/tar*})"
## Find the target.
local TARGET="$(v=${1#/dev/*/target} ; echo ${v%/lun*})"
case "$TYPE" in
ide)
case "$HOST" in
0)
case "$TARGET" in
0)
local DEV=hda
;;
1)
local DEV=hdb
;;
esac
;;
1)
case "$TARGET" in
0)
local DEV=hdc
;;
1)
local DEV=hdd
;;
esac
;;
*)
echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
return 1
esac
local DEV="${DEV}${PARTNUM}"
echo "/dev/$DEV"
return 0
;;
scsi)
local LUN="$(v=${1#/dev/*/lun} ; echo ${v%/*})"
## In this case, we need to figure out what number our device is
local DEVCOUNT=0
## copy scsi file into a variable removing "Attached Devices"
## which is the first line. this avoids a lot of
## [incmopatible] crap later, and improves readability.
## find number of lines once and recycle that number, to save
## some time (linecount is a bit slow). subtract one line
## to scrap Attached Devices:
local SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
local PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
for i in $(smallseq $(($SCSILINES / 3))) ; do
## put every scsi device into one single line
local DEVINFO="$(echo "$PROCSCSI" | head -n $(($i * 3)) | tail -n 3)"
[ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVINFO=$DEVINFO"
## cut the type field, expect "Direct-Access" later.
local DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})"
[ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVTYPE=$DEVTYPE"
if [ "$DEVTYPE" = "Direct-Access" ] ; then
## Lets find out some more information
## get the device id.
local DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
[ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVID=$DEVID"
## get the device lun.
local DEVLUN="$(v=$(echo ${DEVINFO##*Lun: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
[ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVLUN=$DEVLUN"
## get the device channel.
local DEVCHAN="$(v=$(echo ${DEVINFO##*Channel: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
[ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCHAN=$DEVCHAN"
## get the scsi host id.
local DEVHOST="$(v=$(echo ${DEVINFO##*Host: scsi}) ; echo ${v%% *})"
[ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVHOST=$DEVHOST"
local DEVCOUNT="$(($DEVCOUNT + 1))"
[ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCOUNT=$DEVCOUNT"
if [ "$DEVHOST" = "$HOST" -a "$DEVCHAN" = "$BUS" -a \
"$DEVID" = "$TARGET" -a "$DEVLUN" = "$LUN" ] ; then
local DEV="sd$(smalltr $DEVCOUNT)${PARTNUM}"
echo "/dev/$DEV"
return 0
fi
fi
done
echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
return 1
;;
*)
echo 1>&2 "$PRG: Unknown bus $TYPE"
return 1
;;
esac
## we should never get here
return 1
}
Reply to: