2008-12-18 00:57:43 +03:00
#!/bin/bash
2010-09-10 17:23:06 +04:00
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
2008-12-18 00:57:43 +03:00
#
2009-07-22 14:43:26 +04:00
# functions used by dracut and other tools.
2008-12-18 00:57:43 +03:00
#
2009-07-22 14:43:26 +04:00
# Copyright 2005-2009 Red Hat, Inc. All rights reserved.
2008-12-18 00:57:43 +03:00
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
2009-03-04 19:29:42 +03:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2008-12-18 00:57:43 +03:00
#
2012-07-19 15:35:50 +04:00
export LC_MESSAGES = C
2012-06-30 11:12:35 +04:00
if [ [ $DRACUT_KERNEL_LAZY ] ] && ! [ [ $DRACUT_KERNEL_LAZY_HASHDIR ] ] ; then
if ! [ [ -d " $initdir /.kernelmodseen " ] ] ; then
mkdir -p " $initdir /.kernelmodseen "
fi
DRACUT_KERNEL_LAZY_HASHDIR = " $initdir /.kernelmodseen "
fi
2012-06-27 16:18:21 +04:00
2012-06-30 14:46:55 +04:00
if [ [ $initdir ] ] && ! [ [ -d $initdir ] ] ; then
mkdir -p " $initdir "
fi
2012-06-18 14:52:39 +04:00
# Generic substring function. If $2 is in $1, return 0.
2012-06-22 10:57:20 +04:00
strstr( ) { [ [ $1 = *$2 * ] ] ; }
2012-06-18 14:52:39 +04:00
2012-06-30 11:12:35 +04:00
# find a binary. If we were not passed the full path directly,
# search in the usual places to find the binary.
find_binary( ) {
if [ [ -z ${ 1 ##/* } ] ] ; then
if [ [ -x $1 ] ] || { strstr " $1 " ".so" && ldd $1 & >/dev/null; } ; then
echo $1
return 0
fi
fi
2012-10-07 17:29:03 +04:00
type -P ${ 1 ##*/ }
2012-06-30 11:12:35 +04:00
}
2011-03-25 17:40:51 +03:00
if ! [ [ $dracutbasedir ] ] ; then
dracutbasedir = ${ BASH_SOURCE [0]%/* }
[ [ $dracutbasedir = "dracut-functions" ] ] && dracutbasedir = "."
[ [ $dracutbasedir ] ] || dracutbasedir = "."
dracutbasedir = " $( readlink -f $dracutbasedir ) "
fi
2012-06-30 11:12:35 +04:00
if ! [ [ $DRACUT_INSTALL ] ] ; then
DRACUT_INSTALL = $( find_binary dracut-install)
fi
if ! [ [ $DRACUT_INSTALL ] ] && [ [ -x $dracutbasedir /dracut-install ] ] ; then
DRACUT_INSTALL = $dracutbasedir /dracut-install
fi
2012-06-18 14:52:39 +04:00
# Detect lib paths
if ! [ [ $libdirs ] ] ; then
if strstr " $( ldd /bin/sh) " "/lib64/" & >/dev/null \
&& [ [ -d /lib64 ] ] ; then
libdirs += " /lib64"
[ [ -d /usr/lib64 ] ] && libdirs += " /usr/lib64"
else
libdirs += " /lib"
[ [ -d /usr/lib ] ] && libdirs += " /usr/lib"
fi
export libdirs
fi
if ! [ [ $kernel ] ] ; then
kernel = $( uname -r)
export kernel
fi
srcmods = " /lib/modules/ $kernel / "
[ [ $drivers_dir ] ] && {
if vercmp $( modprobe --version | cut -d' ' -f3) lt 3.7; then
dfatal 'To use --kmoddir option module-init-tools >= 3.7 is required.'
exit 1
fi
srcmods = " $drivers_dir "
}
export srcmods
2011-03-25 17:38:54 +03:00
if ! type dinfo >/dev/null 2>& 1; then
2012-02-22 13:14:17 +04:00
. " $dracutbasedir /dracut-logger.sh "
2011-03-15 21:37:45 +03:00
dlog_init
fi
2012-07-09 12:02:04 +04:00
if ! [ [ $initdir ] ] ; then
dfatal "initdir not set"
exit 1
fi
2012-02-16 14:49:19 +04:00
# export standard hookdirs
[ [ $hookdirs ] ] || {
2012-03-02 17:46:11 +04:00
hookdirs = "cmdline pre-udev pre-trigger netroot "
2012-03-07 03:25:25 +04:00
hookdirs += "initqueue initqueue/settled initqueue/online initqueue/finished initqueue/timeout "
2012-04-23 13:31:32 +04:00
hookdirs += "pre-mount pre-pivot cleanup mount "
2013-01-18 13:59:39 +04:00
hookdirs += "emergency shutdown-emergency pre-shutdown shutdown "
2012-02-16 14:49:19 +04:00
export hookdirs
}
2013-03-06 19:00:11 +04:00
dracut_need_initqueue( ) {
>" $initdir /lib/dracut/need-initqueue "
}
dracut_module_included( ) {
strstr " $mods_to_load $modules_loaded " " $@ "
}
2010-07-01 23:17:37 +04:00
# Create all subdirectories for given path without creating the last element.
# $1 = path
2012-06-22 10:58:39 +04:00
mksubdirs( ) { [ [ -e ${ 1 %/* } ] ] || mkdir -m 0755 -p ${ 1 %/* } ; }
2010-07-01 23:17:37 +04:00
2010-06-11 23:10:34 +04:00
# Version comparision function. Assumes Linux style version scheme.
# $1 = version a
# $2 = comparision op (gt, ge, eq, le, lt, ne)
# $3 = version b
2010-06-09 12:36:05 +04:00
vercmp( ) {
2011-05-12 13:03:30 +04:00
local _n1 = ( ${ 1 //./ } ) _op = $2 _n2 = ( ${ 3 //./ } ) _i _res
2010-06-09 12:36:05 +04:00
2011-05-12 13:03:30 +04:00
for ( ( _i = 0; ; _i++) )
2010-06-11 23:10:34 +04:00
do
2011-05-12 13:03:30 +04:00
if [ [ ! ${ _n1 [_i] } ${ _n2 [_i] } ] ] ; then _res = 0
elif ( ( ${ _n1 [_i] :- 0 } > ${ _n2 [_i] :- 0 } ) ) ; then _res = 1
elif ( ( ${ _n1 [_i] :- 0 } < ${ _n2 [_i] :- 0 } ) ) ; then _res = 2
2010-06-11 23:10:34 +04:00
else continue
fi
break
2010-06-09 12:36:05 +04:00
done
2011-05-12 13:03:30 +04:00
case $_op in
gt) ( ( _res = = 1) ) ; ;
ge) ( ( _res != 2) ) ; ;
eq) ( ( _res = = 0) ) ; ;
le) ( ( _res != 1) ) ; ;
lt) ( ( _res = = 2) ) ; ;
ne) ( ( _res != 0) ) ; ;
2010-06-11 23:10:34 +04:00
esac
2010-06-09 12:36:05 +04:00
}
2012-02-16 14:49:19 +04:00
# is_func <command>
# Check whether $1 is a function.
2011-02-02 15:34:58 +03:00
is_func( ) {
2011-03-25 17:56:46 +03:00
[ [ $( type -t $1 ) = "function" ] ]
2011-02-02 15:34:58 +03:00
}
2010-07-01 23:17:37 +04:00
# Function prints global variables in format name=value line by line.
# $@ = list of global variables' name
print_vars( ) {
2011-05-12 13:03:30 +04:00
local _var _value
2010-07-01 23:17:37 +04:00
2011-05-12 13:03:30 +04:00
for _var in $@
2010-07-01 23:17:37 +04:00
do
2011-05-12 13:03:30 +04:00
_value = $( eval echo \$ $_var )
[ [ ${ _value } ] ] && echo " ${ _var } =\" ${ _value } \" "
2010-07-01 23:17:37 +04:00
done
}
2012-02-16 14:49:19 +04:00
# normalize_path <path>
# Prints the normalized path, where it removes any duplicated
# and trailing slashes.
# Example:
# $ normalize_path ///test/test//
# /test/test
2011-07-25 16:28:55 +04:00
normalize_path( ) {
2011-10-08 02:20:50 +04:00
shopt -q -s extglob
set -- " ${ 1 //+( \/ )// } "
shopt -q -u extglob
echo " ${ 1 %/ } "
2011-07-25 16:28:55 +04:00
}
2011-07-25 12:25:44 +04:00
2012-02-16 14:49:19 +04:00
# convert_abs_rel <from> <to>
# Prints the relative path, when creating a symlink to <to> from <from>.
# Example:
# $ convert_abs_rel /usr/bin/test /bin/test-2
# ../../bin/test-2
# $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test
2011-07-25 12:25:44 +04:00
convert_abs_rel( ) {
2012-02-22 16:04:37 +04:00
local __current __absolute __abssize __cursize __newpath
2011-10-08 02:20:50 +04:00
local -i __i __level
2011-07-25 12:25:44 +04:00
2011-10-08 02:20:50 +04:00
set -- " $( normalize_path " $1 " ) " " $( normalize_path " $2 " ) "
2011-10-08 00:23:49 +04:00
# corner case #1 - self looping link
[ [ " $1 " = = " $2 " ] ] && { echo " ${ 1 ##*/ } " ; return ; }
# corner case #2 - own dir link
[ [ " ${ 1 %/* } " = = " $2 " ] ] && { echo "." ; return ; }
2012-02-22 16:04:37 +04:00
IFS = "/" __current = ( $1 )
IFS = "/" __absolute = ( $2 )
2011-07-25 12:25:44 +04:00
__abssize = ${# __absolute [@] }
__cursize = ${# __current [@] }
while [ [ ${ __absolute [__level] } = = ${ __current [__level] } ] ]
do
( ( __level++ ) )
if ( ( __level > __abssize || __level > __cursize ) )
then
break
fi
done
for ( ( __i = __level; __i < __cursize-1; __i++) )
do
if ( ( __i > __level) )
then
__newpath = $__newpath "/"
fi
__newpath = $__newpath ".."
done
for ( ( __i = __level; __i < __abssize; __i++) )
do
if [ [ -n $__newpath ] ]
then
__newpath = $__newpath "/"
fi
__newpath = $__newpath ${ __absolute [__i] }
done
echo " $__newpath "
}
2012-06-29 14:04:30 +04:00
if strstr " $( ln --help) " "--relative" ; then
2012-06-21 03:57:11 +04:00
ln_r( ) {
ln -sfnr " ${ initdir } / $1 " " ${ initdir } / $2 "
}
else
ln_r( ) {
local _source = $1
local _dest = $2
[ [ -d " ${ _dest %/* } " ] ] && _dest = $( readlink -f " ${ _dest %/* } " ) /${ _dest ##*/ }
ln -sfn $( convert_abs_rel " ${ _dest } " " ${ _source } " ) " ${ initdir } / ${ _dest } "
}
fi
2012-09-10 12:10:46 +04:00
get_persistent_dev( ) {
local i _tmp _dev
_dev = $( udevadm info --query= name --name= " $1 " 2>/dev/null)
[ -z " $_dev " ] && return
2012-09-28 13:13:20 +04:00
for i in /dev/mapper/* /dev/disk/by-uuid/* /dev/disk/by-id/*; do
2013-05-31 09:46:08 +04:00
[ [ $i = = /dev/mapper/mpath* ] ] && continue
2012-09-10 12:10:46 +04:00
_tmp = $( udevadm info --query= name --name= " $i " 2>/dev/null)
if [ " $_tmp " = " $_dev " ] ; then
echo $i
return
fi
done
}
2012-02-16 14:49:19 +04:00
# get_fs_env <device>
# Get and set the ID_FS_TYPE and ID_FS_UUID variable from udev for a device.
# Example:
# $ get_fs_env /dev/sda2; echo $ID_FS_TYPE; echo $ID_FS_UUID
# ext4
# 551a39aa-4ae9-4e70-a262-ef665cadb574
2009-08-22 21:04:11 +04:00
get_fs_env( ) {
2012-03-30 12:47:35 +04:00
local evalstr
local found
2010-08-06 15:54:34 +04:00
[ [ $1 ] ] || return
2011-05-12 13:03:30 +04:00
unset ID_FS_TYPE
unset ID_FS_UUID
2012-03-30 12:47:35 +04:00
if evalstr = $( udevadm info --query= env --name= $1 \
| { while read line; do
strstr " $line " "DEVPATH" && found = 1;
strstr " $line " "ID_FS_TYPE=" && { echo $line ; exit 0; }
done ; [ [ $found ] ] && exit 0; exit 1; } ) ; then
eval $evalstr
[ [ $ID_FS_TYPE ] ] && return 0
return 1
fi
2010-05-03 13:34:30 +04:00
2012-03-30 12:47:35 +04:00
# Fallback, if we don't have udev information
2012-03-29 16:56:46 +04:00
if find_binary blkid >/dev/null; then
2012-03-29 17:20:41 +04:00
eval $( blkid -o udev $1 \
2012-03-29 16:56:46 +04:00
| while read line; do
strstr " $line " "ID_FS_TYPE=" && echo $line ;
done )
[ [ $ID_FS_TYPE ] ] && return 0
2010-08-06 15:54:34 +04:00
fi
2012-03-29 16:56:46 +04:00
return 1
}
2009-08-22 21:04:11 +04:00
2012-02-16 14:49:19 +04:00
# get_maj_min <device>
# Prints the major and minor of a device node.
# Example:
# $ get_maj_min /dev/sda2
# 8:2
2011-12-08 13:43:29 +04:00
get_maj_min( ) {
local _dev
2012-01-23 16:50:05 +04:00
_dev = $( stat -L -c '$((0x%t)):$((0x%T))' " $1 " 2>/dev/null)
2011-12-08 13:43:29 +04:00
_dev = $( eval " echo $_dev " )
echo $_dev
}
2012-02-16 14:49:19 +04:00
# find_block_device <mountpoint>
# Prints the major and minor number of the block device
# for a given mountpoint.
# Unless $use_fstab is set to "yes" the functions
# uses /proc/self/mountinfo as the primary source of the
# information and only falls back to /etc/fstab, if the mountpoint
# is not found there.
# Example:
# $ find_block_device /usr
# 8:4
2009-08-20 07:20:12 +04:00
find_block_device( ) {
2013-04-09 12:47:39 +04:00
local _majmin _dev _majmin _find_mpt
2013-01-23 17:10:15 +04:00
_find_mpt = " $1 "
2011-03-25 17:56:46 +03:00
if [ [ $use_fstab != yes ] ] ; then
2013-04-09 12:47:39 +04:00
[ [ -d $_find_mpt /. ] ]
while read _majmin _dev; do
if [ [ -b $_dev ] ] ; then
if ! [ [ $_majmin ] ] || [ [ $_majmin = = 0:* ] ] ; then
read _majmin < <( get_maj_min $_dev )
fi
if [ [ $_majmin ] ] ; then
echo $_majmin
else
echo $_dev
fi
return 0
fi
if [ [ $_dev = *:* ] ] ; then
echo $_dev
return 0
2010-09-10 17:23:06 +04:00
fi
2013-04-09 12:47:39 +04:00
done < <( findmnt -e -v -n -o 'MAJ:MIN,SOURCE' " $_find_mpt " )
2010-08-06 15:54:34 +04:00
fi
2011-03-25 17:56:46 +03:00
# fall back to /etc/fstab
2013-04-09 12:47:39 +04:00
while read _majmin _dev; do
if ! [ [ $_dev ] ] ; then
_dev = " $_majmin "
unset _majmin
2010-09-10 17:23:06 +04:00
fi
2013-04-09 12:47:39 +04:00
if [ [ -b $_dev ] ] ; then
[ [ $_majmin ] ] || read _majmin < <( get_maj_min $_dev )
if [ [ $_majmin ] ] ; then
echo $_majmin
else
echo $_dev
fi
return 0
fi
if [ [ $_dev = *:* ] ] ; then
echo $_dev
return 0
fi
done < <( findmnt -e --fstab -v -n -o 'MAJ:MIN,SOURCE' " $_find_mpt " )
2011-03-25 17:56:46 +03:00
return 1
2009-08-16 19:29:21 +04:00
}
2013-04-09 12:47:39 +04:00
# find_mp_fstype <mountpoint>
# Echo the filesystem type for a given mountpoint.
2012-02-16 14:49:19 +04:00
# /proc/self/mountinfo is taken as the primary source of information
# and /etc/fstab is used as a fallback.
# No newline is appended!
# Example:
2013-04-09 12:47:39 +04:00
# $ find_mp_fstype /;echo
2012-02-16 14:49:19 +04:00
# ext4
2013-04-09 12:47:39 +04:00
find_mp_fstype( ) {
local _fs
2011-12-08 13:25:58 +04:00
2013-04-09 12:47:39 +04:00
if [ [ $use_fstab != yes ] ] ; then
while read _fs; do
[ [ $_fs ] ] || continue
[ [ $_fs = "autofs" ] ] && continue
echo -n $_fs
return 0
done < <( findmnt -e -v -n -o 'FSTYPE' " $1 " )
fi
while read _fs; do
[ [ $_fs ] ] || continue
[ [ $_fs = "autofs" ] ] && continue
echo -n $_fs
return 0
done < <( findmnt --fstab -e -v -n -o 'FSTYPE' " $1 " )
2011-12-08 13:25:58 +04:00
return 1
}
2013-04-09 12:47:39 +04:00
# find_dev_fstype <device>
# Echo the filesystem type for a given device.
2012-07-26 19:00:07 +04:00
# /proc/self/mountinfo is taken as the primary source of information
# and /etc/fstab is used as a fallback.
# No newline is appended!
# Example:
2013-04-09 12:47:39 +04:00
# $ find_dev_fstype /dev/sda2;echo
2012-07-26 19:00:07 +04:00
# ext4
2013-04-09 12:47:39 +04:00
find_dev_fstype( ) {
local _x _mpt _majmin _dev _fs _maj _min _find_dev
_find_dev = " $1 "
[ [ " $_find_dev " = /dev* ] ] || _find_dev = " /dev/block/ $_find_dev "
find_mp_fstype " $_find_dev "
2012-07-26 19:00:07 +04:00
}
2011-12-08 13:25:58 +04:00
# finds the major:minor of the block device backing the root filesystem.
2009-08-20 07:20:12 +04:00
find_root_block_device( ) { find_block_device /; }
2012-02-16 14:49:19 +04:00
# for_each_host_dev_fs <func>
2013-03-11 19:32:16 +04:00
# Execute "<func> <dev> <filesystem>" for every "<dev> <fs>" pair found
2012-02-16 14:49:19 +04:00
# in ${host_fs_types[@]}
2011-12-08 13:43:29 +04:00
for_each_host_dev_fs( )
{
local _func = " $1 "
2011-12-20 10:09:59 +04:00
local _dev
2012-02-22 22:06:00 +04:00
local _ret = 1
2013-03-18 11:43:23 +04:00
[ [ " ${ !host_fs_types[@] } " ] ] || return 0
2013-03-11 19:32:16 +04:00
for _dev in " ${ !host_fs_types[@] } " ; do
$_func " $_dev " " ${ host_fs_types [ $_dev ] } " && _ret = 0
2011-12-08 13:43:29 +04:00
done
2012-02-22 22:06:00 +04:00
return $_ret
2011-12-08 13:43:29 +04:00
}
2013-03-18 11:43:23 +04:00
host_fs_all( )
{
echo " ${ host_fs_types [@] } "
}
2009-08-16 19:29:21 +04:00
# Walk all the slave relationships for a given block device.
# Stop when our helper function returns success
# $1 = function to call on every found block device
# $2 = block device in major:minor format
2011-03-25 17:56:46 +03:00
check_block_and_slaves( ) {
2011-05-12 13:03:30 +04:00
local _x
2009-08-16 19:29:21 +04:00
[ [ -b /dev/block/$2 ] ] || return 1 # Not a block device? So sorry.
" $1 " $2 && return
2009-08-31 16:58:44 +04:00
check_vol_slaves " $@ " && return 0
2010-08-14 23:23:24 +04:00
if [ [ -f /sys/dev/block/$2 /../dev ] ] ; then
2011-03-25 17:56:46 +03:00
check_block_and_slaves $1 $( cat " /sys/dev/block/ $2 /../dev " ) && return 0
2010-05-19 10:13:12 +04:00
fi
2009-08-16 19:29:21 +04:00
[ [ -d /sys/dev/block/$2 /slaves ] ] || return 1
2011-05-12 13:03:30 +04:00
for _x in /sys/dev/block/$2 /slaves/*/dev; do
2012-08-01 07:23:42 +04:00
[ [ -f $_x ] ] || continue
2011-05-12 13:03:30 +04:00
check_block_and_slaves $1 $( cat " $_x " ) && return 0
2009-08-16 19:29:21 +04:00
done
return 1
}
2012-08-23 07:02:23 +04:00
check_block_and_slaves_all( ) {
local _x _ret = 1
[ [ -b /dev/block/$2 ] ] || return 1 # Not a block device? So sorry.
if " $1 " $2 ; then
_ret = 0
fi
check_vol_slaves " $@ " && return 0
if [ [ -f /sys/dev/block/$2 /../dev ] ] ; then
check_block_and_slaves_all $1 $( cat " /sys/dev/block/ $2 /../dev " ) && _ret = 0
fi
[ [ -d /sys/dev/block/$2 /slaves ] ] || return 1
for _x in /sys/dev/block/$2 /slaves/*/dev; do
[ [ -f $_x ] ] || continue
check_block_and_slaves_all $1 $( cat " $_x " ) && _ret = 0
done
return $_ret
}
# for_each_host_dev_and_slaves <func>
# Execute "<func> <dev>" for every "<dev>" found
# in ${host_devs[@]} and their slaves
for_each_host_dev_and_slaves_all( )
{
local _func = " $1 "
local _dev
local _ret = 1
2013-03-18 11:43:23 +04:00
[ [ " ${ host_devs [@] } " ] ] || return 0
2012-08-23 07:02:23 +04:00
for _dev in ${ host_devs [@] } ; do
[ [ -b " $_dev " ] ] || continue
if check_block_and_slaves_all $_func $( get_maj_min $_dev ) ; then
_ret = 0
fi
done
return $_ret
}
for_each_host_dev_and_slaves( )
{
local _func = " $1 "
local _dev
2013-03-18 11:43:23 +04:00
[ [ " ${ host_devs [@] } " ] ] || return 0
2012-08-23 07:02:23 +04:00
for _dev in ${ host_devs [@] } ; do
[ [ -b " $_dev " ] ] || continue
2012-08-28 06:05:49 +04:00
check_block_and_slaves $_func $( get_maj_min $_dev ) && return 0
2012-08-23 07:02:23 +04:00
done
return 1
}
2009-08-31 16:58:44 +04:00
# ugly workaround for the lvm design
# There is no volume group device,
# so, there are no slave devices for volume groups.
# Logical volumes only have the slave devices they really live on,
# but you cannot create the logical volume without the volume group.
2009-10-29 12:29:58 +03:00
# And the volume group might be bigger than the devices the LV needs.
2009-08-31 16:58:44 +04:00
check_vol_slaves( ) {
2011-05-12 13:03:30 +04:00
local _lv _vg _pv
2011-03-25 17:56:46 +03:00
for i in /dev/mapper/*; do
2012-02-16 14:48:17 +04:00
_lv = $( get_maj_min $i )
2011-05-12 13:03:30 +04:00
if [ [ $_lv = $2 ] ] ; then
_vg = $( lvm lvs --noheadings -o vg_name $i 2>/dev/null)
2010-09-10 17:23:06 +04:00
# strip space
2011-05-12 13:03:30 +04:00
_vg = $( echo $_vg )
if [ [ $_vg ] ] ; then
for _pv in $( lvm vgs --noheadings -o pv_name " $_vg " 2>/dev/null)
2011-03-25 17:56:46 +03:00
do
2012-02-16 14:48:17 +04:00
check_block_and_slaves $1 $( get_maj_min $_pv ) && return 0
2010-09-10 17:23:06 +04:00
done
fi
fi
2009-08-31 16:58:44 +04:00
done
return 1
}
2012-07-26 19:22:14 +04:00
# fs_get_option <filesystem options> <search for option>
# search for a specific option in a bunch of filesystem options
# and return the value
fs_get_option( ) {
local _fsopts = $1
local _option = $2
local OLDIFS = " $IFS "
IFS = ,
set -- $_fsopts
IFS = " $OLDIFS "
while [ $# -gt 0 ] ; do
case $1 in
$_option = *)
echo ${ 1 # ${ _option } = }
break
esac
shift
done
}
2012-06-30 11:12:35 +04:00
if [ [ $DRACUT_INSTALL ] ] ; then
2012-06-29 14:07:44 +04:00
[ [ $DRACUT_RESOLVE_LAZY ] ] || export DRACUT_RESOLVE_DEPS = 1
inst_dir( ) {
[ [ -e ${ initdir } /" $1 " ] ] && return 0 # already there
2012-06-30 11:12:35 +04:00
$DRACUT_INSTALL ${ initdir +-D " $initdir " } -d " $@ "
( ( $? != 0) ) && derror $DRACUT_INSTALL ${ initdir +-D " $initdir " } -d " $@ " || :
2012-06-29 14:07:44 +04:00
}
2009-09-27 08:33:41 +04:00
2012-06-29 14:07:44 +04:00
inst( ) {
[ [ -e ${ initdir } /" ${ 2 :- $1 } " ] ] && return 0 # already there
2012-06-30 11:12:35 +04:00
#dinfo "$DRACUT_INSTALL -l $@"
$DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ "
( ( $? != 0) ) && derror $DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ " || :
2012-06-29 14:07:44 +04:00
}
inst_simple( ) {
[ [ -e ${ initdir } /" ${ 2 :- $1 } " ] ] && return 0 # already there
[ [ -e $1 ] ] || return 1 # no source
2012-06-30 11:12:35 +04:00
$DRACUT_INSTALL ${ initdir +-D " $initdir " } " $@ "
( ( $? != 0) ) && derror $DRACUT_INSTALL ${ initdir +-D " $initdir " } " $@ " || :
2012-06-29 14:07:44 +04:00
}
inst_symlink( ) {
[ [ -e ${ initdir } /" ${ 2 :- $1 } " ] ] && return 0 # already there
[ [ -L $1 ] ] || return 1
2012-06-30 11:12:35 +04:00
$DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ "
( ( $? != 0) ) && derror $DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ " || :
2012-06-29 14:07:44 +04:00
}
dracut_install( ) {
2012-10-08 13:40:08 +04:00
local ret
2012-06-30 11:12:35 +04:00
#dinfo "initdir=$initdir $DRACUT_INSTALL -l $@"
$DRACUT_INSTALL ${ initdir +-D " $initdir " } -a ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ "
2012-10-08 13:40:08 +04:00
ret = $?
( ( $ret != 0) ) && derror $DRACUT_INSTALL ${ initdir +-D " $initdir " } -a ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ " || :
return $ret
2012-06-29 14:07:44 +04:00
}
inst_library( ) {
[ [ -e ${ initdir } /" ${ 2 :- $1 } " ] ] && return 0 # already there
[ [ -e $1 ] ] || return 1 # no source
2012-06-30 11:12:35 +04:00
$DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ "
( ( $? != 0) ) && derror $DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ " || :
2012-06-29 14:07:44 +04:00
}
inst_binary( ) {
2012-06-30 11:12:35 +04:00
$DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ "
( ( $? != 0) ) && derror $DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ " || :
2012-06-29 14:07:44 +04:00
}
inst_script( ) {
2012-06-30 11:12:35 +04:00
$DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ "
( ( $? != 0) ) && derror $DRACUT_INSTALL ${ initdir +-D " $initdir " } ${ DRACUT_RESOLVE_DEPS +-l } ${ DRACUT_FIPS_MODE +-H } " $@ " || :
2012-06-29 14:07:44 +04:00
}
else
# Install a directory, keeping symlinks as on the original system.
# Example: if /lib points to /lib64 on the host, "inst_dir /lib/file"
# will create ${initdir}/lib64, ${initdir}/lib64/file,
# and a symlink ${initdir}/lib -> lib64.
inst_dir( ) {
[ [ -e ${ initdir } /" $1 " ] ] && return 0 # already there
local _dir = " $1 " _part = " ${ 1 %/* } " _file
while [ [ " $_part " != " ${ _part %/* } " ] ] && ! [ [ -e " ${ initdir } / ${ _part } " ] ] ; do
_dir = " $_part $_dir "
_part = ${ _part %/* }
done
# iterate over parent directories
for _file in $_dir ; do
[ [ -e " ${ initdir } / $_file " ] ] && continue
if [ [ -L $_file ] ] ; then
inst_symlink " $_file "
else
2009-09-27 08:33:41 +04:00
# create directory
2012-06-29 14:07:44 +04:00
mkdir -m 0755 -p " ${ initdir } / $_file " || return 1
[ [ -e " $_file " ] ] && chmod --reference= " $_file " " ${ initdir } / $_file "
chmod u+w " ${ initdir } / $_file "
fi
done
}
# $1 = file to copy to ramdisk
# $2 (optional) Name for the file on the ramdisk
# Location of the image dir is assumed to be $initdir
# We never overwrite the target if it exists.
inst_simple( ) {
[ [ -f " $1 " ] ] || return 1
strstr " $1 " "/" || return 1
local _src = $1 _target = " ${ 2 :- $1 } "
[ [ -L $_src ] ] && { inst_symlink $_src $_target ; return $? ; }
if ! [ [ -d ${ initdir } /$_target ] ] ; then
[ [ -e ${ initdir } /$_target ] ] && return 0
[ [ -L ${ initdir } /$_target ] ] && return 0
[ [ -d " ${ initdir } / ${ _target %/* } " ] ] || inst_dir " ${ _target %/* } "
2009-09-27 08:33:41 +04:00
fi
2012-06-29 14:07:44 +04:00
if [ [ $DRACUT_FIPS_MODE ] ] ; then
# install checksum files also
if [ [ -e " ${ _src %/* } /. ${ _src ##*/ } .hmac " ] ] ; then
inst " ${ _src %/* } /. ${ _src ##*/ } .hmac " " ${ _target %/* } /. ${ _target ##*/ } .hmac "
fi
2012-08-24 15:31:57 +04:00
if [ [ -e " /lib/fipscheck/ ${ _src ##*/ } .hmac " ] ] ; then
inst " /lib/fipscheck/ ${ _src ##*/ } .hmac " " /lib/fipscheck/ ${ _target ##*/ } .hmac "
fi
if [ [ -e " /lib64/fipscheck/ ${ _src ##*/ } .hmac " ] ] ; then
inst " /lib64/fipscheck/ ${ _src ##*/ } .hmac " " /lib64/fipscheck/ ${ _target ##*/ } .hmac "
fi
2012-06-29 14:07:44 +04:00
fi
ddebug " Installing $_src "
cp --reflink= auto --sparse= auto -pfL " $_src " " ${ initdir } / $_target "
}
2009-09-27 08:33:41 +04:00
2012-06-29 14:07:44 +04:00
# same as above, but specialized for symlinks
inst_symlink( ) {
local _src = $1 _target = ${ 2 :- $1 } _realsrc
strstr " $1 " "/" || return 1
[ [ -L $1 ] ] || return 1
[ [ -L $initdir /$_target ] ] && return 0
_realsrc = $( readlink -f " $_src " )
if ! [ [ -e $initdir /$_realsrc ] ] ; then
if [ [ -d $_realsrc ] ] ; then
inst_dir " $_realsrc "
else
inst " $_realsrc "
fi
fi
[ [ ! -e $initdir /${ _target %/* } ] ] && inst_dir " ${ _target %/* } "
2011-08-27 00:01:33 +04:00
2012-06-29 14:07:44 +04:00
ln_r " ${ _realsrc } " " ${ _target } "
}
2012-06-22 17:09:07 +04:00
2012-06-29 14:07:44 +04:00
# Same as above, but specialized to handle dynamic libraries.
# It handles making symlinks according to how the original library
# is referenced.
inst_library( ) {
local _src = " $1 " _dest = ${ 2 :- $1 } _lib _reallib _symlink
strstr " $1 " "/" || return 1
[ [ -e $initdir /$_dest ] ] && return 0
if [ [ -L $_src ] ] ; then
if [ [ $DRACUT_FIPS_MODE ] ] ; then
# install checksum files also
if [ [ -e " ${ _src %/* } /. ${ _src ##*/ } .hmac " ] ] ; then
inst " ${ _src %/* } /. ${ _src ##*/ } .hmac " " ${ _dest %/* } /. ${ _dest ##*/ } .hmac "
fi
2012-08-24 15:31:57 +04:00
if [ [ -e " /lib/fipscheck/ ${ _src ##*/ } .hmac " ] ] ; then
inst " /lib/fipscheck/ ${ _src ##*/ } .hmac " " /lib/fipscheck/ ${ _dest ##*/ } .hmac "
fi
if [ [ -e " /lib64/fipscheck/ ${ _src ##*/ } .hmac " ] ] ; then
inst " /lib64/fipscheck/ ${ _src ##*/ } .hmac " " /lib64/fipscheck/ ${ _dest ##*/ } .hmac "
fi
2012-06-29 14:07:44 +04:00
fi
_reallib = $( readlink -f " $_src " )
inst_simple " $_reallib " " $_reallib "
inst_dir " ${ _dest %/* } "
ln_r " ${ _reallib } " " ${ _dest } "
else
inst_simple " $_src " " $_dest "
fi
2012-06-22 17:09:07 +04:00
2012-06-29 14:07:44 +04:00
# Create additional symlinks. See rev_symlinks description.
for _symlink in $( rev_lib_symlinks $_src ) $( rev_lib_symlinks $_reallib ) ; do
[ [ ! -e $initdir /$_symlink ] ] && {
ddebug " Creating extra symlink: $_symlink "
inst_symlink $_symlink
}
done
}
# Same as above, but specialized to install binary executables.
# Install binary executable, and all shared library dependencies, if any.
inst_binary( ) {
local _bin _target
_bin = $( find_binary " $1 " ) || return 1
_target = ${ 2 :- $_bin }
[ [ -e $initdir /$_target ] ] && return 0
local _file _line
local _so_regex = '([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)'
# I love bash!
LC_ALL = C ldd " $_bin " 2>/dev/null | while read _line; do
[ [ $_line = 'not a dynamic executable' ] ] && break
if [ [ $_line = ~ $_so_regex ] ] ; then
_file = ${ BASH_REMATCH [1] }
[ [ -e ${ initdir } /$_file ] ] && continue
inst_library " $_file "
continue
fi
if [ [ $_line = ~ not\ found ] ] ; then
dfatal " Missing a shared library required by $_bin . "
dfatal " Run \"ldd $_bin \" to find out what it is. "
dfatal " $_line "
dfatal "dracut cannot create an initrd."
exit 1
fi
done
inst_simple " $_bin " " $_target "
}
# same as above, except for shell scripts.
# If your shell script does not start with shebang, it is not a shell script.
inst_script( ) {
local _bin
_bin = $( find_binary " $1 " ) || return 1
shift
local _line _shebang_regex
read -r -n 80 _line <" $_bin "
# If debug is set, clean unprintable chars to prevent messing up the term
[ [ $debug ] ] && _line = $( echo -n " $_line " | tr -c -d '[:print:][:space:]' )
_shebang_regex = '(#! *)(/[^ ]+).*'
[ [ $_line = ~ $_shebang_regex ] ] || return 1
inst " ${ BASH_REMATCH [2] } " && inst_simple " $_bin " " $@ "
}
# general purpose installation function
# Same args as above.
inst( ) {
local _x
case $# in
1) ; ;
2) [ [ ! $initdir && -d $2 ] ] && export initdir = $2
[ [ $initdir = $2 ] ] && set $1 ; ;
3) [ [ -z $initdir ] ] && export initdir = $2
set $1 $3 ; ;
*) dfatal "inst only takes 1 or 2 or 3 arguments"
exit 1; ;
esac
for _x in inst_symlink inst_script inst_binary inst_simple; do
$_x " $@ " && return 0
done
return 1
}
# dracut_install [-o ] <file> [<file> ... ]
# Install <file> to the initramfs image
# -o optionally install the <file> and don't fail, if it is not there
dracut_install( ) {
local _optional = no
if [ [ $1 = '-o' ] ] ; then
_optional = yes
shift
fi
while ( ( $# > 0) ) ; do
if ! inst " $1 " ; then
if [ [ $_optional = yes ] ] ; then
dinfo " Skipping program $1 as it cannot be found and is " \
"flagged to be optional"
else
dfatal " Failed to install $1 "
exit 1
fi
fi
shift
done
}
fi
2009-02-13 15:42:28 +03:00
2010-07-07 18:39:09 +04:00
# find symlinks linked to given library file
# $1 = library file
# Function searches for symlinks by stripping version numbers appended to
# library filename, checks if it points to the same target and finally
# prints the list of symlinks to stdout.
#
# Example:
# rev_lib_symlinks libfoo.so.8.1
# output: libfoo.so.8 libfoo.so
# (Only if libfoo.so.8 and libfoo.so exists on host system.)
rev_lib_symlinks( ) {
[ [ ! $1 ] ] && return 0
local fn = " $1 " orig = " $( readlink -f " $1 " ) " links = ''
[ [ ${ fn } = ~ .*\. so\. .* ] ] || return 1
until [ [ ${ fn ##*. } = = so ] ] ; do
fn = " ${ fn %.* } "
[ [ -L ${ fn } && $( readlink -f " ${ fn } " ) = = ${ orig } ] ] && links += " ${ fn } "
done
2011-03-25 17:56:46 +03:00
echo " ${ links } "
2010-07-07 18:39:09 +04:00
}
2011-12-17 04:35:08 +04:00
# attempt to install any programs specified in a udev rule
inst_rule_programs( ) {
local _prog _bin
if grep -qE 'PROGRAM==?"[^ "]+' " $1 " ; then
for _prog in $( grep -E 'PROGRAM==?"[^ "]+' " $1 " | sed -r 's/.*PROGRAM==?"([^ "]+).*/\1/' ) ; do
2012-10-08 17:39:23 +04:00
_bin = ""
2012-06-04 14:58:42 +04:00
if [ -x ${ udevdir } /$_prog ] ; then
_bin = ${ udevdir } /$_prog
2013-03-07 17:27:49 +04:00
elif [ [ " ${ _prog / \$ env \{ / } " = = " $_prog " ] ] ; then
2012-06-04 14:58:42 +04:00
_bin = $( find_binary " $_prog " ) || {
2012-07-26 21:35:12 +04:00
dinfo " Skipping program $_prog using in udev rule ${ 1 ##*/ } as it cannot be found "
2012-06-04 14:58:42 +04:00
continue ;
}
fi
2012-10-08 17:39:23 +04:00
[ [ $_bin ] ] && dracut_install " $_bin "
2012-06-04 14:58:42 +04:00
done
fi
2012-10-04 20:15:36 +04:00
if grep -qE 'RUN[+=]=?"[^ "]+' " $1 " ; then
for _prog in $( grep -E 'RUN[+=]=?"[^ "]+' " $1 " | sed -r 's/.*RUN[+=]=?"([^ "]+).*/\1/' ) ; do
2012-10-08 17:39:23 +04:00
_bin = ""
2012-06-04 14:58:42 +04:00
if [ -x ${ udevdir } /$_prog ] ; then
_bin = ${ udevdir } /$_prog
2013-03-07 17:27:49 +04:00
elif [ [ " ${ _prog / \$ env \{ / } " = = " $_prog " ] ] && [ [ " ${ _prog } " != "/sbin/initqueue" ] ] ; then
2012-06-04 14:58:42 +04:00
_bin = $( find_binary " $_prog " ) || {
2012-07-26 21:35:12 +04:00
dinfo " Skipping program $_prog using in udev rule ${ 1 ##*/ } as it cannot be found "
2012-06-04 14:58:42 +04:00
continue ;
}
fi
2012-10-08 17:39:23 +04:00
[ [ $_bin ] ] && dracut_install " $_bin "
2012-06-04 14:58:42 +04:00
done
fi
2012-07-26 21:12:40 +04:00
if grep -qE 'IMPORT\{program\}==?"[^ "]+' " $1 " ; then
for _prog in $( grep -E 'IMPORT\{program\}==?"[^ "]+' " $1 " | sed -r 's/.*IMPORT\{program\}==?"([^ "]+).*/\1/' ) ; do
2012-10-08 17:39:23 +04:00
_bin = ""
2012-06-04 14:58:42 +04:00
if [ -x ${ udevdir } /$_prog ] ; then
_bin = ${ udevdir } /$_prog
2013-03-07 17:27:49 +04:00
elif [ [ " ${ _prog / \$ env \{ / } " = = " $_prog " ] ] ; then
2011-12-17 04:35:08 +04:00
_bin = $( find_binary " $_prog " ) || {
2012-07-26 21:35:12 +04:00
dinfo " Skipping program $_prog using in udev rule ${ 1 ##*/ } as it cannot be found "
2011-12-17 04:35:08 +04:00
continue ;
}
fi
2012-10-08 17:39:23 +04:00
[ [ $_bin ] ] && dracut_install " $_bin "
2011-12-17 04:35:08 +04:00
done
fi
}
2012-10-04 21:04:36 +04:00
# attempt to install any programs specified in a udev rule
inst_rule_group_owner( ) {
local i
if grep -qE 'OWNER=?"[^ "]+' " $1 " ; then
for i in $( grep -E 'OWNER=?"[^ "]+' " $1 " | sed -r 's/.*OWNER=?"([^ "]+).*/\1/' ) ; do
if ! egrep -q " ^ $i : " " $initdir /etc/passwd " 2>/dev/null; then
egrep " ^ $i : " /etc/passwd 2>/dev/null >> " $initdir /etc/passwd "
fi
done
fi
if grep -qE 'GROUP=?"[^ "]+' " $1 " ; then
for i in $( grep -E 'GROUP=?"[^ "]+' " $1 " | sed -r 's/.*GROUP=?"([^ "]+).*/\1/' ) ; do
if ! egrep -q " ^ $i : " " $initdir /etc/group " 2>/dev/null; then
egrep " ^ $i : " /etc/group 2>/dev/null >> " $initdir /etc/group "
fi
done
fi
}
2013-03-06 19:00:11 +04:00
inst_rule_initqueue( ) {
if grep -q -F initqueue " $1 " ; then
dracut_need_initqueue
fi
}
2009-02-13 15:43:26 +03:00
# udev rules always get installed in the same place, so
# create a function to install them to make life simpler.
2011-03-25 17:56:46 +03:00
inst_rules( ) {
2011-05-12 13:03:30 +04:00
local _target = /etc/udev/rules.d _rule _found
2010-07-05 13:25:21 +04:00
2012-06-04 14:58:42 +04:00
inst_dir " ${ udevdir } /rules.d "
2011-05-12 13:03:30 +04:00
inst_dir " $_target "
for _rule in " $@ " ; do
2013-01-03 12:29:05 +04:00
if [ " ${ _rule #/ } " = " $_rule " ] ; then
2012-06-04 14:58:42 +04:00
for r in ${ udevdir } /rules.d /etc/udev/rules.d; do
2011-09-22 17:43:34 +04:00
if [ [ -f $r /$_rule ] ] ; then
_found = " $r / $_rule "
2011-12-17 04:35:08 +04:00
inst_rule_programs " $_found "
2012-10-04 21:04:36 +04:00
inst_rule_group_owner " $_found "
2013-03-06 19:00:11 +04:00
inst_rule_initqueue " $_found "
2012-06-04 14:58:42 +04:00
inst_simple " $_found "
2011-09-22 17:43:34 +04:00
fi
done
fi
2011-03-25 15:05:05 +03:00
for r in '' ./ $dracutbasedir /rules.d/; do
2011-05-12 13:03:30 +04:00
if [ [ -f ${ r } $_rule ] ] ; then
_found = " ${ r } $_rule "
2011-12-17 04:35:08 +04:00
inst_rule_programs " $_found "
2012-10-04 21:04:36 +04:00
inst_rule_group_owner " $_found "
2013-03-06 19:00:11 +04:00
inst_rule_initqueue " $_found "
2012-06-04 14:58:42 +04:00
inst_simple " $_found " " $_target / ${ _found ##*/ } "
2011-03-25 15:05:05 +03:00
fi
done
2011-05-12 13:03:30 +04:00
[ [ $_found ] ] || dinfo " Skipping udev rule: $_rule "
2009-02-13 15:43:26 +03:00
done
}
2013-03-07 17:49:21 +04:00
prepare_udev_rules( ) {
[ -z " $UDEVVERSION " ] && export UDEVVERSION = $( udevadm --version)
for f in " $@ " ; do
f = " ${ initdir } /etc/udev/rules.d/ $f "
[ -e " $f " ] || continue
while read line; do
if [ " ${ line %%IMPORT PATH_ID } " != " $line " ] ; then
if [ $UDEVVERSION -ge 174 ] ; then
printf '%sIMPORT{builtin}="path_id"\n' " ${ line %%IMPORT PATH_ID } "
else
printf '%sIMPORT{program}="path_id %%p"\n' " ${ line %%IMPORT PATH_ID } "
fi
elif [ " ${ line %%IMPORT BLKID } " != " $line " ] ; then
if [ $UDEVVERSION -ge 176 ] ; then
printf '%sIMPORT{builtin}="blkid"\n' " ${ line %%IMPORT BLKID } "
else
printf '%sIMPORT{program}="/sbin/blkid -o udev -p $tempnode"\n' " ${ line %%IMPORT BLKID } "
fi
else
echo " $line "
fi
done < " ${ f } " > " ${ f } .new "
mv " ${ f } .new " " $f "
done
}
2009-02-13 15:43:29 +03:00
# install function specialized for hooks
# $1 = type of hook, $2 = hook priority (lower runs first), $3 = hook
# All hooks should be POSIX/SuS compliant, they will be sourced by init.
inst_hook( ) {
2009-05-23 06:24:31 +04:00
if ! [ [ -f $3 ] ] ; then
2011-03-25 17:56:47 +03:00
dfatal " Cannot install a hook ( $3 ) that does not exist. "
dfatal "Aborting initrd creation."
2010-09-10 17:23:06 +04:00
exit 1
2009-05-23 06:24:31 +04:00
elif ! strstr " $hookdirs " " $1 " ; then
2011-05-10 13:39:10 +04:00
dfatal " No such hook type $1 . Aborting initrd creation. "
2010-09-10 17:23:06 +04:00
exit 1
2009-05-23 06:24:31 +04:00
fi
2012-07-30 19:00:27 +04:00
inst_simple " $3 " " /lib/dracut/hooks/ ${ 1 } / ${ 2 } - ${ 3 ##*/ } "
2009-02-13 15:43:29 +03:00
}
2011-08-21 14:47:13 +04:00
# install any of listed files
#
# If first argument is '-d' and second some destination path, first accessible
# source is installed into this path, otherwise it will installed in the same
# path as source. If none of listed files was installed, function return 1.
# On first successful installation it returns with 0 status.
#
# Example:
#
# inst_any -d /bin/foo /bin/bar /bin/baz
#
# Lets assume that /bin/baz exists, so it will be installed as /bin/foo in
# initramfs.
inst_any( ) {
local to f
[ [ $1 = '-d' ] ] && to = " $2 " && shift 2
for f in " $@ " ; do
if [ [ -e $f ] ] ; then
[ [ $to ] ] && inst " $f " " $to " && return 0
inst " $f " && return 0
fi
done
return 1
}
2012-04-10 17:14:38 +04:00
# inst_libdir_file [-n <pattern>] <file> [<file>...]
# Install a <file> located on a lib directory to the initramfs image
2012-06-14 19:42:34 +04:00
# -n <pattern> install matching files
2012-04-10 17:14:38 +04:00
inst_libdir_file( ) {
2012-06-27 11:38:26 +04:00
local _files
2012-04-10 17:14:38 +04:00
if [ [ " $1 " = = "-n" ] ] ; then
2012-06-14 19:42:34 +04:00
local _pattern = $2
2012-04-10 17:14:38 +04:00
shift 2
for _dir in $libdirs ; do
2012-06-15 11:34:00 +04:00
for _i in " $@ " ; do
2012-04-10 17:14:38 +04:00
for _f in " $_dir " /$_i ; do
2012-06-15 11:34:00 +04:00
[ [ " $_f " = ~ $_pattern ] ] || continue
2012-06-27 11:38:26 +04:00
[ [ -e " $_f " ] ] && _files += " $_f "
2012-04-10 17:14:38 +04:00
done
done
done
else
for _dir in $libdirs ; do
2012-06-15 11:34:00 +04:00
for _i in " $@ " ; do
2012-04-10 17:14:38 +04:00
for _f in " $_dir " /$_i ; do
2012-06-27 11:38:26 +04:00
[ [ -e " $_f " ] ] && _files += " $_f "
2012-04-10 17:14:38 +04:00
done
done
done
fi
2012-06-27 11:38:26 +04:00
[ [ $_files ] ] && dracut_install $_files
2012-04-10 17:14:38 +04:00
}
2010-07-01 23:17:37 +04:00
# install function decompressing the target and handling symlinks
# $@ = list of compressed (gz or bz2) files or symlinks pointing to such files
#
# Function install targets in the same paths inside overlay but decompressed
# and without extensions (.gz, .bz2).
inst_decompress( ) {
2012-06-22 17:09:45 +04:00
local _src _cmd
2010-07-01 23:17:37 +04:00
2011-05-12 13:03:30 +04:00
for _src in $@
2010-07-01 23:17:37 +04:00
do
2011-05-12 13:03:30 +04:00
case ${ _src } in
2012-10-16 11:36:28 +04:00
*.gz) _cmd = 'gzip -f -d' ; ;
2011-05-12 13:03:30 +04:00
*.bz2) _cmd = 'bzip2 -d' ; ;
2010-07-01 23:17:37 +04:00
*) return 1 ; ;
esac
2012-06-22 17:09:45 +04:00
inst_simple ${ _src }
2010-07-01 23:17:37 +04:00
# Decompress with chosen tool. We assume that tool changes name e.g.
# from 'name.gz' to 'name'.
2011-05-12 13:03:30 +04:00
${ _cmd } " ${ initdir } ${ _src } "
2010-07-01 23:17:37 +04:00
done
}
# It's similar to above, but if file is not compressed, performs standard
# install.
# $@ = list of files
inst_opt_decompress( ) {
2011-05-12 13:03:30 +04:00
local _src
2010-07-01 23:17:37 +04:00
2011-05-12 13:03:30 +04:00
for _src in $@
2010-07-01 23:17:37 +04:00
do
2011-05-12 13:03:30 +04:00
inst_decompress " ${ _src } " || inst " ${ _src } "
2010-07-01 23:17:37 +04:00
done
}
2012-02-16 14:49:19 +04:00
# module_check <dracut module>
# execute the check() function of module-setup.sh of <dracut module>
# or the "check" script, if module-setup.sh is not found
# "check $hostonly" is called
2011-02-02 15:34:58 +03:00
module_check( ) {
2011-05-12 13:03:30 +04:00
local _moddir = $( echo ${ dracutbasedir } /modules.d/??${ 1 } )
local _ret
2011-08-01 06:01:23 +04:00
local _forced = 0
local _hostonly = $hostonly
[ $# -eq 2 ] && _forced = $2
2011-05-12 13:03:30 +04:00
[ [ -d $_moddir ] ] || return 1
if [ [ ! -f $_moddir /module-setup.sh ] ] ; then
2011-02-02 15:34:58 +03:00
# if we do not have a check script, we are unconditionally included
2011-05-12 13:03:30 +04:00
[ [ -x $_moddir /check ] ] || return 0
2011-08-01 06:01:23 +04:00
[ $_forced -ne 0 ] && unset hostonly
2011-05-12 13:03:30 +04:00
$_moddir /check $hostonly
2011-08-01 06:01:23 +04:00
_ret = $?
2011-02-02 15:34:58 +03:00
else
unset check depends install installkernel
2011-05-12 13:03:30 +04:00
. $_moddir /module-setup.sh
2011-02-02 15:34:58 +03:00
is_func check || return 0
2011-08-01 06:01:23 +04:00
[ $_forced -ne 0 ] && unset hostonly
check $hostonly
2011-05-12 13:03:30 +04:00
_ret = $?
2011-02-02 15:34:58 +03:00
unset check depends install installkernel
2009-05-24 09:29:44 +04:00
fi
2011-08-01 06:01:23 +04:00
hostonly = $_hostonly
return $_ret
2009-05-24 09:29:44 +04:00
}
2012-02-16 14:49:19 +04:00
# module_check_mount <dracut module>
# execute the check() function of module-setup.sh of <dracut module>
# or the "check" script, if module-setup.sh is not found
# "mount_needs=1 check 0" is called
module_check_mount( ) {
local _moddir = $( echo ${ dracutbasedir } /modules.d/??${ 1 } )
local _ret
mount_needs = 1
[ [ -d $_moddir ] ] || return 1
if [ [ ! -f $_moddir /module-setup.sh ] ] ; then
# if we do not have a check script, we are unconditionally included
[ [ -x $_moddir /check ] ] || return 0
mount_needs = 1 $_moddir /check 0
_ret = $?
else
unset check depends install installkernel
. $_moddir /module-setup.sh
is_func check || return 1
check 0
_ret = $?
unset check depends install installkernel
fi
unset mount_needs
return $_ret
}
# module_depends <dracut module>
# execute the depends() function of module-setup.sh of <dracut module>
# or the "depends" script, if module-setup.sh is not found
2011-02-02 15:34:58 +03:00
module_depends( ) {
2011-05-12 13:03:30 +04:00
local _moddir = $( echo ${ dracutbasedir } /modules.d/??${ 1 } )
local _ret
[ [ -d $_moddir ] ] || return 1
if [ [ ! -f $_moddir /module-setup.sh ] ] ; then
2011-02-02 15:34:58 +03:00
# if we do not have a check script, we have no deps
2011-05-12 13:03:30 +04:00
[ [ -x $_moddir /check ] ] || return 0
$_moddir /check -d
2011-02-02 15:34:58 +03:00
return $?
else
unset check depends install installkernel
2011-05-12 13:03:30 +04:00
. $_moddir /module-setup.sh
2011-02-02 15:34:58 +03:00
is_func depends || return 0
depends
2011-05-12 13:03:30 +04:00
_ret = $?
2011-02-02 15:34:58 +03:00
unset check depends install installkernel
2011-05-12 13:03:30 +04:00
return $_ret
2009-07-22 14:43:26 +04:00
fi
2009-05-24 09:29:44 +04:00
}
2012-02-16 14:49:19 +04:00
# module_install <dracut module>
# execute the install() function of module-setup.sh of <dracut module>
# or the "install" script, if module-setup.sh is not found
2011-02-02 15:34:58 +03:00
module_install( ) {
2011-05-12 13:03:30 +04:00
local _moddir = $( echo ${ dracutbasedir } /modules.d/??${ 1 } )
local _ret
[ [ -d $_moddir ] ] || return 1
if [ [ ! -f $_moddir /module-setup.sh ] ] ; then
[ [ -x $_moddir /install ] ] && . " $_moddir /install "
2011-02-02 15:34:58 +03:00
return $?
else
unset check depends install installkernel
2011-05-12 13:03:30 +04:00
. $_moddir /module-setup.sh
2011-02-02 15:34:58 +03:00
is_func install || return 0
install
2011-05-12 13:03:30 +04:00
_ret = $?
2011-02-02 15:34:58 +03:00
unset check depends install installkernel
2011-05-12 13:03:30 +04:00
return $_ret
2011-02-02 15:34:58 +03:00
fi
}
2012-02-16 14:49:19 +04:00
# module_installkernel <dracut module>
# execute the installkernel() function of module-setup.sh of <dracut module>
# or the "installkernel" script, if module-setup.sh is not found
2011-02-02 15:34:58 +03:00
module_installkernel( ) {
2011-05-12 13:03:30 +04:00
local _moddir = $( echo ${ dracutbasedir } /modules.d/??${ 1 } )
local _ret
[ [ -d $_moddir ] ] || return 1
if [ [ ! -f $_moddir /module-setup.sh ] ] ; then
[ [ -x $_moddir /installkernel ] ] && . " $_moddir /installkernel "
2011-02-02 15:34:58 +03:00
return $?
else
unset check depends install installkernel
2011-05-12 13:03:30 +04:00
. $_moddir /module-setup.sh
2011-02-02 15:34:58 +03:00
is_func installkernel || return 0
installkernel
2011-05-12 13:03:30 +04:00
_ret = $?
2011-02-02 15:34:58 +03:00
unset check depends install installkernel
2011-05-12 13:03:30 +04:00
return $_ret
2011-02-02 15:34:58 +03:00
fi
}
2012-02-16 14:49:19 +04:00
# check_mount <dracut module>
# check_mount checks, if a dracut module is needed for the given
# device and filesystem types in "${host_fs_types[@]}"
2011-12-20 10:09:57 +04:00
check_mount( ) {
local _mod = $1
local _moddir = $( echo ${ dracutbasedir } /modules.d/??${ 1 } )
local _ret
local _moddep
2012-10-04 00:33:50 +04:00
[ " ${# host_fs_types [*] } " -le 0 ] && return 1
2011-12-20 10:09:57 +04:00
# If we are already scheduled to be loaded, no need to check again.
strstr " $mods_to_load " " $_mod " && return 0
strstr " $mods_checked_as_dep " " $_mod " && return 1
# This should never happen, but...
[ [ -d $_moddir ] ] || return 1
[ [ $2 ] ] || mods_checked_as_dep += " $_mod "
2012-07-16 14:21:56 +04:00
if strstr " $omit_dracutmodules " " $_mod " ; then
2012-10-10 16:15:11 +04:00
dinfo " dracut module ' $_mod ' will not be installed, because it's in the list to be omitted! "
2012-07-16 14:21:56 +04:00
return 1
fi
2011-12-20 10:09:57 +04:00
2012-10-04 00:33:50 +04:00
if strstr " $dracutmodules $add_dracutmodules $force_add_dracutmodules " " $_mod " ; then
module_check_mount $_mod ; ret = $?
# explicit module, so also accept ret=255
[ [ $ret = 0 || $ret = 255 ] ] || return 1
2011-12-20 10:09:57 +04:00
else
2012-10-04 00:33:50 +04:00
# module not in our list
if [ [ $dracutmodules = all ] ] ; then
# check, if we can and should install this module
module_check_mount $_mod || return 1
else
# skip this module
return 1
fi
2011-12-20 10:09:57 +04:00
fi
2012-10-04 00:33:50 +04:00
2011-12-20 10:09:57 +04:00
for _moddep in $( module_depends $_mod ) ; do
# handle deps as if they were manually added
strstr " $add_dracutmodules " " $_moddep " || \
add_dracutmodules += " $_moddep "
strstr " $force_add_dracutmodules " " $_moddep " || \
force_add_dracutmodules += " $_moddep "
# if a module we depend on fail, fail also
2012-07-16 14:21:56 +04:00
if ! check_module $_moddep ; then
2012-10-10 16:15:11 +04:00
derror " dracut module ' $_mod ' depends on ' $_moddep ', which can't be installed "
2012-07-16 14:21:56 +04:00
return 1
fi
2011-12-20 10:09:57 +04:00
done
strstr " $mods_to_load " " $_mod " || \
mods_to_load += " $_mod "
return 0
}
2012-02-16 14:49:19 +04:00
# check_module <dracut module> [<use_as_dep>]
# check if a dracut module is to be used in the initramfs process
# if <use_as_dep> is set, then the process also keeps track
# that the modules were checked for the dependency tracking process
2011-02-02 15:34:58 +03:00
check_module( ) {
2011-05-12 13:03:30 +04:00
local _mod = $1
local _moddir = $( echo ${ dracutbasedir } /modules.d/??${ 1 } )
local _ret
local _moddep
2011-02-02 15:34:58 +03:00
# If we are already scheduled to be loaded, no need to check again.
2011-05-12 13:03:30 +04:00
strstr " $mods_to_load " " $_mod " && return 0
strstr " $mods_checked_as_dep " " $_mod " && return 1
2011-02-02 15:34:58 +03:00
# This should never happen, but...
2011-05-12 13:03:30 +04:00
[ [ -d $_moddir ] ] || return 1
2011-02-02 15:34:58 +03:00
2011-05-12 13:03:30 +04:00
[ [ $2 ] ] || mods_checked_as_dep += " $_mod "
2011-02-02 15:34:58 +03:00
2012-07-16 14:21:56 +04:00
if strstr " $omit_dracutmodules " " $_mod " ; then
2012-10-10 16:15:11 +04:00
dinfo " dracut module ' $_mod ' will not be installed, because it's in the list to be omitted! "
2012-07-16 14:21:56 +04:00
return 1
fi
2011-02-02 15:34:58 +03:00
2011-08-01 06:01:23 +04:00
if strstr " $dracutmodules $add_dracutmodules $force_add_dracutmodules " " $_mod " ; then
if strstr " $force_add_dracutmodules " " $_mod " ; then
module_check $_mod 1; ret = $?
else
module_check $_mod 0; ret = $?
fi
2011-02-02 15:34:58 +03:00
# explicit module, so also accept ret=255
[ [ $ret = 0 || $ret = 255 ] ] || return 1
else
# module not in our list
if [ [ $dracutmodules = all ] ] ; then
# check, if we can and should install this module
2011-05-12 13:03:30 +04:00
module_check $_mod || return 1
2010-09-10 17:23:06 +04:00
else
2011-02-02 15:34:58 +03:00
# skip this module
return 1
2009-07-02 13:57:23 +04:00
fi
2011-02-02 15:34:58 +03:00
fi
2010-07-27 13:51:27 +04:00
2011-05-12 13:03:30 +04:00
for _moddep in $( module_depends $_mod ) ; do
2011-02-02 15:34:58 +03:00
# handle deps as if they were manually added
2011-05-12 13:03:30 +04:00
strstr " $add_dracutmodules " " $_moddep " || \
add_dracutmodules += " $_moddep "
2011-08-01 06:01:23 +04:00
strstr " $force_add_dracutmodules " " $_moddep " || \
force_add_dracutmodules += " $_moddep "
2011-02-02 15:34:58 +03:00
# if a module we depend on fail, fail also
2012-07-16 14:21:56 +04:00
if ! check_module $_moddep ; then
2012-10-10 16:15:11 +04:00
derror " dracut module ' $_mod ' depends on ' $_moddep ', which can't be installed "
2012-07-16 14:21:56 +04:00
return 1
fi
2009-05-24 09:29:44 +04:00
done
2010-05-26 19:42:57 +04:00
2011-05-12 13:03:30 +04:00
strstr " $mods_to_load " " $_mod " || \
mods_to_load += " $_mod "
2011-02-02 15:34:58 +03:00
return 0
}
2012-02-16 14:49:19 +04:00
# for_each_module_dir <func>
# execute "<func> <dracut module> 1"
2011-12-20 10:09:57 +04:00
for_each_module_dir( ) {
2011-05-12 13:03:30 +04:00
local _modcheck
local _mod
local _moddir
2011-12-20 10:09:57 +04:00
local _func
_func = $1
2011-05-12 13:03:30 +04:00
for _moddir in " $dracutbasedir /modules.d " /[ 0-9] [ 0-9] *; do
_mod = ${ _moddir ##*/ } ; _mod = ${ _mod #[0-9][0-9] }
2011-12-20 10:09:57 +04:00
$_func $_mod 1
2010-05-26 19:42:57 +04:00
done
2011-03-07 15:08:13 +03:00
# Report any missing dracut modules, the user has specified
2011-08-01 06:01:23 +04:00
_modcheck = " $add_dracutmodules $force_add_dracutmodules "
2011-05-12 13:03:30 +04:00
[ [ $dracutmodules != all ] ] && _modcheck = " $m $dracutmodules "
for _mod in $_modcheck ; do
strstr " $mods_to_load " " $_mod " && continue
strstr " $omit_dracutmodules " " $_mod " && continue
2012-10-10 16:15:11 +04:00
derror " dracut module ' $_mod ' cannot be found or installed. "
2011-03-07 15:08:13 +03:00
done
2009-05-24 09:29:44 +04:00
}
2009-08-15 23:17:19 +04:00
# Install a single kernel module along with any firmware it may require.
# $1 = full path to kernel module to install
install_kmod_with_fw( ) {
2011-03-07 15:09:25 +03:00
# no need to go further if the module is already installed
2012-02-25 19:11:36 +04:00
2011-03-25 17:56:46 +03:00
[ [ -e " ${ initdir } /lib/modules/ $kernel / ${ 1 ##*/lib/modules/ $kernel / } " ] ] \
&& return 0
2012-02-15 17:53:18 +04:00
2012-06-30 11:12:35 +04:00
if [ [ $DRACUT_KERNEL_LAZY_HASHDIR ] ] && [ [ -e " $DRACUT_KERNEL_LAZY_HASHDIR / ${ 1 ##*/ } " ] ] ; then
read ret < " $DRACUT_KERNEL_LAZY_HASHDIR / ${ 1 ##*/ } "
2012-06-27 11:35:39 +04:00
return $ret
fi
2012-02-25 19:11:36 +04:00
2012-02-15 17:53:18 +04:00
if [ [ $omit_drivers ] ] ; then
local _kmod = ${ 1 ##*/ }
_kmod = ${ _kmod %.ko }
_kmod = ${ _kmod /-/_ }
2012-02-22 19:12:10 +04:00
if [ [ " $_kmod " = ~ $omit_drivers ] ] ; then
dinfo " Omitting driver $_kmod "
2012-06-18 14:51:21 +04:00
return 0
2012-02-22 19:12:10 +04:00
fi
if [ [ " ${ 1 ##*/lib/modules/ $kernel / } " = ~ $omit_drivers ] ] ; then
2012-02-15 17:53:18 +04:00
dinfo " Omitting driver $_kmod "
2012-06-18 14:51:21 +04:00
return 0
2012-02-15 17:53:18 +04:00
fi
fi
2012-06-27 11:35:39 +04:00
inst_simple " $1 " " /lib/modules/ $kernel / ${ 1 ##*/lib/modules/ $kernel / } "
ret = $?
2012-06-30 11:12:35 +04:00
[ [ $DRACUT_KERNEL_LAZY_HASHDIR ] ] && \
[ [ -d " $DRACUT_KERNEL_LAZY_HASHDIR " ] ] && \
echo $ret > " $DRACUT_KERNEL_LAZY_HASHDIR / ${ 1 ##*/ } "
2012-06-27 11:35:39 +04:00
( ( $ret != 0) ) && return $ret
2011-08-29 00:24:58 +04:00
local _modname = ${ 1 ##*/ } _fwdir _found _fw
_modname = ${ _modname %.ko* }
2011-05-12 13:03:30 +04:00
for _fw in $( modinfo -k $kernel -F firmware $1 2>/dev/null) ; do
_found = ''
for _fwdir in $fw_dir ; do
if [ [ -d $_fwdir && -f $_fwdir /$_fw ] ] ; then
inst_simple " $_fwdir / $_fw " " /lib/firmware/ $_fw "
_found = yes
2010-09-10 17:23:06 +04:00
fi
done
2011-05-12 13:03:30 +04:00
if [ [ $_found != yes ] ] ; then
2012-06-06 20:20:35 +04:00
if ! [ [ -d $( echo /sys/module/${ _modname //-/_ } | { read a b; echo $a ; } ) ] ] ; then
2011-05-12 13:03:30 +04:00
dinfo " Possible missing firmware \" ${ _fw } \" for kernel module " \
" \" ${ _modname } .ko\" "
2011-05-10 13:18:58 +04:00
else
2011-05-12 13:03:30 +04:00
dwarn " Possible missing firmware \" ${ _fw } \" for kernel module " \
" \" ${ _modname } .ko\" "
2011-05-10 13:18:58 +04:00
fi
2010-09-10 17:23:06 +04:00
fi
2009-08-15 23:17:19 +04:00
done
2011-03-07 15:09:25 +03:00
return 0
2009-08-15 23:17:19 +04:00
}
# Do something with all the dependencies of a kernel module.
# Note that kernel modules depend on themselves using the technique we use
2011-03-25 17:56:46 +03:00
# $1 = function to call for each dependency we find
# It will be passed the full path to the found kernel module
2009-08-15 23:17:19 +04:00
# $2 = module to get dependencies for
# rest of args = arguments to modprobe
2011-10-11 01:58:04 +04:00
# _fderr specifies FD passed from surrounding scope
2009-08-15 23:17:19 +04:00
for_each_kmod_dep( ) {
2012-06-18 14:51:21 +04:00
local _func = $1 _kmod = $2 _cmd _modpath _options
2009-08-15 23:17:19 +04:00
shift 2
2011-10-11 01:58:04 +04:00
modprobe " $@ " --ignore-install --show-depends $_kmod 2>& ${ _fderr } | (
2011-05-12 13:03:30 +04:00
while read _cmd _modpath _options; do
[ [ $_cmd = insmod ] ] || continue
$_func ${ _modpath } || exit $?
2011-03-25 17:56:46 +03:00
done
)
2009-08-15 23:17:19 +04:00
}
2012-06-27 19:02:49 +04:00
dracut_kernel_post( ) {
2012-06-27 11:35:39 +04:00
local _moddirname = ${ srcmods %%/lib/modules/* }
2012-06-30 11:12:35 +04:00
if [ [ $DRACUT_KERNEL_LAZY_HASHDIR ] ] && [ [ -f " $DRACUT_KERNEL_LAZY_HASHDIR /lazylist " ] ] ; then
2012-07-03 00:14:49 +04:00
xargs -r modprobe -a ${ _moddirname +-d ${ _moddirname } / } \
--ignore-install --show-depends --set-version $kernel \
2012-06-30 11:12:35 +04:00
< " $DRACUT_KERNEL_LAZY_HASHDIR /lazylist " 2>/dev/null \
2012-06-29 14:07:44 +04:00
| sort -u \
| while read _cmd _modpath _options; do
[ [ $_cmd = insmod ] ] || continue
echo " $_modpath "
2012-06-30 11:12:35 +04:00
done > " $DRACUT_KERNEL_LAZY_HASHDIR /lazylist.dep "
2012-06-27 11:35:39 +04:00
2012-06-29 14:07:44 +04:00
(
2012-06-30 13:34:13 +04:00
if [ [ $DRACUT_INSTALL ] ] && [ [ -z $_moddirname ] ] ; then
xargs -r $DRACUT_INSTALL ${ initdir +-D " $initdir " } -a < " $DRACUT_KERNEL_LAZY_HASHDIR /lazylist.dep "
2012-06-29 14:07:44 +04:00
else
while read _modpath; do
local _destpath = $_modpath
[ [ $_moddirname ] ] && _destpath = ${ _destpath ## $_moddirname / }
_destpath = ${ _destpath ##*/lib/modules/ $kernel / }
inst_simple " $_modpath " " /lib/modules/ $kernel / ${ _destpath } " || exit $?
2012-06-30 11:12:35 +04:00
done < " $DRACUT_KERNEL_LAZY_HASHDIR /lazylist.dep "
2012-06-29 14:07:44 +04:00
fi
) &
2012-06-27 11:35:39 +04:00
2012-06-30 13:34:13 +04:00
if [ [ $DRACUT_INSTALL ] ] ; then
xargs -r modinfo -k $kernel -F firmware < " $DRACUT_KERNEL_LAZY_HASHDIR /lazylist.dep " \
2012-06-29 14:07:44 +04:00
| while read line; do
for _fwdir in $fw_dir ; do
echo $_fwdir /$line ;
done ;
2012-06-30 13:34:13 +04:00
done | xargs -r $DRACUT_INSTALL ${ initdir +-D " $initdir " } -a -o
2012-06-29 14:07:44 +04:00
else
2012-06-30 13:34:13 +04:00
for _fw in $( xargs -r modinfo -k $kernel -F firmware < " $DRACUT_KERNEL_LAZY_HASHDIR /lazylist.dep " ) ; do
2012-06-29 14:07:44 +04:00
for _fwdir in $fw_dir ; do
if [ [ -d $_fwdir && -f $_fwdir /$_fw ] ] ; then
inst_simple " $_fwdir / $_fw " " /lib/firmware/ $_fw "
break
fi
done
done
fi
2012-06-27 11:35:39 +04:00
2012-06-29 14:07:44 +04:00
wait
fi
2012-06-27 19:02:49 +04:00
for _f in modules.builtin.bin modules.builtin; do
[ [ $srcmods /$_f ] ] && break
done || {
dfatal "No modules.builtin.bin and modules.builtin found!"
return 1
}
for _f in modules.builtin.bin modules.builtin modules.order; do
[ [ $srcmods /$_f ] ] && inst_simple " $srcmods / $_f " " /lib/modules/ $kernel / $_f "
done
# generate module dependencies for the initrd
if [ [ -d $initdir /lib/modules/$kernel ] ] && \
! depmod -a -b " $initdir " $kernel ; then
dfatal " \"depmod -a $kernel \" failed. "
exit 1
fi
2012-06-30 11:12:35 +04:00
[ [ $DRACUT_KERNEL_LAZY_HASHDIR ] ] && rm -fr " $DRACUT_KERNEL_LAZY_HASHDIR "
2012-06-27 11:35:39 +04:00
}
2012-06-06 20:20:35 +04:00
2012-10-04 00:32:07 +04:00
module_is_host_only( ) (
local _mod = $1
_mod = ${ _mod ##*/ }
_mod = ${ _mod %.ko }
[ [ " $add_drivers " = ~ " ${ _mod } " ] ] && return 0
# check if module is loaded
[ [ -d $( echo /sys/module/${ _mod //-/_ } | { read a b; echo $a ; } ) ] ] && return 0
# check if module is loadable on the current kernel
# this covers the case, where a new module is introduced
# or a module was renamed
# or a module changed from builtin to a module
modinfo -F filename " $_mod " & >/dev/null || return 0
return 1
)
2011-08-30 00:40:21 +04:00
find_kernel_modules_by_path ( ) (
2012-06-22 17:10:11 +04:00
local _OLDIFS
2013-02-18 14:57:20 +04:00
[ [ -f $srcmods /modules.dep ] ] || return 0
_OLDIFS = $IFS
IFS = :
while read a rest; do
[ [ $a = */$1 /* ] ] || continue
echo $srcmods /$a
done < $srcmods /modules.dep
IFS = $_OLDIFS
2012-06-22 17:10:11 +04:00
return 0
2011-08-30 00:40:21 +04:00
)
2011-08-12 12:29:00 +04:00
2011-08-30 00:40:21 +04:00
find_kernel_modules ( ) {
find_kernel_modules_by_path drivers
}
2012-07-05 12:42:22 +04:00
# instmods [-c [-s]] <kernel module> [<kernel module> ... ]
# instmods [-c [-s]] <kernel subsystem>
2009-08-15 23:17:19 +04:00
# install kernel modules along with all their dependencies.
2012-02-16 14:49:19 +04:00
# <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
2009-02-13 15:42:25 +03:00
instmods( ) {
2009-08-15 19:56:36 +04:00
[ [ $no_kernel = yes ] ] && return
2011-10-11 01:58:04 +04:00
# called [sub]functions inherit _fderr
local _fderr = 9
2012-05-15 10:19:56 +04:00
local _check = no
2012-07-05 12:42:22 +04:00
local _silent = no
2012-05-15 10:19:56 +04:00
if [ [ $1 = '-c' ] ] ; then
_check = yes
shift
fi
2011-08-30 00:40:21 +04:00
2012-07-05 12:42:22 +04:00
if [ [ $1 = '-s' ] ] ; then
_silent = yes
shift
fi
2011-08-30 00:40:21 +04:00
function inst1mod( ) {
2012-05-15 10:19:56 +04:00
local _ret = 0 _mod = " $1 "
2011-05-12 13:03:30 +04:00
case $_mod in
2011-03-25 17:56:46 +03:00
= *)
2012-06-27 11:35:39 +04:00
( [ [ " $_mpargs " ] ] && echo $_mpargs
find_kernel_modules_by_path " ${ _mod #= } " ) \
| instmods
( ( _ret += $? ) )
2010-09-10 17:23:06 +04:00
; ;
2011-08-30 01:46:25 +04:00
--*) _mpargs += " $_mod " ; ;
2012-02-22 19:12:10 +04:00
*)
2012-02-25 19:11:36 +04:00
_mod = ${ _mod ##*/ }
2009-08-28 15:28:19 +04:00
# if we are already installed, skip this module and go on
2010-09-10 17:23:06 +04:00
# to the next one.
2012-06-30 11:12:35 +04:00
if [ [ $DRACUT_KERNEL_LAZY_HASHDIR ] ] && \
[ [ -f " $DRACUT_KERNEL_LAZY_HASHDIR / ${ _mod %.ko } .ko " ] ] ; then
read _ret <" $DRACUT_KERNEL_LAZY_HASHDIR / ${ _mod %.ko } .ko "
2012-06-27 11:35:39 +04:00
return $_ret
fi
2011-08-30 00:40:21 +04:00
2012-02-22 19:12:10 +04:00
if [ [ $omit_drivers ] ] && [ [ " $1 " = ~ $omit_drivers ] ] ; then
dinfo " Omitting driver ${ _mod ## $srcmods } "
2012-06-18 14:51:21 +04:00
return 0
2012-02-22 19:12:10 +04:00
fi
2012-10-04 00:32:07 +04:00
2010-09-10 17:23:06 +04:00
# If we are building a host-specific initramfs and this
# module is not already loaded, move on to the next one.
2012-06-06 20:20:35 +04:00
[ [ $hostonly ] ] \
2012-10-04 00:32:07 +04:00
&& ! module_is_host_only " $_mod " \
2012-06-18 14:51:21 +04:00
&& return 0
2008-12-18 00:57:43 +03:00
2012-06-30 11:12:35 +04:00
if [ [ " $_check " = "yes" ] ] || ! [ [ $DRACUT_KERNEL_LAZY_HASHDIR ] ] ; then
2012-06-27 11:35:39 +04:00
# We use '-d' option in modprobe only if modules prefix path
2012-10-10 16:15:11 +04:00
# differs from default '/'. This allows us to use dracut with
2012-06-27 11:35:39 +04:00
# old version of modprobe which doesn't have '-d' option.
local _moddirname = ${ srcmods %%/lib/modules/* }
[ [ -n ${ _moddirname } ] ] && _moddirname = " -d ${ _moddirname } / "
# ok, load the module, all its dependencies, and any firmware
# it may require
for_each_kmod_dep install_kmod_with_fw $_mod \
--set-version $kernel ${ _moddirname } $_mpargs
( ( _ret += $? ) )
else
2012-06-30 11:12:35 +04:00
[ [ $DRACUT_KERNEL_LAZY_HASHDIR ] ] && \
echo $_mod >> " $DRACUT_KERNEL_LAZY_HASHDIR /lazylist "
2012-06-27 11:35:39 +04:00
fi
2010-09-10 17:23:06 +04:00
; ;
2011-03-25 17:56:46 +03:00
esac
2012-05-15 10:19:56 +04:00
return $_ret
2011-08-30 00:40:21 +04:00
}
2011-08-30 03:03:35 +04:00
function instmods_1( ) {
2012-05-15 10:19:56 +04:00
local _mod _mpargs
2011-08-30 03:03:35 +04:00
if ( ( $# = = 0) ) ; then # filenames from stdin
while read _mod; do
2012-05-15 10:19:56 +04:00
inst1mod " ${ _mod %.ko* } " || {
2012-07-05 12:42:22 +04:00
if [ [ " $_check " = = "yes" ] ] ; then
2013-05-28 16:25:49 +04:00
[ [ " $_silent " = = "no" ] ] && dfatal " Failed to install module $_mod "
2012-05-15 10:19:56 +04:00
return 1
fi
}
2011-08-30 03:03:35 +04:00
done
fi
while ( ( $# > 0) ) ; do # filenames as arguments
2012-05-15 10:19:56 +04:00
inst1mod ${ 1 %.ko* } || {
2012-07-05 12:42:22 +04:00
if [ [ " $_check " = = "yes" ] ] ; then
2013-05-28 16:25:49 +04:00
[ [ " $_silent " = = "no" ] ] && dfatal " Failed to install module $1 "
2012-05-15 10:19:56 +04:00
return 1
fi
}
2011-08-30 03:03:35 +04:00
shift
2011-08-30 00:40:21 +04:00
done
2012-05-15 10:19:56 +04:00
return 0
2011-08-30 03:03:35 +04:00
}
2012-05-15 10:19:56 +04:00
local _ret _filter_not_found = 'FATAL: Module .* not found.'
2011-10-11 01:58:04 +04:00
# Capture all stderr from modprobe to _fderr. We could use {var}>...
# redirections, but that would make dracut require bash4 at least.
eval " ( instmods_1 \"\$@\" ) ${ _fderr } >&1 " \
2012-02-25 19:08:30 +04:00
| while read line; do [ [ " $line " = ~ $_filter_not_found ] ] || echo $line ; done | derror
2012-05-15 10:19:56 +04:00
_ret = $?
return $_ret
2011-03-25 17:56:46 +03:00
}