]> git.pld-linux.org Git - projects/geninitrd.git/blobdiff - functions
Timeout here is not a good idea. rootfs cannot be mounted and kernel oopses due to...
[projects/geninitrd.git] / functions
index 4671c0699e23a5a4364262f650ad515e38384a58..9015cc3c7107f27567a73e53247539a2e456a765 100644 (file)
--- a/functions
+++ b/functions
@@ -2,45 +2,30 @@
 #
 # geninitrd functions
 
-# Find root device from fstab.
-#
-# @param       string  $fstab location of /etc/fstab
+# Get device name from UUID/LABEL
+# @param       string  device path or UUID/LABEL name
 # @return      false on failure
-# 
-# Sets global variables:
-# - $rootdev
-# - $rootdev_add
-# - $rootFS
 #
-find_root() {
-       local fstab="$1"
-       local function="${PROGRAM:+$PROGRAM: }find_root"
-       local rootopt
-
-       eval $(awk '!/^[\t ]*#/ && $2 == "/" {printf("rootdev=\"%s\"\nrootFs=\"%s\"\nrootopt=\"%s\"\n", $1, $3, $4)}' $fstab)
-       if [ -z "$rootdev" ]; then
-               echo >&2 "$function: can't find fstab entry for root mountpoint"
-               return 1
-       fi
-
-       # additional devices needed (xfs logdev)
-       rootdev_add=$(echo "$rootopt" | awk -F',' '{ for (i=1; i<=NF; i++) { if ($i ~ /^logdev=/) { gsub(/^logdev=/, NIL, $i); print $i; } } }')
+find_devname() {
+       local outname name="$1"
+       local function="${PROGRAM:+$PROGRAM: }find_devname"
 
-       case $rootdev in
+       outname="$name"
+       case $name in
        LABEL=*)
                if [ ! -x /sbin/blkid ]; then
                        echo >&2 "$function: /sbin/blkid is missing"
                        return 2
                fi
 
-               local label=${rootdev#"LABEL="}
+               local label=${name#"LABEL="}
                local dev=$(/sbin/blkid -l -t LABEL="$label" -o device)
                if [ "$dev" ]; then
                        if [ ! -r "$dev" ]; then
                                echo >&2 "$function: blkid returned device $dev which doesn't exist"
                                return 2
                        fi
-                       rootdev=$dev
+                       outname=$dev
                fi
                ;;
 
@@ -50,7 +35,7 @@ find_root() {
                        return 2
                fi
 
-               local uuid=${rootdev#"UUID="}
+               local uuid=${name#"UUID="}
                local dev=$(/sbin/blkid -l -t UUID="$uuid" -o device)
 
                if [ "$dev" ]; then
@@ -58,11 +43,38 @@ find_root() {
                                echo >&2 "$function: blkid returned device $dev which doesn't exist"
                                return 2
                        fi
-                       rootdev=$dev
+                       outname=$dev
                fi
                ;;
        esac
+       echo $outname
+}
+
+# Find root device from fstab.
+#
+# @param       string  $fstab location of /etc/fstab
+# @return      false on failure
+#
+# Sets global variables:
+# - $rootdev
+# - $rootdev_add
+# - $rootFS
+#
+find_root() {
+       local fstab="$1"
+       local function="${PROGRAM:+$PROGRAM: }find_root"
+       local rootopt
+
+       eval $(awk '!/^[\t ]*#/ && $2 == "/" {printf("rootdev=\"%s\"\nrootFs=\"%s\"\nrootopt=\"%s\"\n", $1, $3, $4)}' $fstab)
+       if [ -z "$rootdev" ]; then
+               echo >&2 "$function: can't find fstab entry for root mountpoint"
+               return 1
+       fi
+
+       # additional devices needed (xfs logdev)
+       rootdev_add=$(echo "$rootopt" | awk -F',' '{ for (i=1; i<=NF; i++) { if ($i ~ /^logdev=/) { gsub(/^logdev=/, NIL, $i); print $i; } } }')
 
+       rootdev=$(find_devname "$rootdev")
        case $rootdev in
        /dev/dm-*)
                local node
@@ -97,7 +109,7 @@ find_root() {
        fi
 
        if [ ! -r "$rootdev" ]; then
-               echo >&2 "$function: can't find real device for $rootdev"
+               echo >&2 "$function: rootfs device file $rootdev doesn't exist"
                return 1
        fi
 
@@ -108,7 +120,7 @@ find_root() {
 # which they got from blkid program fs was specifed as UUID= in fstab
 dm_lvm2_name() {
        local node="$1"
-       local dm_minor
+       local dm_minor stat
 
        if [ ! -b "$node" ]; then
                echo >&2 "dm_lvm2_name: $node is not a block device"
@@ -120,7 +132,8 @@ dm_lvm2_name() {
                dm_minor=${node#/dev/dm-}
                ;;
        /dev/mapper/*)
-               dm_minor=$(ls -l $node | awk '{print $6}')
+               stat=$(stat -L -c %T "$node") || die "stat failed: $node"
+               dm_minor=$((0x$stat))
        ;;
        esac
 
@@ -149,15 +162,23 @@ dm_lvm2_name() {
 # @return      DM name
 dm_name() {
        local node="$1"
-       dmsetup info -c --noheadings $node | awk -F: '{print $1}'
+       dmsetup info -c --noheadings -o name $node
 }
 
 # get subsystem name for DM node
 # node can be /dev/dm-0, /dev/mapper/name
 # @return      subsystem name
 dm_subsystem() {
-       local node="$1"
-       dmsetup info -c --noheadings -o subsystem $node
+       local node="$1" out
+       out=$(dmsetup info -c --noheadings -o subsystem $node)
+       if [ $? -eq 0 -a -n "$out" ]; then
+               echo "$out"
+               return
+       fi
+
+       # for very old kernels (2.6.16), subsystem is empty, assume LVM
+       # TODO: fix this if needed to have crypt as well
+       echo "LVM"
 }
 
 # resolve any dm node to it's full path in /dev/mapper
@@ -165,3 +186,126 @@ dm_node() {
        local node="$1"
        printf "/dev/mapper/%s" $(dm_name "$node")
 }
+
+# find modules by class
+# find_modules_by_class 0106 - finds modules for SATA devices in the system
+# find_modules_by_class 0c03 - finds modules for USB controllers
+find_modules_by_class() {
+       if modprobe --version | grep -q "^kmod"; then
+               find_modules_by_class_kmod $@
+       else
+               find_modules_by_class_mit $@
+       fi
+}
+
+# find modules by class (kmod version)
+# find_modules_by_class 0106 - finds modules for SATA devices in the system
+# find_modules_by_class 0c03 - finds modules for USB controllers
+find_modules_by_class_kmod() {
+       local req_class="$1" i j modaliases
+
+       if [ ! -d "/sys/devices" ]; then
+               warn "No /sys/devices/ found. Is /sys mounted?"
+               return
+       fi
+
+       for i in $(grep -li "^0x${req_class}" /sys/devices/pci*/*/class); do
+               j=$(dirname $i)
+               modaliases="$modaliases $(cat $j/modalias)"
+       done
+
+       if [ -z "$modaliases" ]; then
+               return
+       fi
+
+       echo $modaliases | xargs modprobe --set-version $kernel -aRn | awk '
+               BEGIN { skip_modules[notexisting_module]=""; modules[1]=""; xhci=""; ehci_pci=""; ehci_hcd=""; ehci_platform=""; ohci=""; uhci="" }
+               {
+                       module=$1
+                       if (module == "xhci_hcd") {
+                               xhci="xhci_hcd"
+                       } else if (module == "ehci_hcd") {
+                               ehci_hcd="ehci_hcd"
+                       } else if (module == "ehci_pci") {
+                               ehci_pci="ehci_pci"
+                       } else if (module == "ehci_platform") {
+                               ehci_platform="ehci_platform"
+                       } else if (module == "ohci_hcd") {
+                               ohci="ohci_hcd"
+                       } else if (module == "uhci_hcd") {
+                               uhci="uhci_hcd"
+                       } else if (!(module in skip_modules)) {
+                               modules[cnt]=module
+                       }
+                       skip_modules[module]=1;
+               }
+               END {
+                       # ehci/ohci/uhci/xhci hack to preserve such order
+                       printf "%s %s %s %s %s %s ", ehci_hcd, ehci_pci, ehci_platform, ohci, uhci, xhci;
+                       for (i in modules) { printf "%s ", modules[i]; };
+               }
+       '
+}
+
+# find modules by class (module-init-tools version)
+# find_modules_by_class 0106 - finds modules for SATA devices in the system
+# find_modules_by_class 0c03 - finds modules for USB controllers
+find_modules_by_class_mit() {
+       local req_class="$1" pcimap lspci
+
+       pcimap="/lib/modules/$kernel/modules.pcimap"
+
+       lspci=$(find_tool /sbin/lspci)
+       if [ ! -x "$lspci" ]; then
+               warn "Failed to execute lspci. Is pciutils package installed?"
+       fi
+
+       # no pcimap, nothing to lookup from
+       if [ ! -f "$pcimap" ]; then
+               warn "No $pcimap file. Cannot find modules for desired class!"
+               return
+       fi
+
+       if [ -z "$lspci" ]; then
+               return
+       fi
+
+       LC_ALL=C lspci -p "$pcimap" -kvmmn | awk -vreq_class="${req_class}" '
+               BEGIN      { skip_modules[notexisting_module]=""; modules[1]=""; xhci=""; ehci_pci=""; ehci_hcd=""; ehci_platform=""; ohci=""; uhci="" }
+               /^Slot:/   { found=0 }
+               /^Class:/  { if (req_class == $2) { found = 1 } }
+               /^Driver:/ { if (found) {
+                               module = $2;
+                               if (module == "xhci_hcd") {
+                                       xhci = "xhci_hcd"
+                               } else if (module == "ehci_hcd") {
+                                       ehci_hcd = "ehci_hcd"
+                               } else if (module == "ehci_pci") {
+                                       ehci_pci="ehci_pci"
+                               } else if (module == "ehci_platform") {
+                                       ehci_platform="ehci_platform"
+                               } else if (module == "ohci_hcd") {
+                                       ohci = "ohci_hcd"
+                               } else if (module == "uhci_hcd") {
+                                       uhci = "uhci_hcd"
+                               } else if (!(module in skip_modules)) {
+                                       modules[cnt] = module
+                               }
+                               skip_modules[module] = 1;
+                  }
+                  found=0
+               }
+               END {
+                  # ehci/ohci/uhci/xhci hack to preserve such order
+                  printf "%s %s %s %s %s %s ", ehci_hcd, ehci_pci, ehci_platform, ohci, uhci, xhci;
+                  for (i in modules) { printf "%s ", modules[i]; }
+               }
+       '
+}
+
+# get possible paths for specifed patter containing LIBDIR
+get_libdir() {
+       for dir in lib lib64 libx32; do
+               echo -n "${1/LIBDIR/$dir} "
+       done
+}
This page took 0.041599 seconds and 4 git commands to generate.