Import Upstream version 0.136
This commit is contained in:
commit
4073b78a30
|
@ -0,0 +1,8 @@
|
|||
;;; Directory Local Variables
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((sh-mode
|
||||
(sh-basic-offset . 8)
|
||||
(sh-indentation . 8)
|
||||
(sh-indent-for-case-label . 0)
|
||||
(sh-indent-for-case-alt . +)))
|
|
@ -0,0 +1,23 @@
|
|||
# update-initramfs(8) completion
|
||||
|
||||
_update_initramfs()
|
||||
{
|
||||
local cur prev valid_options
|
||||
|
||||
_get_comp_words_by_ref cur prev
|
||||
|
||||
# The only option that takes an argument is -k
|
||||
if [[ "$prev" == '-k' ]]; then
|
||||
# Complete with kernel versions
|
||||
_kernel_versions
|
||||
COMPREPLY=( $( compgen -W '${COMPREPLY[@]} all' -- "$cur" ) )
|
||||
return;
|
||||
fi
|
||||
|
||||
# Complete with available options (obtained from -h)
|
||||
valid_options=$( update-initramfs -h 2>&1 | \
|
||||
sed -e '/^ -/!d;s/^ \(-\w\+\).*/\1/' )
|
||||
COMPREPLY=( $( compgen -W "$valid_options" -- $cur ) )
|
||||
}
|
||||
|
||||
complete -F _update_initramfs update-initramfs
|
|
@ -0,0 +1,81 @@
|
|||
#
|
||||
# initramfs.conf
|
||||
# Configuration file for mkinitramfs(8). See initramfs.conf(5).
|
||||
#
|
||||
# Note that configuration options from this file can be overridden
|
||||
# by config files in the /etc/initramfs-tools/conf.d directory.
|
||||
|
||||
#
|
||||
# MODULES: [ most | netboot | dep | list ]
|
||||
#
|
||||
# most - Add most filesystem and all harddrive drivers.
|
||||
#
|
||||
# dep - Try and guess which modules to load.
|
||||
#
|
||||
# netboot - Add the base modules, network modules, but skip block devices.
|
||||
#
|
||||
# list - Only include modules from the 'additional modules' list
|
||||
#
|
||||
|
||||
MODULES=most
|
||||
|
||||
#
|
||||
# BUSYBOX: [ y | n | auto ]
|
||||
#
|
||||
# Use busybox shell and utilities. If set to n, klibc utilities will be used.
|
||||
# If set to auto (or unset), busybox will be used if installed and klibc will
|
||||
# be used otherwise.
|
||||
#
|
||||
|
||||
BUSYBOX=auto
|
||||
|
||||
#
|
||||
# COMPCACHE_SIZE: [ "x K" | "x M" | "x G" | "x %" ]
|
||||
#
|
||||
# Amount of RAM to use for RAM-based compressed swap space.
|
||||
#
|
||||
# An empty value - compcache isn't used, or added to the initramfs at all.
|
||||
# An integer and K (e.g. 65536 K) - use a number of kilobytes.
|
||||
# An integer and M (e.g. 256 M) - use a number of megabytes.
|
||||
# An integer and G (e.g. 1 G) - use a number of gigabytes.
|
||||
# An integer and % (e.g. 50 %) - use a percentage of the amount of RAM.
|
||||
#
|
||||
# You can optionally install the compcache package to configure this setting
|
||||
# via debconf and have userspace scripts to load and unload compcache.
|
||||
#
|
||||
|
||||
COMPCACHE_SIZE=""
|
||||
|
||||
#
|
||||
# COMPRESS: [ gzip | bzip2 | lz4 | lzma | lzop | xz ]
|
||||
#
|
||||
|
||||
COMPRESS=lz4
|
||||
|
||||
#
|
||||
# NFS Section of the config.
|
||||
#
|
||||
|
||||
#
|
||||
# DEVICE: ...
|
||||
#
|
||||
# Specify a specific network interface, like eth0
|
||||
# Overridden by optional ip= or BOOTIF= bootarg
|
||||
#
|
||||
|
||||
DEVICE=
|
||||
|
||||
#
|
||||
# NFSROOT: [ auto | HOST:MOUNT ]
|
||||
#
|
||||
|
||||
NFSROOT=auto
|
||||
|
||||
#
|
||||
# RUNSIZE: ...
|
||||
#
|
||||
# The size of the /run tmpfs mount point, like 256M or 10%
|
||||
# Overridden by optional initramfs.runsize= bootarg
|
||||
#
|
||||
|
||||
RUNSIZE=10%
|
|
@ -0,0 +1,14 @@
|
|||
### This file is the template for /etc/initramfs-tools/modules.
|
||||
### It is not a configuration file itself.
|
||||
###
|
||||
# List of modules that you want to include in your initramfs.
|
||||
# They will be loaded at boot time in the order below.
|
||||
#
|
||||
# Syntax: module_name [args ...]
|
||||
#
|
||||
# You must run update-initramfs(8) to effect this change.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# raid1
|
||||
# sd_mod
|
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Configuration file for update-initramfs(8)
|
||||
#
|
||||
|
||||
#
|
||||
# update_initramfs [ yes | all | no ]
|
||||
#
|
||||
# Default is yes
|
||||
# If set to all update-initramfs will update all initramfs
|
||||
# If set to no disables any update to initramfs beside kernel upgrade
|
||||
|
||||
update_initramfs=yes
|
||||
|
||||
#
|
||||
# backup_initramfs [ yes | no ]
|
||||
#
|
||||
# Default is no
|
||||
# If set to no leaves no .bak backup files.
|
||||
|
||||
backup_initramfs=no
|
|
@ -0,0 +1,68 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
#
|
||||
# This is an example hook script. It will be run by 'mkinitramfs'
|
||||
# when it creates the image. It's job is to decide which files to
|
||||
# install, then install them into the staging area, where the
|
||||
# initramfs is being created. This happens when a new 'linux-image'
|
||||
# package is installed, or when the administrator runs 'mkinitramfs'
|
||||
# by hand to update an initramfs image.
|
||||
#
|
||||
# CONFDIR -- usually /etc/initramfs-tools, can be set on mkinitramfs
|
||||
# command line.
|
||||
#
|
||||
# DESTDIR -- The staging directory where we are building the image.
|
||||
#
|
||||
# see initramfs-tools(7)
|
||||
|
||||
#
|
||||
# List the soft prerequisites here. This is a space separated list of
|
||||
# names, of scripts that are in the same directory as this one, that
|
||||
# must be run before this one can be.
|
||||
#
|
||||
PREREQ=""
|
||||
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# You can do anything you need to from here on.
|
||||
#
|
||||
|
||||
# Source the optional 'hook-functions' scriptlet, if you need the
|
||||
# functions defined within it. Read it to see what is available to
|
||||
# you. It contains functions for copying dynamically linked program
|
||||
# binaries, and kernel modules into the DESTDIR.
|
||||
#
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
|
||||
# If this hook script is a conffile (and thus stored in
|
||||
# /etc/mkinitramfs/hooks), it must take care to do the right thing
|
||||
# when the package containing it is removed but not purged. There of
|
||||
# course may be other reasons to have custom logic deciding what to
|
||||
# install. The version variable may be useful for this.
|
||||
#
|
||||
if command -v myprog >/dev/null 2>&1; then
|
||||
copy_exec /usr/bin/myprog usr/bin
|
||||
fi
|
||||
|
||||
# To accompany this, there should usually be a script for inside the
|
||||
# initramfs named something like:
|
||||
#
|
||||
# "/etc/mkinitramfs/local-premount/myprog"
|
||||
#
|
||||
# ... and it should do what is necessary to have 'myprog' get run
|
||||
# inside the early runtime environment.
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,48 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# This script is run inside of the initramfs environment during the
|
||||
# system boot process. It is installed there by 'update-initramfs'.
|
||||
# The # package that owns it may opt to install it in an appropriate
|
||||
# location under "/usr/share/initramfs-tools/scripts/".
|
||||
#
|
||||
# see initramfs-tools(7) for more details.
|
||||
|
||||
#
|
||||
# List the soft prerequisites here. This is a space separated list of
|
||||
# names, of scripts that are in the same directory as this one, that
|
||||
# must be run before this one can be.
|
||||
#
|
||||
PREREQ=""
|
||||
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
mountfail) # Called if the script has previously registered a mountroot
|
||||
# failure.
|
||||
# Check status, and display any relevant information about the
|
||||
# failure if there is a problem, then exit with a status of 1.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Do the work here.
|
||||
|
||||
# If this script is to be placed in either init-premount, or local-top,
|
||||
# register a mountroot failure hook, so that further information can be given
|
||||
# to the user, in the event that the root device cannot be found.
|
||||
|
||||
. /scripts/functions
|
||||
|
||||
add_mountroot_fail_hook
|
||||
|
||||
echo "Got here!"
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,116 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# The options part of the kernel "video=" argument (i.e. everyting
|
||||
# after "video=<fbdriver>:") has very inconsistent rules.
|
||||
#
|
||||
# Generally the following applies:
|
||||
# 1) options are comma-separated
|
||||
# 2) options can be in either of these three forms:
|
||||
# <arg>=<value>, <arg>:<value>, <boolean-arg>.
|
||||
# 3) the "mode" or "mode_option" option (name depends on the framebuffer driver)
|
||||
# has the form <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m]
|
||||
# and may or may not start with "mode=" or "mode_option="
|
||||
# -> please adjust as necessary in the parse_video_opts() function
|
||||
#
|
||||
# When the options are used with modules, they need to be space-separated
|
||||
# and the following conversions are needed:
|
||||
# <arg>:<value> -> <arg>=<value>
|
||||
# <boolean-arg> -> <boolean-arg>=1
|
||||
# <modevalue> -> mode=<modevalue> or mode_option=<modevalue>
|
||||
parse_video_opts()
|
||||
{
|
||||
local OPTS="$1"
|
||||
local IFS=","
|
||||
|
||||
# Must be a line like video=<fbdriver>:<opt1>,[opt2]...
|
||||
if [ "${OPTS}" = "${OPTS%%:*}" ]; then
|
||||
return
|
||||
fi
|
||||
OPTS="${OPTS#*:}"
|
||||
for opt in ${OPTS}; do
|
||||
# Already in the "<arg>=<value>" form
|
||||
if [ "${opt}" != "${opt#*=}" ]; then
|
||||
printf "%s" "$opt "
|
||||
# In the "<arg>:<value>" form
|
||||
elif [ "${opt}" != "${opt#*:}" ]; then
|
||||
printf "%s" "${opt%:*}=${opt#*:} "
|
||||
# Presumably a modevalue without the "mode=" prefix
|
||||
elif [ "${opt}" != "${opt#[0-9]*x[0-9]}" ]; then
|
||||
# Adjust: mode= option?
|
||||
printf "%s" "mode=$opt "
|
||||
# ... or mode_option= option?
|
||||
# printf "%s" "mode_option=$opt "
|
||||
# Presumably a boolean
|
||||
else
|
||||
printf "%s" "${opt}=1 "
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
FB=""
|
||||
OPTS=""
|
||||
|
||||
# shellcheck disable=SC2013
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
vga=*)
|
||||
FB="vesafb";
|
||||
OPTS="";
|
||||
;;
|
||||
video=*)
|
||||
FB=${x#*=}
|
||||
FB="${FB%%:*}"
|
||||
OPTS="$(parse_video_opts "${x}")"
|
||||
esac
|
||||
done
|
||||
|
||||
# Module-specific workarounds
|
||||
case ${FB} in
|
||||
matroxfb)
|
||||
# Map command line name to module name
|
||||
FB=matroxfb_base
|
||||
;;
|
||||
intelfb|i810fb|i915)
|
||||
# Needs AGP driver loaded
|
||||
modprobe intel-agp
|
||||
;;
|
||||
uvesafb)
|
||||
# v86d requires /dev/zero and dev/mem, but udev haven't been started yet
|
||||
[ -e /dev/zero ] || mknod -m 0666 /dev/zero c 1 5
|
||||
[ -e /dev/mem ] || mknod -m 0640 /dev/mem c 1 1
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${FB}" ]; then
|
||||
unset MODPROBE_OPTIONS
|
||||
modprobe -q fbcon
|
||||
# shellcheck disable=SC2086
|
||||
modprobe -q ${FB} ${OPTS}
|
||||
fi
|
||||
|
||||
if [ -e /proc/fb ]; then
|
||||
# shellcheck disable=SC2034
|
||||
while read -r fbno desc; do
|
||||
if [ $((fbno < 32)) ]; then
|
||||
mknod -m 0640 "/dev/fb${fbno}" c 29 "${fbno}"
|
||||
fi
|
||||
done < /proc/fb
|
||||
else
|
||||
mknod -m 0640 /dev/fb0 c 29 0
|
||||
fi
|
|
@ -0,0 +1,234 @@
|
|||
***
|
||||
|
||||
# Maintainer documentation for initramfs-tools
|
||||
|
||||
***
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [1. Definitions](#definitions)
|
||||
* [2. Preparations](#preparations)
|
||||
* [3. Workflow for daily work](#workflow)
|
||||
* [3.1 Implement new features](#newfeature)
|
||||
* [3.2 Merge branches](#merge)
|
||||
* [3.3 Test specific branch](#test)
|
||||
* [3.4 Build snapshot version](#snapshot)
|
||||
* [4. Contribute](#contribute)
|
||||
* [5. Release new version](#release)
|
||||
* [6. Resources](#resources)
|
||||
* [7. Credits](#credits)
|
||||
* [8. License](#license)
|
||||
|
||||
***
|
||||
|
||||
**NOTE:** The most recent version of this document is available at
|
||||
docs/maintainer-notes.md in the [the git repository](#checkout)
|
||||
or online at [salsa.debian.org](https://salsa.debian.org/kernel-team/initramfs-tools/blob/master/docs/maintainer-notes.md).
|
||||
|
||||
***
|
||||
|
||||
## <a name="definitions">1. Definitions</a>
|
||||
|
||||
<table>
|
||||
<tr><td><code><b>$mailaddress:</b></code></td><td>mailaddress of the user</td></tr>
|
||||
<tr><td><code><b>$username:</b></code></td><td>name of the Salsa account</td></tr>
|
||||
<tr><td><code><b>$version:</b></code></td><td>version string</td></tr>
|
||||
<tr><td><code><b>$yourname:</b></code></td><td>your fullname</td></tr>
|
||||
</table>
|
||||
|
||||
***
|
||||
|
||||
## <a name="preparations">2. Preparations</a>
|
||||
|
||||
1. Install required software:
|
||||
|
||||
# apt-get install git git-buildpackage dpkg-dev
|
||||
|
||||
1. Set environment variables (e.g. through your ~/.bashrc or ~/.zshrc) for devscripts (gbp dch):
|
||||
|
||||
export DEBEMAIL=$mailaddress
|
||||
export DEBFULLNAME=$yourname
|
||||
|
||||
1. Set user name and email address for git (drop the --global option to use configuration per-repo basis):
|
||||
|
||||
% git config --global user.name "$yourname"
|
||||
% git config --global user.email "$mailaddress"
|
||||
|
||||
1. <a name="checkout">Checkout repository (anonymous):</a>
|
||||
|
||||
% git clone https://salsa.debian.org/kernel-team/initramfs-tools.git
|
||||
% cd initramfs-tools
|
||||
|
||||
1. Checkout repository (with developer access):
|
||||
|
||||
% git clone ssh://git@salsa.debian.org/kernel-team/initramfs-tools.git
|
||||
% cd initramfs-tools
|
||||
|
||||
***
|
||||
|
||||
## <a name="workflow">3. Workflow for daily work</a>
|
||||
|
||||
### <a name="newfeature">3.1 Implement new features</a>
|
||||
|
||||
1. Checkout new branch and switch to it:
|
||||
|
||||
% git checkout -b $username/short-descr-of-new-feature
|
||||
|
||||
1. Hack and commit work:
|
||||
|
||||
% $EDITOR $somefile
|
||||
% git add $somefile
|
||||
% git commit -s
|
||||
|
||||
**NOTE:** Use 'Closes: #BUGID' for closing a bugreport and 'Thanks: Fullname
|
||||
<mailaddress>' for giving credits in your commit message. gbp dch will use
|
||||
this information for generating the changelog using the --meta option later
|
||||
on.
|
||||
|
||||
1. Finally push your branch to Salsa:
|
||||
|
||||
% git push origin $username/short-descr-of-new-feature
|
||||
|
||||
### <a name="merge">3.2 Merge branches</a>
|
||||
|
||||
1. Switch to the branch you want to merge:
|
||||
|
||||
% git checkout $username/new-feature
|
||||
|
||||
1. Rebase to master:
|
||||
|
||||
% git rebase master
|
||||
|
||||
1. Switch to master branch and merge:
|
||||
|
||||
% git checkout master
|
||||
% git merge $username/new-feature
|
||||
|
||||
1. Push:
|
||||
|
||||
% git push
|
||||
|
||||
1. After branch is merged delete branch on server and locally:
|
||||
|
||||
% git push origin :$username/short-descr-of-new-feature
|
||||
% git branch -d $username/short-descr-of-new-feature
|
||||
|
||||
1. If a branch is removed from the server it will stay locally. You can get of
|
||||
any stale remote branches locally by executing:
|
||||
|
||||
% git remote prune origin
|
||||
|
||||
### <a name="test">3.3 Test specific branch</a>
|
||||
|
||||
1. Checkout a specific branch iff branch is not already present locally:
|
||||
|
||||
% git checkout -b somename/short-descr-of-new-feature origin/somename/short-descr-of-new-feature
|
||||
|
||||
1. Checkout a specific branch iff branch is already present locally:
|
||||
|
||||
% git checkout -b somename/short-descr-of-new-feature
|
||||
|
||||
1. Adjust debian/changelog accordingly:
|
||||
|
||||
% gbp dch --debian-branch="$(git branch | awk -F\*\ '/^* / { print $2}' )" \
|
||||
--since="v$(dpkg-parsechangelog | awk '/^Version:/ {print $2}')" -S --id-length=7 --meta --multimaint-merge
|
||||
|
||||
1. Build package:
|
||||
|
||||
% gbp buildpackage --git-ignore-new --git-debian-branch="$(git branch | awk -F\*\ '/^* / { print $2}' )" --post-clean
|
||||
|
||||
***
|
||||
|
||||
### <a name="snapshot">3.4 Build snapshot version</a>
|
||||
|
||||
1. Adjust debian/changelog accordingly:
|
||||
|
||||
% gbp dch --debian-branch="$(git branch | awk -F\*\ '/^* / { print $2}' )" \
|
||||
--since="v$(dpkg-parsechangelog | awk '/^Version:/ {print $2}')" -S --id-length=7 --meta --multimaint-merge
|
||||
|
||||
1. Build package:
|
||||
|
||||
% gbp buildpackage --git-debian-branch="$(git branch | awk -F\*\ '/^* / { print $2}' )" --post-clean [-us -uc]
|
||||
|
||||
***
|
||||
|
||||
## <a name="contribute">4. Contribute</a>
|
||||
|
||||
1. Create patch:
|
||||
|
||||
% git format-patch -s -p origin/master
|
||||
|
||||
1. Send patch file(s) to maintainers via mail (requires Debian package git-email):
|
||||
|
||||
% git send-email --to=initramfs-tools@packages.debian.org $PATCHFILE[S]
|
||||
|
||||
1. The development mailinglists are [debian-kernel@lists.debian.org](mailto:debian-kernel@lists.debian.org)
|
||||
and [initramfs@vger.kernel.org](mailto:initramfs@vger.kernel.org).
|
||||
Discussion of features, bugs and patches are more than welcome on one
|
||||
of these lists.
|
||||
|
||||
***
|
||||
|
||||
## <a name="release">5. Release new version</a>
|
||||
|
||||
1. Creating changelog:
|
||||
|
||||
% gbp dch --debian-branch master --release --since HASH
|
||||
|
||||
or more dynamically:
|
||||
|
||||
% gbp dch --meta --release --since v$(dpkg-parsechangelog | awk '/^Version:/ {print $2}') --debian-branch="$(git branch | awk -F\*\ '/^* / { print $2}' )" --id-length=7 --meta --multimaint-merge
|
||||
|
||||
**NOTE:** we do not use history based sorting for the changelog entries but
|
||||
sort them by author.
|
||||
|
||||
1. Releasing:
|
||||
|
||||
% git commit -a -s -m "Releasing version $version."
|
||||
|
||||
1. Tagging:
|
||||
|
||||
% git tag -s v"$version" -m "release $version"
|
||||
|
||||
1. Pushing:
|
||||
|
||||
% git push
|
||||
% git push --tags
|
||||
|
||||
1. Build in chroot and upload to ftp-master.
|
||||
|
||||
1. Send mail announcing the new initramfs-tools version with subject
|
||||
"initramfs-tools $VERSION release" to initramfs@vger.kernel.org,
|
||||
debian-kernel@lists.debian.org + kernel-team@lists.ubuntu.com - including a
|
||||
shortlog (generated through "git shortlog $TAG..").
|
||||
|
||||
***
|
||||
|
||||
## <a name="resources">6. Resources</a>
|
||||
|
||||
* [initramfs-tools git web interface](https://salsa.debian.org/kernel-team/initramfs-tools)
|
||||
* [initramfs @ debian-wiki](https://wiki.debian.org/initramfs)
|
||||
* [bugreports](https://bugs.debian.org/cgi-bin/pkgreport.cgi?src=initramfs-tools;dist=unstable)
|
||||
* [initramfs-tools @ tracker](https://tracker.debian.org/pkg/initramfs-tools)
|
||||
* [popcon graph](https://qa.debian.org/popcon.php?package=initramfs-tools)
|
||||
* [bugreports @ ubuntu](https://bugs.launchpad.net/ubuntu/+source/initramfs-tools)
|
||||
* [qa page @ ubuntu](http://status.qa.ubuntu.com/qapkgstatus/initramfs-tools)
|
||||
|
||||
***
|
||||
|
||||
## <a name="credits">7. Credits</a>
|
||||
|
||||
* Thanks to Daniel Baumann for his "[Debian Packaging with Git](http://documentation.debian-projects.org/other/debian-packaging-git/)" which inspired this document.
|
||||
|
||||
***
|
||||
|
||||
## <a name="license">8. License</a>
|
||||
|
||||
* This document is licensed under GPL v2 or any later version.
|
||||
|
||||
***
|
||||
|
||||
*-- Michael Prokop <[mika@debian.org](mailto:mika@debian.org)>,
|
||||
Ben Hutchings <[ben@decadent.org.uk](mailto:ben@decadent.org.uk)>*
|
||||
|
||||
***
|
|
@ -0,0 +1,929 @@
|
|||
# -*- shell-script -*-
|
||||
|
||||
catenate_cpiogz() {
|
||||
# Sanity check
|
||||
if [ ! -e "${1}" ]; then
|
||||
echo "W: catenate_cpiogz: arg1='${1}' does not exist." >&2
|
||||
return
|
||||
fi
|
||||
|
||||
cat "${1}" >>"${__TMPCPIOGZ}"
|
||||
}
|
||||
|
||||
prepend_earlyinitramfs() {
|
||||
# Sanity check
|
||||
if [ ! -e "${1}" ]; then
|
||||
echo "W: prepend_earlyinitramfs: arg1='${1}' does not exist." >&2
|
||||
return
|
||||
fi
|
||||
|
||||
cat "${1}" >>"${__TMPEARLYCPIO}"
|
||||
}
|
||||
|
||||
# force_load module [args...]
|
||||
force_load()
|
||||
{
|
||||
manual_add_modules "$1"
|
||||
echo "${@}" >>"${DESTDIR}/conf/modules"
|
||||
}
|
||||
|
||||
# Takes a file containing a list of modules to be added as an
|
||||
# argument, figures out dependancies, and adds them.
|
||||
#
|
||||
# Input file syntax:
|
||||
#
|
||||
# # comment
|
||||
# modprobe_module_name [args ...]
|
||||
# [...]
|
||||
#
|
||||
add_modules_from_file()
|
||||
{
|
||||
# Sanity check
|
||||
if [ ! -e "${1}" ]; then
|
||||
echo "W: add_modules_from_file: arg1='${1}' does not exist." >&2
|
||||
return
|
||||
fi
|
||||
|
||||
grep '^[^#]' "${1}" | while read -r module args; do
|
||||
[ -n "$module" ] || continue
|
||||
force_load "${module}" "${args}"
|
||||
done
|
||||
}
|
||||
|
||||
# Is this module available?
|
||||
have_module()
|
||||
{
|
||||
modprobe --set-version="${version?}" --ignore-install \
|
||||
--show-depends "${1}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Add dependent modules + eventual firmware
|
||||
manual_add_modules()
|
||||
{
|
||||
local prefix kmod options firmware
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# modprobe --ignore-install inhibits processing of 'install'
|
||||
# configuration lines, so that instead we will see 'insmod
|
||||
# module.ko' as we want. However it also means that 'softdep'
|
||||
# configuration lines and embedded softdep information is not
|
||||
# processed. So we run twice, with and without this option.
|
||||
# shellcheck disable=SC2034
|
||||
{ modprobe --all --set-version="${version?}" --ignore-install --quiet --show-depends "$@";
|
||||
modprobe --all --set-version="${version}" --quiet --show-depends "$@"; } |
|
||||
while read -r prefix kmod options ; do
|
||||
if [ "${prefix}" != "insmod" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
copy_file module "${kmod}" || continue
|
||||
|
||||
# Add required firmware
|
||||
for firmware in $(modinfo -k "${version}" -F firmware "${kmod}"); do
|
||||
if [ -e "${DESTDIR}/lib/firmware/${firmware}" ] \
|
||||
|| [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Only print warning for missing fw of loaded module
|
||||
# or forced loaded module
|
||||
if [ ! -e "/lib/firmware/${firmware}" ] \
|
||||
&& [ ! -e "/lib/firmware/${version}/${firmware}" ] ; then
|
||||
# Only warn about missing firmware if
|
||||
# /proc/modules exists
|
||||
if [ ! -e /proc/modules ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
kmod_modname="${kmod##*/}"
|
||||
kmod_modname="${kmod_modname%%.*}"
|
||||
if grep -q "^$kmod_modname\\>" /proc/modules "${CONFDIR}/modules"; then
|
||||
echo "W: Possible missing firmware /lib/firmware/${firmware} for module ${kmod_modname}" >&2
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -e "/lib/firmware/${version}/${firmware}" ]; then
|
||||
copy_file firmware \
|
||||
"/lib/firmware/${version}/${firmware}"
|
||||
else
|
||||
copy_file firmware "/lib/firmware/${firmware}"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
# $1 = file type (for logging)
|
||||
# $2 = file to copy to initramfs
|
||||
# $3 (optional) Name for the file on the initramfs
|
||||
# Location of the image dir is assumed to be $DESTDIR
|
||||
# If the target exists, we leave it and return 1.
|
||||
# On any other error, we return >1.
|
||||
copy_file() {
|
||||
local type src target link_target
|
||||
|
||||
type="${1}"
|
||||
src="${2}"
|
||||
target="${3:-$2}"
|
||||
|
||||
[ -f "${src}" ] || return 2
|
||||
|
||||
if [ -d "${DESTDIR}/${target}" ]; then
|
||||
target="${target}/${src##*/}"
|
||||
fi
|
||||
|
||||
# Canonicalise usr-merged target directories
|
||||
case "${target}" in
|
||||
/bin/* | /lib* | /sbin/*) target="/usr${target}" ;;
|
||||
esac
|
||||
|
||||
# check if already copied
|
||||
[ -e "${DESTDIR}/${target}" ] && return 1
|
||||
|
||||
mkdir -p "${DESTDIR}/${target%/*}"
|
||||
|
||||
if [ -h "${src}" ]; then
|
||||
# We don't need to replicate a chain of links completely;
|
||||
# just link directly to the ultimate target
|
||||
link_target="$(readlink -f "${src}")" || return $(($? + 1))
|
||||
|
||||
# Update source for the copy
|
||||
src="${link_target}"
|
||||
|
||||
# Canonicalise usr-merged target directories
|
||||
case "${link_target}" in
|
||||
/bin/* | /lib* | /sbin/*) link_target="/usr${link_target}" ;;
|
||||
esac
|
||||
|
||||
if [ "${link_target}" != "${target}" ]; then
|
||||
[ "${verbose?}" = "y" ] && echo "Adding ${type}-link ${src}"
|
||||
|
||||
# Create a relative link so it always points
|
||||
# to the right place
|
||||
ln -rs "${DESTDIR}/${link_target}" "${DESTDIR}/${target}"
|
||||
fi
|
||||
|
||||
# Copy the link target if it doesn't already exist
|
||||
target="${link_target}"
|
||||
[ -e "${DESTDIR}/${target}" ] && return 0
|
||||
mkdir -p "${DESTDIR}/${target%/*}"
|
||||
fi
|
||||
|
||||
[ "${verbose}" = "y" ] && echo "Adding ${type} ${src}"
|
||||
|
||||
cp -pP "${src}" "${DESTDIR}/${target}" || return $(($? + 1))
|
||||
}
|
||||
|
||||
# $1 = executable to copy to initramfs, with library dependencies
|
||||
# $2 (optional) Name for the file on the initramfs
|
||||
# Location of the image dir is assumed to be $DESTDIR
|
||||
# We never overwrite the target if it exists.
|
||||
copy_exec() {
|
||||
local src target x nonoptlib ret
|
||||
|
||||
src="${1}"
|
||||
target="${2:-$1}"
|
||||
|
||||
copy_file binary "${src}" "${target}" || return $(($? - 1))
|
||||
|
||||
# Copy the dependant libraries
|
||||
for x in $(env --unset=LD_PRELOAD ldd "${src}" 2>/dev/null | sed -e '
|
||||
/\//!d;
|
||||
/linux-gate/d;
|
||||
/=>/ {s/.*=>[[:blank:]]*\([^[:blank:]]*\).*/\1/};
|
||||
s/[[:blank:]]*\([^[:blank:]]*\) (.*)/\1/' 2>/dev/null); do
|
||||
|
||||
# Try to use non-optimised libraries where possible.
|
||||
# We assume that all HWCAP libraries will be in tls,
|
||||
# sse2, vfp or neon.
|
||||
nonoptlib=$(echo "${x}" | sed -e 's#/lib/\([^/]*/\)\?\(tls\|i686\|sse2\|neon\|vfp\).*/\(lib.*\)#/lib/\1\3#')
|
||||
nonoptlib=$(echo "${nonoptlib}" | sed -e 's#-linux-gnu/\(tls\|i686\|sse2\|neon\|vfp\).*/\(lib.*\)#-linux-gnu/\2#')
|
||||
|
||||
if [ -e "${nonoptlib}" ]; then
|
||||
x="${nonoptlib}"
|
||||
fi
|
||||
|
||||
# Handle common dlopen() dependency (Debian bug #950254)
|
||||
case "${x}" in
|
||||
*/libpthread.so.*)
|
||||
copy_exec "/lib/libgcc_s.so.1" || copy_exec "${x%/*}/libgcc_s.so.1" || return
|
||||
;;
|
||||
esac
|
||||
|
||||
copy_file library "${x}" || {
|
||||
ret=$?
|
||||
[ ${ret} = 1 ] || return $((ret - 1))
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
# Copy entire subtrees to the initramfs
|
||||
copy_modules_dir()
|
||||
{
|
||||
local kmod first exclude
|
||||
local modules=
|
||||
local dir="$1"
|
||||
shift
|
||||
|
||||
if ! [ -d "${MODULESDIR}/${dir}" ]; then
|
||||
return;
|
||||
fi
|
||||
if [ "${verbose}" = "y" ]; then
|
||||
echo "Copying module directory ${dir}"
|
||||
if [ $# -ge 1 ]; then
|
||||
echo "(excluding $*)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build up an expression for find
|
||||
first=true
|
||||
for exclude in "$@"; do
|
||||
# Change .ko suffix in exclusion to .ko*
|
||||
if [ "${exclude%.ko}" != "${exclude}" ]; then
|
||||
exclude="${exclude}*"
|
||||
fi
|
||||
$first && set --
|
||||
set -- "$@" -name "${exclude}" -prune -o
|
||||
first=false
|
||||
done
|
||||
|
||||
# shellcheck disable=SC2044
|
||||
for kmod in $(find "${MODULESDIR}/${dir}" "$@" -name '*.ko*' -printf '%f\n'); do
|
||||
modules="$modules ${kmod%%.*}"
|
||||
done
|
||||
# shellcheck disable=SC2086
|
||||
manual_add_modules $modules
|
||||
}
|
||||
|
||||
# walk /sys for relevant modules
|
||||
sys_walk_mod_add()
|
||||
{
|
||||
local driver_path module device_path modalias
|
||||
device_path="$1"
|
||||
|
||||
while [ "${device_path}" != "/sys" ]; do
|
||||
# device modalias
|
||||
if [ -e "${device_path}/modalias" ]; then
|
||||
modalias=$(cat "${device_path}/modalias")
|
||||
if [ -n "${modalias}" ]; then
|
||||
manual_add_modules "${modalias}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# current driver module
|
||||
driver_path="$(readlink -f "${device_path}/driver/module")"
|
||||
if [ -e "$driver_path" ]; then
|
||||
module="$(basename "$(readlink -f "$driver_path")")"
|
||||
if [ -n "${module}" ]; then
|
||||
manual_add_modules "${module}"
|
||||
fi
|
||||
fi
|
||||
|
||||
device_path="$(dirname "${device_path}")"
|
||||
done
|
||||
}
|
||||
|
||||
nvme_dev_sys_walk_mod_add()
|
||||
{
|
||||
local dev_sys_path component nvme_sys_path
|
||||
dev_sys_path="$(readlink -f "$1")"
|
||||
if ! echo "$dev_sys_path" | grep -q "nvme-subsys"; then
|
||||
return
|
||||
fi
|
||||
for component in "$dev_sys_path"/nvme* ; do
|
||||
if [ -L "$component" ] ; then
|
||||
nvme_sys_path=$(readlink -f "$component")
|
||||
sys_walk_mod_add "$nvme_sys_path"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
block_dev_sys_walk_mod_add()
|
||||
{
|
||||
local dev_sys_path disk_sys_path component
|
||||
|
||||
# Resolve symlink so sys_walk_mod_add can walk up the hierarchy
|
||||
dev_sys_path="$(readlink -f "$1")"
|
||||
|
||||
# Find whole disk from partition
|
||||
if grep -q "^DEVTYPE=partition$" "$dev_sys_path/uevent"; then
|
||||
disk_sys_path="$dev_sys_path/.."
|
||||
else
|
||||
disk_sys_path="$dev_sys_path"
|
||||
fi
|
||||
|
||||
# Iterate over component of a layered device
|
||||
find "$disk_sys_path/slaves" -mindepth 1 -maxdepth 1 | while read -r component; do
|
||||
block_dev_sys_walk_mod_add "$component"
|
||||
done
|
||||
nvme_dev_sys_walk_mod_add "$disk_sys_path/device"
|
||||
|
||||
sys_walk_mod_add "${dev_sys_path}"
|
||||
}
|
||||
|
||||
block_dev_mod_add()
|
||||
{
|
||||
local dev_node dev_num dev_sys_path
|
||||
dev_node="$1"
|
||||
|
||||
# Look up device number and convert to decimal as it appears in sysfs
|
||||
dev_num="$(stat -L -c %t:%T "$dev_node")"
|
||||
dev_num="$((0x${dev_num%:*})):$((0x${dev_num#*:}))"
|
||||
|
||||
# Look up device in sysfs
|
||||
dev_sys_path="/sys/dev/block/$dev_num"
|
||||
if [ ! -d "$dev_sys_path" ]; then
|
||||
echo "mkinitramfs: for device ${dev_node} missing ${dev_sys_path}" >&2
|
||||
echo "mkinitramfs: workaround is MODULES=most" >&2
|
||||
echo "mkinitramfs: Error please report the bug" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
block_dev_sys_walk_mod_add "$dev_sys_path"
|
||||
}
|
||||
|
||||
# Copy all loaded or built-in modules matching the given pattern.
|
||||
# Pattern mustn't include directory or '.ko' suffix but should use
|
||||
# '[-_]' to allow for differences in naming between /sys/module and
|
||||
# modules.builtin.
|
||||
add_loaded_modules()
|
||||
{
|
||||
local pattern="$1"
|
||||
local module builtin
|
||||
builtin="/lib/modules/$(uname -r)/modules.builtin"
|
||||
|
||||
for module in /sys/module/$pattern; do
|
||||
if [ -d "$module" ]; then
|
||||
manual_add_modules "$(basename "$module")"
|
||||
fi
|
||||
done
|
||||
if [ -f "$builtin" ]; then
|
||||
while read -r module; do
|
||||
case "$module" in
|
||||
*/$pattern.ko)
|
||||
manual_add_modules "$(basename "$module" .ko)"
|
||||
;;
|
||||
esac
|
||||
done < "$builtin"
|
||||
fi
|
||||
}
|
||||
|
||||
# find and only copy modules relevant to a mountpoint
|
||||
dep_add_modules_mount()
|
||||
{
|
||||
local dir dev_node FSTYPE
|
||||
|
||||
dir="$1"
|
||||
|
||||
# require mounted sysfs
|
||||
if [ ! -d /sys/devices/ ]; then
|
||||
echo "mkinitramfs: MODULES dep requires mounted sysfs on /sys" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# find out block device + fstype
|
||||
# shellcheck disable=SC2034
|
||||
eval "$(while read -r dev mp fs opts rest ; do \
|
||||
[ "$mp" = "$dir" ] && [ "$fs" != "rootfs" ] \
|
||||
&& printf "dev_node=%s\\nFSTYPE=%s" "$dev" "$fs"\
|
||||
&& break; done < /proc/mounts)"
|
||||
|
||||
# Only the root mountpoint has to exist; do nothing if any other
|
||||
# directory is not a mountpoint.
|
||||
if [ "$dir" != / ] && [ -z "$dev_node" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# handle ubifs and return since ubifs is mounted on char devices
|
||||
# but most of the commands below only work with block devices.
|
||||
if [ "${FSTYPE}" = "ubifs" ]; then
|
||||
manual_add_modules "${FSTYPE}"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "${FSTYPE}" = "zfs" ]; then
|
||||
manual_add_modules "${FSTYPE}"
|
||||
|
||||
# ZFS uses the name of a filesystem instead of a device. Find
|
||||
# the devices that make up the pool containing the specified
|
||||
# filesystem, and add the appropriate driver for each device.
|
||||
local poolname="${dev_node%%/*}"
|
||||
# shellcheck disable=SC2034
|
||||
zpool list -vPL "$poolname" | while read -r dev ignored; do
|
||||
# Ignore non-leaf vdevs by skipping anything that doesn't
|
||||
# look like an absolute path
|
||||
echo "$dev" | grep -q '^/' && block_dev_mod_add "$dev"
|
||||
done
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$dir" = / ] && [ "${dev_node}" = "/dev/root" ] ; then
|
||||
if [ -b "${dev_node}" ]; then
|
||||
# Match it to the canonical device name by UUID
|
||||
dev_node="/dev/disk/by-uuid/"$(blkid -o value -s UUID "${dev_node}") 2>/dev/null
|
||||
else
|
||||
# Does not exist in our namespace, so look at the
|
||||
# kernel command line
|
||||
dev_node=
|
||||
# shellcheck disable=SC2013
|
||||
for arg in $(cat /proc/cmdline); do
|
||||
case "$arg" in
|
||||
root=*)
|
||||
dev_node="${arg#root=}"
|
||||
if [ "${dev_node#/dev/}" = "$dev_node" ]; then
|
||||
dev_node="/dev/$dev_node"
|
||||
fi
|
||||
;;
|
||||
--)
|
||||
break
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# recheck device
|
||||
if [ -z "$dev_node" ] || ! dev_node="$(readlink -f "${dev_node}")" \
|
||||
|| ! [ -b "$dev_node" ]; then
|
||||
echo "mkinitramfs: failed to determine device for $dir" >&2
|
||||
echo "mkinitramfs: workaround is MODULES=most, check:" >&2
|
||||
echo "grep -r MODULES ${CONFDIR}" >&2
|
||||
echo "" >&2
|
||||
echo "Error please report bug on initramfs-tools" >&2
|
||||
echo "Include the output of 'mount' and 'cat /proc/mounts'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# do not trust mount, check superblock
|
||||
FSTYPE=$(blkid -o value -s TYPE "${dev_node}")
|
||||
if [ -z "${FSTYPE}" ]; then
|
||||
echo "mkinitramfs: unknown fstype on device ${dev_node}" >&2
|
||||
echo "mkinitramfs: workaround is MODULES=most" >&2
|
||||
echo "Error please report bug on initramfs-tools" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add filesystem
|
||||
manual_add_modules "${FSTYPE}"
|
||||
|
||||
block_dev_mod_add "$dev_node"
|
||||
}
|
||||
|
||||
dep_add_modules()
|
||||
{
|
||||
local device dev_node
|
||||
local modules=
|
||||
|
||||
dep_add_modules_mount /
|
||||
dep_add_modules_mount /usr
|
||||
|
||||
if [ -n "${RESUME}" ]; then
|
||||
dev_node="$(resolve_device "${RESUME}")"
|
||||
if [ -n "${dev_node}" ]; then
|
||||
block_dev_mod_add "${dev_node}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# sys walk some important device classes
|
||||
for class in backlight extcon gpio phy pwm regulator rtc; do
|
||||
for device in "/sys/class/$class"/*; do
|
||||
device="$(readlink -f "$device")" \
|
||||
&& sys_walk_mod_add "$device"
|
||||
done
|
||||
done
|
||||
|
||||
# clk, USB-PHY and pinctrl devices are outside the device model (!) so
|
||||
# match loaded modules by name
|
||||
add_loaded_modules 'clk[-_]*'
|
||||
add_loaded_modules 'phy[-_]*'
|
||||
add_loaded_modules 'pinctrl[-_]*'
|
||||
|
||||
# Sys walk keyboards. We identify keyboards as input devices
|
||||
# that can generate at least key events 1-31; udev has the
|
||||
# same heuristic. Note that the format of the bitmap
|
||||
# properties depends on the word size of the process reading
|
||||
# the uevent file!
|
||||
for device in /sys/class/input/input*; do
|
||||
if grep -qs "^KEY=.*fffffff[ef]$" "${device}/uevent"; then
|
||||
sys_walk_mod_add "$(readlink -f "$device")"
|
||||
fi
|
||||
done
|
||||
|
||||
# Sys walk graphics for machines that don't have a generic framebuffer
|
||||
# device and wouldn't have a working video console otherwise.
|
||||
walk_graphics=yes
|
||||
for device in /sys/bus/platform/drivers/efi-framebuffer/* \
|
||||
/sys/bus/platform/drivers/platform-framebuffer/* \
|
||||
/sys/bus/platform/drivers/simple-framebuffer/* \
|
||||
/sys/bus/platform/drivers/vesa-framebuffer/*; do
|
||||
if [ -d "$device" ]; then
|
||||
walk_graphics=no
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$walk_graphics" = "yes" ]; then
|
||||
for device in /sys/class/graphics/*; do
|
||||
device="$(readlink -f "$device")" \
|
||||
&& sys_walk_mod_add "$device"
|
||||
done
|
||||
fi
|
||||
|
||||
# catch old-style IDE
|
||||
if [ -e /sys/bus/ide/devices/ ]; then
|
||||
modules="$modules ide-gd_mod ide-cd"
|
||||
fi
|
||||
|
||||
if [ -e /sys/bus/scsi/devices/ ]; then
|
||||
modules="$modules sd_mod"
|
||||
fi
|
||||
|
||||
if [ -e /sys/bus/mmc/devices/ ]; then
|
||||
modules="$modules mmc_block"
|
||||
fi
|
||||
|
||||
if [ -e /sys/bus/virtio ] ; then
|
||||
modules="$modules virtio_pci virtio_mmio"
|
||||
fi
|
||||
|
||||
if [ -e /sys/bus/i2o/devices/ ]; then
|
||||
force_load i2o_block
|
||||
force_load i2o_config
|
||||
fi
|
||||
|
||||
if [ -e /sys/bus/ps3_system_bus/ ]; then
|
||||
modules="$modules ps3disk ps3rom ps3-gelic ps3_sys_manager"
|
||||
fi
|
||||
|
||||
if [ -e /sys/bus/vio/ ]; then
|
||||
modules="$modules sunvnet sunvdc"
|
||||
fi
|
||||
|
||||
if [ -e /sys/devices/platform/edp-panel ]; then
|
||||
sys_walk_mod_add /sys/devices/platform/edp-panel
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
manual_add_modules $modules
|
||||
}
|
||||
|
||||
# The modules "most" classes added per default to the initramfs
|
||||
auto_add_modules()
|
||||
{
|
||||
local arg
|
||||
local modules=
|
||||
|
||||
if [ "$#" -eq 0 ] ; then
|
||||
set -- base net ide scsi block ata i2o dasd ieee1394 firewire mmc usb_storage fb virtual nx
|
||||
fi
|
||||
|
||||
for arg in "$@" ; do
|
||||
case "$arg" in
|
||||
base)
|
||||
modules="$modules btrfs ext2 ext3 ext4 f2fs"
|
||||
modules="$modules isofs jfs reiserfs squashfs udf xfs"
|
||||
modules="$modules nfs nfsv2 nfsv3 nfsv4"
|
||||
modules="$modules af_packet atkbd i8042 psmouse"
|
||||
modules="$modules virtio_pci virtio_mmio"
|
||||
# nls not automatically pulled in as ubuntu has built-in vfat
|
||||
modules="$modules vfat nls_cp437 nls_iso8859-1"
|
||||
|
||||
# Include most USB host and dual-role drivers
|
||||
copy_modules_dir kernel/drivers/usb/host \
|
||||
hwa-hc.ko sl811_cs.ko sl811-hcd.ko \
|
||||
u132-hcd.ko whci-hcd.ko
|
||||
copy_modules_dir kernel/drivers/usb/c67x00
|
||||
copy_modules_dir kernel/drivers/usb/chipidea
|
||||
copy_modules_dir kernel/drivers/usb/dwc2
|
||||
copy_modules_dir kernel/drivers/usb/dwc3
|
||||
copy_modules_dir kernel/drivers/usb/isp1760
|
||||
copy_modules_dir kernel/drivers/usb/musb
|
||||
copy_modules_dir kernel/drivers/usb/renesas_usbhs
|
||||
# and any extcon drivers for USB
|
||||
modules="$modules extcon-usb-gpio extcon-usbc-cros-ec"
|
||||
# Add the axp20x_usb_power power supply driver,
|
||||
# required to initialize the USB host controllers
|
||||
# on a number of armhf systems
|
||||
modules="$modules axp20x_usb_power"
|
||||
|
||||
# Include all keyboard drivers and all HID drivers
|
||||
# unless we're sure they don't support keyboards.
|
||||
# hid-*ff covers various game controllers with
|
||||
# force feedback.
|
||||
copy_modules_dir kernel/drivers/input/keyboard
|
||||
copy_modules_dir kernel/drivers/hid \
|
||||
'hid-*ff.ko' hid-a4tech.ko hid-cypress.ko \
|
||||
hid-dr.ko hid-elecom.ko hid-gyration.ko \
|
||||
hid-icade.ko hid-kensington.ko hid-kye.ko \
|
||||
hid-lcpower.ko hid-magicmouse.ko \
|
||||
hid-multitouch.ko hid-ntrig.ko \
|
||||
hid-petalynx.ko hid-picolcd.ko hid-pl.ko \
|
||||
hid-ps3remote.ko hid-quanta.ko \
|
||||
'hid-roccat-ko*.ko' hid-roccat-pyra.ko \
|
||||
hid-saitek.ko hid-sensor-hub.ko hid-sony.ko \
|
||||
hid-speedlink.ko hid-tivo.ko hid-twinhan.ko \
|
||||
hid-uclogic.ko hid-wacom.ko hid-waltop.ko \
|
||||
hid-wiimote.ko hid-zydacron.ko
|
||||
# needed to access keyboard on some ChromeOS devices
|
||||
modules="$modules cros_ec_spi"
|
||||
|
||||
# Any of these might be needed by other drivers
|
||||
copy_modules_dir kernel/drivers/bus
|
||||
copy_modules_dir kernel/drivers/clk
|
||||
copy_modules_dir kernel/drivers/gpio
|
||||
copy_modules_dir kernel/drivers/i2c/busses
|
||||
copy_modules_dir kernel/drivers/i2c/muxes
|
||||
copy_modules_dir kernel/drivers/mfd
|
||||
copy_modules_dir kernel/drivers/phy
|
||||
copy_modules_dir kernel/drivers/pinctrl
|
||||
copy_modules_dir kernel/drivers/regulator
|
||||
copy_modules_dir kernel/drivers/spi
|
||||
copy_modules_dir kernel/drivers/usb/phy
|
||||
|
||||
# Needed for periodic fsck
|
||||
copy_modules_dir kernel/drivers/rtc
|
||||
;;
|
||||
net)
|
||||
copy_modules_dir kernel/drivers/net \
|
||||
appletalk arcnet bonding can dummy.ko \
|
||||
hamradio hippi ifb.ko irda macvlan.ko \
|
||||
macvtap.ko pcmcia sb1000.ko team tokenring \
|
||||
tun.ko usb veth.ko wan wimax wireless \
|
||||
xen-netback.ko
|
||||
modules="$modules 8021q"
|
||||
;;
|
||||
ide)
|
||||
copy_modules_dir kernel/drivers/ide
|
||||
;;
|
||||
mmc)
|
||||
copy_modules_dir kernel/drivers/mmc
|
||||
;;
|
||||
scsi)
|
||||
copy_modules_dir kernel/drivers/scsi
|
||||
modules="$modules mptfc mptsas mptscsih mptspi zfcp"
|
||||
;;
|
||||
ata)
|
||||
copy_modules_dir kernel/drivers/ata
|
||||
;;
|
||||
block)
|
||||
copy_modules_dir kernel/drivers/block
|
||||
copy_modules_dir kernel/drivers/nvme
|
||||
modules="$modules vmd"
|
||||
;;
|
||||
ubi)
|
||||
modules="$modules deflate zlib lzo ubi ubifs"
|
||||
;;
|
||||
ieee1394)
|
||||
modules="$modules ohci1394 sbp2"
|
||||
;;
|
||||
firewire)
|
||||
modules="$modules firewire-ohci firewire-sbp2"
|
||||
;;
|
||||
i2o)
|
||||
modules="$modules i2o_block"
|
||||
;;
|
||||
dasd)
|
||||
modules="$modules dasd_diag_mod dasd_eckd_mod dasd_fba_mod"
|
||||
;;
|
||||
usb_storage)
|
||||
copy_modules_dir kernel/drivers/usb/storage
|
||||
;;
|
||||
fb)
|
||||
# For machines that don't have a generic framebuffer device.
|
||||
modules="$modules rockchipdrm pwm-cros-ec pwm_bl panel-simple"
|
||||
;;
|
||||
virtual)
|
||||
# Hyper-V
|
||||
modules="$modules hv_vmbus hv_utils hv_netvsc hv_mouse hv_storvsc hyperv-keyboard"
|
||||
;;
|
||||
nx)
|
||||
# PowerPC NX Crypto Coprocessor
|
||||
modules="$modules nx-compress nx-compress-crypto nx-compress-platform"
|
||||
modules="$modules nx-compress-pseries nx-compress-powernv 842-decompress"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
manual_add_modules $modules
|
||||
}
|
||||
|
||||
# 'depmod' only looks at symbol dependencies and the 'softdep' module
|
||||
# information field; there is no way for modules to declare weaker
|
||||
# dependencies (modules that *might* be needed at run-time) through
|
||||
# module information, Until this is fixed, we need to handle those
|
||||
# hidden dependencies.
|
||||
hidden_dep_add_modules()
|
||||
{
|
||||
# shellcheck disable=SC2046
|
||||
manual_add_modules $(
|
||||
{
|
||||
cat "${DESTDIR}/lib/modules/${version}/modules.builtin"
|
||||
find "${DESTDIR}/lib/modules/${version}/kernel" -name '*.ko*'
|
||||
} |
|
||||
while read -r module; do
|
||||
module="${module##*/}"
|
||||
module="${module%%.*}"
|
||||
case "$module" in
|
||||
libcrc32c)
|
||||
echo crc32c
|
||||
;;
|
||||
ubifs)
|
||||
echo deflate zlib lzo
|
||||
;;
|
||||
btrfs)
|
||||
echo crc32c
|
||||
;;
|
||||
f2fs)
|
||||
echo crc32
|
||||
;;
|
||||
mlx4_core)
|
||||
echo mlx4_ib
|
||||
;;
|
||||
mlx5_core)
|
||||
echo mlx5_ib
|
||||
;;
|
||||
i8042)
|
||||
echo psmouse
|
||||
;;
|
||||
nvme)
|
||||
echo vmd
|
||||
;;
|
||||
spi-rockchip)
|
||||
echo pl330
|
||||
;;
|
||||
dw_mmc-rockchip)
|
||||
echo rockchip-io-domain
|
||||
;;
|
||||
esac
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
# Find the source for a script file. This is needed to work around
|
||||
# temporary directories mounted with the noexec option. The source
|
||||
# will be on / or /usr which must be executable.
|
||||
get_source()
|
||||
{
|
||||
if [ -z "$scriptdir" ]; then
|
||||
echo "${initdir}/$1"
|
||||
elif [ -f "${CONFDIR}${scriptdir}/$1" ]; then
|
||||
echo "${CONFDIR}${scriptdir}/$1"
|
||||
else
|
||||
echo "/usr/share/initramfs-tools${scriptdir}/$1"
|
||||
fi
|
||||
}
|
||||
|
||||
set_initlist()
|
||||
{
|
||||
unset initlist
|
||||
for si_x in "${initdir}"/*; do
|
||||
# skip empty dirs without warning
|
||||
[ "${si_x}" = "${initdir}/*" ] && return
|
||||
|
||||
# only allow variable name chars
|
||||
case ${si_x#${initdir}/} in
|
||||
*[![:alnum:]\._-]*)
|
||||
[ "${verbose}" = "y" ] \
|
||||
&& echo "$si_x ignored: not alphanumeric or '_' file" >&2
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
# skip directories
|
||||
if [ -d "${si_x}" ]; then
|
||||
[ "${verbose}" = "y" ] \
|
||||
&& echo "$si_x ignored: a directory" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
si_x="$(get_source "${si_x#${initdir}/}")"
|
||||
|
||||
# skip non executable scripts
|
||||
if [ ! -x "${si_x}" ]; then
|
||||
[ "${verbose}" = "y" ] \
|
||||
&& echo "$si_x ignored: not executable" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
# skip bad syntax
|
||||
if ! sh -n "${si_x}" ; then
|
||||
[ "${verbose}" = "y" ] \
|
||||
&& echo "$si_x ignored: bad syntax" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
initlist="${initlist:-} ${si_x##*/}"
|
||||
done
|
||||
}
|
||||
|
||||
get_prereq_pairs()
|
||||
{
|
||||
set_initlist
|
||||
for gp_x in ${initlist:-}; do
|
||||
echo "${gp_x} ${gp_x}"
|
||||
gp_src="$(get_source "$gp_x")"
|
||||
prereqs=$("${gp_src}" prereqs)
|
||||
for prereq in ${prereqs}; do
|
||||
echo "${prereq} ${gp_x}"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
# cache boot scripts order
|
||||
cache_run_scripts()
|
||||
{
|
||||
DESTDIR=${1}
|
||||
scriptdir=${2}
|
||||
initdir=${DESTDIR}${scriptdir}
|
||||
[ ! -d "${initdir}" ] && return
|
||||
|
||||
true > "${initdir}/ORDER"
|
||||
runlist=$(get_prereq_pairs | tsort)
|
||||
for crs_x in ${runlist}; do
|
||||
[ -f "${initdir}/${crs_x}" ] || continue
|
||||
echo "${scriptdir}/${crs_x} \"\$@\"" >> "${initdir}/ORDER"
|
||||
echo "[ -e /conf/param.conf ] && . /conf/param.conf" >> "${initdir}/ORDER"
|
||||
done
|
||||
}
|
||||
|
||||
call_scripts()
|
||||
{
|
||||
set -e
|
||||
for cs_x in ${runlist}; do
|
||||
[ -f "${initdir}/${cs_x}" ] || continue
|
||||
if [ x"$call_scripts_optional" = "xy" ]; then
|
||||
option=$(sed '/^OPTION=/!d;$d;s/^OPTION=//;s/[[:space:]]*$//' "${initdir}/${cs_x}")
|
||||
# shellcheck disable=SC1083,2086
|
||||
[ -z "${option}" ] || eval test -n \"\${$option}\" -a \"\${$option}\" != \"n\" || continue
|
||||
fi
|
||||
|
||||
# mkinitramfs verbose output
|
||||
if [ "${verbose}" = "y" ]; then
|
||||
echo "Calling hook ${cs_x}"
|
||||
fi
|
||||
"${initdir}/${cs_x}" && ec=$? || ec=$?
|
||||
# allow hooks to abort build:
|
||||
if [ "$ec" -ne 0 ]; then
|
||||
echo "E: ${initdir}/${cs_x} failed with return $ec." >&2
|
||||
# only errexit on mkinitramfs
|
||||
[ -n "${version}" ] && exit $ec
|
||||
fi
|
||||
# allow boot scripts to modify exported boot parameters
|
||||
if [ -e /conf/param.conf ]; then
|
||||
. /conf/param.conf
|
||||
fi
|
||||
done
|
||||
set +e
|
||||
}
|
||||
|
||||
run_scripts()
|
||||
{
|
||||
scriptdir=${2:-}
|
||||
initdir=${1}
|
||||
[ ! -d "${initdir}" ] && return
|
||||
|
||||
runlist=$(get_prereq_pairs | tsort)
|
||||
call_scripts "$scriptdir"
|
||||
}
|
||||
|
||||
run_scripts_optional()
|
||||
{
|
||||
call_scripts_optional=y
|
||||
run_scripts "$@"
|
||||
}
|
||||
|
||||
add_dns() {
|
||||
local destdir="$1" nsswitch="" lib="" libdir="" f="" d=""
|
||||
# find the multiarch lib dir (for example /lib/x86_64-linux-gnu)
|
||||
# by finding a directory with libc.so.6.
|
||||
for d in /lib/* /lib; do
|
||||
for f in "$d"/libc.so.?; do [ -f "$f" ] && break; done
|
||||
[ -f "$f" ] && libdir="$d" && break
|
||||
done
|
||||
if [ -z "$libdir" ]; then
|
||||
echo "WARNING: no libdir found for adding dns." 1>&2
|
||||
return
|
||||
fi
|
||||
nsswitch="$destdir/etc/nsswitch.conf"
|
||||
if ! grep -qs "^hosts:" "$nsswitch"; then
|
||||
echo "hosts: files dns" >> "$nsswitch"
|
||||
fi
|
||||
local found=""
|
||||
for lib in libnss_files libnss_dns libresolv; do
|
||||
found=""
|
||||
for f in "$libdir/$lib.so".?; do
|
||||
[ -e "$f" ] || continue
|
||||
[ "$verbose" = "y" ] && echo "dns: $lib: $f"
|
||||
copy_file library "$f"
|
||||
found="$f"
|
||||
done
|
||||
[ -n "$found" ] || echo "WARNING: no $libdir/$lib.? file" 1>&2
|
||||
done
|
||||
return 0
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$1" = prereqs ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
number=
|
||||
suffix=
|
||||
# shellcheck disable=SC2046
|
||||
eval $(printf "%s" "$COMPCACHE_SIZE" | \
|
||||
sed -nre 's/^ *([1-9][0-9]*) *([%KMGT]) *$/number="\1"; suffix="\2";/p')
|
||||
|
||||
if [ -z "$number" ] || [ -z "$suffix" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if have_module zram; then
|
||||
name=zram
|
||||
manual_add_modules zram
|
||||
elif have_module ramzswap; then
|
||||
name=ramzswap
|
||||
manual_add_modules ramzswap
|
||||
elif have_module compcache; then
|
||||
name=compcache
|
||||
manual_add_modules compcache
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
copy_exec /sbin/swapon
|
||||
copy_exec /sbin/mkswap
|
||||
copy_exec /usr/lib/initramfs-tools/bin/rzscontrol /sbin
|
||||
|
||||
mem_total="\$(sed -nre 's/^MemTotal:\\s*([0-9]+) kB\$/\\1/p' /proc/meminfo)"
|
||||
|
||||
case "$suffix" in
|
||||
%) kbytes="\$(($mem_total * $number / 100))" ;;
|
||||
K) kbytes=$((number)) ;;
|
||||
M) kbytes=$((number * 1024)) ;;
|
||||
G) kbytes=$((number * 1024 * 1024)) ;;
|
||||
T) kbytes=$((number * 1024 * 1024 * 1024)) ;;
|
||||
esac
|
||||
|
||||
cat >"$DESTDIR"/sbin/compcache-enable <<'EOF'
|
||||
#!/bin/sh
|
||||
if [ "$#" != 3 ]; then
|
||||
echo "Usage: $0 <type> <size> <device>" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
type="$1"
|
||||
size="$2"
|
||||
device="$3"
|
||||
|
||||
number=
|
||||
suffix=
|
||||
eval $(printf "%s" "$size" | \
|
||||
sed -nre 's/^ *([1-9][0-9]*) *([%KMGT]) *$/number="\1"; suffix="\2";/p')
|
||||
|
||||
mem_total="$(sed -nre 's/^MemTotal:\s*([0-9]+) kB$/\1/p' /proc/meminfo)"
|
||||
|
||||
case "$suffix" in
|
||||
%) kbytes="$(($mem_total * $number / 100))" ;;
|
||||
K) kbytes=$(($number)) ;;
|
||||
M) kbytes=$(($number * 1024)) ;;
|
||||
G) kbytes=$(($number * 1024 * 1024)) ;;
|
||||
T) kbytes=$(($number * 1024 * 1024 * 1024)) ;;
|
||||
esac
|
||||
bytes="$(($kbytes * 1024))"
|
||||
|
||||
if [ "$type" = zram ]; then
|
||||
echo "$bytes" >/sys/block/$device/disksize && \
|
||||
/sbin/mkswap "/dev/$device" >/dev/null
|
||||
|
||||
elif [ "$type" = ramzswap ]; then
|
||||
/sbin/rzscontrol "/dev/$device" --disksize_kb="$kbytes" --init
|
||||
fi
|
||||
/sbin/swapon -p 100 "/dev/$device" 2>/dev/null
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
chmod 0755 "$DESTDIR"/sbin/compcache-enable
|
||||
|
||||
mkdir -p "$DESTDIR"/etc/udev/rules.d
|
||||
if [ "$name" = zram ]; then
|
||||
cat >"$DESTDIR"/etc/udev/rules.d/80-compcache.rules <<EOF
|
||||
KERNEL=="zram0", ACTION=="add", \\
|
||||
RUN+="/sbin/compcache-enable zram $COMPCACHE_SIZE zram0"
|
||||
EOF
|
||||
elif [ "$name" = ramzswap ]; then
|
||||
cat >"$DESTDIR"/etc/udev/rules.d/80-compcache.rules <<EOF
|
||||
KERNEL=="ramzswap0", ACTION=="add", \\
|
||||
RUN+="/sbin/compcache-enable ramzswap $COMPCACHE_SIZE ramzswap0"
|
||||
EOF
|
||||
else
|
||||
cat >"$DESTDIR"/etc/udev/rules.d/80-compcache.rules <<EOF
|
||||
KERNEL=="ramzswap0", ACTION=="add", \\
|
||||
RUN+="/sbin/compcache-enable compcache $COMPCACHE_SIZE ramzswap0"
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >"$DESTDIR"/scripts/init-top/compcache <<EOF
|
||||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
prereqs()
|
||||
{
|
||||
echo "\$PREREQ"
|
||||
}
|
||||
|
||||
case \$1 in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# find total amount of available ram
|
||||
TOTAL_RAM=\$( grep MemTotal /proc/meminfo |tr -d ': [A-Z][a-z]')
|
||||
|
||||
# Do not use compcache on the liveCD if we have more than 512M
|
||||
if [ "\${BOOT}" = "casper" ]; then
|
||||
if [ "\${TOTAL_RAM}" -gt 524288 ]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
for x in \$(cat /proc/cmdline); do
|
||||
case \${x} in
|
||||
nocompcache)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$name" = zram ]; then
|
||||
cat >>"$DESTDIR"/scripts/init-top/compcache <<EOF
|
||||
modprobe -q --ignore-install zram
|
||||
EOF
|
||||
elif [ "$name" = ramzswap ]; then
|
||||
cat >>"$DESTDIR"/scripts/init-top/compcache <<EOF
|
||||
modprobe -q --ignore-install ramzswap
|
||||
EOF
|
||||
else
|
||||
cat >>"$DESTDIR"/scripts/init-top/compcache <<EOF
|
||||
modprobe -q --ignore-install compcache compcache_size_kbytes="$kbytes"
|
||||
EOF
|
||||
fi
|
||||
|
||||
chmod 0755 "$DESTDIR"/scripts/init-top/compcache
|
||||
|
||||
# vim:set et sw=2 sts=2:
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh -e
|
||||
# initramfs hook for fixing broken rtc clock
|
||||
# without battery
|
||||
|
||||
PREREQ="udev"
|
||||
|
||||
# Output pre-requisites
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
# We use the full dumpe2fs because we basically get it for "free"
|
||||
# if we're already on extN due to e2fsck pulling in all the libs:
|
||||
copy_exec /sbin/dumpe2fs /sbin
|
|
@ -0,0 +1,43 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
OPTION=FRAMEBUFFER
|
||||
PREREQ=""
|
||||
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
copy_modules_dir kernel/drivers/char/agp
|
||||
copy_modules_dir kernel/drivers/gpu
|
||||
copy_modules_dir kernel/ubuntu/i915
|
||||
|
||||
manual_add_modules fbcon
|
||||
manual_add_modules vesafb
|
||||
manual_add_modules vga16fb
|
||||
manual_add_modules vboxvideo
|
||||
|
||||
for x in "${MODULESDIR}"/initrd/*; do
|
||||
x=${x##*/}
|
||||
x=${x%.*}
|
||||
case ${x} in
|
||||
'*')
|
||||
break
|
||||
;;
|
||||
*fb)
|
||||
;;
|
||||
esac
|
||||
|
||||
manual_add_modules "${x}"
|
||||
done
|
|
@ -0,0 +1,98 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
# Find a specific fstab entry
|
||||
# $1=mountpoint
|
||||
# $2=fstype (optional)
|
||||
_read_fstab_entry () {
|
||||
# Not found by default.
|
||||
echo "MNT_FSNAME="
|
||||
echo "MNT_DIR="
|
||||
echo "MNT_TYPE="
|
||||
|
||||
for file in /etc/fstab /etc/fstab.d/*.fstab; do
|
||||
if [ -f "$file" ]; then
|
||||
# shellcheck disable=SC2034
|
||||
while read -r MNT_FSNAME MNT_DIR MNT_TYPE MNT_OPTS MNT_FREQ MNT_PASS MNT_JUNK; do
|
||||
case "$MNT_FSNAME" in
|
||||
""|\#*)
|
||||
continue;
|
||||
;;
|
||||
esac
|
||||
if [ "$MNT_DIR" = "$1" ]; then
|
||||
if [ -n "$2" ]; then
|
||||
[ "$MNT_TYPE" = "$2" ] || continue;
|
||||
fi
|
||||
echo "MNT_FSNAME=$MNT_FSNAME"
|
||||
echo "MNT_DIR=$MNT_DIR"
|
||||
echo "MNT_TYPE=$MNT_TYPE"
|
||||
echo "MNT_PASS=$MNT_PASS"
|
||||
break 2
|
||||
fi
|
||||
MNT_DIR=""
|
||||
done < "$file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Find a specific fstab entry and print its type (if found, and pass != 0)
|
||||
# $1=mountpoint
|
||||
get_fsck_type_fstab () {
|
||||
eval "$(_read_fstab_entry "$1")"
|
||||
|
||||
# Not found by default.
|
||||
if [ "$1" = "$MNT_DIR" ] && [ "$MNT_PASS" != 0 ]; then
|
||||
# Ignore filesystem type for /, as it is not available and
|
||||
# therefore never used at boot time
|
||||
if [ "${MNT_DIR}" = "/" ] || [ "${MNT_TYPE}" = "auto" ]; then
|
||||
MNT_FSNAME="$(resolve_device "${MNT_FSNAME}")"
|
||||
if ! get_fstype "${MNT_FSNAME}"; then
|
||||
echo "W: Couldn't identify type of $2 file system for fsck hook" >&2
|
||||
fi
|
||||
else
|
||||
echo "${MNT_TYPE}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
get_fsck_types() {
|
||||
get_fsck_type_fstab / root
|
||||
get_fsck_type_fstab /usr /usr
|
||||
}
|
||||
|
||||
case $1 in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -x /sbin/fsck ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
. /usr/share/initramfs-tools/scripts/functions
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
fsck_types="$(get_fsck_types | sort | uniq)"
|
||||
|
||||
if [ -z "$fsck_types" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
copy_exec /sbin/fsck
|
||||
copy_exec /sbin/logsave
|
||||
|
||||
for type in $fsck_types; do
|
||||
if prog="$(command -v "fsck.${type}")"; then
|
||||
copy_exec "$prog"
|
||||
else
|
||||
echo "W: /sbin/fsck.${type} doesn't exist, can't install to initramfs" >&2
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,112 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
. /usr/share/initramfs-tools/scripts/functions
|
||||
|
||||
# First check if a location is set and is a valid swap partition.
|
||||
# If so, the config file will be copied in and there is nothing to do.
|
||||
if [ -n "$RESUME" ] && [ "$RESUME" != auto ]; then
|
||||
if [ "$RESUME" = none ]; then
|
||||
exit 0
|
||||
fi
|
||||
if resume_dev_node="$(resolve_device "$RESUME")" && \
|
||||
blkid -p -n swap "$resume_dev_node" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo >&2 "W: initramfs-tools configuration sets RESUME=$RESUME"
|
||||
echo >&2 "W: but no matching swap device is available."
|
||||
fi
|
||||
|
||||
# If we were not explicitly requested to select a device, or the -v
|
||||
# option is used, report that we are doing so
|
||||
report_auto()
|
||||
{
|
||||
test "${verbose?}" != y && test "$RESUME" = auto || echo "I: $*"
|
||||
}
|
||||
|
||||
# Report in excruciating detail if the -v option is used
|
||||
report_verbose()
|
||||
{
|
||||
test "${verbose?}" != y || echo "I: $*"
|
||||
}
|
||||
|
||||
report_verbose "Configuration sets RESUME=$RESUME"
|
||||
|
||||
# Try to autodetect the RESUME partition, using biggest swap device that
|
||||
# is not ephemeral. We need to be able to read the listed swap partitions.
|
||||
resume_auto=
|
||||
if ! ischroot && [ -r /proc/swaps ]; then
|
||||
# shellcheck disable=SC2013
|
||||
for resume_auto in $(grep ^/dev/ /proc/swaps | sort -rnk3 | cut -d " " -f 1); do
|
||||
report_verbose "Checking swap device $resume_auto"
|
||||
ephemeral=false
|
||||
dm_name="$(dmsetup info -c --noheadings -o name "$resume_auto" 2>/dev/null)"
|
||||
|
||||
# dm-crypt is ephemeral if the key file is /dev/urandom
|
||||
if [ -n "$dm_name" ] && [ -e /etc/crypttab ]; then
|
||||
report_verbose "$resume_auto has device-mapper name $dm_name; checking crypttab"
|
||||
# shellcheck disable=SC2034
|
||||
while read -r cryptdev srcdev keyfile junk; do
|
||||
report_verbose "Found cryptdev=$cryptdev keyfile=$keyfile"
|
||||
if [ "$cryptdev" = "$dm_name" ] && [ "$keyfile" = /dev/urandom ]; then
|
||||
report_verbose "Rejecting $resume_auto since it has no permanent key"
|
||||
ephemeral=true
|
||||
fi
|
||||
done < /etc/crypttab
|
||||
fi
|
||||
|
||||
# zram is ephemeral
|
||||
case "$resume_auto" in
|
||||
/dev/zram*)
|
||||
report_verbose "Rejecting $resume_auto since it is zram"
|
||||
ephemeral=true
|
||||
;;
|
||||
esac
|
||||
|
||||
$ephemeral || break
|
||||
done
|
||||
|
||||
if $ephemeral; then
|
||||
resume_auto=
|
||||
fi
|
||||
if [ -n "$resume_auto" ]; then
|
||||
if [ -n "$dm_name" ]; then
|
||||
resume_auto_canon="/dev/mapper/$dm_name"
|
||||
elif UUID=$(blkid -s UUID -o value "$resume_auto"); then
|
||||
resume_auto_canon="UUID=$UUID"
|
||||
else
|
||||
resume_auto_canon=
|
||||
fi
|
||||
report_auto "The initramfs will attempt to resume from $resume_auto"
|
||||
if [ -n "$resume_auto_canon" ]; then
|
||||
report_auto "($resume_auto_canon)"
|
||||
resume_auto="$resume_auto_canon"
|
||||
fi
|
||||
report_auto "Set the RESUME variable to override this."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Write selected resume device to intramfs conf.d
|
||||
if [ "$RESUME" = auto ] || [ -n "$resume_auto" ]; then
|
||||
# If we were explicitly requested to select a device, and we failed,
|
||||
# report that
|
||||
if [ -z "$resume_auto" ]; then
|
||||
echo >&2 "W: initramfs-tools failed to select a resume device"
|
||||
fi
|
||||
echo "RESUME=${resume_auto}" > "${DESTDIR}/conf/conf.d/zz-resume-auto"
|
||||
fi
|
|
@ -0,0 +1,71 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Hooks for loading thermal bits into the initramfs
|
||||
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
case "$DPKG_ARCH" in
|
||||
# copy the right modules
|
||||
powerpc|ppc64)
|
||||
|
||||
# Only G5 Mac machines need to load
|
||||
# windfarm_core or one of the windfarm_pm* modules.
|
||||
|
||||
[ -r /proc/cpuinfo ] || exit 0
|
||||
|
||||
MODEL="$(grep model /proc/cpuinfo)"
|
||||
MODEL="${MODEL##*: }"
|
||||
|
||||
case "$MODEL" in
|
||||
RackMac3,1)
|
||||
force_load windfarm_rm31
|
||||
;;
|
||||
PowerMac7,2|PowerMac7,3)
|
||||
force_load windfarm_pm72
|
||||
;;
|
||||
PowerMac8,1|PowerMac8,2)
|
||||
force_load windfarm_pm81
|
||||
;;
|
||||
PowerMac9,1)
|
||||
force_load windfarm_pm91
|
||||
;;
|
||||
PowerMac11,2)
|
||||
force_load windfarm_pm112
|
||||
;;
|
||||
PowerMac12,1)
|
||||
force_load windfarm_pm121
|
||||
;;
|
||||
*)
|
||||
# No other machine needs windfarm_* modules on initrd.
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
manual_add_modules windfarm_core
|
||||
manual_add_modules windfarm_cpufreq_clamp
|
||||
manual_add_modules windfarm_lm75_sensor
|
||||
manual_add_modules windfarm_max6690_sensor
|
||||
manual_add_modules windfarm_pid
|
||||
manual_add_modules windfarm_smu_controls
|
||||
manual_add_modules windfarm_smu_sat
|
||||
manual_add_modules windfarm_smu_sensors
|
||||
;;
|
||||
i386|amd64|ia64)
|
||||
manual_add_modules fan
|
||||
manual_add_modules thermal
|
||||
;;
|
||||
esac
|
|
@ -0,0 +1,375 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Default PATH differs between shells, and is not automatically exported
|
||||
# by klibc dash. Make it consistent.
|
||||
# Furthermore, this PATH ends up being used by the init, set it to the
|
||||
# Standard PATH, without /snap/bin as documented in
|
||||
# https://wiki.ubuntu.com/PATH
|
||||
# This also matches /etc/environment, but without games path
|
||||
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
[ -d /dev ] || mkdir -m 0755 /dev
|
||||
[ -d /root ] || mkdir -m 0700 /root
|
||||
[ -d /sys ] || mkdir /sys
|
||||
[ -d /proc ] || mkdir /proc
|
||||
[ -d /tmp ] || mkdir /tmp
|
||||
mkdir -p /var/lock
|
||||
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
|
||||
mount -t proc -o nodev,noexec,nosuid proc /proc
|
||||
|
||||
# shellcheck disable=SC2013
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case $x in
|
||||
initramfs.clear)
|
||||
clear
|
||||
;;
|
||||
quiet)
|
||||
quiet=y
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$quiet" != "y" ]; then
|
||||
quiet=n
|
||||
echo "Loading, please wait..."
|
||||
fi
|
||||
export quiet
|
||||
|
||||
# Note that this only becomes /dev on the real filesystem if udev's scripts
|
||||
# are used; which they will be, but it's worth pointing out
|
||||
test -x /usr/sbin/v86d && dev_exec="exec" || dev_exec="noexec"
|
||||
mount -t devtmpfs -o $dev_exec,nosuid,mode=0755 udev /dev
|
||||
mkdir /dev/pts
|
||||
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
|
||||
|
||||
# Export the dpkg architecture
|
||||
export DPKG_ARCH=
|
||||
. /conf/arch.conf
|
||||
|
||||
# Set modprobe env
|
||||
export MODPROBE_OPTIONS="-qb"
|
||||
|
||||
# Export relevant variables
|
||||
export ROOT=
|
||||
export ROOTDELAY=
|
||||
export ROOTFLAGS=
|
||||
export ROOTFSTYPE=
|
||||
export IP=
|
||||
export IP6=
|
||||
export VLAN=
|
||||
export DEVICE=
|
||||
export BOOT=
|
||||
export BOOTIF=
|
||||
export UBIMTD=
|
||||
export NETWORK_SKIP_ENSLAVED=
|
||||
export break=
|
||||
export init=/sbin/init
|
||||
export readonly=y
|
||||
export rootmnt=/root
|
||||
export debug=
|
||||
export panic=
|
||||
export blacklist=
|
||||
export resume=
|
||||
export resume_offset=
|
||||
export noresume=
|
||||
export drop_caps=
|
||||
export fastboot=n
|
||||
export forcefsck=n
|
||||
export fsckfix=
|
||||
|
||||
|
||||
# mdadm needs hostname to be set. This has to be done before the udev rules are called!
|
||||
if [ -f "/etc/hostname" ]; then
|
||||
/bin/hostname -F /etc/hostname >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Bring in the main config
|
||||
. /conf/initramfs.conf
|
||||
for conf in conf/conf.d/*; do
|
||||
[ -f "${conf}" ] && . "${conf}"
|
||||
done
|
||||
. /scripts/functions
|
||||
|
||||
# Parse command line options
|
||||
# shellcheck disable=SC2013
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case $x in
|
||||
init=*)
|
||||
init=${x#init=}
|
||||
;;
|
||||
root=*)
|
||||
ROOT=${x#root=}
|
||||
if [ -z "${BOOT}" ] && [ "$ROOT" = "/dev/nfs" ]; then
|
||||
BOOT=nfs
|
||||
fi
|
||||
;;
|
||||
rootflags=*)
|
||||
ROOTFLAGS="-o ${x#rootflags=}"
|
||||
;;
|
||||
rootfstype=*)
|
||||
ROOTFSTYPE="${x#rootfstype=}"
|
||||
;;
|
||||
rootdelay=*)
|
||||
ROOTDELAY="${x#rootdelay=}"
|
||||
case ${ROOTDELAY} in
|
||||
*[![:digit:].]*)
|
||||
ROOTDELAY=
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
roottimeout=*)
|
||||
ROOTDELAY="${x#roottimeout=}"
|
||||
case ${ROOTDELAY} in
|
||||
*[![:digit:].]*)
|
||||
ROOTDELAY=
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
loop=*)
|
||||
# shellcheck disable=SC2034
|
||||
LOOP="${x#loop=}"
|
||||
;;
|
||||
loopflags=*)
|
||||
# shellcheck disable=SC2034
|
||||
LOOPFLAGS="-o ${x#loopflags=}"
|
||||
;;
|
||||
loopfstype=*)
|
||||
# shellcheck disable=SC2034
|
||||
LOOPFSTYPE="${x#loopfstype=}"
|
||||
;;
|
||||
nfsroot=*)
|
||||
# shellcheck disable=SC2034
|
||||
NFSROOT="${x#nfsroot=}"
|
||||
;;
|
||||
initramfs.runsize=*)
|
||||
RUNSIZE="${x#initramfs.runsize=}"
|
||||
;;
|
||||
ip=*)
|
||||
IP="${x#ip=}"
|
||||
;;
|
||||
ip6=*)
|
||||
IP6="${x#ip6=}"
|
||||
;;
|
||||
vlan=*)
|
||||
VLAN="${x#vlan=}"
|
||||
;;
|
||||
boot=*)
|
||||
BOOT=${x#boot=}
|
||||
;;
|
||||
ubi.mtd=*)
|
||||
UBIMTD=${x#ubi.mtd=}
|
||||
;;
|
||||
resume=*)
|
||||
RESUME="${x#resume=}"
|
||||
case $RESUME in
|
||||
UUID=*)
|
||||
RESUME="/dev/disk/by-uuid/${RESUME#UUID=}"
|
||||
esac
|
||||
;;
|
||||
resume_offset=*)
|
||||
resume_offset="${x#resume_offset=}"
|
||||
;;
|
||||
noresume)
|
||||
noresume=y
|
||||
;;
|
||||
drop_capabilities=*)
|
||||
drop_caps="-d ${x#drop_capabilities=}"
|
||||
;;
|
||||
panic=*)
|
||||
panic="${x#panic=}"
|
||||
case ${panic} in
|
||||
-1) ;;
|
||||
*[![:digit:].]*)
|
||||
panic=
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
ro)
|
||||
readonly=y
|
||||
;;
|
||||
rw)
|
||||
readonly=n
|
||||
;;
|
||||
debug)
|
||||
debug=y
|
||||
quiet=n
|
||||
if [ -n "${netconsole}" ]; then
|
||||
log_output=/dev/kmsg
|
||||
else
|
||||
log_output=/run/initramfs/initramfs.debug
|
||||
fi
|
||||
set -x
|
||||
;;
|
||||
debug=*)
|
||||
debug=y
|
||||
quiet=n
|
||||
set -x
|
||||
;;
|
||||
break=*)
|
||||
break=${x#break=}
|
||||
;;
|
||||
break)
|
||||
break=premount
|
||||
;;
|
||||
blacklist=*)
|
||||
blacklist=${x#blacklist=}
|
||||
;;
|
||||
netconsole=*)
|
||||
netconsole=${x#netconsole=}
|
||||
[ "x$debug" = "xy" ] && log_output=/dev/kmsg
|
||||
;;
|
||||
BOOTIF=*)
|
||||
BOOTIF=${x#BOOTIF=}
|
||||
;;
|
||||
hwaddr=*)
|
||||
BOOTIF=${x#hwaddr=}
|
||||
;;
|
||||
fastboot|fsck.mode=skip)
|
||||
fastboot=y
|
||||
;;
|
||||
forcefsck|fsck.mode=force)
|
||||
forcefsck=y
|
||||
;;
|
||||
fsckfix|fsck.repair=yes)
|
||||
fsckfix=y
|
||||
;;
|
||||
fsck.repair=no)
|
||||
fsckfix=n
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Default to BOOT=local if no boot script defined.
|
||||
if [ -z "${BOOT}" ]; then
|
||||
BOOT=local
|
||||
fi
|
||||
|
||||
if [ -n "${noresume}" ] || [ "$RESUME" = none ]; then
|
||||
noresume=y
|
||||
else
|
||||
resume=${RESUME:-}
|
||||
fi
|
||||
|
||||
mount -t tmpfs -o "nodev,noexec,nosuid,size=${RUNSIZE:-10%},mode=0755" tmpfs /run
|
||||
mkdir -m 0700 /run/initramfs
|
||||
|
||||
if [ -n "$log_output" ]; then
|
||||
exec >$log_output 2>&1
|
||||
unset log_output
|
||||
fi
|
||||
|
||||
maybe_break top
|
||||
|
||||
# export BOOT variable value for compcache,
|
||||
# so we know if we run from casper
|
||||
export BOOT
|
||||
|
||||
# Don't do log messages here to avoid confusing graphical boots
|
||||
run_scripts /scripts/init-top
|
||||
|
||||
maybe_break modules
|
||||
[ "$quiet" != "y" ] && log_begin_msg "Loading essential drivers"
|
||||
[ -n "${netconsole}" ] && modprobe netconsole netconsole="${netconsole}"
|
||||
load_modules
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
|
||||
maybe_break premount
|
||||
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-premount"
|
||||
run_scripts /scripts/init-premount
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
|
||||
maybe_break mount
|
||||
log_begin_msg "Mounting root file system"
|
||||
# Always load local and nfs (since these might be needed for /etc or
|
||||
# /usr, irrespective of the boot script used to mount the rootfs).
|
||||
. /scripts/local
|
||||
. /scripts/nfs
|
||||
. /scripts/${BOOT}
|
||||
parse_numeric "${ROOT}"
|
||||
maybe_break mountroot
|
||||
mount_top
|
||||
mount_premount
|
||||
mountroot
|
||||
log_end_msg
|
||||
|
||||
if read_fstab_entry /usr; then
|
||||
log_begin_msg "Mounting /usr file system"
|
||||
mountfs /usr
|
||||
log_end_msg
|
||||
fi
|
||||
|
||||
# Mount cleanup
|
||||
mount_bottom
|
||||
nfs_bottom
|
||||
local_bottom
|
||||
|
||||
maybe_break bottom
|
||||
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-bottom"
|
||||
# We expect udev's init-bottom script to move /dev to ${rootmnt}/dev
|
||||
run_scripts /scripts/init-bottom
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
|
||||
# Move /run to the root
|
||||
mount -n -o move /run ${rootmnt}/run
|
||||
|
||||
validate_init() {
|
||||
run-init -n "${rootmnt}" "${1}"
|
||||
}
|
||||
|
||||
# Check init is really there
|
||||
if ! validate_init "$init"; then
|
||||
echo "Target filesystem doesn't have requested ${init}."
|
||||
init=
|
||||
for inittest in /sbin/init /etc/init /bin/init /bin/sh; do
|
||||
if validate_init "${inittest}"; then
|
||||
init="$inittest"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# No init on rootmount
|
||||
if ! validate_init "${init}" ; then
|
||||
panic "No init found. Try passing init= bootarg."
|
||||
fi
|
||||
|
||||
maybe_break init
|
||||
|
||||
# don't leak too much of env - some init(8) don't clear it
|
||||
# (keep init, rootmnt, drop_caps)
|
||||
unset debug
|
||||
unset MODPROBE_OPTIONS
|
||||
unset DPKG_ARCH
|
||||
unset ROOTFLAGS
|
||||
unset ROOTFSTYPE
|
||||
unset ROOTDELAY
|
||||
unset ROOT
|
||||
unset IP
|
||||
unset IP6
|
||||
unset VLAN
|
||||
unset BOOT
|
||||
unset BOOTIF
|
||||
unset DEVICE
|
||||
unset UBIMTD
|
||||
unset blacklist
|
||||
unset break
|
||||
unset noresume
|
||||
unset panic
|
||||
unset quiet
|
||||
unset readonly
|
||||
unset resume
|
||||
unset resume_offset
|
||||
unset noresume
|
||||
unset fastboot
|
||||
unset forcefsck
|
||||
unset fsckfix
|
||||
|
||||
# Move virtual filesystems over to the real filesystem
|
||||
mount -n -o move /sys ${rootmnt}/sys
|
||||
mount -n -o move /proc ${rootmnt}/proc
|
||||
|
||||
# Chain to real filesystem
|
||||
# shellcheck disable=SC2086,SC2094
|
||||
exec run-init ${drop_caps} "${rootmnt}" "${init}" "$@" <"${rootmnt}/dev/console" >"${rootmnt}/dev/console" 2>&1
|
||||
echo "Something went badly wrong in the initramfs."
|
||||
panic "Please file a bug on initramfs-tools."
|
|
@ -0,0 +1,708 @@
|
|||
.TH INITRAMFS-TOOLS 7 "2018/07/18" "initramfs\-tools" "Linux Programmer's Manual"
|
||||
|
||||
.SH NAME
|
||||
initramfs-tools \- an introduction to writing scripts for mkinitramfs
|
||||
|
||||
.SH DESCRIPTION
|
||||
initramfs-tools has one main script and two different sets of subscripts which
|
||||
will be used during different phases of execution. Each of these will be
|
||||
discussed separately below with the help of an imaginary tool which performs a
|
||||
frobnication of a lvm partition prior to mounting the root partition.
|
||||
|
||||
.SH Kernel Command Line
|
||||
The root filesystem used by the kernel is specified by the boot loader as
|
||||
always. The traditional \fBroot=/dev/sda1\fR style device specification is
|
||||
allowed. If a label is used, as in \fBroot=LABEL=rootPart\fR the initrd will
|
||||
search all available devices for a filesystem with the appropriate label, and
|
||||
mount that device as the root filesystem. \fBroot=UUID=uuidnumber\fR will
|
||||
mount the partition with that UUID as the root filesystem.
|
||||
|
||||
.SS Standard
|
||||
|
||||
.TP
|
||||
\fB\fI init= "<path to real init>"
|
||||
the binary to hand over execution to on the root fs after the initramfs scripts are done.
|
||||
|
||||
.TP
|
||||
\fB\fI initramfs.clear
|
||||
clear screen at the beginning
|
||||
|
||||
.TP
|
||||
\fB\fI initramfs.runsize
|
||||
The size of the \fI/run\fP tmpfs mount point in bytes (suffixes are supported)
|
||||
or as percentage of your physical RAM. This parameter is used as the value of
|
||||
the size mount option to tmpfs. See
|
||||
\fBhttps://www.kernel.org/doc/Documentation/filesystems/tmpfs.txt\fR for
|
||||
details. The default is 10%.
|
||||
|
||||
.TP
|
||||
\fB\fI root= "<path to blockdevice>"
|
||||
the device node to mount as the root file system.
|
||||
The recommended usage is to specify the UUID as followed "root=UUID=xxx".
|
||||
|
||||
.TP
|
||||
\fB\fI rootfstype
|
||||
set the root file system type.
|
||||
|
||||
.TP
|
||||
\fB\fI roottimeout
|
||||
set timeout in seconds. Determines how long mountroot waits for root to appear.
|
||||
The default is 30 seconds.
|
||||
|
||||
.TP
|
||||
\fB\fI rootdelay
|
||||
alias for roottimeout.
|
||||
|
||||
.TP
|
||||
\fB\fI rootflags
|
||||
set the file system mount option string.
|
||||
|
||||
.TP
|
||||
\fB\fI loop= "<path to image>"
|
||||
path within the original root file system to loop-mount and use as the real
|
||||
root file system.
|
||||
|
||||
.TP
|
||||
\fB\fI loopfstype
|
||||
set the loop file system type, if applicable.
|
||||
|
||||
.TP
|
||||
\fB\fI loopflags
|
||||
set the loop file system mount option string, if applicable.
|
||||
|
||||
.TP
|
||||
\fB\fI nfsroot
|
||||
can be either "auto" to try to get the relevant information from DHCP or a
|
||||
string of the form NFSSERVER:NFSPATH or NFSSERVER:NFSPATH:NFSOPTS.
|
||||
Use root=/dev/nfs for NFS to kick to in. NFSOPTS can be looked up in
|
||||
\fInfs(5)\fP.
|
||||
|
||||
.TP
|
||||
\fB\fI ip
|
||||
tells how to configure the ip address. Allows one to specify an different
|
||||
NFS server than the DHCP server. See Documentation/filesystems/nfsroot.txt
|
||||
in any recent Linux source for details. Optional parameter for NFS root.
|
||||
|
||||
.TP
|
||||
\fB\fI vlan
|
||||
tells to create a VLAN tagged device. Allows one to configure one or
|
||||
multiple VLAN tagged devices using the "vlan=$name.$id:$parent"
|
||||
syntax. E.g. "vlan=eth0.1:eth0" Optional parameter for NFS root.
|
||||
|
||||
.TP
|
||||
\fB\fI BOOTIF
|
||||
is a mac address in pxelinux format with leading "01-" and "-" as separations.
|
||||
pxelinux passes mac address of network card used to PXE boot on with this
|
||||
bootarg.
|
||||
|
||||
.TP
|
||||
\fB\fI boot
|
||||
either local or NFS (affects which initramfs scripts are run, see the "Subdirectories" section under boot scripts).
|
||||
|
||||
.TP
|
||||
\fB\fI resume
|
||||
The resume hook tries to autodetect the resume partition and uses the first
|
||||
swap partition as valid guess. It is possible to set the RESUME variable in
|
||||
/etc/initramfs-tools/conf.d/resume.
|
||||
The boot variable noresume overrides it.
|
||||
|
||||
.TP
|
||||
\fB\fI resume_offset
|
||||
Specify the offset from the partition given by "resume=" at which the swap
|
||||
header of the swap file is located.
|
||||
|
||||
.TP
|
||||
\fB\fI quiet
|
||||
reduces the amount of text output to the console during boot.
|
||||
|
||||
.TP
|
||||
\fB\fI ro
|
||||
mounts the rootfs read-only.
|
||||
|
||||
.TP
|
||||
\fB\fI rw
|
||||
mounts the rootfs read-write.
|
||||
|
||||
.TP
|
||||
\fB\fI blacklist
|
||||
disables load of specific modules.
|
||||
Use blacklist=module1,module2,module3 bootparameter.
|
||||
|
||||
.SS Debug
|
||||
.TP
|
||||
\fB\fI panic
|
||||
sets an timeout on panic.
|
||||
panic=<sec> is a documented security feature: it disables the debug shell.
|
||||
|
||||
.TP
|
||||
\fB\fI debug
|
||||
generates lots of output. It writes a log to /run/initramfs/initramfs.debug.
|
||||
Instead when invoked with an arbitrary argument output is written to console.
|
||||
Use for example "debug=vc".
|
||||
|
||||
.TP
|
||||
\fB\fI break
|
||||
spawns a shell in the initramfs image at the chosen phase
|
||||
(top, modules, premount, mount, mountroot, bottom, init)
|
||||
before actually executing the corresponding scripts
|
||||
(see the "Boot scripts" section) or action. Multiple
|
||||
phases may be specified, delimited by commas.
|
||||
The default, if no phase is specified, is "premount".
|
||||
Beware that if both "panic" and "break" are present,
|
||||
initramfs will not spawn any shells but reboot instead.
|
||||
|
||||
.TP
|
||||
\fB\fI netconsole
|
||||
loads netconsole linux modules with the chosen args.
|
||||
|
||||
.TP
|
||||
\fB\fI all_generic_ide
|
||||
loads generic IDE/ATA chipset support on boot.
|
||||
|
||||
|
||||
.SH SCRIPTS
|
||||
|
||||
Valid boot and hook scripts names consist solely of alphabetics, numerics,
|
||||
dashes and underscores. Other scripts are discarded.
|
||||
|
||||
.SS Configuration hook scripts
|
||||
These are used to override the user configuration where necessary, for
|
||||
example to force use of busybox instead of klibc utilities.
|
||||
|
||||
.SS Hook scripts
|
||||
These are used when an initramfs image is created and not included in the
|
||||
image itself. They can however cause files to be included in the image.
|
||||
Hook scripts are executed under errexit. Thus a hook script can abort the
|
||||
mkinitramfs build on possible errors (exitcode != 0).
|
||||
|
||||
.SS Boot scripts
|
||||
These are included in the initramfs image and normally executed during
|
||||
kernel boot in the early user-space before the root partition has been
|
||||
mounted.
|
||||
|
||||
|
||||
.SH CONFIGURATION HOOK SCRIPTS
|
||||
|
||||
Configuration hook scripts can be found in
|
||||
/usr/share/initramfs-tools/conf-hooks.d. They are sourced by
|
||||
mkinitramfs after the configuration files in /etc and before running
|
||||
any hook scripts. They can override any of the variables documented
|
||||
in \fIinitramfs.conf\fR(5), but this should be done only if absolutely
|
||||
necessary. For example, if a package's boot script requires commands
|
||||
not provided by klibc-utils, it should also install a configuration
|
||||
hook that sets \fBBUSYBOX=y\fR.
|
||||
|
||||
|
||||
.SH HOOK SCRIPTS
|
||||
|
||||
Hooks can be found in two places: /usr/share/initramfs-tools/hooks and
|
||||
/etc/initramfs-tools/hooks. They are executed during generation of the
|
||||
initramfs-image and are responsible for including all the necessary components
|
||||
in the image itself. No guarantees are made as to the order in which the
|
||||
different scripts are executed unless the prereqs are setup in the script.
|
||||
Please notice that PREREQ is only honored inside a single directory. So first
|
||||
the scripts in /usr/share/initramfs-tools are ordered according to their PREREQ
|
||||
values and executed. Then all scripts in /etc/initramfs-tools are ordered
|
||||
according to \fBtheir\fR PREREQ values and executed. This mean that currently
|
||||
there is no possibility to have a local script (/etc/initramfs-tools) get
|
||||
executed before one from the package (/usr/share/initramfs-tools).
|
||||
|
||||
If a hook script requires configuration beyond the exported variables
|
||||
listed below, it should read a private configuration file that is
|
||||
separate from the /etc/initramfs-tools directory. It \fImust not\fR
|
||||
read initramfs-tools configuration files directly.
|
||||
|
||||
.SS Header
|
||||
In order to support prereqs, each script should begin with the following lines:
|
||||
|
||||
.RS
|
||||
.nf
|
||||
#!/bin/sh
|
||||
PREREQ=""
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
\fR. /usr/share/initramfs-tools/hook-functions
|
||||
# Begin real processing below this line
|
||||
.fi
|
||||
.RE
|
||||
|
||||
For example, if you are writing a new hook script which relies on lvm, the line
|
||||
starting with PREREQ should be changed to PREREQ="lvm" which will ensure that
|
||||
the lvm hook script is run before your custom script.
|
||||
|
||||
.SS Help functions
|
||||
/usr/share/initramfs-tools/hook-functions contains a number of functions which
|
||||
deal with some common tasks in a hook script:
|
||||
.TP
|
||||
\fB\fI
|
||||
manual_add_modules
|
||||
adds a module (and any modules which it depends on) to the initramfs image.
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
manual_add_modules isofs
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
add_modules_from_file
|
||||
reads a file containing a list of modules (one per line) to be added to the
|
||||
initramfs image. The file can contain comments (lines starting with #) and
|
||||
arguments to the modules by writing the arguments on the same line as the name
|
||||
of the module.
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
add_modules_from_file /tmp/modlist
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
force_load
|
||||
adds a module (and its dependencies) to the initramfs image and also
|
||||
unconditionally loads the module during boot. Also supports passing arguments
|
||||
to the module by listing them after the module name.
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
force_load cdrom debug=1
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
copy_modules_dir
|
||||
copies an entire module directory from /lib/modules/KERNELVERSION/ into the
|
||||
initramfs image.
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
copy_modules_dir kernel/drivers/ata
|
||||
.RE
|
||||
|
||||
.SS Including binaries
|
||||
If you need to copy binaries to the initramfs module, a command like this
|
||||
should be used:
|
||||
.PP
|
||||
.RS
|
||||
copy_exec /sbin/mdadm /sbin
|
||||
.RE
|
||||
|
||||
mkinitramfs will automatically detect which libraries the executable depends on
|
||||
and copy them to the initramfs. This means that most executables, unless
|
||||
compiled with klibc, will automatically include glibc in the image which will
|
||||
increase its size by several hundred kilobytes.
|
||||
|
||||
.SS Including a system firmware preimage (early initramfs)
|
||||
If you need to prepend data to the initramfs image, you need to prepare it
|
||||
in a file, and call the \fB\fIprepend_earlyinitramfs\fR function. The file
|
||||
can be disposed of as soon as the function returns.
|
||||
|
||||
.B Example:
|
||||
.nf
|
||||
TEMP_FILE=$(mktemp ...)
|
||||
...
|
||||
prepend_earlyinitramfs ${TEMP_FILE}
|
||||
rm -f ${TEMP_FILE}
|
||||
|
||||
.RE
|
||||
|
||||
.SS Exported variables
|
||||
mkinitramfs sets several variables for the hook scripts environment.
|
||||
|
||||
.TP
|
||||
\fB\fI MODULESDIR
|
||||
corresponds to the linux modules dir.
|
||||
.TP
|
||||
\fB\fI version
|
||||
is the $(uname \-r) linux version against mkinitramfs is run.
|
||||
.TP
|
||||
\fB\fI CONFDIR
|
||||
is the path of the used initramfs-tools configurations.
|
||||
.TP
|
||||
\fB\fI DESTDIR
|
||||
is the root path of the newly build initramfs.
|
||||
.TP
|
||||
\fB\fI DPKG_ARCH
|
||||
allows arch specific hook additions.
|
||||
.TP
|
||||
\fB\fI verbose
|
||||
corresponds to the verbosity of the update-initramfs run.
|
||||
.TP
|
||||
\fB\fI BUSYBOX, MODULES
|
||||
are as described in \fIinitramfs.conf\fR(5).
|
||||
.TP
|
||||
\fB\fI BUSYBOXDIR
|
||||
is the directory where busybox utilities should be installed from, or
|
||||
empty if busybox is not being used.
|
||||
|
||||
|
||||
.SH BOOT SCRIPTS
|
||||
|
||||
Similarly to hook scripts, boot scripts can be found in two places
|
||||
/usr/share/initramfs-tools/scripts/ and /etc/initramfs-tools/scripts/. There
|
||||
are a number of subdirectories to these two directories which control the boot
|
||||
stage at which the scripts are executed.
|
||||
|
||||
.SS Header
|
||||
Like for hook scripts, there are no guarantees as to the order in which the
|
||||
different scripts in one subdirectory (see "Subdirectories" below) are
|
||||
executed. In order to define a certain order, a similar header as for hook
|
||||
scripts should be used:
|
||||
|
||||
.RS
|
||||
.nf
|
||||
#!/bin/sh
|
||||
PREREQ=""
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
.fi
|
||||
.RE
|
||||
|
||||
Where PREREQ is modified to list other scripts in the same subdirectory if necessary.
|
||||
|
||||
.SS Help functions
|
||||
A number of functions (mostly dealing with output) are provided to boot scripts in
|
||||
.I /scripts/functions
|
||||
:
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
log_success_msg
|
||||
Logs a success message
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
log_success_msg "Frobnication successful"
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
log_failure_msg
|
||||
Logs a failure message
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
log_failure_msg "Frobnication component froobz missing"
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
log_warning_msg
|
||||
Logs a warning message
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
log_warning_msg "Only partial frobnication possible"
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
log_begin_msg
|
||||
Logs a message that some processing step has begun
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
log_end_msg
|
||||
Logs a message that some processing step is finished
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
log_begin_msg "Frobnication begun"
|
||||
# Do something
|
||||
log_end_msg
|
||||
.fi
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
panic
|
||||
Logs an error message and executes a shell in the initramfs image to allow the
|
||||
user to investigate the situation.
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
panic "Frobnication failed"
|
||||
.fi
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
add_mountroot_fail_hook
|
||||
Registers the script as able to provide possible further information, in the
|
||||
event that the root device cannot be found. See the example script in the
|
||||
initramfs-tools examples directory for more information.
|
||||
.RS
|
||||
.PP
|
||||
.B Example:
|
||||
add_mountroot_fail_hook
|
||||
.RE
|
||||
|
||||
.SS Subdirectories
|
||||
Both /usr/share/initramfs-tools/scripts and /etc/initramfs-tools/scripts
|
||||
contains the following subdirectories.
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
init-top
|
||||
the scripts in this directory are the first scripts to be executed after sysfs
|
||||
and procfs have been mounted.
|
||||
It also runs the udev hook for populating the /dev tree (udev will keep
|
||||
running until init-bottom).
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
init-premount
|
||||
happens after modules specified by hooks and /etc/initramfs-tools/modules
|
||||
have been loaded.
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
local-top OR nfs-top
|
||||
After these scripts have been executed, the root device node is expected to be
|
||||
present (local) or the network interface is expected to be usable (NFS).
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
local-block
|
||||
These scripts are called with the name of a local block device. After
|
||||
these scripts have been executed, that device node should be present.
|
||||
If the local-top or local-block scripts fail to create the wanted
|
||||
device node, the local-block scripts will be called periodically to
|
||||
try again.
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
local-premount OR nfs-premount
|
||||
are run after the sanity of the root device has been verified (local) or the
|
||||
network interface has been brought up (NFS), but before the actual root fs has
|
||||
been mounted.
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
local-bottom OR nfs-bottom
|
||||
are run after the rootfs has been mounted (local) or the NFS root share has
|
||||
been mounted.
|
||||
|
||||
.TP
|
||||
\fB\fI
|
||||
init-bottom
|
||||
are the last scripts to be executed before procfs and sysfs are moved to the
|
||||
real rootfs and execution is turned over to the init binary which should now be
|
||||
found in the mounted rootfs. udev is stopped.
|
||||
|
||||
.SS Boot parameters
|
||||
.TP
|
||||
\fB\fI
|
||||
/conf/param.conf
|
||||
allows boot scripts to change exported variables that are listed on top of init. Write the new values to it. It will be sourced after an boot script run if it exists.
|
||||
|
||||
|
||||
.SH EXAMPLES
|
||||
|
||||
.SS Hook script
|
||||
An example hook script would look something like this (and would usually be
|
||||
placed in /etc/initramfs-tools/hooks/frobnicate):
|
||||
|
||||
.RS
|
||||
.nf
|
||||
#!/bin/sh
|
||||
# Example frobnication hook script
|
||||
|
||||
PREREQ="lvm"
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
\fR. /usr/share/initramfs-tools/hook-functions
|
||||
# Begin real processing below this line
|
||||
|
||||
if [ ! \-x "/sbin/frobnicate" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
force_load frobnicator interval=10
|
||||
copy_exec /sbin/frobnicate /sbin
|
||||
exit 0
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.SS Boot script
|
||||
An example boot script would look something like this (and would usually be placed in /etc/initramfs-tools/scripts/local-top/frobnicate):
|
||||
|
||||
.RS
|
||||
.nf
|
||||
#!/bin/sh
|
||||
# Example frobnication boot script
|
||||
|
||||
PREREQ="lvm"
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
\fR. /scripts/functions
|
||||
# Begin real processing below this line
|
||||
if [ ! \-x "/sbin/frobnicate" ]; then
|
||||
panic "Frobnication executable not found"
|
||||
fi
|
||||
|
||||
if [ ! \-e "/dev/mapper/frobb" ]; then
|
||||
panic "Frobnication device not found"
|
||||
fi
|
||||
|
||||
log_begin_msg "Starting frobnication"
|
||||
/sbin/frobnicate "/dev/mapper/frobb" || panic "Frobnication failed"
|
||||
log_end_msg
|
||||
|
||||
exit 0
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.SS Exported variables
|
||||
init sets several variables for the boot scripts environment.
|
||||
|
||||
.TP
|
||||
\fB\fI ROOT
|
||||
corresponds to the root boot option.
|
||||
Advanced boot scripts like cryptsetup or live-initramfs need to play tricks.
|
||||
Otherwise keep it alone.
|
||||
.TP
|
||||
\fB\fI ROOTDELAY, ROOTFLAGS, ROOTFSTYPE, IP
|
||||
corresponds to the rootdelay, rootflags, rootfstype or ip boot option.
|
||||
Use of ROOTDELAY is deprecated; you should implement a \fIlocal-block\fR
|
||||
boot script rather than delaying or polling.
|
||||
.TP
|
||||
\fB\fI DPKG_ARCH
|
||||
allows arch specific boot actions.
|
||||
.TP
|
||||
\fB\fI blacklist, panic, quiet, resume, noresume, resume_offset
|
||||
set according relevant boot option.
|
||||
.TP
|
||||
\fB\fI break
|
||||
Useful for manual intervention during setup and coding an boot script.
|
||||
.TP
|
||||
\fB\fI REASON
|
||||
Argument passed to the \fIpanic\fP helper function. Use to find out why
|
||||
you landed in the initramfs shell.
|
||||
.TP
|
||||
\fB\fI init
|
||||
passes the path to init(8) usually /sbin/init.
|
||||
.TP
|
||||
\fB\fI readonly
|
||||
is the default for mounting the root corresponds to the ro bootarg.
|
||||
Overridden by rw bootarg.
|
||||
.TP
|
||||
\fB\fI rootmnt
|
||||
is the path where root gets mounted usually /root.
|
||||
.TP
|
||||
\fB\fI debug
|
||||
indicates that a debug log is captured for further investigation.
|
||||
|
||||
|
||||
.SH UPDATING THE INITRAMFS FROM ANOTHER PACKAGE
|
||||
Package maintainer scripts should not run \fBupdate-initramfs\fR
|
||||
directly. A package that installs hooks for initramfs-tools should
|
||||
include a triggers file containing:
|
||||
.RS
|
||||
.nf
|
||||
activate\-noawait update\-initramfs
|
||||
.fi
|
||||
.RE
|
||||
|
||||
Kernel packages must call the kernel hooks as documented in the
|
||||
Debian Kernel Handbook.
|
||||
|
||||
A package that requires an initramfs to function, but is not a kernel
|
||||
package, should include a triggers file containing:
|
||||
.RS
|
||||
.nf
|
||||
activate\-await update\-initramfs
|
||||
.fi
|
||||
.RE
|
||||
|
||||
|
||||
.SH KERNEL HOOKS
|
||||
initramfs-tools includes hook scripts that are called by kernel
|
||||
packages on installation and removal, so that an initramfs is
|
||||
automatically created, updated or deleted as necessary. The hook
|
||||
scripts do nothing if the environment variable \fBINITRD\fR is
|
||||
set to \fBNo\fR. This will be the case for kernel packages
|
||||
built with \fBmake deb-pkg\fR and with \fBCONFIG_BLK_DEV_INITRD\fR
|
||||
not set in the kernel config, or built with \fBmake-kpkg\fR and not
|
||||
using the \fB--initrd\fR option.
|
||||
|
||||
|
||||
.SH DEBUG
|
||||
It is easy to check the generated initramfs for its content. One may need
|
||||
to double-check if it contains the relevant binaries, libs or modules:
|
||||
.RS
|
||||
.nf
|
||||
lsinitramfs /boot/initrd.img\-3.16\-3\-amd64
|
||||
.fi
|
||||
.RE
|
||||
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.I /run/initramfs/fsck.log
|
||||
Log of fsck commands run within the initramfs, with their output.
|
||||
.TP
|
||||
.I /run/initramfs/fsck-root
|
||||
Exists only if fsck ran successfully for the root filesystem.
|
||||
.TP
|
||||
.I /run/initramfs/fsck-usr
|
||||
Exists only if fsck ran successfully for the \fI/usr\fR filesystem.
|
||||
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>,
|
||||
Jeff Bailey <jbailey@raspberryginger.com> and numerous others.
|
||||
.PP
|
||||
This manual was written by David H\[:a]rdeman <david@hardeman.nu>,
|
||||
updated by Maximilian Attems <maks@debian.org>.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR
|
||||
.IR initramfs.conf (5),
|
||||
.IR mkinitramfs (8),
|
||||
.IR update-initramfs (8),
|
||||
.IR lsinitramfs (8).
|
|
@ -0,0 +1,141 @@
|
|||
.TH INITRAMFS.CONF 5 "2018/07/18" "initramfs\-tools" "File Formats Manual"
|
||||
|
||||
.SH NAME
|
||||
initramfs.conf \- configuration file for mkinitramfs
|
||||
|
||||
.SH DESCRIPTION
|
||||
The behaviour of
|
||||
.B mkinitramfs
|
||||
can be modified by its configuration file.
|
||||
|
||||
Each line in the file can be a configuration variable, a blank line,
|
||||
or a comment. The value of an variable is assigned by an statement
|
||||
of the form: \fIname\fP=[\fIvalue\fP]
|
||||
|
||||
Configuration options can be broken out into configuration snippets and
|
||||
placed in individual files in the /etc/initramfs-tools/conf.d directory. Files
|
||||
in this directory are always read \fBafter\fP the main configuration file,
|
||||
so you can override the settings in the main config file without editing it
|
||||
directly.
|
||||
|
||||
.SH GENERAL VARIABLES
|
||||
.TP
|
||||
\fB MODULES
|
||||
Specifies the modules for the initramfs image.
|
||||
|
||||
Modules listed in \fI/etc/initramfs-tools/modules\fP and
|
||||
\fI/usr/share/initramfs-tools/modules.d/*\fP are always included in the
|
||||
initramfs, and are loaded early in the boot process.
|
||||
|
||||
|
||||
\fIlist\fP doesn't load any additional modules at boot time, other than those
|
||||
listed in the above files.
|
||||
|
||||
\fImost\fP adds most file system, all ata, sata, scsi and usb drivers.
|
||||
|
||||
\fIdep\fP tries to guess which modules are necessary for the running box and
|
||||
only adds those modules.
|
||||
|
||||
\fInetboot\fP adds the base and network modules, but skips block devices.
|
||||
|
||||
|
||||
The default setting is \fImost\fP.
|
||||
|
||||
.TP
|
||||
\fB BUSYBOX
|
||||
Include busybox utilities for the boot scripts.
|
||||
If set to 'n'
|
||||
.B mkinitramfs
|
||||
will build an initramfs without busybox.
|
||||
Beware that many boot scripts need busybox utilities.
|
||||
|
||||
.TP
|
||||
\fB COMPCACHE_SIZE
|
||||
Amount of RAM to use for RAM-based compressed swap space.
|
||||
The default is not to use compcache.
|
||||
|
||||
An empty value \- compcache isn't used, or added to the initramfs at all.
|
||||
|
||||
An integer and K (e.g. \fI65536 K\fP) \- use a number of kilobytes.
|
||||
|
||||
An integer and M (e.g. \fI256 M\fP) \- use a number of megabytes.
|
||||
|
||||
An integer and G (e.g. \fI1 G\fP) \- use a number of gigabytes.
|
||||
|
||||
An integer and % (e.g. \fI50 %\fP) \- use a percentage of the amount of RAM.
|
||||
|
||||
You can optionally install the \fIcompcache\fP package to configure this
|
||||
setting via debconf and have userspace scripts to load and unload compcache.
|
||||
|
||||
.TP
|
||||
\fB COMPRESS
|
||||
Specifies the compression method used for the initramfs image.
|
||||
.B mkinitramfs
|
||||
will default to gzip if the kernel lacks support (CONFIG_RD) or the
|
||||
corresponding userspace utility is not present.
|
||||
|
||||
.TP
|
||||
\fB UMASK
|
||||
Set the umask value of the generated initramfs file.
|
||||
Useful to not disclose eventual keys.
|
||||
|
||||
.TP
|
||||
\fB BOOT
|
||||
Allows one to use an nfs drive as the root of the drive.
|
||||
The default is to boot from \fIlocal\fP media (hard drive, USB stick).
|
||||
Set to \fInfs\fP for an NFS root share.
|
||||
|
||||
.TP
|
||||
\fB RUNSIZE
|
||||
The size of the \fI/run\fP tmpfs mount point in bytes (suffixes are supported)
|
||||
or as percentage of your physical RAM. This parameter is used as the value of
|
||||
the size mount option to tmpfs. See
|
||||
\fBhttps://www.kernel.org/doc/Documentation/filesystems/tmpfs.txt\fR for
|
||||
details. Can be overridden by an optional \fBinitramfs.runsize=\fR bootarg.
|
||||
The default is 10%.
|
||||
|
||||
.SH VARIABLES FOR LOCAL BOOT
|
||||
.TP
|
||||
\fB RESUME
|
||||
Specifies the device used for suspend-to-disk (hibernation), which the
|
||||
initramfs code should attempt to resume from. If this is not defined
|
||||
or is set to \fIauto\fP,
|
||||
.B mkinitramfs
|
||||
will automatically select the largest available swap partition.
|
||||
Set it to \fInone\fP to disable resume from disk.
|
||||
|
||||
.SH VARIABLES FOR NFS BOOT
|
||||
.TP
|
||||
\fB DEVICE
|
||||
Specifies the default network interface to use, like eth0. The \fIip\fP or
|
||||
\fIBOOTIF\fP bootargs may override this.
|
||||
|
||||
.TP
|
||||
\fB VLAN
|
||||
Specifies the VLAN tag id to setup, e.g. VLAN=eth0.1:eth0. The \fIvlan\fP
|
||||
bootarg may override this.
|
||||
|
||||
.TP
|
||||
\fB ROOT
|
||||
Allows optional root bootarg hardcoding, when no root bootarg can be passed.
|
||||
A root bootarg overrides that special setting.
|
||||
|
||||
.TP
|
||||
\fB NFSROOT
|
||||
Defaults to \fIauto\fP in order to pick up value from DHCP server.
|
||||
Otherwise you need to specify \fIHOST:MOUNT\fP.
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.I /etc/initramfs-tools/initramfs.conf
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>,
|
||||
Jeff Bailey <jbailey@raspberryginger.com> and numerous others.
|
||||
Loosely based on mkinitrd.conf by Herbert Xu.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR
|
||||
.IR initramfs-tools (7),
|
||||
.IR mkinitramfs (8),
|
||||
.IR update-initramfs (8).
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
version="$1"
|
||||
bootopt=""
|
||||
|
||||
command -v update-initramfs >/dev/null 2>&1 || exit 0
|
||||
|
||||
# passing the kernel version is required
|
||||
if [ -z "${version}" ]; then
|
||||
echo >&2 "W: initramfs-tools: ${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# exit if kernel does not need an initramfs
|
||||
if [ "$INITRD" = 'No' ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# absolute file name of kernel image may be passed as a second argument;
|
||||
# create the initrd in the same directory
|
||||
if [ -n "$2" ]; then
|
||||
bootdir=$(dirname "$2")
|
||||
bootopt="-b ${bootdir}"
|
||||
fi
|
||||
|
||||
# avoid running multiple times
|
||||
if [ -n "$DEB_MAINT_PARAMS" ]; then
|
||||
eval set -- "$DEB_MAINT_PARAMS"
|
||||
if [ -z "$1" ] || [ "$1" != "configure" ]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# we're good - create initramfs. update runs do_bootloader
|
||||
# shellcheck disable=SC2086
|
||||
INITRAMFS_TOOLS_KERNEL_HOOK=1 update-initramfs -c -k "${version}" ${bootopt} >&2
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
version="$1"
|
||||
bootopt=""
|
||||
|
||||
[ -x /usr/sbin/update-initramfs ] || exit 0
|
||||
|
||||
# passing the kernel version is required
|
||||
if [ -z "${version}" ]; then
|
||||
echo >&2 "W: initramfs-tools: ${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# exit if custom kernel does not need an initramfs
|
||||
if [ "$INITRD" = 'No' ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# absolute file name of kernel image may be passed as a second argument;
|
||||
# create the initrd in the same directory
|
||||
if [ -n "$2" ]; then
|
||||
bootdir=$(dirname "$2")
|
||||
bootopt="-b ${bootdir}"
|
||||
fi
|
||||
|
||||
# avoid running multiple times
|
||||
if [ -n "$DEB_MAINT_PARAMS" ]; then
|
||||
eval set -- "$DEB_MAINT_PARAMS"
|
||||
if [ -z "$1" ] || [ "$1" != "remove" ]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# delete initramfs
|
||||
# shellcheck disable=SC2086
|
||||
INITRAMFS_TOOLS_KERNEL_HOOK=1 update-initramfs -d -k "${version}" ${bootopt} >&2
|
|
@ -0,0 +1,57 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
usage()
|
||||
{
|
||||
cat << EOF
|
||||
|
||||
Usage: lsinitramfs [-l] initramfs-file...
|
||||
|
||||
Options:
|
||||
-l Display long and more verbose listing of initramfs content
|
||||
|
||||
See lsinitramfs(8) for further details.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
usage_error()
|
||||
{
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
umi_opts="--list"
|
||||
|
||||
OPTIONS=$(getopt -o hl --long help,long -n "$0" -- "$@") || usage_error
|
||||
|
||||
eval set -- "$OPTIONS"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-l|--long)
|
||||
umi_opts="${umi_opts:+${umi_opts} --verbose}"
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Internal error!" >&2
|
||||
exit 1
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$#" -eq 0 ] ; then
|
||||
usage_error
|
||||
fi
|
||||
|
||||
for initramfs in "$@" ; do
|
||||
unmkinitramfs $umi_opts -- "$initramfs"
|
||||
done
|
|
@ -0,0 +1,56 @@
|
|||
.TH LSINITRAMFS 8 "2015/12/09" "initramfs\-tools" "System Administration"
|
||||
|
||||
.SH NAME
|
||||
lsinitramfs \- list content of an initramfs image
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B lsinitramfs
|
||||
.RB [ -l ]
|
||||
.IR initramfs-file ...
|
||||
.br
|
||||
.BR lsinitramfs " " -h
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B lsinitramfs
|
||||
command lists the content of given initramfs images. It allows one to quickly check
|
||||
the content of one (or multiple) specified initramfs files.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
.B -h
|
||||
Display usage information and exit.
|
||||
|
||||
.TP
|
||||
.B -l
|
||||
Display long and more verbose listing of initramfs content.
|
||||
|
||||
.SH USAGE EXAMPLES
|
||||
|
||||
List initramfs content of current running kernel:
|
||||
|
||||
.PP
|
||||
.B lsinitramfs /boot/initrd.img-$(uname -r)
|
||||
|
||||
List content of two initramfs files in verbose mode:
|
||||
|
||||
.PP
|
||||
.B lsinitramfs -l /boot/vmlinuz-2.6.31-grml64 /boot/vmlinuz-2.6.33-grml64
|
||||
|
||||
.SH BUGS
|
||||
.BR lsinitramfs
|
||||
cannot deal with multiple-segmented initramfs images, except where an
|
||||
early (uncompressed) initramfs with system firmware is prepended to
|
||||
the regular compressed initramfs.
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>
|
||||
and numerous others.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR
|
||||
.IR initramfs-tools (7),
|
||||
.IR mkinitramfs (8),
|
||||
.IR unmkinitramfs (8),
|
||||
.IR update-initramfs (8).
|
|
@ -0,0 +1,476 @@
|
|||
#!/bin/sh
|
||||
|
||||
umask 0022
|
||||
export PATH='/usr/bin:/sbin:/bin'
|
||||
|
||||
# Defaults
|
||||
keep="n"
|
||||
CONFDIR="/etc/initramfs-tools"
|
||||
verbose="n"
|
||||
# Will be updated by busybox's conf hook, if present
|
||||
BUSYBOXDIR=
|
||||
export BUSYBOXDIR
|
||||
|
||||
usage()
|
||||
{
|
||||
cat << EOF
|
||||
|
||||
Usage: mkinitramfs [option]... -o outfile [version]
|
||||
|
||||
Options:
|
||||
-c compress Override COMPRESS setting in initramfs.conf.
|
||||
-d confdir Specify an alternative configuration directory.
|
||||
-k Keep temporary directory used to make the image.
|
||||
-o outfile Write to outfile.
|
||||
-r root Override ROOT setting in initramfs.conf.
|
||||
|
||||
See mkinitramfs(8) for further details.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
usage_error()
|
||||
{
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
OPTIONS=$(getopt -o c:d:hko:r:v --long help -n "$0" -- "$@") || usage_error
|
||||
|
||||
eval set -- "$OPTIONS"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-c)
|
||||
compress="$2"
|
||||
shift 2
|
||||
;;
|
||||
-d)
|
||||
CONFDIR="$2"
|
||||
shift 2
|
||||
if [ ! -d "${CONFDIR}" ]; then
|
||||
echo "${0}: ${CONFDIR}: Not a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-o)
|
||||
outfile="$2"
|
||||
shift 2
|
||||
;;
|
||||
-k)
|
||||
keep="y"
|
||||
shift
|
||||
;;
|
||||
-r)
|
||||
ROOT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-v)
|
||||
verbose="y"
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Internal error!" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# For dependency ordered mkinitramfs hook scripts.
|
||||
. /usr/share/initramfs-tools/scripts/functions
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
# Auto-export any variables set in the conf snippets such that
|
||||
# initramfs hooks can configure each other
|
||||
# i.e. initramfs-tools-ubuntu-core affecting
|
||||
# intel-microcode/amd-microcode hook defaults
|
||||
set -a
|
||||
|
||||
. "${CONFDIR}/initramfs.conf"
|
||||
|
||||
EXTRA_CONF=''
|
||||
maybe_add_conf() {
|
||||
if [ -e "$1" ] && \
|
||||
basename "$1" \
|
||||
| grep '^[[:alnum:]][[:alnum:]\._-]*$' \
|
||||
| grep -qv '\.dpkg-.*$'; then
|
||||
if [ -d "$1" ]; then
|
||||
echo "W: $1 is a directory instead of file" >&2
|
||||
else
|
||||
EXTRA_CONF="${EXTRA_CONF} $1"
|
||||
. "$1"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
for i in /usr/share/initramfs-tools/conf.d/*; do
|
||||
# Configuration files in /etc mask those in /usr/share
|
||||
if ! [ -e "${CONFDIR}"/conf.d/"$(basename "${i}")" ]; then
|
||||
maybe_add_conf "${i}"
|
||||
fi
|
||||
done
|
||||
for i in "${CONFDIR}"/conf.d/*; do
|
||||
maybe_add_conf "${i}"
|
||||
done
|
||||
|
||||
# source package confs
|
||||
for i in /usr/share/initramfs-tools/conf-hooks.d/*; do
|
||||
if [ -d "${i}" ]; then
|
||||
echo "W: ${i} is a directory instead of file." >&2
|
||||
elif [ -e "${i}" ]; then
|
||||
. "${i}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Finish loading conf snippets
|
||||
set +a
|
||||
|
||||
# Check busybox dependency
|
||||
if [ "${BUSYBOX}" = "y" ] && [ -z "${BUSYBOXDIR}" ]; then
|
||||
echo >&2 "E: @BUSYBOX_PACKAGES@, version @BUSYBOX_MIN_VERSION@ or later, is required but not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "${UMASK:-}" ]; then
|
||||
umask "${UMASK}"
|
||||
fi
|
||||
|
||||
if [ -z "${outfile}" ]; then
|
||||
usage_error
|
||||
fi
|
||||
|
||||
touch "$outfile"
|
||||
outfile="$(readlink -f "$outfile")"
|
||||
|
||||
# And by "version" we really mean path to kernel modules
|
||||
# This is braindead, and exists to preserve the interface with mkinitrd
|
||||
if [ ${#} -ne 1 ]; then
|
||||
version="$(uname -r)"
|
||||
else
|
||||
version="${1}"
|
||||
fi
|
||||
|
||||
case "${version}" in
|
||||
/lib/modules/*/[!/]*)
|
||||
;;
|
||||
/lib/modules/[!/]*)
|
||||
version="${version#/lib/modules/}"
|
||||
version="${version%%/*}"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${version}" in
|
||||
*/*)
|
||||
echo "$PROG: ${version} is not a valid kernel version" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "${compress:-}" ]; then
|
||||
compress=${COMPRESS?}
|
||||
fi
|
||||
unset COMPRESS
|
||||
|
||||
if ! command -v "${compress}" >/dev/null 2>&1; then
|
||||
compress=gzip
|
||||
[ "${verbose}" = y ] && \
|
||||
echo "No ${compress} in ${PATH}, using gzip"
|
||||
fi
|
||||
|
||||
case "${compress}" in
|
||||
gzip) # If we're doing a reproducible build, use gzip -n
|
||||
if [ -n "${SOURCE_DATE_EPOCH}" ]; then
|
||||
compress="gzip -n"
|
||||
# Otherwise, substitute pigz if it's available
|
||||
elif command -v pigz >/dev/null; then
|
||||
compress=pigz
|
||||
fi
|
||||
;;
|
||||
lz4) compress="lz4 -9 -l" ;;
|
||||
xz) compress="xz --check=crc32"
|
||||
# If we're not doing a reproducible build, enable multithreading
|
||||
test -z "${SOURCE_DATE_EPOCH}" && compress="$compress --threads=0"
|
||||
;;
|
||||
bzip2|lzma|lzop)
|
||||
# no parameters needed
|
||||
;;
|
||||
*) echo "W: Unknown compression command ${compress}" >&2 ;;
|
||||
esac
|
||||
|
||||
if [ -d "${outfile}" ]; then
|
||||
echo "${outfile} is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MODULESDIR="/lib/modules/${version}"
|
||||
|
||||
if [ ! -e "${MODULESDIR}" ]; then
|
||||
echo "W: missing ${MODULESDIR}" >&2
|
||||
echo "W: Ensure all necessary drivers are built into the linux image!" >&2
|
||||
fi
|
||||
if [ ! -e "${MODULESDIR}/modules.dep" ]; then
|
||||
depmod "${version}"
|
||||
fi
|
||||
|
||||
# Prepare to clean up temporary files on exit
|
||||
DESTDIR=
|
||||
__TMPCPIOGZ=
|
||||
__TMPEARLYCPIO=
|
||||
clean_on_exit() {
|
||||
if [ "${keep}" = "y" ]; then
|
||||
echo "Working files in ${DESTDIR:-<not yet created>}, early initramfs in ${__TMPEARLYCPIO:-<not yet created>} and overlay in ${__TMPCPIOGZ:-<not yet created>}"
|
||||
else
|
||||
for path in "${DESTDIR}" "${__TMPCPIOGZ}" "${__TMPEARLYCPIO}"; do
|
||||
test -z "${path}" || rm -rf "${path}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
trap clean_on_exit EXIT
|
||||
trap "exit 1" INT TERM # makes the EXIT trap effective even when killed
|
||||
|
||||
# Create temporary directory and files for initramfs contents
|
||||
[ -n "${TMPDIR}" ] && [ ! -w "${TMPDIR}" ] && unset TMPDIR
|
||||
DESTDIR="$(mktemp -d "${TMPDIR:-/var/tmp}/mkinitramfs_XXXXXX")" || exit 1
|
||||
chmod 755 "${DESTDIR}"
|
||||
__TMPCPIOGZ="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-OL_XXXXXX")" || exit 1
|
||||
__TMPEARLYCPIO="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-FW_XXXXXX")" || exit 1
|
||||
|
||||
DPKG_ARCH=$(dpkg --print-architecture)
|
||||
|
||||
# Export environment for hook scripts.
|
||||
#
|
||||
export MODULESDIR
|
||||
export version
|
||||
export CONFDIR
|
||||
export DESTDIR
|
||||
export DPKG_ARCH
|
||||
export verbose
|
||||
export MODULES
|
||||
export BUSYBOX
|
||||
export COMPCACHE_SIZE
|
||||
export RESUME
|
||||
|
||||
# Private, used by 'catenate_cpiogz'.
|
||||
export __TMPCPIOGZ
|
||||
|
||||
# Private, used by 'prepend_earlyinitramfs'.
|
||||
export __TMPEARLYCPIO
|
||||
|
||||
# Create usr-merged filesystem layout, to avoid duplicates if the host
|
||||
# filesystem is usr-merged.
|
||||
for d in /bin /lib* /sbin; do
|
||||
mkdir -p "${DESTDIR}/usr${d}"
|
||||
ln -s "usr${d}" "${DESTDIR}${d}"
|
||||
done
|
||||
for d in conf/conf.d etc run scripts ${MODULESDIR}; do
|
||||
mkdir -p "${DESTDIR}/${d}"
|
||||
done
|
||||
|
||||
# Copy in modules.builtin and modules.order (not generated by depmod)
|
||||
# and modules.builtin.bin (generated by depmod, but too late to avoid
|
||||
# error messages as in #948257)
|
||||
for x in modules.builtin modules.builtin.bin modules.order; do
|
||||
if [ -f "${MODULESDIR}/${x}" ]; then
|
||||
cp -p "${MODULESDIR}/${x}" "${DESTDIR}${MODULESDIR}/${x}"
|
||||
fi
|
||||
done
|
||||
|
||||
# MODULES=list case. Always honour.
|
||||
for x in "${CONFDIR}/modules" /usr/share/initramfs-tools/modules.d/*; do
|
||||
if [ -f "${x}" ]; then
|
||||
add_modules_from_file "${x}"
|
||||
fi
|
||||
done
|
||||
|
||||
# MODULES=most is default
|
||||
case "${MODULES}" in
|
||||
dep)
|
||||
dep_add_modules
|
||||
;;
|
||||
most)
|
||||
auto_add_modules
|
||||
;;
|
||||
netboot)
|
||||
auto_add_modules base
|
||||
auto_add_modules net
|
||||
;;
|
||||
list)
|
||||
# nothing to add
|
||||
;;
|
||||
*)
|
||||
echo "W: mkinitramfs: unsupported MODULES setting: ${MODULES}." >&2
|
||||
echo "W: mkinitramfs: Falling back to MODULES=most." >&2
|
||||
auto_add_modules
|
||||
;;
|
||||
esac
|
||||
|
||||
# Resolve hidden dependencies
|
||||
hidden_dep_add_modules
|
||||
|
||||
# First file executed by linux
|
||||
cp -p /usr/share/initramfs-tools/init "${DESTDIR}/init"
|
||||
|
||||
# add existant boot scripts
|
||||
for b in $(cd /usr/share/initramfs-tools/scripts/ && find . \
|
||||
-regextype posix-extended -regex '.*/[[:alnum:]\._-]+$' -type f); do
|
||||
option=$(sed '/^OPTION=/!d;$d;s/^OPTION=//;s/[[:space:]]*$//' "/usr/share/initramfs-tools/scripts/${b}")
|
||||
# shellcheck disable=SC1083,SC2086
|
||||
[ -z "$option" ] || eval test -n \"\${$option}\" -a \"\${$option}\" != \"n\" || continue
|
||||
|
||||
[ -d "${DESTDIR}/scripts/$(dirname "${b}")" ] \
|
||||
|| mkdir -p "${DESTDIR}/scripts/$(dirname "${b}")"
|
||||
cp -p "/usr/share/initramfs-tools/scripts/${b}" \
|
||||
"${DESTDIR}/scripts/$(dirname "${b}")/"
|
||||
done
|
||||
# Prune dot-files/directories and limit depth to exclude VCS files
|
||||
for b in $(cd "${CONFDIR}/scripts" && find . -maxdepth 2 -name '.?*' -prune -o \
|
||||
-regextype posix-extended -regex '.*/[[:alnum:]\._-]+$' -type f -print); do
|
||||
option=$(sed '/^OPTION=/!d;$d;s/^OPTION=//;s/[[:space:]]*$//' "${CONFDIR}/scripts/${b}")
|
||||
# shellcheck disable=SC1083,SC2086
|
||||
[ -z "$option" ] || eval test -n \"\${$option}\" -a \"\${$option}\" != \"n\" || continue
|
||||
[ -d "${DESTDIR}/scripts/$(dirname "${b}")" ] \
|
||||
|| mkdir -p "${DESTDIR}/scripts/$(dirname "${b}")"
|
||||
cp -p "${CONFDIR}/scripts/${b}" "${DESTDIR}/scripts/$(dirname "${b}")/"
|
||||
done
|
||||
|
||||
echo "DPKG_ARCH=${DPKG_ARCH}" > "${DESTDIR}/conf/arch.conf"
|
||||
cp -p "${CONFDIR}/initramfs.conf" "${DESTDIR}/conf"
|
||||
for i in ${EXTRA_CONF}; do
|
||||
copy_file config "${i}" /conf/conf.d
|
||||
done
|
||||
|
||||
# ROOT hardcoding
|
||||
if [ -n "${ROOT:-}" ]; then
|
||||
echo "ROOT=${ROOT}" > "${DESTDIR}/conf/conf.d/root"
|
||||
fi
|
||||
|
||||
if ! command -v ldd >/dev/null 2>&1 ; then
|
||||
echo "E: no ldd around - install libc-bin" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# fstab and mtab
|
||||
touch "${DESTDIR}/etc/fstab"
|
||||
ln -s /proc/mounts "${DESTDIR}/etc/mtab"
|
||||
|
||||
# install wait-for-root binary.
|
||||
copy_exec /usr/lib/initramfs-tools/bin/wait-for-root /sbin
|
||||
|
||||
# module-init-tools
|
||||
copy_exec /sbin/modprobe /sbin
|
||||
copy_exec /sbin/rmmod /sbin
|
||||
mkdir -p "${DESTDIR}/etc/modprobe.d" "${DESTDIR}/lib/modprobe.d"
|
||||
for file in /etc/modprobe.d/*.conf /lib/modprobe.d/*.conf ; do
|
||||
if test -e "$file" || test -L "$file" ; then
|
||||
copy_file config "$file"
|
||||
fi
|
||||
done
|
||||
|
||||
run_scripts_optional /usr/share/initramfs-tools/hooks
|
||||
run_scripts_optional "${CONFDIR}"/hooks
|
||||
|
||||
# cache boot run order
|
||||
for b in $(cd "${DESTDIR}/scripts" && find . -mindepth 1 -type d); do
|
||||
cache_run_scripts "${DESTDIR}" "/scripts/${b#./}"
|
||||
done
|
||||
|
||||
# generate module deps
|
||||
depmod -a -b "${DESTDIR}" "${version}"
|
||||
rm -f "${DESTDIR}/lib/modules/${version}"/modules.*map
|
||||
|
||||
# make sure that library search path is up to date
|
||||
cp -pPr /etc/ld.so.conf* "$DESTDIR"/etc/
|
||||
if ! ldconfig -r "$DESTDIR" ; then
|
||||
[ "$(id -u)" != "0" ] \
|
||||
&& echo "ldconfig might need uid=0 (root) for chroot()" >&2
|
||||
fi
|
||||
# The auxiliary cache is not reproducible and is always invalid at boot
|
||||
# (see #845034)
|
||||
if [ -d "${DESTDIR}"/var/cache/ldconfig ]; then
|
||||
rm -f "${DESTDIR}"/var/cache/ldconfig/aux-cache
|
||||
rmdir --ignore-fail-on-non-empty "${DESTDIR}"/var/cache/ldconfig
|
||||
fi
|
||||
|
||||
# Apply DSDT to initramfs
|
||||
if [ -e "${CONFDIR}/DSDT.aml" ]; then
|
||||
copy_file DSDT "${CONFDIR}/DSDT.aml"
|
||||
fi
|
||||
|
||||
case "${MODULES}" in
|
||||
netboot|most) add_dns "${DESTDIR}/";;
|
||||
esac
|
||||
|
||||
# Remove any looping or broken symbolic links, since they break cpio.
|
||||
[ "${verbose}" = y ] && xargs_verbose="-t"
|
||||
(cd "${DESTDIR}" && find . -type l -printf '%p %Y\n' | sed -n 's/ [LN]$//p' \
|
||||
| xargs ${xargs_verbose:-} -rL1 rm -f)
|
||||
|
||||
[ "${verbose}" = y ] && echo "Building cpio ${outfile} initramfs"
|
||||
|
||||
if [ -s "${__TMPEARLYCPIO}" ]; then
|
||||
cat "${__TMPEARLYCPIO}" >"${outfile}" || exit 1
|
||||
else
|
||||
# truncate
|
||||
true > "${outfile}"
|
||||
fi
|
||||
|
||||
(
|
||||
# preserve permissions if root builds the image, see #633582
|
||||
[ "$(id -ru)" != 0 ] && cpio_owner_root="-R 0:0"
|
||||
|
||||
# if SOURCE_DATE_EPOCH is set, try and create a reproducible image
|
||||
if [ -n "${SOURCE_DATE_EPOCH}" ]; then
|
||||
# ensure that no timestamps are newer than $SOURCE_DATE_EPOCH
|
||||
find "${DESTDIR}" -newermt "@${SOURCE_DATE_EPOCH}" -print0 | \
|
||||
xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
|
||||
|
||||
# --reproducible requires cpio >= 2.12
|
||||
cpio_reproducible="--reproducible"
|
||||
fi
|
||||
|
||||
# work around lack of "set -o pipefail" for the following pipe:
|
||||
# cd "${DESTDIR}" && find . | LC_ALL=C sort | cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc | gzip >>"${outfile}" || exit 1
|
||||
ec1=1
|
||||
ec2=1
|
||||
ec3=1
|
||||
exec 3>&1
|
||||
eval "$(
|
||||
# http://cfaj.freeshell.org/shell/cus-faq-2.html
|
||||
exec 4>&1 >&3 3>&-
|
||||
cd "${DESTDIR}"
|
||||
{
|
||||
find . 4>&-; echo "ec1=$?;" >&4
|
||||
} | {
|
||||
LC_ALL=C sort
|
||||
} | {
|
||||
# shellcheck disable=SC2086
|
||||
cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc 4>&-; echo "ec2=$?;" >&4
|
||||
} | ${compress} >>"${outfile}"
|
||||
echo "ec3=$?;" >&4
|
||||
)"
|
||||
if [ "$ec1" -ne 0 ]; then
|
||||
echo "E: mkinitramfs failure find $ec1 cpio $ec2 $compress $ec3" >&2
|
||||
exit "$ec1"
|
||||
fi
|
||||
if [ "$ec2" -ne 0 ]; then
|
||||
echo "E: mkinitramfs failure cpio $ec2 $compress $ec3" >&2
|
||||
exit "$ec2"
|
||||
fi
|
||||
if [ "$ec3" -ne 0 ]; then
|
||||
echo "E: mkinitramfs failure $compress $ec3" >&2
|
||||
exit "$ec3"
|
||||
fi
|
||||
) || exit 1
|
||||
|
||||
if [ -s "${__TMPCPIOGZ}" ]; then
|
||||
cat "${__TMPCPIOGZ}" >>"${outfile}" || exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,146 @@
|
|||
.TH MKINITRAMFS 8 "2018/07/18" "initramfs\-tools" "System Administration"
|
||||
|
||||
.SH NAME
|
||||
mkinitramfs \- low-level tool for generating an initramfs image
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B mkinitramfs
|
||||
.RI [ option ]...
|
||||
.B \-o
|
||||
.IR outfile
|
||||
.RI [ version ]
|
||||
.br
|
||||
.BR mkinitramfs " " -h
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B mkinitramfs
|
||||
script generates an initramfs image.
|
||||
The initramfs is a compressed cpio archive. The archive can be used on a
|
||||
different box of the same arch with the corresponding Linux kernel.
|
||||
.B mkinitramfs
|
||||
is meant for advanced usage. On your local box
|
||||
.B update-initramfs
|
||||
calls
|
||||
.B mkinitramfs
|
||||
with the relevant parameters.
|
||||
.B update-initramfs
|
||||
keeps sha1sum of generated initramfs. It takes care to generate backups
|
||||
and eventually runs the bootloader.
|
||||
|
||||
At boot time, the kernel unpacks that archive into RAM disk, mounts and
|
||||
uses it as initial root file system. All finding of the root device
|
||||
happens in this early userspace.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-c \fI compress
|
||||
Override the
|
||||
.B COMPRESS
|
||||
setting in
|
||||
.IR initramfs.conf .
|
||||
|
||||
.TP
|
||||
\fB\-d \fI confdir
|
||||
Set an alternate configuration directory.
|
||||
|
||||
.TP
|
||||
\fB\-k
|
||||
Keep the temporary directory used to make the image.
|
||||
|
||||
.TP
|
||||
\fB\-o \fI outfile
|
||||
Write the image to
|
||||
.IR outfile .
|
||||
|
||||
.TP
|
||||
\fB\-r \fI root
|
||||
Override the
|
||||
.B ROOT
|
||||
setting in
|
||||
.IR initramfs.conf .
|
||||
|
||||
.TP
|
||||
\fB\-v
|
||||
Set the verbose mode output.
|
||||
|
||||
.TP
|
||||
\fIversion
|
||||
Set the kernel version of the initramfs image
|
||||
(defaults to the running kernel).
|
||||
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
Display usage information and exit.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.B mkinitramfs
|
||||
honours the
|
||||
.B TMPDIR
|
||||
environment variable. If set, it uses subdirectories in the given
|
||||
directory to create its temporary working directories. Else it uses
|
||||
.I /var/tmp
|
||||
as default value for that purpose. The given directory should be on a
|
||||
filesystem which allows the execution of files stored there, i.e.
|
||||
should not be mounted with the
|
||||
.B noexec
|
||||
mount option.
|
||||
|
||||
If
|
||||
.B SOURCE_DATE_EPOCH
|
||||
is set,
|
||||
.B mkinitramfs
|
||||
attempts to generate a reproducible initramfs image.
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.I /etc/initramfs-tools/initramfs.conf
|
||||
The default configuration file for the script. See
|
||||
.BR initramfs.conf (5)
|
||||
for a description of the available configuration parameter.
|
||||
|
||||
.TP
|
||||
.I /etc/initramfs-tools/modules
|
||||
Specified modules will be put in the generated image and loaded when the system boots. The format - one per line - is identical to that of
|
||||
.I /etc/modules,
|
||||
which is described in
|
||||
.BR modules (5).
|
||||
|
||||
.TP
|
||||
.I /etc/initramfs-tools/conf.d
|
||||
The conf.d directory allows one to hardcode bootargs at initramfs build time
|
||||
via config snippets. This allows one to set ROOT or RESUME.
|
||||
This is especially useful for bootloaders, which do not pass an root bootarg.
|
||||
|
||||
.TP
|
||||
.I /etc/initramfs-tools/DSDT.aml
|
||||
If this file exists, it will be appended to the initramfs in a way that causes
|
||||
it to be loaded by ACPI.
|
||||
|
||||
.SH EXAMPLES
|
||||
|
||||
Create an initramfs for current running kernel:
|
||||
|
||||
.PP
|
||||
.B mkinitramfs -o ~/tmp/initramfs-$(uname -r)
|
||||
|
||||
Create an initramfs for specific kernel and keep builddirs:
|
||||
|
||||
.PP
|
||||
.B mkinitramfs -k -o ~/tmp/initramfs-2.6.21-686 2.6.21-686
|
||||
|
||||
Debug initramfs creation (check out written logfile)
|
||||
.PP
|
||||
.B sh -x mkinitramfs -o ~/tmp/initramfs-$(uname -r) 2> ~/tmp/log
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>,
|
||||
Jeff Bailey <jbailey@raspberryginger.com> and numerous others.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR
|
||||
.IR initramfs.conf (5),
|
||||
.IR initramfs-tools (7),
|
||||
.IR update-initramfs (8),
|
||||
.IR lsinitramfs (8),
|
||||
.IR unmkinitramfs (8).
|
|
@ -0,0 +1,910 @@
|
|||
# -*- shell-script -*-
|
||||
|
||||
_log_msg()
|
||||
{
|
||||
if [ "${quiet?}" = "y" ]; then return; fi
|
||||
# shellcheck disable=SC2059
|
||||
printf "$@"
|
||||
}
|
||||
|
||||
log_success_msg()
|
||||
{
|
||||
_log_msg "Success: %s\\n" "$*"
|
||||
}
|
||||
|
||||
log_failure_msg()
|
||||
{
|
||||
_log_msg "Failure: %s\\n" "$*"
|
||||
}
|
||||
|
||||
log_warning_msg()
|
||||
{
|
||||
_log_msg "Warning: %s\\n" "$*"
|
||||
}
|
||||
|
||||
log_begin_msg()
|
||||
{
|
||||
_log_msg "Begin: %s ... " "$*"
|
||||
}
|
||||
|
||||
log_end_msg()
|
||||
{
|
||||
_log_msg "done.\\n"
|
||||
}
|
||||
|
||||
# Add failure hook
|
||||
add_mountroot_fail_hook()
|
||||
{
|
||||
mkdir -p /tmp/mountroot-fail-hooks.d
|
||||
ln -s "$0" /tmp/mountroot-fail-hooks.d/"$0"
|
||||
}
|
||||
|
||||
# Run failure hooks.
|
||||
# When a failure hook exits "1", it has not done anything to correct the
|
||||
# system. Exiting "0" means that something has been attempted to resolve
|
||||
# the lack of a root filesystem.
|
||||
# Hooks are run in lexigraphical order, and are responsible for removing
|
||||
# themselves if they should not re-run in a later cycle. When one exits
|
||||
# "0", the stack is stopped, so the caller can return to the main rootfs
|
||||
# wait loop.
|
||||
try_failure_hooks()
|
||||
{
|
||||
local hook
|
||||
|
||||
chvt 1
|
||||
if [ -x /bin/plymouth ] && plymouth --ping; then
|
||||
/bin/plymouth hide-splash > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
for hook in /tmp/mountroot-fail-hooks.d/*; do
|
||||
if [ -x "${hook}" ] && "${hook}" mountfail; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
panic()
|
||||
{
|
||||
local console rest IFS
|
||||
|
||||
if command -v chvt >/dev/null 2>&1; then
|
||||
chvt 1
|
||||
fi
|
||||
|
||||
echo "$@"
|
||||
# Disallow console access
|
||||
if [ -n "${panic?}" ]; then
|
||||
echo "Rebooting automatically due to panic= boot argument"
|
||||
[ "$panic" = "-1" ] || sleep "${panic}"
|
||||
reboot -f
|
||||
exit # in case reboot fails, force kernel panic
|
||||
fi
|
||||
|
||||
run_scripts /scripts/panic
|
||||
|
||||
# Try to use setsid, which will enable job control in the shell
|
||||
# and paging in more
|
||||
if command -v setsid >/dev/null 2>&1; then
|
||||
unset IFS
|
||||
read -r console rest </proc/consoles
|
||||
if [ "${console}" = "tty0" ]; then
|
||||
# Need to choose a specific VT
|
||||
console="tty1"
|
||||
fi
|
||||
# We don't have 'setsid -c' so we need to setsid, open
|
||||
# the tty, and finally exec an interactive shell
|
||||
REASON="$*" PS1='(initramfs) ' setsid sh -c "exec sh -i <>/dev/${console} 1>&0 2>&1"
|
||||
else
|
||||
REASON="$*" PS1='(initramfs) ' sh -i </dev/console >/dev/console 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
maybe_break()
|
||||
{
|
||||
case ",${break?}," in
|
||||
*,$1,*)
|
||||
if [ "$1" = "top" ]; then
|
||||
# udev is not yet running, so load keyboard drivers
|
||||
if [ "${quiet}" = "y" ]; then
|
||||
opts="-q"
|
||||
else
|
||||
opts="-v"
|
||||
fi
|
||||
modprobe ${opts} -a i8042 atkbd ehci-pci ehci-orion \
|
||||
ehci-hcd ohci-hcd ohci-pci uhci-hcd usbhid xhci \
|
||||
xhci-pci xhci-hcd
|
||||
sleep 2
|
||||
for modalias in /sys/bus/hid/devices/*/modalias; do
|
||||
if [ -f "${modalias}" ]; then
|
||||
modprobe ${opts} -b "$(cat "${modalias}")"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
panic "Spawning shell within the initramfs"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# For boot time only; this is overridden at build time in hook-functions
|
||||
run_scripts()
|
||||
{
|
||||
initdir=${1}
|
||||
[ ! -d "${initdir}" ] && return
|
||||
|
||||
shift
|
||||
. "${initdir}/ORDER"
|
||||
}
|
||||
|
||||
# Load custom modules first
|
||||
load_modules()
|
||||
{
|
||||
if [ -e /conf/modules ]; then
|
||||
while read -r m; do
|
||||
# Skip empty lines
|
||||
if [ -z "$m" ]; then
|
||||
continue
|
||||
fi
|
||||
# Skip comments - d?ash removes whitespace prefix
|
||||
com=$(printf "%.1s" "${m}")
|
||||
if [ "$com" = "#" ]; then
|
||||
continue
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
modprobe $m
|
||||
done < /conf/modules
|
||||
fi
|
||||
}
|
||||
|
||||
# lilo compatibility
|
||||
parse_numeric() {
|
||||
case $1 in
|
||||
*:*)
|
||||
# Does it match /[0-9]*:[0-9]*/?
|
||||
minor=${1#*:}
|
||||
major=${1%:*}
|
||||
case $major$minor in
|
||||
*[!0-9]*)
|
||||
# No.
|
||||
return
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"" | *[!A-Fa-f0-9]*)
|
||||
# "", "/*", etc.
|
||||
return
|
||||
;;
|
||||
*)
|
||||
# [A-Fa-f0-9]*
|
||||
value=$(( 0x${1} ))
|
||||
minor=$(( (value & 0xff) | (value >> 12) & 0xfff00 ))
|
||||
major=$(( (value >> 8) & 0xfff ))
|
||||
;;
|
||||
esac
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
ROOT="/dev/block/${major}:${minor}"
|
||||
}
|
||||
|
||||
# Parameter: device node to check
|
||||
# Echos fstype to stdout
|
||||
# Return value: indicates if an fs could be recognized
|
||||
get_fstype ()
|
||||
{
|
||||
local FS FSTYPE
|
||||
FS="${1}"
|
||||
|
||||
FSTYPE=$(blkid -o value -s TYPE "${FS}") || return
|
||||
echo "${FSTYPE}"
|
||||
return 0
|
||||
}
|
||||
|
||||
_handle_device_vs_ip()
|
||||
{
|
||||
# If the ip= parameter is present and is a colon-separated list,
|
||||
# then:
|
||||
# - If it specifies a device, use that in preference to any
|
||||
# device name we already have
|
||||
# - Otherwise, substitute in any device name we already have
|
||||
local IFS=:
|
||||
set -f
|
||||
# shellcheck disable=SC2086
|
||||
set -- ${IP}
|
||||
set +f
|
||||
if [ -n "$6" ]; then
|
||||
DEVICE="$6"
|
||||
elif [ $# -ge 2 ] && [ -n "${DEVICE}" ]; then
|
||||
IP="$1:$2:$3:$4:$5:${DEVICE}"
|
||||
shift 6 || shift $#
|
||||
IP="${IP}:$*"
|
||||
fi
|
||||
}
|
||||
|
||||
run_dhclient() {
|
||||
local timeout conffile pidfile pid
|
||||
|
||||
timeout=$1
|
||||
shift
|
||||
|
||||
conffile="/etc/dhcp/dhclient.conf.$timeout"
|
||||
pidfile="/tmp/dhclient.pid.$timeout"
|
||||
cp /etc/dhcp/dhclient.conf "$conffile"
|
||||
echo "timeout $timeout;" >> "$conffile"
|
||||
|
||||
rm -f "$pidfile"
|
||||
dhclient -v -1 -cf "$conffile" -pf "$pidfile" "$@"
|
||||
|
||||
# We do not want the dhclient persisting past the initramfs so
|
||||
# just kill it here (the pid file will only be written if
|
||||
# dhclient daemonized, i.e. found an address).
|
||||
[ -f "$pidfile" ] && read -r pid < "$pidfile" && [ -n "$pid" ] && kill "$pid"
|
||||
}
|
||||
|
||||
all_non_enslaved_devices()
|
||||
{
|
||||
for device in /sys/class/net/* ; do
|
||||
if [ ! -e "$device/flags" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
loop=$(($(cat "$device/flags") & 0x8 && 1 || 0))
|
||||
bc=$(($(cat "$device/flags") & 0x2 && 1 || 0))
|
||||
ptp=$(($(cat "$device/flags") & 0x10 && 1 || 0))
|
||||
|
||||
# Skip any device that is a loopback
|
||||
if [ $loop = 1 ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Skip any device that isn't a broadcast
|
||||
# or point-to-point.
|
||||
if [ $bc = 0 ] && [ $ptp = 0 ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Skip any enslaved device (has "master" link
|
||||
# attribute on it)
|
||||
device=$(basename "$device")
|
||||
ip -o link show "$device" | grep -q -w master && continue
|
||||
DEVICE="$DEVICE $device"
|
||||
done
|
||||
echo "$DEVICE"
|
||||
}
|
||||
|
||||
configure_networking()
|
||||
{
|
||||
if [ -n "${BOOTIF}" ]; then
|
||||
# pxelinux sets BOOTIF to a value based on the mac address of the
|
||||
# network card used to PXE boot, so use this value for DEVICE rather
|
||||
# than a hard-coded device name from initramfs.conf. this facilitates
|
||||
# network booting when machines may have multiple network cards.
|
||||
# pxelinux sets BOOTIF to 01-$mac_address
|
||||
|
||||
# strip off the leading "01-", which isn't part of the mac
|
||||
# address
|
||||
temp_mac=${BOOTIF#*-}
|
||||
|
||||
# convert to typical mac address format by replacing "-" with ":"
|
||||
bootif_mac=""
|
||||
IFS='-'
|
||||
for x in $temp_mac ; do
|
||||
if [ -z "$bootif_mac" ]; then
|
||||
bootif_mac="$x"
|
||||
else
|
||||
bootif_mac="$bootif_mac:$x"
|
||||
fi
|
||||
done
|
||||
unset IFS
|
||||
|
||||
# look for devices with matching mac address, and set DEVICE to
|
||||
# appropriate value if match is found.
|
||||
for device in /sys/class/net/* ; do
|
||||
if [ -f "$device/address" ]; then
|
||||
current_mac=$(cat "$device/address")
|
||||
if [ "$bootif_mac" = "$current_mac" ]; then
|
||||
DEVICE=${device##*/}
|
||||
DEVICE6=${device##*/}
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
_handle_device_vs_ip
|
||||
|
||||
for v in $VLAN; do
|
||||
VLAN_LINK="$VLAN_LINK ${v##*:}"
|
||||
done
|
||||
|
||||
# activate non-autoconfigured s390x devices
|
||||
for dev in $DEVICE $DEVICE6 $IP6 $VLAN_LINK; do
|
||||
case ${dev} in
|
||||
enc*)
|
||||
zdev=${dev#enc}
|
||||
chzdev -e "$zdev" || true
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for v in $VLAN; do
|
||||
vlink=${v##*:}
|
||||
vname=${v%:*}
|
||||
vid=${vname#*.}
|
||||
ip link set up dev "$vlink"
|
||||
ip link add name "$vname" link "$vlink" type vlan id "$vid"
|
||||
done
|
||||
|
||||
wait_for_udev 10
|
||||
|
||||
# support ip options see linux sources
|
||||
# Documentation/filesystems/nfs/nfsroot.txt
|
||||
# Documentation/frv/booting.txt
|
||||
|
||||
for ROUNDTTT in 2 3 4 6 9 16 25 36 64 100; do
|
||||
|
||||
# The NIC is to be configured if this file does not exist.
|
||||
# Ip-Config tries to create this file and when it succeds
|
||||
# creating the file, ipconfig is not run again.
|
||||
for x in /run/net-"${DEVICE}".conf /run/net-*.conf ; do
|
||||
if [ -e "$x" ]; then
|
||||
IP=done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
for x in /run/net6-"${DEVICE}".conf /run/net6-*.conf ; do
|
||||
if [ -e "$x" ]; then
|
||||
IP6=done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# if we've reached a point where both IP and IP6 are "done",
|
||||
# then we're finished with network configuration.
|
||||
if [ "$IP" = done ] && [ "$IP6" = done ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
case ${IP} in
|
||||
none|done|off)
|
||||
# Do nothing
|
||||
IP=done
|
||||
;;
|
||||
""|on|any|dhcp|bootp|both)
|
||||
if [ "${NETWORK_SKIP_ENSLAVED:-0}" = 0 ] || [ -n "${DEVICE}" ]; then
|
||||
run_dhclient $ROUNDTTT -4 ${DEVICE:+"${DEVICE}"}
|
||||
else
|
||||
# shellcheck disable=SC2046
|
||||
run_dhclient $ROUNDTTT -4 $(all_non_enslaved_devices)
|
||||
fi
|
||||
|
||||
;;
|
||||
*)
|
||||
ipconfig -t ${ROUNDTTT} -d "$IP"
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${IP6} in
|
||||
""|none|done|off)
|
||||
# Do nothing
|
||||
IP6=done
|
||||
;;
|
||||
*)
|
||||
# check the content of IP6 and if it is not on/dhcp/any use it as
|
||||
# a device name. Otherwise all devices will be tried (unless
|
||||
# BOOTIF was set, see above).
|
||||
case "${IP6}" in
|
||||
on|dhcp|any)
|
||||
;;
|
||||
*)
|
||||
DEVICE6="$IP6" ;;
|
||||
esac
|
||||
|
||||
if [ "${NETWORK_SKIP_ENSLAVED:-0}" = 0 ] || [ -n "${DEVICE6}" ]; then
|
||||
run_dhclient $ROUNDTTT -6 ${DEVICE6:+"${DEVICE6}"}
|
||||
else
|
||||
# shellcheck disable=SC2046
|
||||
run_dhclient $ROUNDTTT -6 $(all_non_enslaved_devices)
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# source ipconfig output for either $DEVICE or the first one.
|
||||
# If the user is booting with only IPv6, then DEVICE may be set,
|
||||
# but no IPv4 conf files exist.
|
||||
for conf in /run/"net-$DEVICE.conf" /run/net-*.conf; do
|
||||
if [ -e "$conf" ]; then
|
||||
# source specific bootdevice
|
||||
. "$conf"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
netinfo_to_resolv_conf /etc/resolv.conf \
|
||||
/run/"net-${DEVICE}.conf" /run/net-*.conf /run/net6-*.conf
|
||||
netinfo_to_netplan /run/netplan \
|
||||
/run/"net-${DEVICE}.conf" /run/net-*.conf /run/net6-*.conf
|
||||
}
|
||||
|
||||
netinfo_to_resolv_conf() {
|
||||
# netinfo_to_resolv_conf(output, files)
|
||||
# write resolv_conf from /run/net-<device> style files.
|
||||
if [ "${_in_subshell:-0}" = "0" ]; then
|
||||
# subshell to avoid modification of variables by '.'
|
||||
# shellcheck disable=SC2030
|
||||
( _in_subshell=1; netinfo_to_resolv_conf "$@" )
|
||||
return
|
||||
fi
|
||||
local output="$1" search="" ns="" f="" n=""
|
||||
shift
|
||||
for f in "$@"; do
|
||||
[ -f "$f" ] || continue
|
||||
unset IPV4DNS0 IPV4DNS1 IPV6DNS0 IPV6DNS1
|
||||
unset DOMAINSEARCH IPV6DOMAINSEARCH
|
||||
. "$f" || { echo "WARN: failed '. \"$f\"'" 1>&2; return 1; }
|
||||
for n in "${IPV4DNS0}" "${IPV4DNS1}" \
|
||||
"${IPV6DNS0}" "${IPV6DNS1}"; do
|
||||
[ -n "$n" ] && [ "$n" != 0.0.0.0 ] || continue
|
||||
# skip if 'n' already in list.
|
||||
case " ${ns} " in
|
||||
*\ $n\ *) continue;;
|
||||
esac
|
||||
ns="${ns} ${n}"
|
||||
done
|
||||
for n in "${DOMAINSEARCH}" "${IPV6DOMAINSEARCH}"; do
|
||||
[ -n "$n" ] || continue
|
||||
# skip if already in search.
|
||||
case " ${search}" in
|
||||
*\ $n\ *) continue;;
|
||||
esac
|
||||
search="$search $n"
|
||||
done
|
||||
search=${search# }
|
||||
ns=${ns# }
|
||||
done
|
||||
|
||||
local rconf="" CR="
|
||||
"
|
||||
for n in ${ns}; do
|
||||
rconf="${rconf}nameserver $n${CR}"
|
||||
done
|
||||
if [ -n "${search}" ]; then
|
||||
rconf="${rconf}search ${search}${CR}"
|
||||
fi
|
||||
if [ -z "$rconf" ]; then
|
||||
echo "no search or nameservers found in $*" 1>&2
|
||||
fi
|
||||
if [ "$rconf" = "-" ]; then
|
||||
echo -n "$rconf"
|
||||
else
|
||||
echo -n "$rconf" > "$output"
|
||||
fi
|
||||
}
|
||||
|
||||
mask2cidr() {
|
||||
# https://forum.openwrt.org/viewtopic.php?pid=220781#p220781
|
||||
# Assumes there's no "255." after a non-255 byte in the mask
|
||||
local x=${1##*255.}
|
||||
set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) "${x%%.*}"
|
||||
x=${1%%$3*}
|
||||
echo $(( $2 + (${#x}/4) ))
|
||||
}
|
||||
|
||||
_declare_sh_append_var() {
|
||||
# append_var(name, skip, strings)
|
||||
# write a declaration of name that will append to any existing
|
||||
local name="$1" skip="$2" add="" n=""
|
||||
shift 2
|
||||
for n in "$@"; do
|
||||
[ -n "$n" ] && [ "$n" != "$skip" ] || continue
|
||||
add="$add $n"
|
||||
done
|
||||
add=${add# }
|
||||
[ -n "$add" ] || return 0
|
||||
echo "$name=\"\${${name}:+\${${name}} }${add}\""
|
||||
}
|
||||
|
||||
_declare_ip_info() {
|
||||
# declare_ip_info(version, proto, address, netmask, gateway)
|
||||
local version="$1" proto="$2" address="$3" netmask="$4" gateway="$5"
|
||||
local netprefix=""
|
||||
case $proto in
|
||||
dhcp|dhcp4|dhcp6)
|
||||
echo "dhcp${version}=true"
|
||||
;;
|
||||
none)
|
||||
if [ -n "$address" ]; then
|
||||
netprefix=$netmask
|
||||
if [ "$version" = "4" ]; then
|
||||
netprefix=$(mask2cidr "$netmask")
|
||||
fi
|
||||
_declare_sh_append_var addresses "" "$address/$netprefix"
|
||||
fi
|
||||
if [ -n "$gateway" ]; then
|
||||
echo "gateway${version}=$gateway"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_render_netplan() {
|
||||
# write a netplan stanza for the given device.
|
||||
local name="$1" mac="$2" dhcp4="$3" dhcp6="$4" addrs="$5" \
|
||||
gateway4="$6" gateway6="$7" ns_addrs="$8" ns_search="$9" \
|
||||
vlink="${10}" vname="${11}" vid="${12}"
|
||||
local n found=""
|
||||
if [ -n "$vlink" ]; then
|
||||
name=$vlink
|
||||
fi
|
||||
echo "network:"
|
||||
echo " version: 2"
|
||||
echo " renderer: networkd"
|
||||
echo " ethernets:"
|
||||
echo " $name:"
|
||||
if [ -n "$mac" ] && grep -q net.ifnames=0 /proc/cmdline 2>/dev/null; then
|
||||
echo " match:"
|
||||
echo " macaddress: \"$mac\""
|
||||
echo " set-name: $name"
|
||||
elif [ -n "$vname" ]; then
|
||||
echo " {}"
|
||||
fi
|
||||
if [ -n "$vname" ]; then
|
||||
echo " vlans:"
|
||||
echo " $vname:"
|
||||
echo " id: $vid"
|
||||
echo " link: $name"
|
||||
fi
|
||||
if [ -n "$dhcp4" ]; then
|
||||
echo " dhcp4: $dhcp4"
|
||||
echo " dhcp-identifier: mac"
|
||||
fi
|
||||
[ -n "$dhcp6" ] && echo " dhcp6: $dhcp6" || true
|
||||
[ -n "$dhcp4$dhcp6" ] && echo " critical: true" || true
|
||||
if [ -n "$addrs" ]; then
|
||||
echo " addresses:"
|
||||
found=","
|
||||
for n in $addrs; do
|
||||
# remove dups
|
||||
[ "${found#*,$n,}" = "${found}" ] || continue
|
||||
found="${found}$n,"
|
||||
echo " - \"$n\""
|
||||
done
|
||||
fi
|
||||
[ -n "$gateway4" ] && echo " gateway4: \"$gateway4\"" || true
|
||||
[ -n "$gateway6" ] && echo " gateway6: \"$gateway6\"" || true
|
||||
|
||||
if [ -n "$ns_addrs" ]; then
|
||||
local alist="[" slist=""
|
||||
for n in $ns_addrs; do
|
||||
# do not put in duplicates
|
||||
[ "${alist#*\"$n\"}" = "$alist" ] || continue
|
||||
alist="${alist}\"$n\", ";
|
||||
done
|
||||
alist="${alist%, }]"
|
||||
|
||||
if [ -n "$ns_search" ]; then
|
||||
slist="["
|
||||
for n in ${ns_search}; do
|
||||
# do not put in duplicates
|
||||
[ "${slist#*\"$n\"}" = "$slist" ] || continue
|
||||
slist="${slist}\"$n\", ";
|
||||
done
|
||||
slist="${slist%, }]"
|
||||
fi
|
||||
echo " nameservers:"
|
||||
echo " addresses: $alist"
|
||||
[ -n "$slist" ] && echo " search: $slist" || true
|
||||
fi
|
||||
}
|
||||
|
||||
netinfo_to_netplan() {
|
||||
# read /run/net-* files write netplan config.
|
||||
# shellcheck disable=SC2031
|
||||
if [ "${_in_subshell:-0}" = "0" ]; then
|
||||
# subshell to avoid modification of variables by '.'
|
||||
( _in_subshell=1; netinfo_to_netplan "$@" )
|
||||
return
|
||||
fi
|
||||
local out_d="$1" tmpd
|
||||
if command -v mktemp >/dev/null 2>&1; then
|
||||
tmpd=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX")
|
||||
else
|
||||
tmpd="${TMPDIR:-/tmp}/${0##*/}.niinfo.$$"
|
||||
mkdir -p "$tmpd" || return
|
||||
fi
|
||||
|
||||
local devices="" mac=""
|
||||
# we go through all the files presented and create per-device files in
|
||||
# a tmpdir that are shell sourceable and closer to the netplan that
|
||||
# we want to render. Then render those to netplan stanzas.
|
||||
for f in "$@"; do
|
||||
[ -f "$f" ] || continue
|
||||
unset DEVICE DEVICE6 PROTO IPV6PROTO
|
||||
unset IPV6ADDR IPV6NETMASK IPV6GATEWAY
|
||||
unset IPV4ADDR IPV4NETMASK IPV4GATEWAY
|
||||
. "$f" || { echo "WARN: failed '. \"$f\"'" 1>&2; return 1; }
|
||||
local name=""
|
||||
name=${DEVICE:-${DEVICE6}}
|
||||
[ -n "$name" ] || {
|
||||
echo "WARN: $f did not define DEVICE or DEVICE6" 1>&2;
|
||||
return 1;
|
||||
}
|
||||
case " ${devices} " in
|
||||
*\ ${name}\ *) :;;
|
||||
*) devices="${devices} ${name}"
|
||||
esac
|
||||
if [ ! -e "$tmpd/$name" ] \
|
||||
&& [ -r "/sys/class/net/$name/address" ]
|
||||
then
|
||||
read -r mac < /sys/class/net/"$name"/address &&
|
||||
echo "macaddress=$mac" > "$tmpd/$name"
|
||||
fi
|
||||
|
||||
{
|
||||
for v in $VLAN; do
|
||||
vlink=${v##*:}
|
||||
vname=${v%:*}
|
||||
vid=${vname#*.}
|
||||
if [ "$name" = "$vname" ]; then
|
||||
echo "vlink=$vlink"
|
||||
echo "vname=$vname"
|
||||
echo "vid=$vid"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ -n "$DEVICE" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
_declare_ip_info 4 "$PROTO" "$IPV4ADDR" "$IPV4NETMASK" "$IPV4GATEWAY"
|
||||
elif [ -n "$DEVICE6" ]; then
|
||||
_declare_ip_info 6 "$IPV6PROTO" "$IPV6ADDR" "$IPV6NETMASK" \
|
||||
"$IPV6GATEWAY"
|
||||
fi
|
||||
_declare_sh_append_var ns_addresses "0.0.0.0" \
|
||||
"${IPV4DNS0}" "${IPV4DNS1}" "${IPV6DNS0}" "${IPV6DNS1}"
|
||||
_declare_sh_append_var ns_search "" "$DOMAINSEARCH" "$IPV6DOMAINSEARCH"
|
||||
} >> "$tmpd/$name"
|
||||
done
|
||||
|
||||
[ -d "$out_d" ] || mkdir -p "$out_d" ||
|
||||
{ echo "WARN: failed mkdir $out_d"; return 1; }
|
||||
|
||||
for name in $devices; do
|
||||
local macaddress="" dhcp4="" dhcp6="" addresses=""
|
||||
local gateway4="" gateway6="" ns_addresses="" ns_search=""
|
||||
local vlink="" vname="" vid=""
|
||||
. "$tmpd/$name"
|
||||
_render_netplan "$name" "$macaddress" "$dhcp4" "$dhcp6" "$addresses" \
|
||||
"$gateway4" "$gateway6" "$ns_addresses" "$ns_search" \
|
||||
"$vlink" "$vname" "$vid" \
|
||||
> "${out_d}/$name.yaml"
|
||||
done
|
||||
rm -Rf "$tmpd"
|
||||
}
|
||||
|
||||
# Wait for queued kernel/udev events
|
||||
wait_for_udev()
|
||||
{
|
||||
command -v udevadm >/dev/null 2>&1 || return 0
|
||||
udevadm settle ${1:+--timeout=$1}
|
||||
}
|
||||
|
||||
# Find a specific fstab entry
|
||||
# $1=mountpoint
|
||||
# $2=fstype (optional)
|
||||
# returns 0 on success, 1 on failure (not found or no fstab)
|
||||
read_fstab_entry() {
|
||||
# Not found by default.
|
||||
found=1
|
||||
|
||||
for file in ${rootmnt?}/etc/fstab; do
|
||||
if [ -f "$file" ]; then
|
||||
# shellcheck disable=SC2034
|
||||
while read -r MNT_FSNAME MNT_DIR MNT_TYPE MNT_OPTS MNT_FREQ MNT_PASS MNT_JUNK; do
|
||||
case "$MNT_FSNAME" in
|
||||
""|\#*)
|
||||
continue;
|
||||
;;
|
||||
esac
|
||||
if [ "$MNT_DIR" = "$1" ]; then
|
||||
if [ -n "$2" ]; then
|
||||
[ "$MNT_TYPE" = "$2" ] || continue;
|
||||
fi
|
||||
found=0
|
||||
break 2
|
||||
fi
|
||||
done < "$file"
|
||||
fi
|
||||
done
|
||||
|
||||
return $found
|
||||
}
|
||||
|
||||
# Resolve device node from a name. This expands any LABEL or UUID.
|
||||
# $1=name
|
||||
# Resolved name is echoed.
|
||||
resolve_device() {
|
||||
DEV="$1"
|
||||
local orig="$DEV"
|
||||
|
||||
case "$DEV" in
|
||||
LABEL=* | UUID=* | PARTLABEL=* | PARTUUID=*)
|
||||
if ! DEV="$(blkid -l -t "$DEV" -o device)"; then
|
||||
DEV="$orig"
|
||||
|
||||
# Support uppercase and lowercase UUIDs -- see RFC#4122:
|
||||
# "Each field is treated as an integer and has its value printed as
|
||||
# a zero-filled hexadecimal digit string with the most significant
|
||||
# digit first. The hexadecimal values "a" through "f" are output as
|
||||
# lower case characters and are case insensitive on input."
|
||||
#
|
||||
# Note: that blkid which we will use to map these assums the input is lower
|
||||
# case.
|
||||
|
||||
# Only apply this behaviour to UUIDs.
|
||||
case "$DEV" in
|
||||
UUID=* | PARTUUID=*) ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
|
||||
# Pull DEV apart and map it.
|
||||
local type value fmt
|
||||
type=$(echo "${DEV}" | cut -f 1 -d =)
|
||||
value=$(echo "${DEV}" | cut -f 2 -d = | tr 'A-F' 'a-f')
|
||||
|
||||
# ... in RFC#4122 format;
|
||||
# look for five hexadecimal fragments separated by minus signs.
|
||||
fmt=$( echo "$value" | sed -e 's/[0-9a-fA-F]*//g' )
|
||||
if [ "$fmt" != '----' ]; then
|
||||
return 1
|
||||
fi
|
||||
DEV="${type}=${value}"
|
||||
|
||||
# Retry with the lower cased UUID.
|
||||
DEV="$(blkid -l -t "$DEV" -o device)" || return 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
[ -e "$DEV" ] && echo "$DEV"
|
||||
}
|
||||
|
||||
# Check a file system.
|
||||
# $1=device
|
||||
# $2=mountpoint (for diagnostics only)
|
||||
# $3=type (may be "auto")
|
||||
_checkfs_once()
|
||||
{
|
||||
DEV="$1"
|
||||
NAME="$2"
|
||||
TYPE="$3"
|
||||
if [ "$NAME" = "/" ] ; then
|
||||
NAME="root"
|
||||
fi
|
||||
FSCK_LOGFILE=/run/initramfs/fsck.log
|
||||
FSCK_STAMPFILE=/run/initramfs/fsck-${NAME#/}
|
||||
|
||||
if [ "${TYPE}" = "auto" ]; then
|
||||
TYPE="$(get_fstype "${DEV}")"
|
||||
fi
|
||||
|
||||
FSCKCODE=0
|
||||
if [ -z "${TYPE}" ]; then
|
||||
log_warning_msg "Type of $NAME file system is unknown, so skipping check."
|
||||
return
|
||||
fi
|
||||
if ! command -v fsck >/dev/null 2>&1; then
|
||||
log_warning_msg "fsck not present, so skipping $NAME file system"
|
||||
return
|
||||
fi
|
||||
if [ "${fastboot?}" = "y" ] ; then
|
||||
log_warning_msg "Fast boot enabled, so skipping $NAME file system check."
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "${forcefsck?}" = "y" ]
|
||||
then
|
||||
force="-f"
|
||||
else
|
||||
force=""
|
||||
fi
|
||||
|
||||
if [ "${fsckfix?}" = "y" ]
|
||||
then
|
||||
fix="-y"
|
||||
elif [ "${fsckfix?}" = "n" ]
|
||||
then
|
||||
fix="-n"
|
||||
else
|
||||
fix="-a"
|
||||
fi
|
||||
|
||||
spinner=""
|
||||
if [ -z "${debug?}" ]; then
|
||||
spinner="-C"
|
||||
fi
|
||||
|
||||
if [ "${quiet}" = n ]
|
||||
then
|
||||
log_begin_msg "Will now check $NAME file system"
|
||||
logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -V -t "$TYPE" "$DEV"
|
||||
FSCKCODE=$?
|
||||
log_end_msg
|
||||
else
|
||||
log_begin_msg "Checking $NAME file system"
|
||||
logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -T -t "$TYPE" "$DEV"
|
||||
FSCKCODE=$?
|
||||
log_end_msg
|
||||
fi
|
||||
|
||||
# NOTE: "failure" is defined as exiting with a return code of
|
||||
# 4, possibly or-ed with other flags. A return code of 1
|
||||
# indicates that file system errors were corrected but that
|
||||
# the boot may proceed.
|
||||
#
|
||||
if [ "$FSCKCODE" -eq 32 ]
|
||||
then
|
||||
log_warning_msg "File system check was interrupted by user"
|
||||
elif [ $((FSCKCODE & 4)) -eq 4 ]
|
||||
then
|
||||
log_failure_msg "File system check of the $NAME filesystem failed"
|
||||
return 1
|
||||
elif [ "$FSCKCODE" -gt 1 ]
|
||||
then
|
||||
log_warning_msg "File system check failed but did not detect errors"
|
||||
sleep 5
|
||||
else
|
||||
true > $FSCK_STAMPFILE
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
checkfs()
|
||||
{
|
||||
while ! _checkfs_once "$@"; do
|
||||
panic "The $2 filesystem on $1 requires a manual fsck"
|
||||
done
|
||||
}
|
||||
|
||||
# Mount a file system. We parse the information from the fstab. This
|
||||
# should be overridden by any boot script which can mount arbitrary
|
||||
# filesystems such as /usr. This default implementation delegates to
|
||||
# local or nfs based upon the filesystem type.
|
||||
# $1=mountpoint mount location
|
||||
mountfs()
|
||||
{
|
||||
type=local
|
||||
read_fstab_entry "$1"
|
||||
if [ "${MNT_TYPE}" = "nfs" ] || [ "${MNT_TYPE}" = "nfs4" ]; then
|
||||
type=nfs
|
||||
fi
|
||||
|
||||
${type}_mount_fs "$1"
|
||||
}
|
||||
|
||||
# Mount the root file system. It should be overridden by all
|
||||
# boot scripts.
|
||||
mountroot()
|
||||
{
|
||||
:
|
||||
}
|
||||
|
||||
# Run /scripts/${boot}-top. This should be overridden by all boot
|
||||
# scripts.
|
||||
mount_top()
|
||||
{
|
||||
:
|
||||
}
|
||||
|
||||
# Run /scripts/${boot}-premount. This should be overridden by all boot
|
||||
# scripts.
|
||||
mount_premount()
|
||||
{
|
||||
:
|
||||
}
|
||||
|
||||
# Run /scripts/${boot}-bottom. This should be overridden by all boot
|
||||
# scripts.
|
||||
mount_bottom()
|
||||
{
|
||||
:
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# shellcheck disable=SC2013
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
all_generic_ide)
|
||||
modprobe ata_generic all_generic_ide=1
|
||||
;;
|
||||
all_generic_ide=*)
|
||||
if [ -n "${x#all_generic_ide=}" ]; then
|
||||
modprobe ata_generic all_generic_ide=1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# blacklist vga16fb when vga= or video= given
|
||||
# shellcheck disable=SC2013
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
vga=*|video=*)
|
||||
echo "blacklist vga16fb" >> /etc/modprobe.d/initramfs.conf
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# sanity check
|
||||
[ -z "${blacklist?}" ] && exit 0
|
||||
|
||||
# write blacklist to modprobe.d
|
||||
IFS=','
|
||||
for b in ${blacklist}; do
|
||||
echo "blacklist $b" >> /etc/modprobe.d/initramfs.conf
|
||||
done
|
|
@ -0,0 +1,129 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
OPTION=FRAMEBUFFER
|
||||
PREREQ="udev"
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# The options part of the kernel "video=" argument (i.e. everyting
|
||||
# after "video=<fbdriver>:") has very inconsistent rules.
|
||||
#
|
||||
# Generally the following applies:
|
||||
# 1) options are comma-separated
|
||||
# 2) options can be in either of these three forms:
|
||||
# <arg>=<value>, <arg>:<value>, <boolean-arg>.
|
||||
# 3) the "mode" option has the form <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m]
|
||||
# and may or may not start with "mode="
|
||||
#
|
||||
# When the options are used with modules, they need to be space-separated
|
||||
# and the following conversions are needed:
|
||||
# <arg>:<value> -> <arg>=<value>
|
||||
# <boolean-arg> -> <boolean-arg>=1
|
||||
# <modevalue> -> mode=<modevalue>
|
||||
parse_video_opts()
|
||||
{
|
||||
local OPTS="$1"
|
||||
local IFS=","
|
||||
|
||||
# Must be a line like video=<fbdriver>:<opt1>,[opt2]...
|
||||
if [ "${OPTS}" = "${OPTS%%:*}" ]; then
|
||||
return
|
||||
fi
|
||||
OPTS="${OPTS#*:}"
|
||||
for opt in ${OPTS}; do
|
||||
# Already in the "<arg>=<value>" form
|
||||
if [ "${opt}" != "${opt#*=}" ]; then
|
||||
echo -n "$opt "
|
||||
# In the "<arg>:<value>" form
|
||||
elif [ "${opt}" != "${opt#*:}" ]; then
|
||||
echo -n "${opt%:*}=${opt#*:} "
|
||||
# Presumably a modevalue without the "mode=" prefix
|
||||
elif [ "${opt}" != "${opt#[0-9]*x[0-9]}" ]; then
|
||||
echo -n "mode=$opt "
|
||||
# Presumably a boolean
|
||||
else
|
||||
echo -n "${opt}=1 "
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
FB=""
|
||||
OPTS=""
|
||||
|
||||
# shellcheck disable=SC2013
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
vga=*)
|
||||
FB="vesafb";
|
||||
OPTS="";
|
||||
;;
|
||||
video=*)
|
||||
FB=${x#*=}
|
||||
FB="${FB%%:*}"
|
||||
OPTS="$(parse_video_opts "${x}")"
|
||||
esac
|
||||
done
|
||||
|
||||
# Map command line name to module name
|
||||
case ${FB} in
|
||||
matroxfb)
|
||||
FB=matroxfb_base
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${FB}" ]; then
|
||||
# Some framebuffer devices need character devices :-/
|
||||
udevadm settle
|
||||
# shellcheck disable=SC2086
|
||||
MODPROBE_OPTIONS=-q modprobe ${FB} ${OPTS}
|
||||
# Wait for the framebuffer devices to be ready
|
||||
udevadm settle
|
||||
else
|
||||
# If we have no graphics devices yet, wait for udev to settle
|
||||
[ -d /sys/class/graphics/fbcon ] && \
|
||||
[ -d /sys/class/graphics/fb0 ] && \
|
||||
[ -d /sys/class/drm/card0 ] || udevadm settle
|
||||
|
||||
# If we still have no graphics device, fall back to vesafb like
|
||||
# we do in the post-initramfs case in
|
||||
# /etc/init/udev-fallback-graphics.conf.
|
||||
# There is a higher risk of racing the regular video driver init
|
||||
# than there is in the post-initramfs case, because this is earlier
|
||||
# in boot and the kernel has had less time to finish probing the
|
||||
# video drivers; and if we probe vesafb when we aren't meant to it
|
||||
# will cause problems later. So just to be sure, add a sleep(1)
|
||||
# which seems to be enough time to let the drm interface get loaded.
|
||||
[ -d /sys/class/graphics/fbcon ] && \
|
||||
[ -d /sys/class/graphics/fb0 ] && \
|
||||
[ -d /sys/class/drm/card0 ] || sleep 1
|
||||
|
||||
if ! [ -d /sys/class/graphics/fbcon ] \
|
||||
|| ! [ -d /sys/class/graphics/fb0 ] \
|
||||
|| ! [ -d /sys/class/drm/card0 ]
|
||||
then
|
||||
modprobe -q vesafb 2>/dev/null
|
||||
udevadm settle
|
||||
fi
|
||||
fi
|
||||
|
||||
# Force fb mode via /sys interface
|
||||
# shellcheck disable=SC2013
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
fbmode=*)
|
||||
MODE=${x#*=}
|
||||
echo "$MODE" > /sys/class/graphics/fb0/mode
|
||||
;;
|
||||
esac
|
||||
done
|
|
@ -0,0 +1,303 @@
|
|||
# Local filesystem mounting -*- shell-script -*-
|
||||
|
||||
local_top()
|
||||
{
|
||||
if [ "${local_top_used}" != "yes" ]; then
|
||||
[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/local-top"
|
||||
run_scripts /scripts/local-top
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
fi
|
||||
local_top_used=yes
|
||||
|
||||
# Start time for measuring elapsed time in local_device_setup
|
||||
if [ -z "${local_top_time}" ]; then
|
||||
local_top_time="$(cat /proc/uptime)"
|
||||
local_top_time="${local_top_time%%[. ]*}"
|
||||
local_top_time=$((local_top_time + 1)) # round up
|
||||
export local_top_time
|
||||
fi
|
||||
}
|
||||
|
||||
local_block()
|
||||
{
|
||||
[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/local-block"
|
||||
run_scripts /scripts/local-block "$@"
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
}
|
||||
|
||||
local_premount()
|
||||
{
|
||||
if [ "${local_premount_used}" != "yes" ]; then
|
||||
[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/local-premount"
|
||||
run_scripts /scripts/local-premount
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
fi
|
||||
local_premount_used=yes
|
||||
}
|
||||
|
||||
local_bottom()
|
||||
{
|
||||
if [ "${local_premount_used}" = "yes" ] || [ "${local_top_used}" = "yes" ]; then
|
||||
[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/local-bottom"
|
||||
run_scripts /scripts/local-bottom
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
fi
|
||||
local_premount_used=no
|
||||
local_top_used=no
|
||||
unset local_top_time
|
||||
}
|
||||
|
||||
# $1=device ID to mount
|
||||
# $2=optionname (for root and etc)
|
||||
# $3=panic if device is missing (true or false, default: true)
|
||||
# Sets $DEV to the resolved device node
|
||||
local_device_setup()
|
||||
{
|
||||
local dev_id="$1"
|
||||
local name="$2"
|
||||
local may_panic="${3:-true}"
|
||||
local real_dev
|
||||
local time_elapsed
|
||||
local count
|
||||
|
||||
# If wait-for-root understands this prefix, then use it to wait for
|
||||
# the device rather than settling the whole of udev.
|
||||
|
||||
# Timeout is max(30, rootdelay) seconds (approximately)
|
||||
local slumber=30
|
||||
case $DPKG_ARCH in
|
||||
powerpc|ppc64|ppc64el)
|
||||
slumber=180
|
||||
;;
|
||||
*)
|
||||
slumber=30
|
||||
;;
|
||||
esac
|
||||
if [ "${ROOTDELAY:-0}" -gt $slumber ]; then
|
||||
slumber=$ROOTDELAY
|
||||
fi
|
||||
|
||||
case "$dev_id" in
|
||||
UUID=*|LABEL=*|PARTUUID=*|/dev/*)
|
||||
FSTYPE=$( wait-for-root "$dev_id" "$slumber" )
|
||||
;;
|
||||
*)
|
||||
wait_for_udev 10
|
||||
;;
|
||||
esac
|
||||
|
||||
# Load ubi with the correct MTD partition and return since fstype
|
||||
# doesn't work with a char device like ubi.
|
||||
if [ -n "$UBIMTD" ]; then
|
||||
modprobe ubi "mtd=$UBIMTD"
|
||||
DEV="${dev_id}"
|
||||
return
|
||||
fi
|
||||
|
||||
# Don't wait for a device that doesn't have a corresponding
|
||||
# device in /dev and isn't resolvable by blkid (e.g. mtd0)
|
||||
if [ "${dev_id#/dev}" = "${dev_id}" ] &&
|
||||
[ "${dev_id#*=}" = "${dev_id}" ]; then
|
||||
DEV="${dev_id}"
|
||||
return
|
||||
fi
|
||||
|
||||
# If the root device hasn't shown up yet, give it a little while
|
||||
# to allow for asynchronous device discovery (e.g. USB). We
|
||||
# also need to keep invoking the local-block scripts in case
|
||||
# there are devices stacked on top of those.
|
||||
#
|
||||
# in Ubuntu, we should never actually enter this loop as wait-for-root
|
||||
# above should have waited until the device appeared.
|
||||
if ! real_dev=$(resolve_device "${dev_id}") ||
|
||||
! get_fstype "${real_dev}" >/dev/null; then
|
||||
log_begin_msg "Waiting for ${name}"
|
||||
|
||||
while true; do
|
||||
sleep 1
|
||||
time_elapsed="$(cat /proc/uptime)"
|
||||
time_elapsed="${time_elapsed%%[. ]*}"
|
||||
time_elapsed=$((time_elapsed - local_top_time))
|
||||
|
||||
local_block "${dev_id}"
|
||||
|
||||
# If mdadm's local-block script counts the
|
||||
# number of times it is run, make sure to
|
||||
# run it the expected number of times.
|
||||
while true; do
|
||||
if [ -f /run/count.mdadm.initrd ]; then
|
||||
count="$(cat /run/count.mdadm.initrd)"
|
||||
elif [ -n "${count}" ]; then
|
||||
# mdadm script deleted it; put it back
|
||||
count=$((count + 1))
|
||||
echo "${count}" >/run/count.mdadm.initrd
|
||||
else
|
||||
break
|
||||
fi
|
||||
if [ ${count} -ge ${time_elapsed} ]; then
|
||||
break;
|
||||
fi
|
||||
/scripts/local-block/mdadm "${dev_id}"
|
||||
done
|
||||
|
||||
if real_dev=$(resolve_device "${dev_id}") &&
|
||||
get_fstype "${real_dev}" >/dev/null; then
|
||||
wait_for_udev 10
|
||||
log_end_msg 0
|
||||
break
|
||||
fi
|
||||
if [ ${time_elapsed} -ge "${slumber}" ]; then
|
||||
log_end_msg 1 || true
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# We've given up, but we'll let the user fix matters if they can
|
||||
while ! real_dev=$(resolve_device "${dev_id}") ||
|
||||
! get_fstype "${real_dev}" >/dev/null; do
|
||||
if ! $may_panic; then
|
||||
echo "Gave up waiting for ${name}"
|
||||
return 1
|
||||
fi
|
||||
echo "Gave up waiting for ${name} device. Common problems:"
|
||||
echo " - Boot args (cat /proc/cmdline)"
|
||||
echo " - Check rootdelay= (did the system wait long enough?)"
|
||||
if [ "${name}" = root ]; then
|
||||
echo " - Check root= (did the system wait for the right device?)"
|
||||
fi
|
||||
echo " - Missing modules (cat /proc/modules; ls /dev)"
|
||||
panic "ALERT! ${dev_id} does not exist. Dropping to a shell!"
|
||||
done
|
||||
|
||||
DEV="${real_dev}"
|
||||
}
|
||||
|
||||
local_mount_root()
|
||||
{
|
||||
local_top
|
||||
if [ -z "${ROOT}" ]; then
|
||||
panic "No root device specified. Boot arguments must include a root= parameter."
|
||||
fi
|
||||
local_device_setup "${ROOT}" "root file system"
|
||||
ROOT="${DEV}"
|
||||
|
||||
# Get the root filesystem type if not set
|
||||
if [ -z "${ROOTFSTYPE}" ] || [ "${ROOTFSTYPE}" = auto ]; then
|
||||
FSTYPE=$(get_fstype "${ROOT}")
|
||||
else
|
||||
FSTYPE=${ROOTFSTYPE}
|
||||
fi
|
||||
|
||||
local_premount
|
||||
|
||||
if [ "${readonly?}" = "y" ] && \
|
||||
[ -z "$LOOP" ]; then
|
||||
roflag=-r
|
||||
else
|
||||
roflag=-w
|
||||
fi
|
||||
|
||||
checkfs "${ROOT}" root "${FSTYPE}"
|
||||
|
||||
# Mount root
|
||||
# shellcheck disable=SC2086
|
||||
mount ${roflag} ${FSTYPE:+-t "${FSTYPE}"} ${ROOTFLAGS} "${ROOT}" "${rootmnt?}"
|
||||
mountroot_status="$?"
|
||||
if [ "$LOOP" ]; then
|
||||
if [ "$mountroot_status" != 0 ]; then
|
||||
if [ "${FSTYPE}" = ntfs ] || [ "${FSTYPE}" = vfat ]
|
||||
then
|
||||
panic "
|
||||
Could not mount the partition ${ROOT}.
|
||||
This could also happen if the file system is not clean because of an operating
|
||||
system crash, an interrupted boot process, an improper shutdown, or unplugging
|
||||
of a removable device without first unmounting or ejecting it. To fix this,
|
||||
simply reboot into Windows, let it fully start, log in, run 'chkdsk /r', then
|
||||
gracefully shut down and reboot back into Windows. After this you should be
|
||||
able to reboot again and resume the installation.
|
||||
(filesystem = ${FSTYPE}, error code = $mountroot_status)
|
||||
"
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p /host
|
||||
mount -o move "$rootmnt" /host
|
||||
|
||||
while [ ! -e "/host/${LOOP#/}" ]; do
|
||||
panic "ALERT! /host/${LOOP#/} does not exist. Dropping to a shell!"
|
||||
done
|
||||
|
||||
# Get the loop filesystem type if not set
|
||||
FSTYPE="$LOOPFSTYPE"
|
||||
if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then
|
||||
FSTYPE=$(/sbin/blkid -s TYPE -o value "/host/${LOOP#/}")
|
||||
[ -z "$FSTYPE" ] && FSTYPE="unknown"
|
||||
fi
|
||||
|
||||
if [ "$readonly" = y ]; then
|
||||
roflag=-r
|
||||
else
|
||||
roflag=-w
|
||||
fi
|
||||
|
||||
# FIXME This has no error checking
|
||||
modprobe loop
|
||||
|
||||
# FIXME This has no error checking
|
||||
# shellcheck disable=SC2086
|
||||
mount ${roflag} -o loop -t ${FSTYPE} ${LOOPFLAGS} "/host/${LOOP#/}" "${rootmnt?}"
|
||||
|
||||
if [ -d "$rootmnt/host" ]; then
|
||||
mount -o move /host "$rootmnt/host"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
local_mount_fs()
|
||||
{
|
||||
read_fstab_entry "$1"
|
||||
|
||||
local_device_setup "$MNT_FSNAME" "$1 file system"
|
||||
MNT_FSNAME="${DEV}"
|
||||
|
||||
local_premount
|
||||
|
||||
if [ "${readonly}" = "y" ]; then
|
||||
roflag=-r
|
||||
else
|
||||
roflag=-w
|
||||
fi
|
||||
|
||||
if [ "$MNT_PASS" != 0 ]; then
|
||||
checkfs "$MNT_FSNAME" "$MNT_DIR" "${MNT_TYPE}"
|
||||
fi
|
||||
|
||||
# Mount filesystem
|
||||
if ! mount ${roflag} -t "${MNT_TYPE}" -o "${MNT_OPTS}" "$MNT_FSNAME" "${rootmnt}${MNT_DIR}"; then
|
||||
panic "Failed to mount ${MNT_FSNAME} as $MNT_DIR file system."
|
||||
fi
|
||||
}
|
||||
|
||||
mountroot()
|
||||
{
|
||||
local_mount_root
|
||||
}
|
||||
|
||||
mount_top()
|
||||
{
|
||||
# Note, also called directly in case it's overridden.
|
||||
local_top
|
||||
}
|
||||
|
||||
mount_premount()
|
||||
{
|
||||
# Note, also called directly in case it's overridden.
|
||||
local_premount
|
||||
}
|
||||
|
||||
mount_bottom()
|
||||
{
|
||||
# Note, also called directly in case it's overridden.
|
||||
local_bottom
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
#!/bin/sh -e
|
||||
# initramfs local-premount script for fixrtc
|
||||
|
||||
PREREQ=""
|
||||
|
||||
# Output pre-requisites
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# use the fixrtc cmdline option in your bootloader to
|
||||
# automatically set the hardware clock to the date of
|
||||
# the last mount of your root filesystem to avoid fsck
|
||||
# to get confused by the superblock being in the future
|
||||
|
||||
BROKEN_CLOCK=""
|
||||
ROOTDEV=""
|
||||
# System partition is currently used by ubuntu touch only
|
||||
SYSTEMPART=""
|
||||
|
||||
# shellcheck disable=SC2013
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
root=*)
|
||||
value=${x#*=}
|
||||
|
||||
# Find the device node path depending on the form of root= :
|
||||
case ${value} in
|
||||
UUID=*)
|
||||
ROOTDEV=/dev/disk/by-uuid/${value#UUID=}
|
||||
;;
|
||||
LABEL=*)
|
||||
ROOTDEV=/dev/disk/by-label/${value#LABEL=}
|
||||
;;
|
||||
*)
|
||||
ROOTDEV=${value}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
systempart=*)
|
||||
value=${x#*=}
|
||||
|
||||
# Find the device node path depending on the form of root= :
|
||||
case ${value} in
|
||||
UUID=*)
|
||||
SYSTEMPART=/dev/disk/by-uuid/${value#UUID=}
|
||||
;;
|
||||
LABEL=*)
|
||||
SYSTEMPART=/dev/disk/by-label/${value#LABEL=}
|
||||
;;
|
||||
*)
|
||||
SYSTEMPART=${value}
|
||||
;;
|
||||
esac
|
||||
# if systempart= is defined we do not want root=/dev/ram
|
||||
# been taken into account
|
||||
[ "$ROOTDEV" = "/dev/ram" ] && ROOTDEV=""
|
||||
;;
|
||||
fixrtc)
|
||||
BROKEN_CLOCK=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Touch devices might not have a valid 'root', so use system part if available
|
||||
if [ -z "$ROOTDEV" ] && [ -n "$SYSTEMPART" ]; then
|
||||
ROOTDEV=$SYSTEMPART
|
||||
fi
|
||||
|
||||
if [ -n "$BROKEN_CLOCK" ] && [ -n "$ROOTDEV" ]; then
|
||||
# need udev settle for /dev/disk/by-* symlinks to be added
|
||||
udevadm settle
|
||||
|
||||
wait-for-root "$ROOTDEV" "${ROOTDELAY:-180}"
|
||||
|
||||
ROOTDISK=$(readlink -f "$ROOTDEV")
|
||||
|
||||
MOUNTDATESTR=$(dumpe2fs -h "$ROOTDISK" 2>/dev/null|grep "Last mount time")
|
||||
# Trim whitespace for busybox
|
||||
MOUNTDATE="${MOUNTDATESTR#*:}"
|
||||
|
||||
CREATEDATESTR=$(dumpe2fs -h "$ROOTDISK" 2>/dev/null|grep "Filesystem created") || true
|
||||
# Trim whitespace for busybox
|
||||
CREATEDATE="${CREATEDATESTR#*:}"
|
||||
|
||||
# Hide stderr to avoid ugly message:
|
||||
# can't open '/dev/misc/rtc': No such file or directory
|
||||
# on pi2 (and possible more PIs) where there is no /dev/rtc of
|
||||
# any kind. We still need to keep this call because we use
|
||||
# fixrtc on all armhf images.
|
||||
hwclock -s 2>/dev/null || true
|
||||
|
||||
# make sure we're also compatible with busybox, if available
|
||||
DATE="/bin/date -D%c"
|
||||
date -D%c 2>/dev/null || DATE=/bin/date
|
||||
|
||||
if [ "$MOUNTDATE" = "n/a" ]; then
|
||||
# some versions of mkfs set n/a now, date is not happy with this so
|
||||
# let us use some half way sane epoch instead
|
||||
MOUNTDATE="Fri Jan 1 00:00:00 1999"
|
||||
fi
|
||||
TIMESTR=$MOUNTDATE
|
||||
TIME=$(${DATE} --utc --date "${TIMESTR}" +%s)
|
||||
|
||||
CURTIME=$(${DATE} --utc +%s)
|
||||
|
||||
# in case the created time is newer than last mount, use that instead
|
||||
if [ -n "$CREATEDATE" ]; then
|
||||
CREATETIME=$(${DATE} --utc --date "${CREATEDATE}" +%s)
|
||||
if [ "$CREATETIME" -gt "$TIME" ]; then
|
||||
TIMESTR=$CREATEDATE
|
||||
TIME=$CREATETIME
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$TIME" -gt "$CURTIME" ]; then
|
||||
${DATE} --set="${TIMESTR} 1 minute" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# This script is best-effort. If we couldn't fudge the clock as desired,
|
||||
# just try to carry on boot anyway:
|
||||
# It will probably fail, but we won't have made the situation any worse.
|
||||
exit 0
|
|
@ -0,0 +1,76 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "${resume?}" ] || [ ! -e /sys/power/resume ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
. /scripts/functions
|
||||
. /scripts/local
|
||||
|
||||
PAGE_SIZE=4096
|
||||
if [ -x /bin/getconf ]; then
|
||||
PAGE_SIZE=$(getconf PAGESIZE)
|
||||
fi
|
||||
export PAGE_SIZE
|
||||
|
||||
if ! local_device_setup "${resume}" "suspend/resume device" false; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
DEV=$(readlink "$resume")
|
||||
DEV=/sys/class/block/${DEV##*/}/dev
|
||||
if [ -r "$DEV" ]; then
|
||||
read -r MAJMIN < "$DEV"
|
||||
fi
|
||||
if [ -z "$MAJMIN" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${resume_offset?}" -ge 0 ] 2>/dev/null; then
|
||||
offset_option=$((${resume_offset?} * PAGE_SIZE))
|
||||
SWAPTYPE=$(blkid -p -O ${offset_option} "${resume}" -s TYPE -o value)
|
||||
MAJMIN="${MAJMIN}:${resume_offset?}"
|
||||
else
|
||||
SWAPTYPE=$(blkid -p -o value -s TYPE "$resume")
|
||||
fi
|
||||
|
||||
use_plymouth=false
|
||||
if command -v plymouth >/dev/null && plymouth --ping; then
|
||||
use_plymouth=true
|
||||
fi
|
||||
|
||||
case "${SWAPTYPE}" in
|
||||
swsuspend|s1suspend|s2suspend|ulsuspend|tuxonice)
|
||||
if "$use_plymouth"; then
|
||||
plymouth message --text="Resuming from $resume"
|
||||
|
||||
# The above command does not wait for a framebuffer update to
|
||||
# complete, so the kernel can freeze the framebuffer before
|
||||
# the message is even visible. Wait just a moment to make
|
||||
# that less likely.
|
||||
sleep 0.1
|
||||
fi
|
||||
|
||||
echo "${MAJMIN}" > /sys/power/resume
|
||||
;;
|
||||
esac
|
||||
|
||||
if "$use_plymouth"; then
|
||||
# plymouth hide-message does not work yet
|
||||
plymouth display-message --text=""
|
||||
fi
|
|
@ -0,0 +1,166 @@
|
|||
# NFS filesystem mounting -*- shell-script -*-
|
||||
|
||||
# FIXME This needs error checking
|
||||
|
||||
nfs_top()
|
||||
{
|
||||
if [ "${nfs_top_used}" != "yes" ]; then
|
||||
[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/nfs-top"
|
||||
run_scripts /scripts/nfs-top
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
fi
|
||||
nfs_top_used=yes
|
||||
}
|
||||
|
||||
nfs_premount()
|
||||
{
|
||||
if [ "${nfs_premount_used}" != "yes" ]; then
|
||||
[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/nfs-premount"
|
||||
run_scripts /scripts/nfs-premount
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
fi
|
||||
nfs_premount_used=yes
|
||||
}
|
||||
|
||||
nfs_bottom()
|
||||
{
|
||||
if [ "${nfs_premount_used}" = "yes" ] || [ "${nfs_top_used}" = "yes" ]; then
|
||||
[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/nfs-bottom"
|
||||
run_scripts /scripts/nfs-bottom
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
fi
|
||||
nfs_premount_used=no
|
||||
nfs_top_used=no
|
||||
}
|
||||
|
||||
# parse nfs bootargs and mount nfs
|
||||
nfs_mount_root_impl()
|
||||
{
|
||||
configure_networking
|
||||
|
||||
# get nfs root from dhcp
|
||||
if [ "x${NFSROOT}" = "xauto" ]; then
|
||||
# check if server ip is part of dhcp root-path
|
||||
if [ "${ROOTPATH#*:}" = "${ROOTPATH}" ]; then
|
||||
NFSROOT=${ROOTSERVER}:${ROOTPATH}
|
||||
else
|
||||
NFSROOT=${ROOTPATH}
|
||||
fi
|
||||
|
||||
# nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
|
||||
elif [ -n "${NFSROOT}" ]; then
|
||||
# nfs options are an optional arg
|
||||
if [ "${NFSROOT#*,}" != "${NFSROOT}" ]; then
|
||||
NFSOPTS="-o ${NFSROOT#*,}"
|
||||
fi
|
||||
NFSROOT=${NFSROOT%%,*}
|
||||
if [ "${NFSROOT#*:}" = "$NFSROOT" ]; then
|
||||
NFSROOT=${ROOTSERVER}:${NFSROOT}
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${NFSOPTS}" ]; then
|
||||
NFSOPTS="-o retrans=10"
|
||||
fi
|
||||
|
||||
nfs_premount
|
||||
|
||||
if [ "${readonly?}" = y ]; then
|
||||
roflag="-o ro"
|
||||
else
|
||||
roflag="-o rw"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
nfsmount -o nolock ${roflag} ${NFSOPTS} "${NFSROOT}" "${rootmnt?}"
|
||||
}
|
||||
|
||||
# NFS root mounting
|
||||
nfs_mount_root()
|
||||
{
|
||||
nfs_top
|
||||
|
||||
# For DHCP
|
||||
modprobe af_packet
|
||||
|
||||
wait_for_udev 10
|
||||
|
||||
# Default delay is around 180s
|
||||
delay=${ROOTDELAY:-180}
|
||||
|
||||
# loop until nfsmount succeeds
|
||||
nfs_mount_root_impl
|
||||
ret=$?
|
||||
nfs_retry_count=0
|
||||
while [ ${nfs_retry_count} -lt "${delay}" ] \
|
||||
&& [ $ret -ne 0 ] ; do
|
||||
[ "$quiet" != "y" ] && log_begin_msg "Retrying nfs mount"
|
||||
sleep 1
|
||||
nfs_mount_root_impl
|
||||
ret=$?
|
||||
nfs_retry_count=$(( nfs_retry_count + 1 ))
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
done
|
||||
}
|
||||
|
||||
nfs_mount_fs_impl()
|
||||
{
|
||||
configure_networking
|
||||
|
||||
if [ -z "${NFSOPTS}" ]; then
|
||||
NFSOPTS="-o retrans=10"
|
||||
fi
|
||||
|
||||
nfs_premount
|
||||
|
||||
if [ "${readonly}" = y ]; then
|
||||
roflag="-o ro"
|
||||
else
|
||||
roflag="-o rw"
|
||||
fi
|
||||
|
||||
read_fstab_entry "$1"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
nfsmount ${roflag} ${NFSOPTS} -o "${MNT_OPTS}" "$MNT_FSNAME" "${rootmnt}${MNT_DIR}"
|
||||
}
|
||||
|
||||
nfs_mount_fs()
|
||||
{
|
||||
nfs_top
|
||||
|
||||
# For DHCP
|
||||
modprobe af_packet
|
||||
|
||||
wait_for_udev 10
|
||||
|
||||
# Default delay is around 180s
|
||||
delay=${ROOTDELAY:-180}
|
||||
|
||||
# Don't loop here; we can't sanely check if it worked like for
|
||||
# the rootfs or /etc.
|
||||
nfs_mount_fs_impl "$1"
|
||||
}
|
||||
|
||||
mountroot()
|
||||
{
|
||||
nfs_mount_root
|
||||
}
|
||||
|
||||
mount_top()
|
||||
{
|
||||
# Note, also called directly in case it's overridden.
|
||||
nfs_top
|
||||
}
|
||||
|
||||
mount_premount()
|
||||
{
|
||||
# Note, also called directly in case it's overridden.
|
||||
nfs_premount
|
||||
}
|
||||
|
||||
mount_bottom()
|
||||
{
|
||||
# Note, also called directly in case it's overridden.
|
||||
nfs_bottom
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
PKG_CONFIG = pkg-config
|
||||
UDEV_CFLAGS = $(shell $(PKG_CONFIG) --cflags libudev)
|
||||
UDEV_LIBS = $(shell $(PKG_CONFIG) --libs libudev)
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -Wall -O2 $(UDEV_CFLAGS)
|
||||
LDFLAGS =
|
||||
|
||||
|
||||
.PHONY: all
|
||||
all: wait-for-root rzscontrol
|
||||
|
||||
wait-for-root: wait-for-root.o
|
||||
$(CC) $(LDFLAGS) -o $@ $< $(UDEV_LIBS)
|
||||
|
||||
rzscontrol: rzscontrol.o
|
||||
$(CC) $(LDFLAGS) -o $@ $<
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f wait-for-root.o wait-for-root rzscontrol.o rzscontrol core *~
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Compressed RAM based swap device
|
||||
*
|
||||
* Copyright (C) 2008, 2009, 2010 Nitin Gupta
|
||||
*
|
||||
* This code is released using a dual license strategy: BSD/GPL
|
||||
* You can choose the licence that better fits your requirements.
|
||||
*
|
||||
* Released under the terms of 3-clause BSD License
|
||||
* Released under the terms of GNU General Public License Version 2.0
|
||||
*
|
||||
* Project home: http://compcache.googlecode.com
|
||||
*/
|
||||
|
||||
#ifndef _RAMZSWAP_IOCTL_H_
|
||||
#define _RAMZSWAP_IOCTL_H_
|
||||
|
||||
struct ramzswap_ioctl_stats {
|
||||
u64 disksize; /* user specified or equal to backing swap
|
||||
* size (if present) */
|
||||
u64 num_reads; /* failed + successful */
|
||||
u64 num_writes; /* --do-- */
|
||||
u64 failed_reads; /* should NEVER! happen */
|
||||
u64 failed_writes; /* can happen when memory is too low */
|
||||
u64 invalid_io; /* non-swap I/O requests */
|
||||
u64 notify_free; /* no. of swap slot free notifications */
|
||||
u32 pages_zero; /* no. of zero filled pages */
|
||||
u32 good_compress_pct; /* no. of pages with compression ratio<=50% */
|
||||
u32 pages_expand_pct; /* no. of incompressible pages */
|
||||
u32 pages_stored;
|
||||
u32 pages_used;
|
||||
u64 orig_data_size;
|
||||
u64 compr_data_size;
|
||||
u64 mem_used_total;
|
||||
} __attribute__ ((packed, aligned(4)));
|
||||
|
||||
#define RZSIO_SET_DISKSIZE_KB _IOW('z', 0, size_t)
|
||||
#define RZSIO_GET_STATS _IOR('z', 1, struct ramzswap_ioctl_stats)
|
||||
#define RZSIO_INIT _IO('z', 2)
|
||||
#define RZSIO_RESET _IO('z', 3)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* rzscontrol - Control ramzswap devices
|
||||
*
|
||||
* Copyright (C) 2008, 2009 Nitin Gupta
|
||||
*
|
||||
* This code is released using a dual license strategy: BSD/GPL
|
||||
* You can choose the licence that better fits your requirements.
|
||||
*
|
||||
* Released under the terms of 3-clause BSD License
|
||||
* Released under the terms of GNU General Public License Version 2.0
|
||||
*
|
||||
* Project home: http://compcache.googlecode.com
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
#include "ramzswap_ioctl.h"
|
||||
|
||||
/* Flag set by '--verbose' */
|
||||
static int verbose_flag;
|
||||
|
||||
/* /dev/ramzswapX */
|
||||
#define MAX_DEVICE_NAME_LEN 32
|
||||
|
||||
/*
|
||||
* 10 decimal digits can represent 2^32.
|
||||
* All input sizes are in KB, so 10 digits are sufficient.
|
||||
*/
|
||||
#define MAX_SIZE_LEN 10
|
||||
|
||||
#define VERBOSE(args...) do { \
|
||||
if (verbose_flag) \
|
||||
printf(args); \
|
||||
} while (0)
|
||||
|
||||
struct rzs_args {
|
||||
u64 disksize_kb;
|
||||
int init;
|
||||
int reset;
|
||||
int stats;
|
||||
};
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf("Usage: rzscontrol {<ramzswap device>} [<options>]\n"
|
||||
"Example: rzscontrol /dev/ramzswap0 --init\n"
|
||||
"See rzscontrol manpage for details.\n");
|
||||
}
|
||||
|
||||
void show_stats(struct ramzswap_ioctl_stats *s)
|
||||
{
|
||||
#define K(x) ((x) >> 10)
|
||||
/* Basic stats */
|
||||
printf(
|
||||
"DiskSize: %8" PRIu64 " kB\n",
|
||||
K(s->disksize)
|
||||
);
|
||||
|
||||
/* Extended stats */
|
||||
printf(
|
||||
"NumReads: %8" PRIu64 "\n"
|
||||
"NumWrites: %8" PRIu64 "\n"
|
||||
"FailedReads: %8" PRIu64 "\n"
|
||||
"FailedWrites: %8" PRIu64 "\n"
|
||||
"InvalidIO: %8" PRIu64 "\n"
|
||||
"NotifyFree: %8" PRIu64 "\n"
|
||||
"ZeroPages: %8u\n"
|
||||
"GoodCompress: %8u %%\n"
|
||||
"NoCompress: %8u %%\n"
|
||||
"PagesStored: %8u\n"
|
||||
"PagesUsed: %8u\n"
|
||||
"OrigDataSize: %8" PRIu64 " kB\n"
|
||||
"ComprDataSize: %8" PRIu64 " kB\n"
|
||||
"MemUsedTotal: %8" PRIu64 " kB\n",
|
||||
s->num_reads,
|
||||
s->num_writes,
|
||||
s->failed_reads,
|
||||
s->failed_writes,
|
||||
s->invalid_io,
|
||||
s->notify_free,
|
||||
s->pages_zero,
|
||||
s->good_compress_pct,
|
||||
s->pages_expand_pct,
|
||||
s->pages_stored,
|
||||
s->pages_used,
|
||||
K(s->orig_data_size),
|
||||
K(s->compr_data_size),
|
||||
K(s->mem_used_total)
|
||||
);
|
||||
}
|
||||
|
||||
int do_ioctl(int fd, int argc, struct rzs_args *args)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Print an error message if ioctl fails */
|
||||
#define ON_ERR(str) do { \
|
||||
int err; \
|
||||
if (ret == -1) { \
|
||||
err = errno; \
|
||||
printf("%s: %s\n", str, strerror(err)); \
|
||||
goto out; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
while (argc--) {
|
||||
|
||||
if (args->disksize_kb) {
|
||||
VERBOSE("disksize_kb: %" PRIu64 "\n", args->disksize_kb);
|
||||
ret = ioctl(fd, RZSIO_SET_DISKSIZE_KB, &args->disksize_kb);
|
||||
args->disksize_kb = 0;
|
||||
ON_ERR("disksize_kb");
|
||||
}
|
||||
|
||||
if (args->init) {
|
||||
ret = ioctl(fd, RZSIO_INIT);
|
||||
args->init = 0;
|
||||
ON_ERR("init");
|
||||
}
|
||||
|
||||
if (args->reset) {
|
||||
ret = ioctl(fd, RZSIO_RESET);
|
||||
args->reset = 0;
|
||||
ON_ERR("reset");
|
||||
}
|
||||
|
||||
if (args->stats) {
|
||||
struct ramzswap_ioctl_stats s;
|
||||
memset(&s, 0, sizeof(s));
|
||||
ret = ioctl(fd, RZSIO_GET_STATS, &s);
|
||||
args->stats = 0;
|
||||
ON_ERR("stats");
|
||||
show_stats(&s);
|
||||
}
|
||||
|
||||
} /* while (argc--) */
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fd, ret, opt, idx;
|
||||
struct rzs_args args;
|
||||
char dev_name[MAX_DEVICE_NAME_LEN];
|
||||
|
||||
if (argc < 3) {
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
strncpy(dev_name, argv[1], MAX_DEVICE_NAME_LEN - 1);
|
||||
dev_name[MAX_DEVICE_NAME_LEN - 1] = '\0';
|
||||
|
||||
fd = open(dev_name, O_NONBLOCK);
|
||||
if (fd == -1) {
|
||||
ret = errno;
|
||||
printf("Failed to open %s: %s\n", dev_name, strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
VERBOSE("device: %s\n", dev_name);
|
||||
|
||||
ret = 0;
|
||||
while (1) {
|
||||
char *endptr = NULL;
|
||||
|
||||
static struct option long_options[] = {
|
||||
{ "disksize_kb", required_argument, 0, 'd' },
|
||||
{ "init", no_argument, 0, 'i' },
|
||||
{ "reset", no_argument, 0, 'r' },
|
||||
{ "stats", no_argument, 0, 's' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
opt = getopt_long(argc, argv, "m:d:b:irsvh", long_options, &idx);
|
||||
|
||||
if (opt == -1)
|
||||
break;
|
||||
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
if (strnlen(optarg, MAX_SIZE_LEN + 1) > MAX_SIZE_LEN) {
|
||||
printf("disksize_kb: %s\n", strerror(EOVERFLOW));
|
||||
ret = -EOVERFLOW;
|
||||
goto out;
|
||||
}
|
||||
|
||||
args.disksize_kb = strtoul(optarg, &endptr, 10);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
args.stats = 1;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
args.init = 1;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
args.reset = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose_flag = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage();
|
||||
break;
|
||||
|
||||
case '?':
|
||||
usage();
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
/* We never reach here */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = do_ioctl(fd, argc - 2, &args);
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
#include <libudev.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
static int matching_device (struct udev_device *device, const char *path);
|
||||
|
||||
static void alarm_handler (int signum);
|
||||
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
const char * devpath;
|
||||
char path[PATH_MAX];
|
||||
int timeout;
|
||||
struct udev * udev;
|
||||
struct udev_monitor *udev_monitor;
|
||||
struct stat devstat;
|
||||
struct udev_device * udev_device;
|
||||
const char * type;
|
||||
int flags;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf (stderr, "Usage: %s DEVICE TIMEOUT\n", argv[0]);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
devpath = argv[1];
|
||||
if (! strncmp (devpath, "UUID=", 5)) {
|
||||
strcpy (path, "/dev/disk/by-uuid/");
|
||||
strcat (path, devpath + 5);
|
||||
} else if (! strncmp (devpath, "LABEL=", 6)) {
|
||||
strcpy (path, "/dev/disk/by-label/");
|
||||
strcat (path, devpath + 6);
|
||||
} else if (! strncmp (devpath, "PARTUUID=", 9)) {
|
||||
strcpy (path, "/dev/disk/by-partuuid/");
|
||||
strcat (path, devpath + 9);
|
||||
} else {
|
||||
strcpy (path, devpath);
|
||||
}
|
||||
|
||||
timeout = atoi (argv[2]);
|
||||
|
||||
signal (SIGALRM, alarm_handler);
|
||||
alarm (timeout);
|
||||
|
||||
/* Connect to the udev monitor first; if we stat() first, the
|
||||
* event might happen between the stat() and the time we actually
|
||||
* get hooked up.
|
||||
*/
|
||||
udev = udev_new ();
|
||||
udev_monitor = udev_monitor_new_from_netlink (udev, "udev");
|
||||
|
||||
udev_monitor_filter_add_match_subsystem_devtype (udev_monitor, "block", NULL);
|
||||
udev_monitor_enable_receiving (udev_monitor);
|
||||
udev_monitor_set_receive_buffer_size(udev_monitor, 128*1024*1024);
|
||||
|
||||
/* Check to see whether the device exists already on the filesystem.
|
||||
* If this is true, we don't need to wait for it can obtain the
|
||||
* filesystem type by looking up the udevdb record by major/minor.
|
||||
*/
|
||||
if (stat (path, &devstat) == 0 && S_ISBLK (devstat.st_mode))
|
||||
{
|
||||
udev_device = udev_device_new_from_devnum (udev, 'b', devstat.st_rdev);
|
||||
if (udev_device) {
|
||||
type = udev_device_get_property_value (udev_device, "ID_FS_TYPE");
|
||||
if (type) {
|
||||
printf ("%s\n", type);
|
||||
|
||||
udev_device_unref (udev_device);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
udev_device_unref (udev_device);
|
||||
}
|
||||
}
|
||||
|
||||
/* udev monitor socket is nonblocking by default, but we want to wait
|
||||
* for events */
|
||||
flags = fcntl (udev_monitor_get_fd (udev_monitor), F_GETFL, 0);
|
||||
flags &= ~O_NONBLOCK;
|
||||
fcntl (udev_monitor_get_fd (udev_monitor), F_SETFL, flags);
|
||||
|
||||
/* When the device doesn't exist yet, or is still being processed
|
||||
* by udev, use the monitor socket to wait it to be done.
|
||||
*/
|
||||
while (1) {
|
||||
/* even though we use a blocking socket this might still fail
|
||||
* due to ENOBUFS or similar. */
|
||||
while ((udev_device = udev_monitor_receive_device (udev_monitor)) == NULL)
|
||||
sleep (1);
|
||||
if (matching_device (udev_device, devpath)) {
|
||||
type = udev_device_get_property_value (udev_device, "ID_FS_TYPE");
|
||||
if (type) {
|
||||
printf ("%s\n", type);
|
||||
|
||||
udev_device_unref (udev_device);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
udev_device_unref (udev_device);
|
||||
}
|
||||
|
||||
exit:
|
||||
udev_monitor_unref (udev_monitor);
|
||||
udev_unref (udev);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
matching_device (struct udev_device *device,
|
||||
const char * path)
|
||||
{
|
||||
const char * devnode;
|
||||
struct udev_list_entry *devlinks_entry;
|
||||
|
||||
/* Match by name */
|
||||
devnode = udev_device_get_devnode (device);
|
||||
if (devnode && (! strcmp (path, devnode)))
|
||||
return 1;
|
||||
|
||||
/* Match by UUID */
|
||||
if (! strncmp (path, "UUID=", 5)) {
|
||||
const char *uuid;
|
||||
|
||||
uuid = udev_device_get_property_value (device, "ID_FS_UUID");
|
||||
if (uuid && (! strcmp (path + 5, uuid)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Match by LABEL */
|
||||
if (! strncmp (path, "LABEL=", 6)) {
|
||||
const char *label;
|
||||
|
||||
label = udev_device_get_property_value (device, "ID_FS_LABEL");
|
||||
if (label && (! strcmp (path + 6, label)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Match by symlink */
|
||||
for (devlinks_entry = udev_device_get_devlinks_list_entry (device);
|
||||
devlinks_entry != NULL;
|
||||
devlinks_entry = udev_list_entry_get_next (devlinks_entry))
|
||||
if (! strcmp (path, udev_list_entry_get_name (devlinks_entry)))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
alarm_handler (int signum)
|
||||
{
|
||||
exit (1);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/sh
|
||||
# Simply call all files named 'test_*' in the same directory as this file.
|
||||
# Record their exit code as pass or fail. exit 1 if any failed.
|
||||
my_dir=$(dirname "$0")
|
||||
|
||||
npass=0
|
||||
nfail=0
|
||||
for test_file in "${my_dir}/test_"*; do
|
||||
[ -f "$test_file" -a -x "$test_file" ] || continue
|
||||
echo "executing $test_file" 1>&2
|
||||
"$test_file"
|
||||
ret=$?
|
||||
if [ $ret -eq 0 ]; then
|
||||
npass=$(($npass+1))
|
||||
else
|
||||
nfail=$(($nfail+1))
|
||||
fails="${fails:+${fails} }${test_file}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $nfail -ne 0 ]; then
|
||||
echo "Passed $npass tests. Failed $nfail tests: ${fails}." 1>&2
|
||||
exit 1
|
||||
elif [ $npass -eq 0 ]; then
|
||||
echo "No tests executed?" 1>&2
|
||||
else
|
||||
echo "Passed $npass tests. Failed 0 tests." 1>&2
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,2 @@
|
|||
nameserver 192.168.122.1
|
||||
search foo.com
|
|
@ -0,0 +1,17 @@
|
|||
DEVICE='example1'
|
||||
PROTO='dhcp'
|
||||
IPV4ADDR='192.168.122.89'
|
||||
IPV4BROADCAST='192.168.122.255'
|
||||
IPV4NETMASK='255.255.255.0'
|
||||
IPV4GATEWAY='192.168.122.1'
|
||||
IPV4DNS0='192.168.122.1'
|
||||
IPV4DNS1='0.0.0.0'
|
||||
HOSTNAME='foohost'
|
||||
DNSDOMAIN=''
|
||||
NISDOMAIN=''
|
||||
ROOTSERVER='192.168.122.1'
|
||||
ROOTPATH=''
|
||||
filename=''
|
||||
UPTIME='21'
|
||||
DHCPLEASETIME='3600'
|
||||
DOMAINSEARCH='foo.com'
|
|
@ -0,0 +1,11 @@
|
|||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
example1:
|
||||
dhcp4: true
|
||||
dhcp-identifier: mac
|
||||
critical: true
|
||||
nameservers:
|
||||
addresses: ["192.168.122.1"]
|
||||
search: ["foo.com"]
|
|
@ -0,0 +1,3 @@
|
|||
nameserver 192.168.122.1
|
||||
nameserver 2001:67c:1562:8010::2:1
|
||||
search foo.com example.com ubuntu.com
|
|
@ -0,0 +1,17 @@
|
|||
DEVICE='example1'
|
||||
PROTO='dhcp'
|
||||
IPV4ADDR='192.168.122.89'
|
||||
IPV4BROADCAST='192.168.122.255'
|
||||
IPV4NETMASK='255.255.255.0'
|
||||
IPV4GATEWAY='192.168.122.1'
|
||||
IPV4DNS0='192.168.122.1'
|
||||
IPV4DNS1='0.0.0.0'
|
||||
HOSTNAME='foohost'
|
||||
DNSDOMAIN=''
|
||||
NISDOMAIN=''
|
||||
ROOTSERVER='192.168.122.1'
|
||||
ROOTPATH=''
|
||||
filename=''
|
||||
UPTIME='21'
|
||||
DHCPLEASETIME='3600'
|
||||
DOMAINSEARCH='foo.com'
|
|
@ -0,0 +1,10 @@
|
|||
DEVICE6=example1
|
||||
HOSTNAME=
|
||||
DNSDOMAIN=
|
||||
IPV6PROTO=dhcp6
|
||||
IPV6ADDR=2001:67c:1562:8010:0:1::
|
||||
IPV6NETMASK=64
|
||||
IPV6DNS0=2001:67c:1562:8010::2:1
|
||||
IPV6DOMAINSEARCH="example.com ubuntu.com"
|
||||
HOSTNAME=
|
||||
DNSDOMAIN=
|
|
@ -0,0 +1,12 @@
|
|||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
example1:
|
||||
dhcp4: true
|
||||
dhcp-identifier: mac
|
||||
dhcp6: true
|
||||
critical: true
|
||||
nameservers:
|
||||
addresses: ["192.168.122.1", "2001:67c:1562:8010::2:1"]
|
||||
search: ["foo.com", "example.com", "ubuntu.com"]
|
|
@ -0,0 +1,12 @@
|
|||
DEVICE='example1'
|
||||
PROTO='none'
|
||||
IPV4ADDR='10.0.0.2'
|
||||
IPV4BROADCAST='10.0.0.255'
|
||||
IPV4NETMASK='255.255.255.0'
|
||||
IPV4GATEWAY='10.0.0.1'
|
||||
IPV4DNS0='0.0.0.0'
|
||||
IPV4DNS1='0.0.0.0'
|
||||
HOSTNAME='foohost'
|
||||
UPTIME='21'
|
||||
DHCPLEASETIME=''
|
||||
DOMAINSEARCH=''
|
|
@ -0,0 +1,8 @@
|
|||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
example1:
|
||||
addresses:
|
||||
- "10.0.0.2/24"
|
||||
gateway4: "10.0.0.1"
|
|
@ -0,0 +1,2 @@
|
|||
nameserver 2001:67c:1562:8010::2:1
|
||||
search example.com ubuntu.com
|
|
@ -0,0 +1,10 @@
|
|||
DEVICE6=example1
|
||||
HOSTNAME=
|
||||
DNSDOMAIN=
|
||||
IPV6PROTO=dhcp6
|
||||
IPV6ADDR=2001:67c:1562:8010:0:1::
|
||||
IPV6NETMASK=64
|
||||
IPV6DNS0=2001:67c:1562:8010::2:1
|
||||
IPV6DOMAINSEARCH="example.com ubuntu.com"
|
||||
HOSTNAME=
|
||||
DNSDOMAIN=
|
|
@ -0,0 +1,10 @@
|
|||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
example1:
|
||||
dhcp6: true
|
||||
critical: true
|
||||
nameservers:
|
||||
addresses: ["2001:67c:1562:8010::2:1"]
|
||||
search: ["example.com", "ubuntu.com"]
|
|
@ -0,0 +1,3 @@
|
|||
nameserver 192.168.122.1
|
||||
nameserver 2001:67c:1562:8010::2:1
|
||||
search foo.com example.com ubuntu.com
|
|
@ -0,0 +1,22 @@
|
|||
# VLAN actually comes from vlan= kernel cmdline...
|
||||
# ... but this file is sourced, so pretend it was
|
||||
# parsed out kernel cmdline
|
||||
VLAN=example1.1:example1
|
||||
# end of hack
|
||||
DEVICE='example1.1'
|
||||
PROTO='dhcp'
|
||||
IPV4ADDR='192.168.122.89'
|
||||
IPV4BROADCAST='192.168.122.255'
|
||||
IPV4NETMASK='255.255.255.0'
|
||||
IPV4GATEWAY='192.168.122.1'
|
||||
IPV4DNS0='192.168.122.1'
|
||||
IPV4DNS1='0.0.0.0'
|
||||
HOSTNAME='foohost'
|
||||
DNSDOMAIN=''
|
||||
NISDOMAIN=''
|
||||
ROOTSERVER='192.168.122.1'
|
||||
ROOTPATH=''
|
||||
filename=''
|
||||
UPTIME='21'
|
||||
DHCPLEASETIME='3600'
|
||||
DOMAINSEARCH='foo.com'
|
|
@ -0,0 +1,15 @@
|
|||
# VLAN actually comes from vlan= kernel cmdline...
|
||||
# ... but this file is sourced, so pretend it was
|
||||
# parsed out kernel cmdline
|
||||
VLAN=example1.1:example1
|
||||
# end of hack
|
||||
DEVICE6=example1.1
|
||||
HOSTNAME=
|
||||
DNSDOMAIN=
|
||||
IPV6PROTO=dhcp6
|
||||
IPV6ADDR=2001:67c:1562:8010:0:1::
|
||||
IPV6NETMASK=64
|
||||
IPV6DNS0=2001:67c:1562:8010::2:1
|
||||
IPV6DOMAINSEARCH="example.com ubuntu.com"
|
||||
HOSTNAME=
|
||||
DNSDOMAIN=
|
|
@ -0,0 +1,17 @@
|
|||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
example1:
|
||||
{}
|
||||
vlans:
|
||||
example1.1:
|
||||
id: 1
|
||||
link: example1
|
||||
dhcp4: true
|
||||
dhcp-identifier: mac
|
||||
dhcp6: true
|
||||
critical: true
|
||||
nameservers:
|
||||
addresses: ["192.168.122.1", "2001:67c:1562:8010::2:1"]
|
||||
search: ["foo.com", "example.com", "ubuntu.com"]
|
|
@ -0,0 +1,119 @@
|
|||
#!/bin/sh
|
||||
|
||||
data_dir="${0%.sh}.d"
|
||||
my_dir=$(dirname "$0")
|
||||
SCRIPTS_D=$(cd "$my_dir/../scripts" && pwd)
|
||||
RET_SKIP=99
|
||||
RET_FAIL=2
|
||||
RET_PASS=0
|
||||
|
||||
PASSES=0
|
||||
FAILS=0
|
||||
SKIPS=0
|
||||
|
||||
logfail() { echo "FAIL:" "$@" 1>&2; return $RET_FAIL; }
|
||||
logpass() { echo "PASS:" "$@" 1>&2; return $RET_PASS; }
|
||||
|
||||
pass_on_nodiff() {
|
||||
# log_on_diff(tname, expected, found)
|
||||
local tname="$1" expected="$2" found="$3" out="" opts="-u"
|
||||
[ -d "$expected" ] && opts="-Naur"
|
||||
out=$(diff $opts "$expected" "$found")
|
||||
r=$?
|
||||
if [ $r -eq 0 ]; then
|
||||
logpass "$tname"
|
||||
else
|
||||
logfail "$tname: expected output differed"
|
||||
echo "$out" 1>&2
|
||||
return $RET_FAIL
|
||||
fi
|
||||
}
|
||||
|
||||
_run_in_functions() {
|
||||
local name="$1" r=""
|
||||
shift
|
||||
sh -ec '. "$1"; shift; "$@";' \
|
||||
"test-$name" "$SCRIPTS_D/functions" "$@" || {
|
||||
r=$?
|
||||
logfail "$name execution returned $r. ($*)"
|
||||
return $r
|
||||
}
|
||||
}
|
||||
|
||||
run_resolvconf() {
|
||||
local bname="$1" testdir="$2" results_d="$3"
|
||||
local tname="$bname-netinfo-to-resolv.conf"
|
||||
shift 3
|
||||
local expected="$testdir/expected-resolv.conf"
|
||||
local found="$results_d/resolv.conf"
|
||||
[ -f "$expected" ] || return $RET_SKIP
|
||||
_run_in_functions "$tname" netinfo_to_resolv_conf "$found" "$@" || return
|
||||
|
||||
pass_on_nodiff "$tname" "$expected" "$found"
|
||||
}
|
||||
|
||||
run_netinfo_to_netplan() {
|
||||
local bname="$1" testdir="$2" results_d="$3"
|
||||
local tname="$bname-netinfo-to-netplan"
|
||||
shift 3
|
||||
local found_d="$results_d/netplan"
|
||||
local expected_d="$testdir/netplan"
|
||||
[ -d "$expected_d" ] || return $RET_SKIP
|
||||
|
||||
_run_in_functions "$tname" netinfo_to_netplan "$found_d" "$@" || return
|
||||
pass_on_nodiff "$tname" "$expected_d" "$found_d"
|
||||
}
|
||||
|
||||
run_netplan_generate() {
|
||||
local bname="$1" testdir="$2" results_d="$3"
|
||||
local tname="$bname-netplan-generate"
|
||||
shift 3
|
||||
local expected_d="$testdir/netplan"
|
||||
[ -d "$expected_d" ] || return $RET_SKIP
|
||||
type netplan >/dev/null 2>/dev/null || return $RET_SKIP
|
||||
|
||||
mkdir -p $results_d/lib/
|
||||
cp -r $expected_d $results_d/lib
|
||||
netplan generate --root-dir $results_d
|
||||
r=$?
|
||||
if [ $r -eq 0 ]; then
|
||||
logpass "$tname"
|
||||
else
|
||||
logfail "$tname: netplan generate failed"
|
||||
return $RET_FAIL
|
||||
fi
|
||||
}
|
||||
|
||||
record() {
|
||||
local ret="$1"
|
||||
case "$ret" in
|
||||
0) PASSES=$(($PASSES+1));;
|
||||
$RET_SKIP) SKIPS=$(($SKIPS+1));;
|
||||
*) FAILS=$(($FAILS+1));;
|
||||
esac
|
||||
}
|
||||
|
||||
for testdir in "${data_dir}"/*; do
|
||||
[ -d "$testdir" ] || continue
|
||||
dname="${testdir##*/}"
|
||||
results_d=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXX")
|
||||
confs=$(
|
||||
for f in "${testdir}"/net-*.conf "${testdir}/net6-"*.conf; do
|
||||
[ -f "$f" ] && echo "$f"
|
||||
done
|
||||
)
|
||||
run_resolvconf "$dname" "$testdir" "$results_d" $confs
|
||||
record $?
|
||||
|
||||
run_netinfo_to_netplan "$dname" "$testdir" "$results_d" $confs
|
||||
record $?
|
||||
|
||||
run_netplan_generate "$dname" "$testdir" "$results_d" $confs
|
||||
record $?
|
||||
|
||||
rm -Rf "${results_d}"
|
||||
done
|
||||
|
||||
echo "INFO: ran $(($PASSES+$FAILS)) tests: $PASSES pass. $FAILS fail."
|
||||
[ $FAILS -eq 0 ]
|
||||
exit
|
|
@ -0,0 +1,172 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
usage()
|
||||
{
|
||||
cat << EOF
|
||||
|
||||
Usage: unmkinitramfs [-v] initramfs-file directory
|
||||
|
||||
Options:
|
||||
-v Display verbose messages about extraction
|
||||
|
||||
See unmkinitramfs(8) for further details.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
usage_error()
|
||||
{
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
# Extract a compressed cpio archive
|
||||
xcpio()
|
||||
{
|
||||
archive="$1"
|
||||
dir="$2"
|
||||
shift 2
|
||||
|
||||
if gzip -t "$archive" >/dev/null 2>&1 ; then
|
||||
gzip -c -d "$archive"
|
||||
elif xzcat -t "$archive" >/dev/null 2>&1 ; then
|
||||
xzcat "$archive"
|
||||
elif lz4cat -t < "$archive" >/dev/null 2>&1 ; then
|
||||
lz4cat "$archive"
|
||||
elif bzip2 -t "$archive" >/dev/null 2>&1 ; then
|
||||
bzip2 -c -d "$archive"
|
||||
elif lzop -t "$archive" >/dev/null 2>&1 ; then
|
||||
lzop -c -d "$archive"
|
||||
# Ignoring other data, which may be garbage at the end of the file
|
||||
fi | (
|
||||
if [ -n "$dir" ]; then
|
||||
mkdir -p -- "$dir"
|
||||
cd -- "$dir"
|
||||
fi
|
||||
cpio "$@"
|
||||
)
|
||||
}
|
||||
|
||||
# Read bytes out of a file, checking that they are valid hex digits
|
||||
readhex()
|
||||
{
|
||||
dd < "$1" bs=1 skip="$2" count="$3" 2> /dev/null | \
|
||||
LANG=C grep -E "^[0-9A-Fa-f]{$3}\$"
|
||||
}
|
||||
|
||||
# Check for a zero byte in a file
|
||||
checkzero()
|
||||
{
|
||||
dd < "$1" bs=1 skip="$2" count=1 2> /dev/null | \
|
||||
LANG=C grep -q -z '^$'
|
||||
}
|
||||
|
||||
# Split an initramfs into archives and call xcpio on each
|
||||
splitinitramfs()
|
||||
{
|
||||
initramfs="$1"
|
||||
dir="$2"
|
||||
shift 2
|
||||
|
||||
count=0
|
||||
start=0
|
||||
while true; do
|
||||
# There may be prepended uncompressed archives. cpio
|
||||
# won't tell us the true size of these so we have to
|
||||
# parse the headers and padding ourselves. This is
|
||||
# very roughly based on linux/lib/earlycpio.c
|
||||
end=$start
|
||||
while true; do
|
||||
if checkzero "$initramfs" $end; then
|
||||
# This is the EOF marker. There might
|
||||
# be more zero padding before the next
|
||||
# archive, so read through all of it.
|
||||
end=$((end + 4))
|
||||
while checkzero "$initramfs" $end; do
|
||||
end=$((end + 4))
|
||||
done
|
||||
break
|
||||
fi
|
||||
magic="$(readhex "$initramfs" $end 6)" || break
|
||||
test "$magic" = 070701 || test "$magic" = 070702 || break
|
||||
namesize=0x$(readhex "$initramfs" $((end + 94)) 8)
|
||||
filesize=0x$(readhex "$initramfs" $((end + 54)) 8)
|
||||
end=$(((end + 110)))
|
||||
end=$(((end + namesize + 3) & ~3))
|
||||
end=$(((end + filesize + 3) & ~3))
|
||||
done
|
||||
if [ $end -eq $start ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
# Extract to early, early2, ... subdirectories
|
||||
count=$((count + 1))
|
||||
if [ $count -eq 1 ]; then
|
||||
subdir=early
|
||||
else
|
||||
subdir=early$count
|
||||
fi
|
||||
dd < "$initramfs" skip=$start count=$((end - start)) iflag=skip_bytes 2> /dev/null |
|
||||
(
|
||||
if [ -n "$dir" ]; then
|
||||
mkdir -p -- "$dir/$subdir"
|
||||
cd -- "$dir/$subdir"
|
||||
fi
|
||||
cpio -i "$@"
|
||||
)
|
||||
start=$end
|
||||
done
|
||||
|
||||
if [ $end -gt 0 ]; then
|
||||
# Extract to main subdirectory
|
||||
subarchive=$(mktemp "${TMPDIR:-/var/tmp}/unmkinitramfs_XXXXXX")
|
||||
trap 'rm -f "$subarchive"' EXIT
|
||||
dd < "$initramfs" skip=$end iflag=skip_bytes 2> /dev/null \
|
||||
> "$subarchive"
|
||||
xcpio "$subarchive" "${dir:+$dir/main}" -i "$@"
|
||||
else
|
||||
# Don't use subdirectories (for backward compatibility)
|
||||
xcpio "$initramfs" "$dir" -i "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
OPTIONS=$(getopt -o hv --long help,list,verbose -n "$0" -- "$@") || usage_error
|
||||
|
||||
cpio_opts="--preserve-modification-time --no-absolute-filenames --quiet"
|
||||
expected_args=2
|
||||
eval set -- "$OPTIONS"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--list)
|
||||
# For lsinitramfs
|
||||
cpio_opts="${cpio_opts:+${cpio_opts} --list}"
|
||||
expected_args=1
|
||||
shift
|
||||
;;
|
||||
-v|--verbose)
|
||||
cpio_opts="${cpio_opts:+${cpio_opts} --verbose}"
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Internal error!" >&2
|
||||
exit 1
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $# -ne $expected_args ]; then
|
||||
usage_error
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
splitinitramfs "$1" "${2:-}" $cpio_opts
|
|
@ -0,0 +1,56 @@
|
|||
.TH UNMKINITRAMFS 8 "2016/12/15" "initramfs\-tools" "System Administration"
|
||||
|
||||
.SH NAME
|
||||
unmkinitramfs \- extract content from an initramfs image
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B unmkinitramfs
|
||||
.RB [ -v ]
|
||||
.IR initramfs-file " " directory
|
||||
.br
|
||||
.BR unmkinitramfs " " -h
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B unmkinitramfs
|
||||
command extracts the content of a given initramfs image using
|
||||
.BR cpio .
|
||||
If the image contains multiple segments, each are passed to
|
||||
.B cpio
|
||||
in order.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
.B -h
|
||||
Display usage information and exit.
|
||||
|
||||
.TP
|
||||
.B -v
|
||||
Display verbose messages about extraction.
|
||||
|
||||
|
||||
.SH USAGE EXAMPLES
|
||||
|
||||
Extract initramfs content of current running kernel:
|
||||
|
||||
.PP
|
||||
.B unmkinitramfs /boot/initrd.img-$(uname -r) initramfs/
|
||||
|
||||
|
||||
.SH BUGS
|
||||
.BR unmkinitramfs
|
||||
cannot deal with multiple-segmented initramfs images, except where an
|
||||
early (uncompressed) initramfs with system firmware is prepended to
|
||||
the regular compressed initramfs.
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>
|
||||
and numerous others.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR
|
||||
.IR initramfs-tools (7),
|
||||
.IR lsinitramfs (8),
|
||||
.IR mkinitramfs (8),
|
||||
.IR update-initramfs (8).
|
|
@ -0,0 +1,427 @@
|
|||
#!/bin/sh
|
||||
|
||||
STATEDIR=/var/lib/initramfs-tools
|
||||
BOOTDIR=/boot
|
||||
CONF=/etc/initramfs-tools/update-initramfs.conf
|
||||
mode=""
|
||||
version=""
|
||||
update_initramfs=yes
|
||||
backup_initramfs=no
|
||||
|
||||
set -e
|
||||
|
||||
[ -r ${CONF} ] && . ${CONF}
|
||||
|
||||
case "$DPKG_MAINTSCRIPT_PACKAGE" in
|
||||
linux-image-*)
|
||||
if [ -z "$INITRAMFS_TOOLS_KERNEL_HOOK" ]; then
|
||||
# kernel maintainer script called us directly; ignore
|
||||
# it and let the hook script handle it instead
|
||||
echo "update-initramfs: deferring update (hook will be called later)"
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
?*)
|
||||
if [ $# = 1 ] \
|
||||
&& [ x"$1" = x-u ]
|
||||
then
|
||||
if dpkg-trigger --no-await update-initramfs; then
|
||||
echo "update-initramfs: deferring update (trigger activated)"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
usage()
|
||||
{
|
||||
cat << EOF
|
||||
|
||||
Usage: update-initramfs {-c|-d|-u} [-k version] [-v] [-b directory]
|
||||
|
||||
Options:
|
||||
-k version Specify kernel version or 'all'
|
||||
-c Create a new initramfs
|
||||
-u Update an existing initramfs
|
||||
-d Remove an existing initramfs
|
||||
-b directory Set alternate boot directory
|
||||
-v Be verbose
|
||||
|
||||
See update-initramfs(8) for further details.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
usage_error()
|
||||
{
|
||||
if [ -n "${1:-}" ]; then
|
||||
printf "%s\\n\\n" "${*}" >&2
|
||||
fi
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
mild_panic()
|
||||
{
|
||||
if [ -n "${1:-}" ]; then
|
||||
printf "%s\\n" "${*}" >&2
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
panic()
|
||||
{
|
||||
if [ -n "${1:-}" ]; then
|
||||
printf "%s\\n" "${*}" >&2
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
verbose()
|
||||
{
|
||||
if [ "${verbose}" = 1 ]; then
|
||||
printf "%s\\n" "${*}"
|
||||
fi
|
||||
}
|
||||
|
||||
set_initramfs()
|
||||
{
|
||||
initramfs="${BOOTDIR}/initrd.img-${version}"
|
||||
}
|
||||
|
||||
|
||||
# backup initramfs while running
|
||||
backup_initramfs()
|
||||
{
|
||||
[ ! -r "${initramfs}" ] && return 0
|
||||
initramfs_bak="${initramfs}.dpkg-bak"
|
||||
[ -r "${initramfs_bak}" ] && rm -f "${initramfs_bak}"
|
||||
ln -f "${initramfs}" "${initramfs_bak}" \
|
||||
|| cp -a "${initramfs}" "${initramfs_bak}"
|
||||
verbose "Keeping ${initramfs_bak}"
|
||||
}
|
||||
|
||||
# keep booted initramfs
|
||||
backup_booted_initramfs()
|
||||
{
|
||||
initramfs_bak="${initramfs}.dpkg-bak"
|
||||
|
||||
# first time run thus no backup
|
||||
[ ! -r "${initramfs_bak}" ] && return 0
|
||||
|
||||
# chroot with no /proc
|
||||
[ ! -r /proc/uptime ] && rm -f "${initramfs_bak}" && return 0
|
||||
|
||||
# no kept backup wanted
|
||||
[ "${backup_initramfs}" = "no" ] && rm -f "${initramfs_bak}" && return 0
|
||||
|
||||
# no backup yet
|
||||
if [ ! -r "${initramfs}.bak" ]; then
|
||||
mv -f ${initramfs_bak} "${initramfs}.bak"
|
||||
verbose "Backup ${initramfs}.bak"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# keep booted initramfs
|
||||
boot_initramfs=
|
||||
uptime_days=$(awk '{printf "%d", $1 / 3600 / 24}' /proc/uptime)
|
||||
if [ -n "$uptime_days" ]; then
|
||||
boot_initramfs=$(find "${initramfs}.bak" -mtime "+${uptime_days}")
|
||||
fi
|
||||
if [ -n "${boot_initramfs}" ]; then
|
||||
mv -f "${initramfs_bak}" "${initramfs}.bak"
|
||||
verbose "Backup ${initramfs}.bak"
|
||||
return 0
|
||||
fi
|
||||
verbose "Removing current backup ${initramfs_bak}"
|
||||
rm -f ${initramfs_bak}
|
||||
}
|
||||
|
||||
# nuke generated copy
|
||||
remove_initramfs_bak()
|
||||
{
|
||||
[ -z "${initramfs_bak:-}" ] && return 0
|
||||
rm -f "${initramfs_bak}"
|
||||
verbose "Removing ${initramfs_bak}"
|
||||
}
|
||||
|
||||
|
||||
generate_initramfs()
|
||||
{
|
||||
echo "update-initramfs: Generating ${initramfs}"
|
||||
OPTS="-o"
|
||||
if [ "${verbose}" = 1 ]; then
|
||||
OPTS="-v ${OPTS}"
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
if mkinitramfs ${OPTS} "${initramfs}.new" "${version}"; then
|
||||
mv -f "${initramfs}.new" "${initramfs}"
|
||||
set_sha1
|
||||
# Guard against an unclean shutdown
|
||||
sync -f "${initramfs}"
|
||||
else
|
||||
mkinitramfs_return="$?"
|
||||
remove_initramfs_bak
|
||||
rm -f "${initramfs}.new"
|
||||
echo "update-initramfs: failed for ${initramfs} with $mkinitramfs_return." >&2
|
||||
exit $mkinitramfs_return
|
||||
fi
|
||||
}
|
||||
|
||||
# Invoke bootloader
|
||||
run_bootloader()
|
||||
{
|
||||
# invoke policy conformant bootloader hooks
|
||||
if [ -d /etc/initramfs/post-update.d/ ]; then
|
||||
run-parts --arg=${version} --arg=${initramfs} \
|
||||
/etc/initramfs/post-update.d/
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Note that this must overwrite so that updates work.
|
||||
set_sha1()
|
||||
{
|
||||
sha1sum "${initramfs}" > "${STATEDIR}/${version}"
|
||||
}
|
||||
|
||||
delete_sha1()
|
||||
{
|
||||
rm -f "${STATEDIR}/${version}"
|
||||
}
|
||||
|
||||
# ro /boot is not modified
|
||||
ro_boot_check()
|
||||
{
|
||||
# check irrelevant inside of a chroot
|
||||
if [ ! -r /proc/mounts ] || ischroot; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1004
|
||||
boot_opts=$(awk '/boot/{if ((match($4, /^ro/) || match($4, /,ro/)) \
|
||||
&& $2 == "/boot") print "ro"}' /proc/mounts)
|
||||
if [ -n "${boot_opts}" ]; then
|
||||
echo "W: /boot is ro mounted." >&2
|
||||
echo "W: update-initramfs: Not updating ${initramfs}" >&2
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
get_sorted_versions()
|
||||
{
|
||||
version_list="$(
|
||||
linux-version list |
|
||||
while read -r version; do
|
||||
test -e "${BOOTDIR}/initrd.img-$version" && echo "$version"
|
||||
done |
|
||||
linux-version sort --reverse
|
||||
)"
|
||||
verbose "Available versions: ${version_list}"
|
||||
}
|
||||
|
||||
set_current_version()
|
||||
{
|
||||
if [ -f "/boot/initrd.img-$(uname -r)" ]; then
|
||||
version=$(uname -r)
|
||||
fi
|
||||
}
|
||||
|
||||
set_linked_version()
|
||||
{
|
||||
linktarget=
|
||||
if [ -e /initrd.img ] && [ -L /initrd.img ]; then
|
||||
linktarget="$(basename "$(readlink /initrd.img)")"
|
||||
fi
|
||||
|
||||
if [ -e /boot/initrd.img ] && [ -L /boot/initrd.img ]; then
|
||||
linktarget="$(basename "$(readlink /boot/initrd.img)")"
|
||||
fi
|
||||
|
||||
if [ -z "${linktarget}" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
version="${linktarget##initrd.img-}"
|
||||
}
|
||||
|
||||
set_highest_version()
|
||||
{
|
||||
get_sorted_versions
|
||||
if [ -z "${version_list}" ]; then
|
||||
version=
|
||||
return
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
set -- ${version_list}
|
||||
version=${1}
|
||||
}
|
||||
|
||||
create()
|
||||
{
|
||||
if [ -z "${version}" ]; then
|
||||
usage_error "Create mode requires a version argument"
|
||||
fi
|
||||
|
||||
set_initramfs
|
||||
|
||||
generate_initramfs
|
||||
|
||||
run_bootloader
|
||||
}
|
||||
|
||||
update()
|
||||
{
|
||||
if [ "${update_initramfs}" = "no" ]; then
|
||||
echo "update-initramfs: Not updating initramfs."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "${version}" ]; then
|
||||
set_highest_version
|
||||
fi
|
||||
|
||||
if [ -z "${version}" ]; then
|
||||
set_linked_version
|
||||
fi
|
||||
|
||||
if [ -z "${version}" ]; then
|
||||
set_current_version
|
||||
fi
|
||||
|
||||
if [ -z "${version}" ]; then
|
||||
verbose "Nothing to do, exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set_initramfs
|
||||
|
||||
ro_boot_check
|
||||
|
||||
backup_initramfs
|
||||
|
||||
generate_initramfs
|
||||
|
||||
run_bootloader
|
||||
|
||||
backup_booted_initramfs
|
||||
}
|
||||
|
||||
delete()
|
||||
{
|
||||
if [ -z "${version}" ]; then
|
||||
usage_error "Delete mode requires a version argument"
|
||||
fi
|
||||
|
||||
set_initramfs
|
||||
|
||||
echo "update-initramfs: Deleting ${initramfs}"
|
||||
|
||||
delete_sha1
|
||||
|
||||
rm -f "${initramfs}" "${initramfs}.bak"
|
||||
}
|
||||
|
||||
# Defaults
|
||||
verbose=0
|
||||
|
||||
##
|
||||
|
||||
OPTIONS=$(getopt -o "k:cudvtb:h?" --long help -n "$0" -- "$@") || usage_error
|
||||
|
||||
eval set -- "$OPTIONS"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-k)
|
||||
version="$2"
|
||||
shift 2
|
||||
;;
|
||||
-c)
|
||||
mode="c"
|
||||
shift
|
||||
;;
|
||||
-d)
|
||||
mode="d"
|
||||
shift
|
||||
;;
|
||||
-u)
|
||||
mode="u"
|
||||
shift
|
||||
;;
|
||||
-v)
|
||||
verbose="1"
|
||||
shift
|
||||
;;
|
||||
-t)
|
||||
# accepted for compatibility, but ignored
|
||||
shift
|
||||
;;
|
||||
-b)
|
||||
BOOTDIR="$2"
|
||||
if [ ! -d "${BOOTDIR}" ]; then
|
||||
echo "E: ${BOOTDIR} is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
-h|-\?|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $# -ne 0 ]; then
|
||||
printf "Extra argument '%s'\\n\\n" "$1" >&2
|
||||
usage_error
|
||||
fi
|
||||
|
||||
# Validate arguments
|
||||
if [ -z "${mode}" ]; then
|
||||
usage_error "You must specify at least one of -c, -u, or -d."
|
||||
fi
|
||||
|
||||
if [ "${version}" = "all" ] \
|
||||
|| { [ "${update_initramfs}" = "all" ] && [ -z "${version}" ]; }; then
|
||||
case "${mode}" in
|
||||
c)
|
||||
version_list="$(linux-version list)"
|
||||
;;
|
||||
d | u)
|
||||
get_sorted_versions
|
||||
;;
|
||||
esac
|
||||
if [ -z "${version_list}" ]; then
|
||||
verbose "Nothing to do, exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
OPTS="-b ${BOOTDIR}"
|
||||
if [ "${verbose}" = "1" ]; then
|
||||
OPTS="${OPTS} -v"
|
||||
fi
|
||||
for u_version in ${version_list}; do
|
||||
verbose "Execute: ${0} -${mode} -k \"${u_version}\" ${OPTS}"
|
||||
# shellcheck disable=SC2086
|
||||
"${0}" -${mode} -k "${u_version}" ${OPTS}
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
case "${mode}" in
|
||||
c)
|
||||
create
|
||||
;;
|
||||
d)
|
||||
delete
|
||||
;;
|
||||
u)
|
||||
update
|
||||
;;
|
||||
esac
|
|
@ -0,0 +1,95 @@
|
|||
.TH UPDATE-INITRAMFS 8 "2014/10/16" "initramfs\-tools" "System Administration"
|
||||
|
||||
.SH NAME
|
||||
update\-initramfs \- generate an initramfs image
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B update\-initramfs
|
||||
.RB { \-c | \-d | \-u }
|
||||
.RB [ \-k
|
||||
.IR version ]
|
||||
.RB [ \-v ]
|
||||
.RB [ \-b
|
||||
.IR directory ]
|
||||
.br
|
||||
.BR update\-initramfs " " \-h
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B update\-initramfs
|
||||
script manages your initramfs images on your local box.
|
||||
It keeps track of the existing initramfs archives in /boot.
|
||||
There are three modes of operation create, update or delete.
|
||||
You must at least specify one of those modes.
|
||||
|
||||
The initramfs is a gzipped cpio archive.
|
||||
At boot time, the kernel unpacks that archive into RAM disk, mounts and
|
||||
uses it as initial root file system. All finding of the root device
|
||||
happens in this early userspace.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-k \fI version
|
||||
Set the specific kernel version for whom the initramfs will be generated.
|
||||
For example the output of uname \-r for your currently running kernel.
|
||||
This argument is optional for update. The default is the latest kernel version.
|
||||
|
||||
The use of "all" for the
|
||||
.I version
|
||||
string specifies that
|
||||
.B update\-initramfs
|
||||
should operate on all installed kernel versions (with \fB\-c\fR), or
|
||||
on all installed kernel versions that already have an initramfs
|
||||
(with \fB\-d\fR or \fB\-u\fR).
|
||||
|
||||
.TP
|
||||
\fB\-c
|
||||
This mode creates a new initramfs.
|
||||
|
||||
.TP
|
||||
\fB\-u
|
||||
This mode updates an existing initramfs.
|
||||
|
||||
.TP
|
||||
\fB\-d
|
||||
This mode deletes an existing initramfs.
|
||||
|
||||
.TP
|
||||
\fB\-v
|
||||
This option increases the amount of information you are given during
|
||||
the chosen action.
|
||||
|
||||
.TP
|
||||
\fB\-b \fI directory
|
||||
Set an different bootdir for the image creation.
|
||||
|
||||
.TP
|
||||
\fB\-h\fR, \fB--help\fR
|
||||
Print a short help page describing the available options in
|
||||
.B update\-initramfs.
|
||||
|
||||
.SH EXAMPLES
|
||||
|
||||
Update the initramfs of the newest kernel:
|
||||
|
||||
.PP
|
||||
.B update\-initramfs -u
|
||||
|
||||
|
||||
Create the initramfs for a specific kernel:
|
||||
|
||||
.PP
|
||||
.B update\-initramfs -c -k 2.6.18-1-686
|
||||
|
||||
.SH FILES
|
||||
/etc/initramfs-tools/update-initramfs.conf
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>,
|
||||
Jeff Bailey <jbailey@raspberryginger.com> and numerous others.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR
|
||||
.IR initramfs.conf (5),
|
||||
.IR initramfs-tools (7),
|
||||
.IR mkinitramfs (8),
|
||||
.IR lsinitramfs (8).
|
|
@ -0,0 +1,35 @@
|
|||
.TH UPDATE-INITRAMFS.CONF 5 "2010/04/05" "initramfs\-tools" "File Formats Manual"
|
||||
|
||||
.SH NAME
|
||||
update-initramfs.conf \- configuration file for update-initramfs
|
||||
|
||||
.SH DESCRIPTION
|
||||
The configuration file allows one to disable the update action from
|
||||
.B update-initramfs.
|
||||
|
||||
.SH GENERAL VARIABLES
|
||||
.TP
|
||||
\fB update_initramfs
|
||||
Default is \fIyes\fP for running the latest initramfs-tools hooks in the
|
||||
newest Linux image.
|
||||
Setting it to \fIall\fP updates any known initramfs.
|
||||
It is possible to set it to \fIno\fP for remote servers or boxes where
|
||||
conservative manners needs to be applied. This disables
|
||||
the \fBupdate_initramfs \-u\fP call.
|
||||
.TP
|
||||
\fB backup_initramfs
|
||||
If set \fBupdate_initramfs\fP keeps an .bak file of the previous initramfs. If unset the backup initramfs will not be kept.
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.I /etc/initramfs-tools/update-initramfs.conf
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>,
|
||||
Jeff Bailey <jbailey@raspberryginger.com> and numerous others.
|
||||
.SH SEE ALSO
|
||||
.BR
|
||||
.IR initramfs.conf (5),
|
||||
.IR initramfs-tools (7),
|
||||
.IR mkinitramfs (8),
|
||||
.IR update-initramfs (8).
|
Loading…
Reference in New Issue