aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Nottingham <notting@redhat.com>2004-08-26 08:10:20 +0000
committerBill Nottingham <notting@redhat.com>2004-08-26 08:10:20 +0000
commit255335de9b1ad76cef878078e8965a45fc5db273 (patch)
tree9695d3d90c4e3d76b2de5b72ae6c756bdd0c0a4c
parent19a8799235360e8839c0da1da755197e24f949c8 (diff)
downloadinitscripts-255335de9b1ad76cef878078e8965a45fc5db273.tar
initscripts-255335de9b1ad76cef878078e8965a45fc5db273.tar.gz
initscripts-255335de9b1ad76cef878078e8965a45fc5db273.tar.bz2
initscripts-255335de9b1ad76cef878078e8965a45fc5db273.tar.xz
initscripts-255335de9b1ad76cef878078e8965a45fc5db273.zip
autoloading of hardware at boot time
-rwxr-xr-xrc.d/rc.sysinit179
-rw-r--r--src/Makefile6
-rw-r--r--src/kmodule.c119
3 files changed, 215 insertions, 89 deletions
diff --git a/rc.d/rc.sysinit b/rc.d/rc.sysinit
index 09a9d0ac..e2b670f1 100755
--- a/rc.d/rc.sysinit
+++ b/rc.d/rc.sysinit
@@ -26,13 +26,7 @@ fi
mount -n -t proc /proc /proc
mount -n -t sysfs /sys /sys >/dev/null 2>&1
-if [ -f /etc/udev/udev.conf ];then
- . /etc/udev/udev.conf
-fi
-
-if [ "$USE_UDEV" = "yes" -a "$UDEV_RAMFS" = "yes" ]; then
- [ -x /sbin/start_udev ] && /sbin/start_udev
-fi
+. /etc/init.d/functions
# Check SELinux status
selinuxfs=`awk '/ selinuxfs / { print $2 }' /proc/mounts`
@@ -72,7 +66,6 @@ relabel_selinux() {
}
-. /etc/init.d/functions
if [ "$HOSTTYPE" != "s390" -a "$HOSTTYPE" != "s390x" ]; then
last=0
@@ -125,6 +118,96 @@ if [ -n "$LOGLEVEL" ]; then
/bin/dmesg -n $LOGLEVEL
fi
+if [ -f /etc/udev/udev.conf ];then
+ . /etc/udev/udev.conf
+fi
+
+if [ "$USE_UDEV" = "yes" -a "$UDEV_RAMFS" = "yes" ]; then
+ [ -x /sbin/start_udev ] && /sbin/start_udev
+fi
+
+# Initialize hardware
+if [ -f /proc/sys/kernel/modprobe ]; then
+ if ! strstr cmdline nomodules && [ -f /proc/modules ] ; then
+ sysctl -w kernel.modprobe="/sbin/modprobe" >/dev/null 2>&1
+ sysctl -w kernel.hotplug="/sbin/hotplug" >/dev/null 2>&1
+ else
+ # We used to set this to NULL, but that causes 'failed to exec' messages"
+ sysctl -w kernel.modprobe="/bin/true" >/dev/null 2>&1
+ sysctl -w kernel.hotplug="/bin/true" >/dev/null 2>&1
+ fi
+fi
+
+echo -n $"Initializing hardware... "
+
+ide=""
+scsi=""
+network=""
+audio=""
+other=""
+eval `kmodule | while read devtype mod ; do
+ case "$devtype" in
+ "IDE") ide="$ide $mod"
+ echo "ide=\"$ide"\";;
+ "SCSI") scsi="$scsi $mod"
+ echo "scsi=\"$scsi"\";;
+ "NETWORK") network="$network $mod"
+ echo "network=\"$network"\";;
+ "AUDIO") audio="$audio $mod"
+ echo "audio=\"$audio"\";;
+ *) other="$other $mod"
+ echo "other=\"$other"\";;
+ esac
+done`
+
+# IDE
+for module in $ide ; do
+ modprobe $module >/dev/null 2>&1
+done
+
+# SCSI
+for module in `/sbin/modprobe -c | awk '/^alias[[:space:]]+scsi_hostadapter[[:space:]]/ { print $3 }'` $scsi; do
+ modprobe $module >/dev/null 2>&1
+done
+modprobe floppy >/dev/null 2>&1
+
+echo -n $" storage"
+
+# Network
+pushd /etc/sysconfig/network-scripts >/dev/null 2>&1
+interfaces=`ls ifcfg* | LANG=C egrep -v '(ifcfg-lo|:|rpmsave|rpmorig|rpmnew)' | \
+ LANG=C egrep -v '(~|\.bak)$' | \
+ LANG=C egrep 'ifcfg-[A-Za-z0-9\._-]+$' | \
+ sed 's/^ifcfg-//g' |
+ sed 's/[0-9]/ &/' | LANG=C sort -k 1,1 -k 2n | sed 's/ //'`
+
+for i in $interfaces ; do
+ eval $(LANG=C fgrep "DEVICE=" ifcfg-$i)
+ modprobe $DEVICE >/dev/null 2>&1
+done
+popd >/dev/null 2>&1
+
+for module in $network ; do
+ modprobe $module >/dev/null 2>&1
+done
+
+echo -n $" network"
+
+# Sound
+for module in `/sbin/modprobe -c | awk '/^alias[[:space:]]+snd-card-[[:digit:]]+[[:space:]]/ { print $3 }'` $audio; do
+ modprobe $module >/dev/null 2>&1
+done
+
+echo -n $" audio"
+
+# Everything else (duck and cover)
+for module in $other ; do
+ modprobe $module >/dev/null 2>&1
+done
+
+echo -n $" done"
+success
+echo
# Start the graphical boot, if necessary; /usr may not be mounted yet, so we
# may have to do this again after mounting
@@ -219,30 +302,6 @@ if [ -d /proc/acpi ]; then
done
fi
-# Initialize USB controller and HID devices
-update_boot_stage RCusb
-usb=0
-if ! strstr "$cmdline" nousb && ! strstr "$cmdline" nomodules ; then
- aliases=`/sbin/modprobe -c | awk '/^alias[[:space:]]+usb-controller/ { print $3 }'`
- if [ -n "$aliases" -a "$aliases" != "off" ]; then
- modprobe usbcore >/dev/null 2>&1
- for alias in $aliases ; do
- [ "$alias" = "off" ] && continue
- action $"Initializing USB controller ($alias): " modprobe $alias
- done
- [ $? -eq 0 -a -n "$aliases" ] && usb=1
- fi
-fi
-
-if [ $usb -eq 1 -a ! -f /proc/bus/usb/devices ]; then
- action $"Mounting USB filesystem: " mount -t usbdevfs usbdevfs /proc/bus/usb
-fi
-
-needusbstorage=
-if [ $usb -eq "1" ]; then
- needusbstorage=`LC_ALL=C grep -e "^I.*Cls=08" /proc/bus/usb/devices 2>/dev/null`
-fi
-
if [ -f /fastboot ] || strstr "$cmdline" fastboot ; then
fastboot=yes
fi
@@ -465,34 +524,6 @@ if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then
USEMODULES=y
fi
-# tweak isapnp settings if needed.
-if [ -n "$PNP" -a -f /proc/isapnp -a -x /sbin/sndconfig ]; then
- /sbin/sndconfig --mungepnp >/dev/null 2>&1
-fi
-
-# Load sound modules if and only if they need persistent DMA buffers
-if LC_ALL=C grep -q "options[[:space:]]\+sound[[:space:]].*dmabuf=1" /etc/modules.conf 2>/dev/null ; then
- alias=`/sbin/modprobe -c | awk '/^alias[[:space:]]+sound[[:space:]]/ { print $3 }'`
- if [ -n "$alias" -a "$alias" != "off" ]; then
- action $"Loading sound module ($alias): " modprobe sound
- fi
- alias=`/sbin/modprobe -c | awk '/^alias[[:space:]]+sound-slot-0[[:space:]]/ { print $3 }'`
- if [ -n "$alias" -a "$alias" != "off" ]; then
- action $"Loading sound module ($alias): " modprobe sound-slot-0
- fi
-fi
-
-if [ -f /proc/sys/kernel/modprobe ]; then
- if [ -n "$USEMODULES" ]; then
- sysctl -w kernel.modprobe="/sbin/modprobe" >/dev/null 2>&1
- sysctl -w kernel.hotplug="/sbin/hotplug" >/dev/null 2>&1
- else
- # We used to set this to NULL, but that causes 'failed to exec' messages"
- sysctl -w kernel.modprobe="/bin/true" >/dev/null 2>&1
- sysctl -w kernel.hotplug="/bin/true" >/dev/null 2>&1
- fi
-fi
-
# Load modules (for backward compatibility with VARs)
if [ -f /etc/rc.modules ]; then
/etc/rc.modules
@@ -783,34 +814,6 @@ if [ -f /etc/rc.serial ]; then
. /etc/rc.serial
fi
-# If a SCSI tape has been detected, load the st module unconditionally
-# since many SCSI tapes don't deal well with st being loaded and unloaded
-if [ -f /proc/scsi/scsi -a -n "$USEMODULES" ]; then
- if LC_ALL=C fgrep -q 'Type: Sequential-Access' /proc/scsi/scsi 2>/dev/null ; then
- if LC_ALL=C fgrep -qv ' 9 st' /proc/devices ; then
- modprobe st >/dev/null 2>&1
- fi
- fi
-fi
-
-# Load usb storage here, to match most other things
-if [ -n "$needusbstorage" ]; then
- modprobe usb-storage >/dev/null 2>&1
-fi
-
-# Ooh, firewire too.
-if ! strstr "$cmdline" nofirewire && ! strstr "$cmdline" nomodules ; then
- aliases=`/sbin/modprobe -c | awk '/^alias[[:space:]]+ieee1394-controller/ { print $3 }'`
- if [ -n "$aliases" -a "$aliases" != "off" ]; then
- for alias in $aliases ; do
- [ "$alias" = "off" ] && continue
- action $"Initializing firewire controller ($alias): " modprobe $alias
- done
- LC_ALL=C fgrep -q "SBP2" /proc/bus/ieee1394/devices 2>/dev/null && \
- modprobe sbp2 >/dev/null 2>&1
- fi
-fi
-
# If they asked for ide-scsi, load it
if strstr "$cmdline" ide-scsi ; then
modprobe ide-cd >/dev/null 2>&1
diff --git a/src/Makefile b/src/Makefile
index fc67203c..ba2378cd 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,7 @@
CFLAGS+=$(RPM_OPT_FLAGS) -Wall -D_GNU_SOURCE
PROGS=usernetctl doexec netreport testd usleep ipcalc initlog minilogd \
- getkey ppp-watch consoletype genhostid
+ getkey ppp-watch consoletype genhostid kmodule
PPPWATCH_OBJS=ppp-watch.o shvar.o
INITLOG_OBJS=initlog.o process.o
USLEEP_OBJS=usleep.o
@@ -16,6 +16,7 @@ clean:
install:
mkdir -p $(ROOT)/bin $(ROOT)/usr/sbin $(ROOT)$(mandir)/man{1,8} $(ROOT)/etc
install -m 755 doexec $(ROOT)/bin/doexec
+ install -m 755 kmodule $(ROOT)/sbin/kmodule
install -m 755 usleep $(ROOT)/bin/usleep
install -m 4755 usernetctl $(ROOT)/usr/sbin/usernetctl
install -m 2755 netreport $(ROOT)/sbin/netreport
@@ -69,3 +70,6 @@ shvar.o: shvar.c
ppp-watch.o: ppp-watch.c
$(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c ppp-watch.c -o ppp-watch.o
+
+kmodule: kmodule.o
+ $(CC) $(LDFLAGS) -o $@ $< -Wl,-Bstatic -lpopt -Wl,-Bdynamic -lkudzu -lpci
diff --git a/src/kmodule.c b/src/kmodule.c
new file mode 100644
index 00000000..b08b9557
--- /dev/null
+++ b/src/kmodule.c
@@ -0,0 +1,119 @@
+/* Copyright 2004 Red Hat, Inc.
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <ctype.h>
+#include <ftw.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <newt.h>
+#include <popt.h>
+
+#include <sys/utsname.h>
+
+#include <kudzu/kudzu.h>
+
+
+/* HACK. This is so not thread-safe. */
+static char mod_name[100], cmod_name[100];
+
+static int isModule(const char *filename, const struct stat *sb, int flag) {
+ char *fname = basename(filename);
+ if ((!strcmp(fname,mod_name) || !strcmp(fname,cmod_name))) {
+ return 1;
+ }
+ return 0;
+}
+
+
+int isAvailable(char *modulename)
+{
+ struct utsname utsbuf;
+ char path[512];
+
+ uname(&utsbuf);
+ snprintf(mod_name,100,"%s.ko",modulename);
+ snprintf(cmod_name,100,"%s.ko.gz",modulename);
+ snprintf(path,512,"/lib/modules/%s/kernel",utsbuf.release);
+ /* Do not set the third argument of this function to < 6. Blarg. */
+ if (ftw(path,isModule,15) == 1) {
+ return 1;
+ }
+ return 0;
+}
+
+
+int main(int argc, char **argv)
+{
+ char *bus = NULL, *class = NULL;
+ int x, rc;
+ enum deviceBus probeBus = BUS_UNSPEC;
+ enum deviceClass probeClass = CLASS_UNSPEC;
+ poptContext context;
+ struct device **devs;
+ struct poptOption options[] = {
+ POPT_AUTOHELP
+ { "bus", 'b', POPT_ARG_STRING, &bus, 0,
+ "probe only the specified 'bus'",
+ NULL
+ },
+ { "class", 'c', POPT_ARG_STRING, &class, 0,
+ "probe only for the specified 'class'",
+ NULL
+ },
+ { 0, 0, 0, 0, 0, 0 }
+ };
+
+ context = poptGetContext("kmodule", argc, (const char **)argv, options, 0);
+ while ((rc = poptGetNextOpt(context)) > 0) {
+ }
+ if (( rc < -1)) {
+ fprintf(stderr, "%s: %s\n",
+ poptBadOption(context, POPT_BADOPTION_NOALIAS),
+ poptStrerror(rc));
+ exit(-1);
+ }
+
+ if (bus) {
+ for (x=0; bus[x]; x++)
+ bus[x] = toupper(bus[x]);
+ for (x=0; buses[x].string && strcmp(buses[x].string,bus); x++);
+ if (buses[x].string)
+ probeBus = buses[x].busType;
+ }
+ if (class) {
+ for (x=0; class[x]; x++)
+ class[x] = toupper(class[x]);
+ for (x=0; classes[x].string && strcmp(classes[x].string,class); x++);
+ if (classes[x].string)
+ probeClass = classes[x].classType;
+ }
+ initializeBusDeviceList(probeBus);
+
+ devs = probeDevices(probeClass, probeBus, PROBE_NOLOAD);
+ if (!devs)
+ return 0;
+ for (x = 0; devs[x]; x++) {
+ if (devs[x]->driver && isAvailable(devs[x]->driver)) {
+ int i;
+
+ for (i = 0; classes[i].classType; i++)
+ if (devs[x]->type == classes[i].classType) {
+ break;
+ }
+ printf("%s %s\n",classes[i].string,devs[x]->driver);
+ }
+ }
+ return 0;
+}