On ���, 2002-02-08 at 17:47, Chmouel Boudjnah wrote:
> Borsenkow Andrej <[EMAIL PROTECTED]> writes:
> 
> > Unfortunately kernel parameters are poorly documented for normal users
> > that Mandrake is targeted at. I already have an idea about using direct
> > echo -n setting:val > /proc/bus/hdXX/settings in our rc.sysinit using
> > definitions from /etc/sysconfig/harddisks if we detect ide-scsi'd drive
> > on devfs (for those settings that appear there). It looks pretty
> > trivial, I probably send patch to Chmouel later this week.
> 
> I got no idea what are you talking about but sent patch and it will
> look good.
> 

The problem - if you have hdd=ide-scsi and mounted devfs, there is no
node created for IDE device (i.e. /dev/ide/.../{cd,disc} or /dev/hdd).
So you cannot use hdparm to tune it. For some old drives you must turn
DMA off to make them work reliably (example is my Philips CDD-3610).

The patch is using direct /proc/ide/hdd/settings interface to set some
parameters. Of course not all of them (that can be defined in
/etc/sysconfig/hardddisk*) are settable in this way. For those that do
not work patch currently displays an error to make you aware about it.

It is trivial to add support for EXTRA_SETTINGS with format
"setting:value ...". It may be useful to set speed on new fast drives
(my 40x is not usable at this speed at all - I have to set it to 20x to
be able to do anything).

If anybody can suggest clean kernel patch that resurrects IDE nodes in
this case - you are welcome. Creating /dev/hdd in user space is not an
option.

While working on this patch I found another problem. hdd is not
available until ide-scsi has been loaded (it is independent of devfs at
all). It is obvious - hdd=ide-scsi makes hdd use ide-scsi driver so
until driver has been loaded no device can be accessed. In our case
ide-scsi is loaded very late; moreover loading it may involve
(auto-)loading of other modules as well, at least scsi_mod. So patch
moves hdparm tuning and ide-scsi loading immediately after module
initialization. This is as near to old location as possible.

It also fixes small output bug in init.d/functions (success and pass).

comments are welcome. Works for me both with and without mounted devfs.
My aim was to be as transparent as possible - /etc/sysconfig/harddisk*
is pretty much well known trick today.

-andrej

--- /etc/rc.d/rc.sysinit.orig	Thu Feb  7 18:55:20 2002
+++ /etc/rc.d/rc.sysinit	Sat Feb  9 18:34:05 2002
@@ -515,53 +515,6 @@
  fi
 fi
 
-# Turn on harddisk optimization
-# There is only one file /etc/sysconfig/harddisks for all disks
-# after installing the hdparm-RPM. If you need different hdparm parameters
-# for each of your disks, copy /etc/sysconfig/harddisks to
-# /etc/sysconfig/harddiskhda (hdb, hdc...) and modify it.
-# each disk witch has no special parameters will use the defaults.
- 
-disk[0]=s; disk[1]=hda; disk[2]=hdb; disk[3]=hdc;
-disk[4]=hdd; disk[5]=hde; disk[6]=hdf; disk[7]=hdg; disk[8]=hdh;
- 
- 
-if [ -x /sbin/hdparm ]; then
-   for device in 0 1 2 3 4 5 6 7 8; do
-   unset MULTIPLE_IO USE_DMA EIDE_32BIT LOOKAHEAD EXTRA_PARAMS
-        if [ -f /etc/sysconfig/harddisk${disk[$device]} ]; then
-                . /etc/sysconfig/harddisk${disk[$device]}
-                HDFLAGS[$device]=
-                if [ -n "$MULTIPLE_IO" ]; then
-                    HDFLAGS[$device]="-q -m$MULTIPLE_IO"
-                fi
-                if [ -n "$USE_DMA" ]; then
-                    HDFLAGS[$device]="${HDFLAGS[$device]} -q -d$USE_DMA"
-                fi
-                if [ -n "$EIDE_32BIT" ]; then
-                    HDFLAGS[$device]="${HDFLAGS[$device]} -q -c$EIDE_32BIT"
-                fi
-                if [ -n "$LOOKAHEAD" ]; then
-                    HDFLAGS[$device]="${HDFLAGS[$device]} -q -A$LOOKAHEAD"
-                fi
-                if [ -n "$EXTRA_PARAMS" ]; then
-                    HDFLAGS[$device]="${HDFLAGS[$device]} $EXTRA_PARAMS"
-                fi
-        else
-                HDFLAGS[$device]="${HDFLAGS[0]}"
-        fi
-        if [ -e "/proc/ide/${disk[$device]}/media" ] ; then
-             hdmedia=`cat /proc/ide/${disk[$device]}/media`
-             if [ "$hdmedia" = "disk" -o "$hdmedia" = "cdrom" ]; then
-                  if [ -n "${HDFLAGS[$device]}" ]; then
-                      action "Setting hard drive parameters for %s: " ${disk[$device]}  /sbin/hdparm ${HDFLAGS[$device]} /dev/${disk[$device]}
-                  fi
-             fi
-        fi
-   done
-fi
-
-
 # The root filesystem is now read-write, so we can now log via syslog() directly..
 if [ -n "$IN_INITLOG" ]; then
     IN_INITLOG=
@@ -617,6 +570,131 @@
 	/etc/rc.d/rc.modules
 fi
 
+# If they asked for ide-scsi, load it
+# This must come before hdparm call because if hdd=ide-scsi
+# /dev/hdd is inaccessible until ide-scsi is loaded
+if grep -q "ide-scsi" /proc/cmdline ; then
+	modprobe ide-cd >/dev/null 2>&1
+	modprobe ide-scsi >/dev/null 2>&1
+fi
+
+# Turn on harddisk optimization
+# There is only one file /etc/sysconfig/harddisks for all disks
+# after installing the hdparm-RPM. If you need different hdparm parameters
+# for each of your disks, copy /etc/sysconfig/harddisks to
+# /etc/sysconfig/harddiskhda (hdb, hdc...) and modify it.
+# each disk witch has no special parameters will use the defaults.
+ 
+get_devfs_name() {
+    declare -i bus target
+    let "bus = (36#${1#hd} - 36#a)/2"
+    let "target = (36#${1#hd} - 36#a)%2"
+    echo "ide/host0/bus$bus/target$target/lun0"
+}
+    
+# directly set IDE parameter via /proc interface
+# 1 = drive name
+# 2 = setting name
+# 3 = name setting value
+set_ide_setting() {
+    [ -e /proc/ide/$1/settings ] || return 1
+    declare device=$1 setting=$2 value=$3
+
+    # map hdparm parameters from harddisk*
+    case $setting in
+	MULTIPLE_IO ) setting=multcount ;;
+	USE_DMA     ) setting=using_dma ;;
+	EIDE_32BIT  ) setting=io_32bit ;;
+	LOOKAHEAD | EXTRA_PARAMS ) return 1 ;;
+    esac
+
+    grep -q -- "^$setting[[:space:]]*" "/proc/ide/$1/settings" || return 1
+    set -- $(grep -- "^$setting[[:space:]]*" "/proc/ide/$device/settings")
+    [ "$5" = rw -o "$5" = w ] || return 1
+    echo -n "$setting:$value" > "/proc/ide/$device/settings"
+    [ "$5" = w ] && return 0
+    set -- $(grep -- "^$setting[[:space:]]*" "/proc/ide/$device/settings")
+    [ "$2" = "$value" ] && return 0
+    return 1
+}
+
+log_set_ide_setting() {
+    gprintf "Setting parameter %s for %s: " "$2" "$1"
+    set_ide_setting "$1" "$2" "$3" && \
+	success "Setting parameter %s for %s: " "$2" "$1" || \
+	failure "Setting parameter %s for %s: " "$2" "$1"
+    echo
+}
+
+typeset -a hds
+[ -n "$(echo /proc/ide/hd* 2> /dev/null)" ] && hds=( $(echo /proc/ide/hd*) )
+[ -n "$hds" ] && hds=( ${hds[*]##*/} )
+[ -z "$hds" ] && hds=(hda hdb hdc hdd hde hdf hdg hdh)
+ 
+ 
+if [ -x /sbin/hdparm ]; then
+    for device in ${hds[*]}; do
+
+	# sanity checks
+        [ -e "/proc/ide/${device}/media" ] || continue
+	hdmedia=`cat /proc/ide/${device}/media`
+	[ "$hdmedia" = "disk" -o "$hdmedia" = "cdrom" ] || continue
+
+	# braindamadge :(
+	[ "$hdmedia" = "disk" ] && hdmedia=disc
+	[ "$hdmedia" = "cdrom" ] && hdmedia=cd
+
+	unset MULTIPLE_IO USE_DMA EIDE_32BIT LOOKAHEAD EXTRA_PARAMS
+        if [ -f /etc/sysconfig/harddisk${device} ]; then
+                . /etc/sysconfig/harddisk${device}
+	elif [ -f /etc/sysconfig/harddisks ]; then
+                . /etc/sysconfig/harddisks
+        fi
+
+	# if running without devfs pass everything directly to hdparm
+	# if running with devfs check for ide-scsi'd drives
+	# and try to still apply settings where possible
+	realdevice=
+	devfsdevice=$(get_devfs_name "$device")
+	[ -c /dev/.devfsd ] || realdevice=$device
+	[ -z "$realdevice" -a -b "/dev/$devfsdevice/$hdmedia" ] && realdevice=$devfsdevice/$hdmedia
+	if [ -z "$realdevice" ]; then
+	    if grep -q -- "$device=ide-scsi" /proc/cmdline; then
+		[ -n "$MULTIPLE_IO" ] && \
+		    log_set_ide_setting "$device" MULTIPLE_IO "$MULTIPLE_IO"
+		[ -n "$USE_DMA" ] && \
+		    log_set_ide_setting "$device" USE_DMA "$USE_DMA"
+		[ -n "$EIDE_32BIT" ] && \
+		    log_set_ide_setting "$device" EIDE_32BIT "$EIDE_32BIT"
+		[ -n "$LOOKAHEAD" ] && \
+		    log_set_ide_setting "$device" LOOKAHEAD "$EIDE_32BIT"
+		[ -n "$EXTRA_PARAMS" ] && \
+		    log_set_ide_setting "$device" EXTRA_PARAMS "$EIDE_32BIT"
+	    fi
+	else
+	    HDFLAGS=
+	    if [ -n "$MULTIPLE_IO" ]; then
+		HDFLAGS="-q -m$MULTIPLE_IO"
+	    fi
+	    if [ -n "$USE_DMA" ]; then
+		HDFLAGS="${HDFLAGS} -q -d$USE_DMA"
+	    fi
+	    if [ -n "$EIDE_32BIT" ]; then
+		HDFLAGS="${HDFLAGS} -q -c$EIDE_32BIT"
+	    fi
+	    if [ -n "$LOOKAHEAD" ]; then
+		HDFLAGS="${HDFLAGS} -q -A$LOOKAHEAD"
+	    fi
+	    if [ -n "$EXTRA_PARAMS" ]; then
+		HDFLAGS="${HDFLAGS} $EXTRA_PARAMS"
+	    fi
+	    if [ -n "${HDFLAGS}" ]; then
+		action "Setting hard drive parameters for %s: " ${device}  /sbin/hdparm ${HDFLAGS} /dev/${realdevice}
+	    fi
+        fi
+   done
+fi
+
 # Add raid devices
 if [ ! -f /proc/mdstat ]; then
 	modprobe md >/dev/null 2>&1
@@ -999,12 +1077,6 @@
 			insmod -p st >/dev/null 2>&1 && modprobe st >/dev/null 2>&1
 		fi
 	fi
-fi
-
-# If they asked for ide-scsi, load it
-if grep -q "ide-scsi" /proc/cmdline ; then
-	modprobe ide-cd >/dev/null 2>&1
-	modprobe ide-scsi >/dev/null 2>&1
 fi
 
 # Adjust symlinks as necessary in /boot to keep system services from
--- /etc/rc.d/init.d/functions.orig	Thu Feb  7 18:55:20 2002
+++ /etc/rc.d/init.d/functions	Sat Feb  9 17:33:23 2002
@@ -437,7 +437,7 @@
   else
      # silly hack to avoid EPIPE killing rc.sysinit
      trap "" SIGPIPE
-     echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 1" >&21
+     echo "$INITLOG_ARGS -n $0 -s \"$GPRINTF_MSG\" -e 1" >&21
      trap - SIGPIPE
   fi
   [ "$BOOTUP" != "verbose" ] && echo_success
@@ -467,7 +467,7 @@
      initlog $INITLOG_ARGS -n $0 -s "$GPRINTF_MSG" -e 1
   else
      trap "" SIGPIPE
-     echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 1" >&21
+     echo "$INITLOG_ARGS -n $0 -s \"$GPRINTF_MSG\" -e 1" >&21
      trap - SIGPIPE
   fi
   [ "$BOOTUP" != "verbose" ] && echo_passed

Reply via email to