init openkylin 2.0 initramfs-tools code

This commit is contained in:
liushanwen 2023-10-13 16:57:07 +08:00
parent fbdd05274f
commit fefe9157ab
50 changed files with 1587 additions and 1217 deletions

View File

@ -35,6 +35,19 @@ BUSYBOX=auto
COMPRESS=zstd
#
# COMPRESSLEVEL: ...
#
# Set a compression level for the compressor.
# Defaults vary by compressor.
#
# Valid values are:
# 1 - 9 for gzip|bzip2|lzma|lzop
# 0 - 9 for lz4|xz
# 0 - 19 for zstd
#
# COMPRESSLEVEL=1
#
# DEVICE: ...
#

37
debian/changelog vendored
View File

@ -1,37 +1,6 @@
initramfs-tools (0.140kylin18k0.2) yangtze; urgency=medium
initramfs-tools (0.142kylin13.0.1) yangtze; urgency=medium
* rebuild
* rebuild initramfs-tools latest community version
-- liushanwen <liushanwen@kylinos.cn> Thu, 20 Apr 2023 17:39:33 +0800
initramfs-tools (0.140kylin18k0.1) yangtze; urgency=medium
* fix openkylin control file git address
-- liushanwen <liushanwen@kylinos.cn> Thu, 20 Apr 2023 17:39:33 +0800
initramfs-tools (0.140kylin18k0.0) yangtze; urgency=medium
* build initramfs-tools 140 version
-- liushanwen <liushanwen@kylinos.cn> Thu, 20 Apr 2023 17:23:19 +0800
initramfs-tools (0.136-ok3) yangtze; urgency=medium
* update version info
-- luzhiping <luzhiping@kylinos.cn> Mon, 22 Aug 2022 13:59:26 +0800
initramfs-tools (0.136-ok2) yangtze; urgency=medium
* debian/rules:
fix openkylin vendor
-- Luoyaoming <luoyaoming@kylinos.cn> Fri, 03 Jun 2022 15:31:23 +0800
initramfs-tools (0.136-ok1) yangtze; urgency=medium
* Build for openKylin.
-- openKylinBot <openKylinBot@openkylin.com> Mon, 25 Apr 2022 22:03:04 +0800
-- liushanwen <liushanwen@kylinos.cn> Thu, 12 Oct 2023 14:53:54 +0800

11
debian/control vendored
View File

@ -2,13 +2,13 @@ Source: initramfs-tools
Section: utils
Priority: optional
Uploaders: Michael Prokop <mika@debian.org>, Ben Hutchings <benh@debian.org>
Maintainer: Openkylin Developers <packaging@lists.openkylin.top>
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
XSBC-Original-Maintainer: Debian kernel team <debian-kernel@lists.debian.org>
Build-Depends: debhelper-compat (= 12), bash-completion, shellcheck [!i386] <!nocheck>, pkg-config, libudev-dev, netplan.io [!i386] <!nocheck>
Build-Depends: debhelper-compat (= 12), bash-completion, pkg-config, libudev-dev, netplan.io [!i386] <!nocheck>, shellcheck [!i386] <!nocheck>
Rules-Requires-Root: no
Standards-Version: 4.1.5
Vcs-Browser: https://gitee.com/openkylin/initramfs-tools.git
Vcs-Git: https://gitee.com/openkylin/initramfs-tools.git
Vcs-Browser: https://code.launchpad.net/~ubuntu-core-dev/ubuntu/+source/initramfs-tools/+git/initramfs-tools
Vcs-Git: https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/initramfs-tools
X-Debian-Vcs-Browser: https://salsa.debian.org/kernel-team/initramfs-tools
X-Debian-Vcs-Git: https://salsa.debian.org/kernel-team/initramfs-tools.git
@ -28,7 +28,8 @@ Description: generic modular initramfs generator (automation)
Package: initramfs-tools-core
Architecture: all
Multi-Arch: foreign
Depends: ${busybox:Depends}, initramfs-tools-bin (= ${binary:Version}), klibc-utils (>= 2.0.4-8~), cpio (>= 2.12), zstd, kmod, udev, coreutils (>= 8.24), logsave | e2fsprogs (<< 1.45.3-1~), ${misc:Depends}
Recommends: zstd
Depends: ${busybox:Depends}, dhcpcd-base, dracut-install, initramfs-tools-bin (= ${binary:Version}), klibc-utils (>= 2.0.4-8~), cpio (>= 2.12), kmod, udev, coreutils (>= 8.24), logsave | e2fsprogs (<< 1.45.3-1~), ${misc:Depends}
Suggests: bash-completion
Breaks: initramfs-tools (<< 0.121~), ${busybox:Breaks}
Replaces: initramfs-tools (<< 0.121~)

1
debian/files vendored Normal file
View File

@ -0,0 +1 @@
initramfs-tools_0.142kylin13.0.1_source.buildinfo utils optional

View File

@ -6,3 +6,4 @@ conf/initramfs.conf etc/initramfs-tools
hooks usr/share/initramfs-tools
hook-functions usr/share/initramfs-tools
conf/modules usr/share/initramfs-tools
dhcpcd-hooks usr/share/initramfs-tools

View File

@ -1,3 +1,3 @@
initramfs-tools-core: package-contains-empty-directory usr/share/initramfs-tools/conf.d/
initramfs-tools-core: package-contains-empty-directory usr/share/initramfs-tools/conf-hooks.d/
initramfs-tools-core: package-contains-empty-directory usr/share/initramfs-tools/modules.d/
initramfs-tools-core: package-contains-empty-directory [usr/share/initramfs-tools/conf.d/]
initramfs-tools-core: package-contains-empty-directory [usr/share/initramfs-tools/conf-hooks.d/]
initramfs-tools-core: package-contains-empty-directory [usr/share/initramfs-tools/modules.d/]

10
debian/rules vendored
View File

@ -5,8 +5,8 @@
# On Debian we can use either busybox or busybox-static, but on Ubuntu
# and derivatives only busybox-initramfs will work.
BUSYBOX_PACKAGES := $(shell if dpkg-vendor --derives-from openkylin; then echo busybox-initramfs; else echo busybox busybox-static; fi)
BUSYBOX_MIN_VERSION := 1:1.30.1-4ok5~
BUSYBOX_PACKAGES := $(shell if dpkg-vendor --derives-from ubuntu; then echo busybox-initramfs; else echo busybox busybox-static; fi)
BUSYBOX_MIN_VERSION := 1:1.30.1-4ubuntu5~
override_dh_gencontrol:
echo >> debian/initramfs-tools-core.substvars "busybox:Breaks=$(wordlist 2,100,$(BUSYBOX_PACKAGES:%=, % (<< $(BUSYBOX_MIN_VERSION))))"
@ -42,8 +42,8 @@ DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
override_dh_auto_test:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
ifeq (,$(filter i386,$(DEB_HOST_ARCH)))
shellcheck -e SC1010,SC1090,SC1091,SC2015 -s dash hook-functions $$(find hooks scripts -type f) $$({ find . -maxdepth 1 -type f -executable; find debian -maxdepth 1 -type f; find docs kernel -type f; } | xargs grep -l '^#!/bin/sh')
endif
ifeq (,$(filter i386,$(DEB_HOST_ARCH)))
shellcheck -e SC1090,SC1091 -s dash hook-functions $$(find hooks scripts -type f) $$({ find . -maxdepth 1 -type f -executable; find debian -maxdepth 1 -type f; find docs kernel -type f; } | xargs grep -l '^#!/bin/sh')
endif
./tests/run-tests
endif

18
debian/salsa-ci.yml vendored
View File

@ -4,3 +4,21 @@ include:
variables:
RELEASE: 'unstable'
# We only build arch:all packages
SALSA_CI_DISABLE_BLHC: 'true'
SALSA_CI_DISABLE_BUILD_PACKAGE_I386: 'true'
SALSA_CI_DISABLE_BUILD_PACKAGE_ANY: 'true'
SALSA_CI_DISABLE_CROSSBUILD_ARM64: 'true'
shellcheck:
stage: test
image: $SALSA_CI_IMAGES_BASE
except:
variables:
- $CI_COMMIT_TAG != null
script:
- apt-get update
- apt-get install -y shellcheck
- |
shellcheck -e SC1090,SC1091 -s dash hook-functions $(find hooks scripts -type f) $({ find . -maxdepth 1 -type f -executable; find debian -maxdepth 1 -type f; find docs kernel -type f; } | xargs grep -l '^#!/bin/sh')
needs: []

267
debian/tests/check-log vendored Executable file
View File

@ -0,0 +1,267 @@
#!/usr/bin/python3
# pylint: disable=invalid-name
# pylint: enable=invalid-name
"""Run given checks on the log output."""
import argparse
import json
import pathlib
import re
import shlex
import subprocess
import sys
import typing
class Check:
"""The Check class contains all the checks that the caller can run."""
def __init__(self, log: str) -> None:
self.errors = 0
self.command_outputs = self._extract_command_outputs_from_log(log)
def _error(self, msg: str) -> None:
print("ERROR: " + msg)
self.errors += 1
@staticmethod
def _extract_command_outputs_from_log(log: str) -> dict[str, str]:
"""Extract command outputs from the given log output.
The output must be framed by a header and a footer line. The header
line contains the key surrounded by 10 # characters. The footer
line consist of 40 # characters. Returns a mapping from the output
key to the command output.
"""
marker = "#" * 10
footer = "#" * 40
matches = re.findall(
f"^{marker} ([^#]+) {marker}\n(.*?\n){footer}$",
log,
flags=re.DOTALL | re.MULTILINE,
)
return {m[0]: m[1] for m in matches}
def get_commands_from_ps_output(self) -> list[str]:
"""Get list of command from `ps -ww aux` output."""
ps_output = self.command_outputs["ps -ww aux"]
lines = ps_output.strip().split("\n")[1:]
commands = []
for line in lines:
columns = re.split(r"\s+", line, maxsplit=10)
commands.append(columns[10])
return commands
def get_ip_addr(self) -> list[typing.Any]:
"""Get IP address information from `ip addr` JSON output."""
ip_addr = json.loads(self.command_outputs["ip -json addr"])
assert isinstance(ip_addr, list)
return ip_addr
def get_ip_route(self) -> list[typing.Any]:
"""Get IP route information from `ip route` JSON output."""
ip_route = json.loads(self.command_outputs["ip -json route"])
assert isinstance(ip_route, list)
return ip_route
def run_checks(self, args: list[str]) -> int:
"""Run the checks and return the number of errors found.
The methods of this class can be u
"""
if not args:
return self.errors
try:
check = getattr(self, args[0])
except AttributeError:
self._error(f"Check '{args[0]}' not found.")
return self.errors
check_args = []
for arg in args[1:]:
if not hasattr(self, arg):
check_args.append(arg)
continue
check(*check_args)
check = getattr(self, arg)
check_args = []
check(*check_args)
return self.errors
def _check_is_subset(self, expected: set[str], actual: set[str]) -> None:
"""Check that the first dictionary is a subset of the second one.
Log errors if the sets are different.
"""
unexpected = actual - expected
if unexpected:
self._error(f"Not expected entries: {unexpected}")
def _check_is_subdict(
self,
expected_dict: dict[str, str],
actual_dict: dict[str, str],
log_prefix: str,
) -> None:
"""Check that the first dictionary is a subset of the second one.
Log errors if differences are found.
"""
missing_keys = set(expected_dict.keys()) - set(actual_dict.keys())
if missing_keys:
self._error(f"{log_prefix}Missing keys: {missing_keys}")
for key, expected_value in sorted(expected_dict.items()):
actual_value = actual_dict.get(key, "")
if expected_value != actual_value:
self._error(
f"{log_prefix}Value for key '{key}' differs:"
f" '{expected_value}' expected, but got '{actual_value}'"
)
# Below are all checks that the user might call.
def has_hostname(self, hostname_pattern: str) -> None:
"""Check that the hostname matches the given regular expression."""
hostname = self.command_outputs["hostname"].strip()
if re.fullmatch(hostname_pattern, hostname):
print(f"hostname '{hostname}' matches pattern '{hostname_pattern}'")
return
self._error(
f"hostname '{hostname}' does not match"
f" expected pattern '{hostname_pattern}'"
)
def has_ip_addr(self, family: str, addr_pattern: str, device_pattern: str) -> None:
"""Check that a matching network device has a matching IP address."""
for device in self.get_ip_addr():
if not re.fullmatch(device_pattern, device["ifname"]):
continue
for addr in device["addr_info"]:
if addr["family"] != family or addr["scope"] != "global":
continue
address = f"{addr['local']}/{addr['prefixlen']}"
if re.fullmatch(addr_pattern, address):
print(f"found addr {address} for {device['ifname']}: {addr}")
return
self._error(
f"addr {address} for {device['ifname']}"
f" does not match {addr_pattern}: {addr}"
)
return
name = {"inet": "IPv4", "inet6": "IPv6"}[family]
self._error(
f"no link found that matches '{device_pattern}' and has an {name} address"
)
def has_ipv4_addr(self, addr_pattern: str, device_pattern: str) -> None:
"""Check that a matching network device has a matching IPv4 address."""
self.has_ip_addr("inet", addr_pattern, device_pattern)
def has_ipv6_addr(self, addr_pattern: str, device_pattern: str) -> None:
"""Check that a matching network device has a matching IPv6 address."""
self.has_ip_addr("inet6", addr_pattern, device_pattern)
def has_ipv4_default_route(self, gateway_pattern: str, device_pattern: str) -> None:
"""Check that the IPv4 default route is via a matching gateway and device."""
for route in self.get_ip_route():
if route["dst"] != "default":
continue
if not re.fullmatch(gateway_pattern, route["gateway"]) or not re.fullmatch(
device_pattern, route["dev"]
):
self._error(
f"Default IPv4 route does not match expected gateway pattern"
f" '{gateway_pattern}' or dev pattern '{device_pattern}': {route}"
)
continue
print(
f"found IPv4 default route via {route['gateway']}"
f" for {route['dev']}: {route}"
)
return
self._error("no IPv4 default route found")
def has_net_conf(self, min_expected_files: str, *expected_net_confs: str) -> None:
"""Compare the /run/net*.conf files.
There must be at least one /run/net*.conf file in the log output and no
unexpected one. The format is `<file name>=<expected content>`.
"""
expected = dict(nc.split("=", maxsplit=1) for nc in expected_net_confs)
prog = re.compile(r"/run/net[^#]+\.conf")
got = {
key: value for key, value in self.command_outputs.items() if prog.match(key)
}
if len(got) < int(min_expected_files):
self._error(
f"Expected at least {min_expected_files} /run/net*.conf files,"
f" but got only {len(got)}: {set(got.keys())}"
)
self._check_is_subset(set(expected.keys()), set(got.keys()))
for net_dev in sorted(got.keys()):
log_prefix = f"{net_dev}: "
expected_net_conf = parse_net_conf(expected.get(net_dev, ""))
actual_net_conf = parse_net_conf(got.get(net_dev, ""))
self._check_is_subdict(expected_net_conf, actual_net_conf, log_prefix)
print(f"compared {len(expected_net_conf)} items from {net_dev}")
def has_no_running_processes(self) -> None:
"""Check that there are no remaining running processes from the initrd."""
processes = drop_kernel_processes(self.get_commands_from_ps_output())
udevd = "/lib/systemd/systemd-udevd --daemon --resolve-names=never"
if udevd in processes and get_architecture() != "amd64":
print(
"Warning: Ignoring running /lib/systemd/systemd-udevd processes."
" See https://launchpad.net/bugs/2025369"
)
processes = [p for p in processes if p != udevd]
if len(processes) == 2:
print(f"found only expected init and ps process: {processes}")
return
self._error(
f"Expected only init and ps process, but got {len(processes)}: {processes}"
)
def drop_kernel_processes(processes: list[str]) -> list[str]:
"""Return a list of processes with the kernel processes dropped."""
return [p for p in processes if not p.startswith("[") and not p.endswith("]")]
def get_architecture() -> str:
"""Return architecture of packages dpkg installs."""
cmd = ["dpkg", "--print-architecture"]
process = subprocess.run(cmd, capture_output=True, check=True, text=True)
return process.stdout.strip()
def parse_net_conf(net_conf: str) -> dict[str, str]:
"""Parse /run/net*.conf file and return a key to value mapping."""
items = shlex.split(net_conf)
return dict(item.split("=", maxsplit=1) for item in items)
def main(arguments: list[str]) -> int:
"""Run given checks on the log output. Return number of errors."""
parser = argparse.ArgumentParser()
parser.add_argument("log_file", metavar="log-file")
parser.add_argument("checks", metavar="check", nargs="+")
args = parser.parse_args(arguments)
log = pathlib.Path(args.log_file).read_text(encoding="ascii")
check = Check(log)
return check.run_checks(args.checks)
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))

View File

@ -1,86 +0,0 @@
#!/usr/bin/python3
import json
import os
import sys
in_error = False
def error(msg):
print("ERROR: " + msg)
global in_error
in_error = True
def has_link(name):
for l in links:
if l['ifname'] == name:
return
error("link {} not found".format(name))
def has_an_ipv4_addr(name):
for l in addrs:
if l['ifname'] == name:
for addr in l['addr_info']:
if addr['family'] == 'inet' and addr['scope'] == 'global':
print("found addr {} for {}".format(addr, name))
return
error("{} appears to have no addresses".format(name))
return
error("link {} not found".format(name))
def has_no_ipv4_addr(name):
for l in addrs:
if l['ifname'] == name:
for addr in l['addr_info']:
if addr['family'] == 'inet' and addr['scope'] == 'global':
error("found addr {} for {}".format(addr, name))
return
print("{} appears to have no addresses".format(name))
return
error("link {} not found".format(name))
def has_ipv4_addr(name, wanted_addr):
for l in addrs:
if l['ifname'] == name:
for addr in l['addr_info']:
if addr['family'] == 'inet' and addr['scope'] == 'global':
if addr['local'] == wanted_addr:
print("found addr {} for {}".format(addr, name))
return
error("{} appears not to have address {}".format(name, wanted_addr))
return
error("link {} not found".format(name))
result_dir = sys.argv[1]
with open(os.path.join(result_dir, 'link.json')) as fp:
links = json.load(fp)
with open(os.path.join(result_dir, 'addr.json')) as fp:
addrs = json.load(fp)
with open(os.path.join(result_dir, 'ps.txt'), encoding='utf-8', errors='replace') as fp:
ps_output = fp.read()
if 'dhclient' in ps_output:
error("dhclient appears to be running")
i = 2
while i < len(sys.argv):
a = sys.argv[i]
i += 1
if a == 'has_link':
has_link(sys.argv[i])
i += 1
elif a == 'has_an_ipv4_addr':
has_an_ipv4_addr(sys.argv[i])
i += 1
elif a == 'has_no_ipv4_addr':
has_no_ipv4_addr(sys.argv[i])
i += 1
elif a == 'has_ipv4_addr':
has_ipv4_addr(sys.argv[i], sys.argv[i+1])
i += 2
else:
error("unknown check {}".format(a))
if in_error:
sys.exit(1)

112
debian/tests/control vendored
View File

@ -1,42 +1,82 @@
Tests: shellcheck
Depends: @, shellcheck
Restrictions: superficial
Tests: amd64-klibc
Depends: @, qemu-system-x86, linux-image-amd64 | linux-image-generic:amd64, klibc-utils, genext2fs
Restrictions: skip-not-installable, needs-root
Tests: amd64-busybox
Depends: @, qemu-system-x86, linux-image-amd64 | linux-image-generic:amd64, klibc-utils, busybox | busybox-initramfs, genext2fs
Restrictions: skip-not-installable, needs-root
Tests: amd64-ata-only
Depends: @, qemu-system-x86, linux-image-amd64 | linux-image-generic:amd64, klibc-utils, genext2fs
Restrictions: skip-not-installable, needs-root
Tests: amd64-virtio-only
Depends: @, qemu-system-x86, linux-image-amd64 | linux-image-generic:amd64, klibc-utils, genext2fs
Restrictions: skip-not-installable, needs-root
Tests: amd64-separate-usr
Depends: @, qemu-system-x86, linux-image-amd64 | linux-image-generic:amd64, klibc-utils, genext2fs
Restrictions: skip-not-installable, needs-root
Tests: amd64-panic-shell
Depends: @, qemu-system-x86, linux-image-amd64 | linux-image-generic:amd64, klibc-utils, genext2fs
Restrictions: skip-not-installable, needs-root
Test-Command: ./tests/run-tests
Depends: netplan.io
Restrictions: allow-stderr
Features: test-name=unit-tests
Tests: net
Depends: curl,
initramfs-tools,
isc-dhcp-client,
# Note: These tests need root on Ubuntu, because the kernel is only readable by root. See https://launchpad.net/bugs/759725
Tests: qemu-klibc
Architecture: amd64 armhf s390x
Depends: genext2fs,
ipxe-qemu,
klibc-utils,
linux-image-generic,
lsb-release,
parted,
qemu-efi-arm [armhf],
qemu-kvm,
zstd,
@
Restrictions: needs-root
Tests: qemu-busybox
Architecture: amd64 armhf s390x
Depends: busybox | busybox-initramfs,
genext2fs,
ipxe-qemu,
klibc-utils,
linux-image-generic,
qemu-efi-arm [armhf],
qemu-kvm,
zstd,
@
Restrictions: needs-root
Tests: qemu-ata-only
Architecture: amd64
Depends: genext2fs, klibc-utils, linux-image-generic, qemu-kvm, zstd, @
Restrictions: needs-root
Tests: qemu-virtio-only qemu-separate-usr qemu-panic-shell
Architecture: amd64 arm64 armhf ppc64el s390x
Depends: genext2fs,
ipxe-qemu,
klibc-utils,
linux-image-generic,
qemu-efi-aarch64 [arm64],
qemu-efi-arm [armhf],
qemu-kvm,
seabios [ppc64el],
zstd,
@
Restrictions: needs-root
Tests: qemu-net
Architecture: amd64 arm64 armhf ppc64el s390x
Depends: genext2fs,
iproute2,
ipxe-qemu,
klibc-utils,
linux-image-generic,
procps,
python3,
qemu-system
Restrictions: needs-root, allow-stderr
qemu-efi-aarch64 [arm64],
qemu-efi-arm [armhf],
qemu-kvm,
seabios [ppc64el],
zstd,
@
Restrictions: needs-root
Tests: qemu-net-dnsmasq
Architecture: amd64 armhf s390x
Depends: dnsmasq,
genext2fs,
iproute2,
ipxe-qemu,
klibc-utils,
linux-image-generic,
procps,
python3,
qemu-efi-arm [armhf],
qemu-kvm,
zstd,
@
Restrictions: needs-root

17
debian/tests/hooks/drop-hostname vendored Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
rm -f "${DESTDIR}/etc/hostname"

33
debian/tests/hooks/persistent-net vendored Executable file
View File

@ -0,0 +1,33 @@
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
persist_net() {
name="$1"
mac="$2"
mkdir -p "${DESTDIR}/etc/systemd/network"
cat >"${DESTDIR}/etc/systemd/network/10-persistent-${name}.link" <<EOF
[Match]
MACAddress=${mac}
[Link]
Name=${name}
EOF
}
persist_net lan0 "52:54:00:65:43:21"
persist_net lan1 "52:54:00:12:34:56"
persist_net lan9 "52:54:00:12:33:21"

60
debian/tests/net vendored
View File

@ -1,60 +0,0 @@
#!/bin/bash
set -ux
# Some simple tests of the initramfs network configuration.
# The basic idea is to make an image that has /sbin/init overwritten
# to just gather some data and shutdown again and boot it in qemu
# system emulation (not KVM, so it can be run in the autopkgtest
# architecture without hoping nested kvm works). Currently it only
# sets up qemu user networking which limits our ability to be
# clever. In the long run we should set up a tun and a bridge and
# specify the mac address of the NICs in the emuilated system and run
# dnsmasq on it so we test ipv6 and can control which ips which nics
# get and so on -- but this is still better than nothing.
# Also the current qemu command lines only work on intel. That should
# be fixed too :)
arch=$(dpkg --print-architecture)
[ $arch = amd64 ] || [ $arch = i386 ] || exit 0
./debian/tests/prep-image image.img
ret=$?
if [ $ret -eq 100 ]; then
# This indicates that a rootfs was not found (maybe very early
# in development for this cycle?), skip in this case.
exit 0
elif [ $ret -ne 0 ]; then
exit $ret
fi
set -e
basecmdline="root=UUID=$(cat image.img-uuid) rw console=ttyS0"
mkinitramfs -o myinitrd
nicslot=5
nicname=ens$nicslot
kernel=$(echo /boot/vmlinu*-"$(uname -r)")
run () {
./debian/tests/run-image kernel=$kernel initrd=myinitrd \
image=image.img cmdline="$basecmdline ${1-}" \
output=result nicslot=$nicslot
}
run ""
./debian/tests/check-results result has_no_ipv4_addr $nicname
run "ip=dhcp"
./debian/tests/check-results result has_an_ipv4_addr $nicname
run "ip=:::::$nicname:dhcp"
./debian/tests/check-results result has_an_ipv4_addr $nicname
run "ip=10.0.2.100::10.0.2.2:255.0.0.0::$nicname:"
./debian/tests/check-results result has_ipv4_addr $nicname 10.0.2.100

View File

@ -1,56 +0,0 @@
#!/bin/bash
# prep-image $IMAGE preps an image for the tests. Specifically it:
#
# 1. downloads a cloud image rootfs
# 2. creates an image containing a single partition at $IMAGE,
# 3. writes the UUID of the partition to $IMAGE-uuid,
# 4. extracts the rootfs to the image, and
# 5. overwrites /sbin/init with a script that gathers some data to
# /result and shuts the machine down
set -eux
IMAGE="$1"
series=$(lsb_release -sc)
url=http://cloud-images.ubuntu.com/$series/current/$series-server-cloudimg-$(dpkg --print-architecture)-root.tar.xz
filename=$(basename "$url")
mkdir -p images
if [ ! -f images/"$filename" ]; then
status=$(curl --silent --write-out "%{http_code}\n" --output images/"$filename" "$url")
if [ "$status" = 404 ]; then
exit 100
fi
fi
rm -f "$IMAGE" "${IMAGE}-uuid"
truncate -s 2G "$IMAGE"
parted --script --align optimal "$IMAGE" -- mklabel gpt mkpart primary ext4 1MiB -2048s
dev="$(losetup -Pf --show "$IMAGE")"
partprobe
mke2fs -q "${dev}p1"
blkid --output=value "${dev}p1" | head -n1 > "${IMAGE}-uuid"
mkdir -p mnt
mount "${dev}p1" mnt
tar --xattrs-include=* -C mnt -xf images/"$filename"
rm -f mnt/sbin/init
cat > mnt/sbin/init << \EOF
#!/bin/sh
set -x
rm -rf /result
mkdir /result
# Run twice, once for the logs, once for the test harness
ip addr
ip link
for file in /run/net-*.conf /run/net6-*.conf; do
[ -f $file ] || continue;
cat $file
cp $file /result
done
ip -json addr > /result/addr.json
ip -json link > /result/link.json
ps aux | tee /result/ps.txt
sync
exec /lib/systemd/systemd-shutdown poweroff
EOF
chmod u+x mnt/sbin/init
umount mnt
losetup -d "$dev"

View File

@ -1,5 +1,6 @@
#!/bin/sh -e
# Note: The qemu machines used on arm64, armhf, ppc64el, and s390x have no IDE
SUPPORTED_FLAVOURS='amd64 generic'
ROOTDISK_QEMU_IF=ide
ROOTDISK_LINUX_NAME=sda
@ -19,4 +20,5 @@ build_initramfs
build_rootfs_ext2
run_qemu_amd64
run_qemu
check_no_network_configuration

View File

@ -1,6 +1,7 @@
#!/bin/sh -e
SUPPORTED_FLAVOURS='amd64 generic'
# The qemu machines on arm64 and ppc64el are too slow for MODULES=most.
SUPPORTED_FLAVOURS='amd64 armmp s390x generic'
. debian/tests/test-common
cat >>"${CONFDIR}/initramfs.conf" <<EOF
@ -13,7 +14,8 @@ lsinitramfs "${INITRAMFS}" | grep -qw busybox
build_rootfs_ext2
run_qemu_amd64
run_qemu
check_no_network_configuration
# Check that fsck ran
grep -q "^/dev/${ROOTDISK_LINUX_NAME}: clean," "${OUTPUT}"

View File

@ -1,6 +1,7 @@
#!/bin/sh -e
SUPPORTED_FLAVOURS='amd64 generic'
# The qemu machines on arm64 and ppc64el are too slow for MODULES=most.
SUPPORTED_FLAVOURS='amd64 armmp s390x generic'
. debian/tests/test-common
cat >>"${CONFDIR}/initramfs.conf" <<EOF
@ -13,7 +14,8 @@ build_initramfs
build_rootfs_ext2
run_qemu_amd64
run_qemu
check_no_network_configuration
# Check that fsck ran
grep -q "^/dev/${ROOTDISK_LINUX_NAME}: clean," "${OUTPUT}"

123
debian/tests/qemu-net vendored Executable file
View File

@ -0,0 +1,123 @@
#!/bin/sh
set -eu
# Some simple tests of the initramfs network configuration.
# The basic idea is to make an ext2 root image that only ships a /sbin/init to
# just gather some data and shutdown again and boot it in qemu system
# emulation (not KVM, so it can be run in the autopkgtest architecture without
# hoping nested kvm works). Currently it only sets up qemu user networking
# which limits our ability to be clever. In the long run we should set up a
# tun and a bridge and specify the mac address of the NICs in the emulated
# system and run dnsmasq on it so we test ipv6 and can control which ips which
# nics get and so on -- but this is still better than nothing.
# TODO: Add a test case for classless static routes. This needs support in
# Qemu first. Following patch should be refreshed:
# https://lore.kernel.org/all/20180314190814.22631-1-benjamin.drung@profitbricks.com/
SUPPORTED_FLAVOURS='amd64 arm64 armmp powerpc64 s390x generic'
ROOTDISK_QEMU_IF=virtio
ROOTDISK_LINUX_NAME=vda
. debian/tests/test-common
cat >>"${CONFDIR}/initramfs.conf" <<EOF
MODULES=list
BUSYBOX=n
FSTYPE=ext2
EOF
cat >"${CONFDIR}/modules" <<EOF
ext2
virtio_pci
virtio_blk
virtio_net
EOF
install -m 755 debian/tests/hooks/drop-hostname "${CONFDIR}/hooks/drop-hostname"
install -m 755 debian/tests/hooks/persistent-net "${CONFDIR}/hooks/persistent-net"
build_initramfs
prepare_network_dumping_rootfs
build_rootfs_ext2
EXPECTED_DHCP_LAN0="
DEVICE='lan0'
PROTO='dhcp'
IPV4ADDR='10.0.3.15'
IPV4BROADCAST='10.0.3.255'
IPV4NETMASK='255.255.255.0'
IPV4GATEWAY='10.0.3.2'
IPV4DNS0='10.0.3.3'
HOSTNAME='pizza'
DNSDOMAIN='example.com'
ROOTSERVER='10.0.3.2'
filename='/path/to/bootfile2'
DOMAINSEARCH='test.'
"
EXPECTED_DHCP_LAN1="
DEVICE='lan1'
PROTO='dhcp'
IPV4ADDR='10.0.2.15'
IPV4BROADCAST='10.0.2.255'
IPV4NETMASK='255.255.255.0'
IPV4GATEWAY='10.0.2.2'
IPV4DNS0='10.0.2.3'
HOSTNAME='goulash'
DNSDOMAIN='test'
ROOTSERVER='10.0.2.2'
filename='/path/to/bootfile'
DOMAINSEARCH='example. example.net.'
"
run_qemu "ip=dhcp"
check_output "Begin: Waiting up to 180 secs for any network device to become available"
./debian/tests/check-log "${OUTPUT}" has_no_running_processes \
has_hostname "goulash|pizza" \
has_ipv4_addr "10\.0\.[23]\.15/24" "lan[01]" \
has_ipv4_default_route "10\.0\.[23]\.2" "lan[01]" \
has_net_conf 1 "/run/net-lan0.conf=${EXPECTED_DHCP_LAN0}" "/run/net-lan1.conf=${EXPECTED_DHCP_LAN1}"
# Test _set_netdev_from_ip_param
run_qemu "ip=:::::lan1:dhcp"
check_output "Begin: Waiting up to 180 secs for lan1 to become available"
./debian/tests/check-log "${OUTPUT}" has_no_running_processes \
has_hostname "goulash" \
has_ipv4_addr "10\.0\.2\.15/24" "lan1" \
has_ipv4_default_route "10\.0\.2\.2" "lan1" \
has_net_conf 1 "/run/net-lan1.conf=${EXPECTED_DHCP_LAN1}"
# Test setting the IP address manually
run_qemu "ip=10.0.2.100::10.0.2.2:255.0.0.0:lasagne:lan1:"
check_output "Begin: Waiting up to 180 secs for lan1 to become available"
./debian/tests/check-log "${OUTPUT}" has_no_running_processes \
has_hostname "lasagne" \
has_ipv4_addr "10\.0\.2\.100/8" "lan1" \
has_ipv4_default_route "10\.0\.2\.2" "lan1" \
has_net_conf 1 "/run/net-lan1.conf=DEVICE='lan1'
PROTO='none'
IPV4ADDR='10.0.2.100'
IPV4BROADCAST='10.255.255.255'
IPV4NETMASK='255.0.0.0'
IPV4GATEWAY='10.0.2.2'
IPV4DNS0='0.0.0.0'
HOSTNAME='lasagne'
DNSDOMAIN=''
ROOTSERVER='0.0.0.0'
filename=''
DOMAINSEARCH=''"
# Test DHCP configuration with BOOTIF specified
run_qemu "BOOTIF=01-52-54-00-12-34-56 ip=dhcp"
check_output "Begin: Waiting up to 180 secs for device with address 52:54:00:12:34:56 to become available"
./debian/tests/check-log "${OUTPUT}" has_no_running_processes \
has_hostname "goulash" \
has_ipv4_addr "10\.0\.2\.15/24" "lan1" \
has_ipv4_default_route "10\.0\.2\.2" "lan1" \
has_net_conf 1 "/run/net-lan1.conf=${EXPECTED_DHCP_LAN1}"
run_qemu "ip=on"
check_output "Begin: Waiting up to 180 secs for any network device to become available"
./debian/tests/check-log "${OUTPUT}" has_no_running_processes \
has_hostname "goulash|pizza" \
has_ipv4_addr "10\.0\.[23]\.15/24" "lan[01]" \
has_ipv4_default_route "10\.0\.[23]\.2" "lan[01]" \
has_net_conf 1 "/run/net-lan0.conf=${EXPECTED_DHCP_LAN0}" "/run/net-lan1.conf=${EXPECTED_DHCP_LAN1}"

184
debian/tests/qemu-net-dnsmasq vendored Executable file
View File

@ -0,0 +1,184 @@
#!/bin/sh
set -eu
# Test the initramfs network configuration with a dnsmasq server.
#
# The qemu-net autopkgtest uses QEMU user networking that is limited. To test
# more cases use dnsmasq as DHCP server. To avoid needing root permission
# or a special setup on the host, use QEMU socket network. One qemu process
# runs dnsmasq on a listening socket and the test qemu process connects to it.
# The qemu machines on arm64 and ppc64el are too slow and the network setup runs into a timeout.
SUPPORTED_FLAVOURS='amd64 armmp s390x generic'
ROOTDISK_QEMU_IF=virtio
ROOTDISK_LINUX_NAME=vda
. debian/tests/test-common
DNSMASQ_QEMU_LOG="${BASEDIR}/dnsmasq.log"
DNSMASQ_QEMU_PID="${BASEDIR}/dnsmasq.pid"
build_dnsmasq_rootfs_ext2() {
local root_disk="$1"
local root_dir="${BASEDIR}/dnsmasq-rootdir"
for subdir in etc dev proc run sys usr usr/bin usr/lib/modules usr/lib64 usr/sbin tmp; do
mkdir -p "${root_dir}/${subdir}"
done
for subdir in bin lib lib64 sbin; do
ln -s "usr/${subdir}" "${root_dir}/${subdir}"
done
echo "root:x:0:0:root:/root:/bin/sh" > "${root_dir}/etc/passwd"
echo "root:x:0:" > "${root_dir}/etc/group"
cat >"${root_dir}/sbin/init" <<EOF
#!/bin/sh
set -eu
echo "I: Executing /sbin/init from root fs"
trap poweroff INT TERM EXIT
ip link set up dev lan9
ip addr add 10.0.7.1/24 dev lan9
ip addr add fc07::1/64 dev lan9
echo "I: ip addr"
ip addr
echo "I: ip route"
ip route
echo "I: ip -6 route"
ip -6 route
mount -t tmpfs tmpfs /tmp
dnsmasq --log-debug
EOF
cat >"${root_dir}/etc/dnsmasq.conf" <<EOF
dhcp-leasefile=/tmp/dnsmasq.leases
keep-in-foreground
log-facility=-
no-hosts
no-resolv
user=root
group=root
pid-file=
enable-ra
dhcp-range=10.0.7.100,10.0.7.150
dhcp-range=fc07::a0,fc07::ef
domain=test
dhcp-option=option6:domain-search,example.com,example
# lan0
dhcp-host=52:54:00:65:43:21,10.0.7.30
dhcp-host=id:00:03:00:01:52:54:00:65:43:21,[fc07::beef],pizza
EOF
chmod a+x "${root_dir}/sbin/init"
. /usr/share/initramfs-tools/hook-functions
verbose=y
DESTDIR="$root_dir"
copy_exec /usr/lib/initramfs-tools/bin/busybox /bin/busybox
ln -s busybox "${root_dir}/bin/sh"
copy_exec /sbin/dnsmasq
build_fs_ext2 "${root_dir}" "${root_disk}"
}
clean_up() {
if test -f "${DNSMASQ_QEMU_PID}"; then
dnsmasq_qemu_pid=$(cat "${DNSMASQ_QEMU_PID}")
echo "Clean up: Killing dnsmasq qemu process $dnsmasq_qemu_pid..."
kill "$dnsmasq_qemu_pid" || true
fi
if test -e "${DNSMASQ_QEMU_LOG}"; then
echo ">>>>>>>>>>>>>>>>>>>> dnsmasq qemu log >>>>>>>>>>>>>>>>>>>>"
cat "${DNSMASQ_QEMU_LOG}"
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
fi
}
wait_for_dnsmasq_startup() {
local timeout="$QEMU_TIMEOUT"
while ! grep -q "Executing /sbin/init from root fs" "${DNSMASQ_QEMU_LOG}"; do
echo "Waiting up to $timeout seconds for dnsmasq to get started..."
timeout=$((timeout - 1))
if test "$timeout" -le 0; then
echo >&2 "Error: dnsmasq was not started within $QEMU_TIMEOUT seconds."
return 1
fi
sleep 1
done
}
trap clean_up INT TERM EXIT
cat >>"${CONFDIR}/initramfs.conf" <<EOF
MODULES=list
BUSYBOX=n
FSTYPE=ext2
EOF
cat >"${CONFDIR}/modules" <<EOF
ext2
virtio_pci
virtio_blk
virtio_net
EOF
install -m 755 debian/tests/hooks/drop-hostname "${CONFDIR}/hooks/drop-hostname"
install -m 755 debian/tests/hooks/persistent-net "${CONFDIR}/hooks/persistent-net"
build_initramfs
build_dnsmasq_rootfs_ext2 "${BASEDIR}/dnsmasq.raw"
run_qemu_in_background "${BASEDIR}/dnsmasq.raw" "${DNSMASQ_QEMU_PID}" "${DNSMASQ_QEMU_LOG}"
prepare_network_dumping_rootfs
build_rootfs_ext2
wait_for_dnsmasq_startup
EXPECTED_DHCP_LAN0="
DEVICE='lan0'
PROTO='dhcp'
IPV4ADDR='10.0.7.30'
IPV4BROADCAST='10.0.7.255'
IPV4NETMASK='255.255.255.0'
IPV4GATEWAY='10.0.7.1'
IPV4DNS0='10.0.7.1'
HOSTNAME=''
DNSDOMAIN='test'
ROOTSERVER='10.0.7.1'
filename=''
DOMAINSEARCH=''
"
EXPECTED_DHCP6_LAN0="
DEVICE6='lan0'
IPV6PROTO='dhcp6'
IPV6ADDR='fc07::beef'
IPV6NETMASK='128'
IPV6DNS0='fc07::1'
IPV6DOMAINSEARCH='example.com. example.'
"
run_qemu_with_socket_network "ip6=dhcp"
check_output "Begin: Waiting up to 180 secs for any network device to become available"
./debian/tests/check-log "${OUTPUT}" has_no_running_processes \
has_hostname "pizza" \
has_ipv4_addr "10\.0\.7\.30/24" "lan0" \
has_ipv4_default_route "10\.0\.7\.1" "lan0" \
has_ipv6_addr "fc07::beef/128" "lan0" \
has_net_conf 2 "/run/net-lan0.conf=${EXPECTED_DHCP_LAN0}" "/run/net6-lan0.conf=${EXPECTED_DHCP6_LAN0}"
# Test DHCP configuration with BOOTIF specified
run_qemu_with_socket_network "BOOTIF=01-52-54-00-65-43-21 ip6=dhcp"
check_output "Begin: Waiting up to 180 secs for device with address 52:54:00:65:43:21 to become available"
./debian/tests/check-log "${OUTPUT}" has_no_running_processes \
has_hostname "pizza" \
has_ipv4_addr "10\.0\.7\.30/24" "lan0" \
has_ipv4_default_route "10\.0\.7\.1" "lan0" \
has_ipv6_addr "fc07::beef/128" "lan0" \
has_net_conf 2 "/run/net-lan0.conf=${EXPECTED_DHCP_LAN0}" "/run/net6-lan0.conf=${EXPECTED_DHCP6_LAN0}"
# Test specifying the device
run_qemu_with_socket_network "ip6=lan0"
check_output "Begin: Waiting up to 180 secs for lan0 to become available"
./debian/tests/check-log "${OUTPUT}" has_no_running_processes \
has_hostname "pizza" \
has_ipv4_addr "10\.0\.7\.30/24" "lan0" \
has_ipv4_default_route "10\.0\.7\.1" "lan0" \
has_ipv6_addr "fc07::beef/128" "lan0" \
has_net_conf 2 "/run/net-lan0.conf=${EXPECTED_DHCP_LAN0}" "/run/net6-lan0.conf=${EXPECTED_DHCP6_LAN0}"

View File

@ -1,6 +1,6 @@
#!/bin/sh -e
SUPPORTED_FLAVOURS='amd64 generic'
SUPPORTED_FLAVOURS='amd64 arm64 armmp powerpc64 s390x generic'
ROOTDISK_QEMU_IF=virtio
ROOTDISK_LINUX_NAME=nonexistent
. debian/tests/test-common
@ -19,14 +19,17 @@ build_initramfs
build_rootfs_ext2
run_qemu_nocheck_amd64
run_qemu_nocheck
check_no_network_configuration
grep -qF "ALERT! /dev/nonexistent does not exist. Dropping to a shell!" "${OUTPUT}"
grep -qF "(initramfs) " "${OUTPUT}"
run_qemu_nocheck_amd64 "panic=-1"
run_qemu_nocheck "panic=-1"
check_no_network_configuration
grep -qF "Rebooting automatically due to panic= boot argument" "${OUTPUT}"
! grep -qF "(initramfs) " "${OUTPUT}"
run_qemu_nocheck_amd64 "panic=0"
run_qemu_nocheck "panic=0"
check_no_network_configuration
grep -qF "Halting automatically due to panic= boot argument" "${OUTPUT}"
! grep -qF "(initramfs) " "${OUTPUT}"

View File

@ -1,6 +1,6 @@
#!/bin/sh -e
SUPPORTED_FLAVOURS='amd64 generic'
SUPPORTED_FLAVOURS='amd64 arm64 armmp powerpc64 s390x generic'
ROOTDISK_QEMU_IF=virtio
ROOTDISK_LINUX_NAME=vda
USRDISK="$(mktemp)"
@ -29,7 +29,8 @@ mv "${ROOTDIR}/usr/"* "${USRDIR}"
build_rootfs_ext2
build_fs_ext2 "${USRDIR}" "${USRDISK}"
run_qemu_amd64
run_qemu
check_no_network_configuration
# Check that fsck ran on both devices
grep -q "^/dev/${ROOTDISK_LINUX_NAME}: clean," "${OUTPUT}"

View File

@ -1,6 +1,6 @@
#!/bin/sh -e
SUPPORTED_FLAVOURS='amd64 generic'
SUPPORTED_FLAVOURS='amd64 arm64 armmp powerpc64 s390x generic'
ROOTDISK_QEMU_IF=virtio
ROOTDISK_LINUX_NAME=vda
. debian/tests/test-common
@ -19,4 +19,5 @@ build_initramfs
build_rootfs_ext2
run_qemu_amd64
run_qemu
check_no_network_configuration

View File

@ -1,51 +0,0 @@
#!/bin/bash
set -eux
NICSLOT=3
while [ $# -gt 0 ]; do
case $1 in
kernel=*) KERNEL="${1#kernel=}" ;;
initrd=*) INITRD="${1#initrd=}" ;;
image=*) IMAGE="${1#image=}" ;;
cmdline=*) CMDLINE="${1#cmdline=}" ;;
output=*) OUTPUT="${1#output=}" ;;
nicslot=*) NICSLOT="${1#nicslot=}" ;;
esac
shift
done
archopts=()
case $(uname -m) in
i?86)
qemu="qemu-system-i386"
;;
ppc64*)
qemu="qemu-system-ppc64"
archopts=( -machine "pseries,usb=off" )
;;
aarch64)
qemu="qemu-system-aarch64"
archopts=( -machine "virt" )
;;
*)
qemu=qemu-system-$(uname -m)
esac
timeout --foreground 10m \
"$qemu" "${archopts[@]}" -m 512m \
-kernel "$KERNEL" -initrd "$INITRD" \
-append "$CMDLINE" \
-drive file="$IMAGE",format=raw \
-nographic -monitor none \
-netdev user,id=net0 -device virtio-net-pci,netdev=net0,bus=pci.0,addr="$NICSLOT"
dev=$(losetup -Pf --show "$IMAGE")
partprobe
mount "${dev}p1" mnt
rm -rf "$OUTPUT"
cp -aT mnt/result "$OUTPUT"
umount mnt
losetup -d "$dev"

64
debian/tests/run-qemu vendored Executable file
View File

@ -0,0 +1,64 @@
#!/bin/sh
set -eu
# Run qemu-system for the system architecture
if test "$#" -lt 3; then
echo "${0##*/}: Error: Not enough parameters." >&2
echo "Usage: ${0##*/} kernel initrd append [extra_args]" >&2
exit 1
fi
kernel="$1"
initrd="$2"
append="$3"
shift 3
ARCHITECTURE=$(dpkg --print-architecture)
case "$ARCHITECTURE" in
amd64)
qemu="qemu-system-x86_64"
;;
arm64)
qemu="qemu-system-aarch64"
machine="virt,gic-version=max"
cpu="max,pauth-impdef=on"
efi_code=/usr/share/AAVMF/AAVMF_CODE.fd
efi_vars=/usr/share/AAVMF/AAVMF_VARS.fd
;;
armhf)
qemu="qemu-system-arm"
machine="virt"
cpu=cortex-a7
efi_code=/usr/share/AAVMF/AAVMF32_CODE.fd
efi_vars=/usr/share/AAVMF/AAVMF32_VARS.fd
console=ttyAMA0
;;
ppc64el)
qemu="qemu-system-ppc64"
machine="cap-ccf-assist=off,cap-cfpc=broken,cap-ibs=broken,cap-sbbc=broken"
console=hvc0
;;
*)
qemu="qemu-system-${ARCHITECTURE}"
esac
if [ -c /dev/kvm ] && [ "$ARCHITECTURE" != "ppc64el" ]; then
kvm=-enable-kvm
cpu=host
fi
if test -f "${efi_vars-}"; then
efi_vars_copy="$(mktemp -t "${efi_vars##*/}.XXXXXXXXXX")"
cp "$efi_vars" "$efi_vars_copy"
fi
set -- ${machine:+-machine "${machine}"} ${kvm:+"$kvm"} ${cpu:+-cpu "${cpu}"} -m 1G \
${efi_code:+-drive "file=${efi_code},if=pflash,format=raw,read-only=on"} \
${efi_vars:+-drive "file=${efi_vars_copy},if=pflash,format=raw"} \
-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 \
-nodefaults -no-reboot -kernel "${kernel}" -initrd "${initrd}" "$@" \
-append "console=${console:-ttyS0},115200 ro ${append}"
echo "${0##*/}: $qemu $*"
exec "$qemu" "$@"

View File

@ -1,25 +0,0 @@
#!/bin/sh -eu
export LC_COLLATE=C.UTF-8
unset LC_ALL
# The packages that install hook/boot scripts
dpkg -S /usr/share/initramfs-tools/hooks /usr/share/initramfs-tools/scripts \
| sed 's/: .*//; s/, /\n/g' \
| sort -u \
> "$AUTOPKGTEST_TMP/installed-packages"
# The packages that we're prepared to test
echo "initramfs-tools initramfs-tools-core klibc-utils kmod udev" \
| sed 's/ /\n/g' \
| sort -u \
> "$AUTOPKGTEST_TMP/tested-packages"
# Installed hook/boot scripts that we're prepared to test
join "$AUTOPKGTEST_TMP/installed-packages" "$AUTOPKGTEST_TMP/tested-packages" \
| xargs dpkg -L \
| grep -E '^/usr/share/initramfs-tools/(hooks|scripts)/' \
| while read file; do test -f "$file" && printf '%s\n' "$file"; done \
> "$AUTOPKGTEST_TMP/hook-boot-scripts"
shellcheck -e SC1010,SC1090,SC1091,SC2015 -s dash /usr/bin/lsinitramfs /usr/sbin/mkinitramfs /usr/bin/unmkinitramfs /usr/share/initramfs-tools/hook-functions /usr/share/initramfs-tools/init /etc/kernel/postinst.d/initramfs-tools /etc/kernel/postrm.d/initramfs-tools /usr/sbin/update-initramfs $(cat "$AUTOPKGTEST_TMP/hook-boot-scripts")

View File

@ -13,32 +13,60 @@ if [ -z "$KVER" ]; then
exit 2
fi
if [ -n "${AUTOPKGTEST_TMP}" ]; then
case "$(dpkg --print-architecture)" in
arm64)
# Slowest execution seen in Ubuntu arm64 autopkgtest: 562 seconds
QEMU_TIMEOUT=1200
;;
armhf)
# Slowest execution seen in Ubuntu armhf autopkgtest: 145 seconds
QEMU_TIMEOUT=300
;;
ppc64el)
# Slowest execution seen in Ubuntu ppc64el autopkgtest: 230 seconds
QEMU_TIMEOUT=600
;;
s390x)
# Slowest execution seen in Ubuntu s390x autopkgtest: 58 seconds
QEMU_TIMEOUT=120
;;
*)
QEMU_TIMEOUT=60
esac
if [ -n "${AUTOPKGTEST_TMP-}" ]; then
export TMPDIR="${AUTOPKGTEST_TMP}"
fi
BASEDIR="$(mktemp -d -t initramfs-test.XXXXXXXXXX)"
# Skeleton configuration directory
CONFDIR="$(mktemp -d)"
CONFDIR="${BASEDIR}/config"
mkdir -p "${CONFDIR}"
cp conf/initramfs.conf "${CONFDIR}/initramfs.conf"
echo "RESUME=none" >>"${CONFDIR}/initramfs.conf"
mkdir "${CONFDIR}/hooks"
touch "${CONFDIR}/modules"
mkdir "${CONFDIR}/scripts"
# initramfs image file
INITRAMFS="$(mktemp)"
INITRAMFS="${BASEDIR}/initrd.img"
# root disk image file
ROOTDISK="$(mktemp)"
ROOTDISK="${BASEDIR}/rootdisk.raw"
# root disk interface type (for qemu) and device name (for Linux)
test -n "${ROOTDISK_QEMU_IF}" || ROOTDISK_QEMU_IF=virtio
test -n "${ROOTDISK_LINUX_NAME}" || ROOTDISK_LINUX_NAME=vda
# Create a root fs with a trivial userspace
ROOTDIR="$(mktemp -d)"
ROOTDIR="${BASEDIR}/rootdir"
INIT_MESSAGE='root fs init system started successfully'
for subdir in bin dev lib proc run sbin sys usr usr/bin; do
mkdir "${ROOTDIR}/${subdir}"
for subdir in dev proc run sys usr usr/bin usr/lib/modules usr/lib64 usr/sbin; do
mkdir -p "${ROOTDIR}/${subdir}"
done
for subdir in bin lib lib64 sbin; do
ln -s "usr/${subdir}" "${ROOTDIR}/${subdir}"
done
cat >"${ROOTDIR}/sbin/init" <<EOF
#!/bin/sh -e
@ -56,7 +84,56 @@ cp /usr/lib/klibc/bin/poweroff "${ROOTDIR}/bin/poweroff"
cp "$(dpkg -L libklibc | grep '^/lib/klibc.*\.so$')" "${ROOTDIR}/lib/"
# VM output file
OUTPUT="$(mktemp)"
OUTPUT="${BASEDIR}/output.log"
prepare_network_dumping_rootfs() {
local root_dir="${1-$ROOTDIR}"
cat >"${root_dir}/sbin/init" <<EOF
#!/bin/sh
echo "I: Executing /sbin/init from root fs"
# Stop the kernel from spamming the output
current_printk=\$(sysctl kernel.printk)
sysctl -w kernel.printk="4 4 1 7"
# Run twice, once for the human, once for the test harness
echo "I: ip addr"
ip addr
echo "I: ip route"
ip route
echo "I: ip -6 route"
ip -6 route
for file in /run/net*.conf; do
[ -f \$file ] || continue;
echo "########## \$file ##########"
cat \$file
echo "########################################"
done
echo "########## hostname ##########"
hostname
echo "########################################"
echo "########## ip -json addr ##########"
ip -json addr
echo "########################################"
echo "########## ip -json route ##########"
ip -json route
echo "########################################"
echo "########## ip -json -6 route ##########"
ip -json -6 route
echo "########################################"
echo "########## ps -ww aux ##########"
ps -ww aux
echo "########################################"
sysctl -w "\${current_printk}"
echo '${INIT_MESSAGE}'
poweroff
EOF
. /usr/share/initramfs-tools/hook-functions
verbose=y
DESTDIR="$root_dir"
for binary in /bin/cat /bin/hostname /bin/ps /sbin/ip /sbin/sysctl; do
copy_exec "$binary"
done
}
build_initramfs() {
/usr/sbin/mkinitramfs -d "${CONFDIR}" -o "${INITRAMFS}" "${KVER}"
@ -71,7 +148,7 @@ build_fs_ext2() {
local inodes="$(du --summarize --inodes "${dir}" | cut -f 1)"
# Add fudge factor
blocks="$((blocks + 20 + blocks / 4))"
blocks="$((blocks + 28 + blocks / 4))"
inodes="$((inodes + 10))"
# genext2fs writes status messages to stderr; hide that from
@ -83,18 +160,70 @@ build_rootfs_ext2() {
build_fs_ext2 "${ROOTDIR}" "${ROOTDISK}"
}
_run_qemu_amd64() {
local extra_params="$*"
_run_qemu() {
local extra_append="$1"
shift
timeout --foreground 60 qemu-system-x86_64 -m 1G -drive "file=${ROOTDISK},if=${ROOTDISK_QEMU_IF},media=disk,format=raw" ${USRDISK:+-drive "file=${USRDISK},if=${USRDISK_QEMU_IF},media=disk,format=raw"} -nographic -no-reboot -kernel "/boot/vmlinuz-${KVER}" -initrd "${INITRAMFS}" -append "root=/dev/${ROOTDISK_LINUX_NAME} ro console=ttyS0,115200 ${extra_params}" | tee "${OUTPUT}"
echo "I: Running qemu (with a timeout of $QEMU_TIMEOUT seconds)..."
timeout --foreground "$QEMU_TIMEOUT" \
debian/tests/run-qemu /boot/vmlinu*-"${KVER}" "${INITRAMFS}" \
"root=/dev/${ROOTDISK_LINUX_NAME} ${extra_append}" -nographic \
-drive "file=${ROOTDISK},if=${ROOTDISK_QEMU_IF},media=disk,format=raw" \
${USRDISK:+-drive "file=${USRDISK},if=${USRDISK_QEMU_IF},media=disk,format=raw"} \
-chardev stdio,id=char0 -serial chardev:char0 "$@" | tee "${OUTPUT}"
}
run_qemu_nocheck_amd64() {
run_qemu_in_background() {
local rootdisk="$1"
local pidfile="$2"
local logfile="$3"
echo "I: Running qemu in background..."
debian/tests/run-qemu /boot/vmlinu*-"${KVER}" "${INITRAMFS}" \
"root=/dev/${ROOTDISK_LINUX_NAME} panic=-1" -display none \
-drive "file=${rootdisk},if=${ROOTDISK_QEMU_IF},media=disk,format=raw" \
-device "virtio-net-pci,netdev=lan9,mac=52:54:00:12:33:21" \
-netdev "socket,id=lan9,listen=localhost:1234" \
-pidfile "${pidfile}" -serial "file:${logfile}" -daemonize
}
run_qemu_nocheck() {
# hide error messages from autopkgtest
_run_qemu_amd64 2>&1 "$@"
_run_qemu "${1-}" 2>&1
}
run_qemu_amd64() {
_run_qemu_amd64 "panic=-1"
run_qemu() {
_run_qemu "panic=-1 $*" \
-device "virtio-net-pci,netdev=lan0,mac=52:54:00:65:43:21" \
-netdev "user,id=lan0,net=10.0.3.0/24,ipv6-net=fec7::/48,hostname=pizza,dnssearch=test,domainname=example.com,bootfile=/path/to/bootfile2" \
-device "virtio-net-pci,netdev=lan1,mac=52:54:00:12:34:56" \
-netdev "user,id=lan1,hostname=goulash,dnssearch=example,dnssearch=example.net,domainname=test,bootfile=/path/to/bootfile"
grep -qF "${INIT_MESSAGE}" "${OUTPUT}"
}
run_qemu_with_socket_network() {
_run_qemu "panic=-1 $*" \
-device "virtio-net-pci,netdev=lan0,mac=52:54:00:65:43:21" \
-netdev "socket,id=lan0,connect=localhost:1234"
grep -qF "${INIT_MESSAGE}" "${OUTPUT}"
}
check_no_output() {
local msg="$1"
if grep -qF "${msg}" "${OUTPUT}"; then
echo >&2 "E: Message '${msg}' found in log output '${OUTPUT}."
exit 1
fi
}
check_output() {
local msg="$1"
if ! grep -qF "${msg}" "${OUTPUT}"; then
echo >&2 "E: Message '${msg}' not found in log output '${OUTPUT}."
exit 1
fi
}
check_no_network_configuration() {
check_no_output "Waiting up to 180 secs for"
}

64
dhcpcd-hooks/70-net-conf Executable file
View File

@ -0,0 +1,64 @@
#!/bin/sh
set -e
# dhcpcd client hook to write /run/net*.conf files compatible to ipconfig from klibc-utils
# Ensure that the search domain ends with dots
domain_search_with_trailing_dots() {
local domain_search=""
for domain in $1; do
domain_search="${domain_search}${domain_search:+ }${domain%.}."
done
echo "$domain_search"
}
write_dhcp_netinfo() {
local domain_search netinfo_path="$1"
domain_search=$(domain_search_with_trailing_dots "${new_domain_search-}")
cat >"$netinfo_path" << EOF
DEVICE='${interface-}'
PROTO='${protocol-}'
IPV4ADDR='${new_ip_address-}'
IPV4BROADCAST='${new_broadcast_address-}'
IPV4NETMASK='${new_subnet_mask-}'
IPV4GATEWAY='${new_routers-}'
IPV4DNS0='${new_domain_name_servers-}'
HOSTNAME='${new_host_name-}'
DNSDOMAIN='${new_domain_name-}'
ROOTSERVER='${new_routers-}'
filename='${new_filename-}'
DHCPLEASETIME='${new_dhcp_lease_time-}'
DOMAINSEARCH='${domain_search}'
EOF
}
write_dhcp6_netinfo() {
local domain_search netinfo_path="$1"
domain_search=$(domain_search_with_trailing_dots "${new_dhcp6_domain_search-}")
cat >"$netinfo_path" << EOF
DEVICE6='${interface-}'
IPV6PROTO='${protocol-}'
IPV6ADDR='${new_dhcp6_ia_na1_ia_addr1-}'
IPV6NETMASK='128'
IPV6DNS0='${new_dhcp6_name_servers-}'
IPV6DOMAINSEARCH='${domain_search}'
EOF
}
if ${if_configured?}; then
if ${if_up?}; then
if [ "${protocol?}" = dhcp ]; then
write_dhcp_netinfo "/run/net-${interface?}.conf"
elif [ "${protocol}" = dhcp6 ]; then
write_dhcp6_netinfo "/run/net6-${interface?}.conf"
fi
elif ${if_down?}; then
if [ "${protocol?}" = dhcp ]; then
rm -f "/run/net-${interface?}.conf"
elif [ "${protocol}" = dhcp6 ]; then
rm -f "/run/net6-${interface?}.conf"
fi
fi
fi

View File

@ -86,7 +86,7 @@ matroxfb)
;;
intelfb|i810fb|i915)
# Needs AGP driver loaded
modprobe intel-agp
/sbin/modprobe intel-agp
;;
uvesafb)
# v86d requires /dev/zero and dev/mem, but udev haven't been started yet
@ -99,9 +99,9 @@ esac
if [ -n "${FB}" ]; then
unset MODPROBE_OPTIONS
modprobe -q fbcon
/sbin/modprobe -q fbcon
# shellcheck disable=SC2086
modprobe -q ${FB} ${OPTS}
/sbin/modprobe -q ${FB} ${OPTS}
fi
if [ -e /proc/fb ]; then

View File

@ -57,85 +57,47 @@ add_modules_from_file()
# whether a warning should be printed in that case.)
add_firmware()
{
local firmware fwloc
local ext firmware found_fwloc fwloc path
firmware="${1}"
if [ -e "${DESTDIR}/lib/firmware/updates/${version?}/${firmware}" ] \
|| [ -e "${DESTDIR}/lib/firmware/updates/${version?}/${firmware}.xz" ] \
|| [ -e "${DESTDIR}/lib/firmware/updates/${firmware}" ] \
|| [ -e "${DESTDIR}/lib/firmware/updates/${firmware}.xz" ] \
|| [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ] \
|| [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}.xz" ] \
|| [ -e "${DESTDIR}/lib/firmware/${firmware}" ] \
|| [ -e "${DESTDIR}/lib/firmware/${firmware}.xz" ]; then
return 0
fi
for fwloc in "/lib/firmware/updates/${version}/${firmware}" \
"/lib/firmware/updates/${firmware}" \
"/lib/firmware/${version}/${firmware}" \
"/lib/firmware/${firmware}"; do
if [ -e "${fwloc}" ]; then
copy_file firmware "${fwloc}"
return 0
elif [ -e "${fwloc}.xz" ]; then
copy_file firmware "${fwloc}.xz"
if command -v xz >/dev/null 2>&1; then
xz -d "${DESTDIR}/${fwloc}.xz"
for path in "updates/${version?}" "updates" "${version}" ""; do
for ext in ".xz" ".zst" ""; do
fwloc="/lib/firmware${path:+/}${path}/${firmware}${ext}"
if [ -e "${DESTDIR}${fwloc}" ]; then
# DESTDIR already contains a matching firmware file.
return 0
fi
return 0
fi
if [ -z "${found_fwloc}" ] && [ -e "${fwloc}" ]; then
found_fwloc="$fwloc"
fi
done
done
# We can't figure out where to get that firmware from.
return 1
if [ -z "${found_fwloc}" ]; then
# We can't figure out where to get that firmware from.
return 1
fi
copy_file firmware "${found_fwloc}"
}
# Add dependent modules + eventual firmware
manual_add_modules()
{
local prefix kmod options firmware
local dracut_verbose
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
if [ "${verbose?}" = "y" ]; then
dracut_verbose=-v
fi
copy_file module "${kmod}" || continue
# Add required firmware
for firmware in $(modinfo -k "${version}" -F firmware "${kmod}"); do
# Only print warning for missing fw of loaded module
# or forced loaded module
if ! add_firmware "$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
done
done
/usr/lib/dracut/dracut-install -D "$DESTDIR" --kerneldir "/lib/modules/${version?}" \
--firmwaredirs "/lib/firmware/updates/${version?}:/lib/firmware/updates:/lib/firmware/${version?}:/lib/firmware" \
${dracut_verbose-} -o -m "$@"
}
# manual_add_modules() takes care of adding firmware for things that were built
@ -612,11 +574,6 @@ dep_add_modules()
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
@ -636,13 +593,23 @@ dep_add_modules()
# The modules "most" classes added per default to the initramfs
auto_add_modules()
{
local arg
local arg blockfuncs exclude exclude_dir
local modules=
if [ "$#" -eq 0 ] ; then
set -- base hw_random net ide scsi block ata i2o dasd ieee1394 firewire mmc usb_storage fb virtual nx
set -- base hw_random net ide scsi block ata dasd firewire mmc usb_storage fb virtual nx
fi
blockfuncs="ahci_platform_get_resources|ata_scsi_ioctl|scsi_add_host|blk_cleanup_queue"
blockfuncs="${blockfuncs}|register_mtd_blktrans|scsi_esp_register|register_virtio_device"
blockfuncs="${blockfuncs}|usb_stor_disconnect|mmc_add_host|sdhci_add_host|scsi_add_host_with_dma"
blockfuncs="${blockfuncs}|blk_mq_alloc_disk|blk_mq_alloc_request|blk_mq_destroy_queue|blk_cleanup_disk"
case "$DPKG_ARCH" in
arm64|armel|armhf|riscv64)
blockfuncs="${blockfuncs}|dw_mc_probe|dw_mci_pltfm_register|nvme_init_ctrl"
;;
esac
for arg in "$@" ; do
case "$arg" in
base)
@ -655,120 +622,125 @@ auto_add_modules()
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
modules="$modules ehci-hcd ehci-pci ehci-platform ohci-hcd ohci-pci"
modules="$modules uhci-hcd usbhid xhci-hcd xhci-pci xhci-plat-hcd"
modules="$modules =drivers/usb/typec"
modules="$modules =drivers/usb/c67x00"
modules="$modules =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
modules="$modules =drivers/input/keyboard"
exclude="a4tech|cypress|dr|elecom|gyration|icade|kensington"
exclude="${exclude}|kye|lcpower|magicmouse|multitouch|ntrig"
exclude="${exclude}|petalynx|picolcd|pl|ps3remote|quanta"
exclude="${exclude}|roccat-ko.*|roccat-pyra|saitek|sensor-hub|sony"
exclude="${exclude}|speedlink|tivo|twinhan|uclogic|wacom|waltop"
exclude="${exclude}|wiimote|zydacron|.*ff"
manual_add_modules -P "/hid-(${exclude})\.ko" =drivers/hid
# 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/pci/controller
copy_modules_dir kernel/drivers/phy
copy_modules_dir kernel/drivers/pinctrl
copy_modules_dir kernel/drivers/regulator
copy_modules_dir kernel/drivers/reset
copy_modules_dir kernel/drivers/spi
copy_modules_dir kernel/drivers/usb/phy
# For Linux console access
modules="$modules =drivers/tty/serial"
# Needed for periodic fsck
copy_modules_dir kernel/drivers/rtc
# Any of these might be needed by other drivers
modules="$modules =drivers/bus"
modules="$modules =drivers/i2c/muxes"
modules="$modules =drivers/pci/controller"
modules="$modules =drivers/pinctrl"
case "$DPKG_ARCH" in
arm64|armel|armhf|riscv64)
manual_add_modules "=drivers/usb/host" \
-P "/(hwa-hc|sl811_cs|sl811-hcd|u132-hcd|whci-hcd)\.ko"
modules="$modules =drivers/clk"
modules="$modules =drivers/i2c/busses"
modules="$modules =drivers/gpio"
modules="$modules =drivers/mfd"
modules="$modules =drivers/phy"
modules="$modules =drivers/regulator"
modules="$modules =drivers/reset"
modules="$modules =drivers/spi"
modules="$modules =drivers/usb/chipidea"
modules="$modules =drivers/usb/dwc2"
modules="$modules =drivers/usb/dwc3"
modules="$modules =drivers/usb/isp1760"
modules="$modules =drivers/usb/musb"
modules="$modules =drivers/usb/phy"
# Needed for periodic fsck
modules="$modules =drivers/rtc"
# 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"
;;
esac
;;
hw_random)
copy_modules_dir kernel/drivers/char/hw_random
modules="$modules =drivers/char/hw_random"
;;
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 veth.ko wan wimax wireless \
cdc_mbim.ko cdc-phonet.ko hso.ko huawei_cdc_ncm.ko ipheth.ko kalmia.ko \
lg-vl600.ko qmi_wwan.ko sierra_net.ko cdc_subset.ko gl620a.ko \
net1080.ko plusb.ko cx82310_eth.ko zaurus.ko \
xen-netback.ko
modules="$modules 8021q"
exclude="cdc_mbim|ipheth|qmi_wwan|sierra_net|veth|xen-netback"
exclude_dir="isdn|net/ethernet|net/phy|net/team|uwb|wan|wireless"
manual_add_modules -P "/((${exclude})\.ko|(${exclude_dir})/)" \
-s "eth_type_trans|register_virtio_device|usbnet_open" \
"=drivers/net"
modules="$modules =drivers/net/ethernet =drivers/net/mdio"
modules="$modules =drivers/net/phy 8021q ipvlan"
# Required to initialize Ethernet (FEC) on ARM64 iMX8M
# devices.
modules="$modules nvmem-imx-ocotp"
;;
ide)
copy_modules_dir kernel/drivers/ide
modules="$modules =drivers/ide"
;;
mmc)
copy_modules_dir kernel/drivers/mmc
modules="$modules =drivers/mmc"
;;
scsi)
copy_modules_dir kernel/drivers/scsi
manual_add_modules -s "${blockfuncs}|iscsi_register_transport" \
"=drivers/scsi" "=drivers/ufs"
modules="$modules be2iscsi bnx2i cxgb3i cxgb4i qedi qla4xxx"
modules="$modules scsi_dh_alua scsi_dh_emc scsi_dh_rdac"
modules="$modules mptfc mptsas mptscsih mptspi zfcp"
# scsi_transport_srp should have been pulled in by =drivers/scsi
modules="$modules scsi_transport_srp"
;;
ata)
copy_modules_dir kernel/drivers/ata
manual_add_modules -s "${blockfuncs}" "=drivers/ata"
;;
block)
copy_modules_dir kernel/drivers/block
copy_modules_dir kernel/drivers/nvme
copy_modules_dir kernel/drivers/nvdimm
copy_modules_dir kernel/drivers/dax
copy_modules_dir kernel/drivers/acpi/nfit
modules="$modules vmd"
manual_add_modules -s "${blockfuncs}" "=drivers/block" \
"=drivers/nvme" "=drivers/dax" vmd
manual_add_modules -s nvdimm_bus_register "=drivers/nvdimm" "=drivers/acpi"
;;
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
modules="$modules =drivers/usb/storage"
;;
fb)
# For machines that don't have a generic framebuffer device.
modules="$modules rockchipdrm pwm-cros-ec pwm_bl panel-simple"
modules="$modules analogix-anx6345 pwm-sun4i sun4i-drm sun8i-mixer"
modules="$modules rockchipdrm pwm-cros-ec pwm_bl pwm-rockchip panel-simple"
modules="$modules analogix-anx6345 pwm-sun4i sun4i-drm sun8i-mixer panel-edp"
# For panel/backlight on MNT Reform 2
modules="$modules pwm_imx27 nwl-dsi ti-sn65dsi86 imx-dcss"
modules="$modules mux-mmio mxsfb imx8mq-interconnect"
;;
virtual)
# Hyper-V
@ -833,7 +805,7 @@ hidden_dep_add_modules()
echo pl330
;;
dw_mmc-rockchip)
echo rockchip-io-domain
echo rockchip-io-domain io-domain
;;
esac
done
@ -862,7 +834,7 @@ set_initlist()
[ "${si_x}" = "${initdir}/*" ] && return
# only allow variable name chars
case ${si_x#"${initdir}"/} in
case "${si_x#"${initdir}"/}" in
*[![:alnum:]\._-]*)
[ "${verbose}" = "y" ] \
&& echo "$si_x ignored: not alphanumeric or '_' file" >&2
@ -947,7 +919,7 @@ call_scripts()
if [ "$ec" -ne 0 ]; then
echo "E: ${initdir}/${cs_x} failed with return $ec." >&2
# only errexit on mkinitramfs
[ -n "${version}" ] && exit $ec
[ -n "${version}" ] && exit "$ec"
fi
# allow boot scripts to modify exported boot parameters
if [ -e /conf/param.conf ]; then
@ -974,13 +946,9 @@ run_scripts_optional()
}
add_dns() {
local destdir="$1" nsswitch="" lib="" libdir="" f="" d=""
local destdir="$1" nsswitch="" lib="" libdir="" f=""
# 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
libdir=$(ldd /bin/sh | sed -En 's;^.*\s(\S+)/libc\.so\..*$;\1;p')
if [ -z "$libdir" ]; then
echo "WARNING: no libdir found for adding dns." 1>&2
return

View File

@ -1,156 +0,0 @@
#!/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:

53
hooks/dhcpcd Executable file
View File

@ -0,0 +1,53 @@
#!/bin/sh
set -e
# initramfs hook to include dhcpcd as DHCP client
PREREQ=""
# Output pre-requisites
prereqs()
{
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
if ! [ -x /usr/sbin/dhcpcd ]; then
exit 0
fi
copy_exec /usr/sbin/dhcpcd
copy_exec /usr/lib/dhcpcd/dhcpcd-run-hooks
copy_file config /usr/lib/dhcpcd/dhcpcd-hooks/30-hostname
copy_file config /usr/share/initramfs-tools/dhcpcd-hooks/70-net-conf /usr/lib/dhcpcd/dhcpcd-hooks/70-net-conf
mkdir -p "${DESTDIR}/var/lib/dhcpcd"
mkdir -p "${DESTDIR}/etc"
cat >"${DESTDIR}/etc/dhcpcd.conf" <<EOF
# Options from default configuration
persistent
vendorclassid
option domain_name_servers, domain_name, domain_search
option classless_static_routes
option interface_mtu
option host_name
option rapid_commit
require dhcp_server_identifier
slaac private
# initramfs-tools specific options
duid ll
env hostname_fqdn=no
EOF
# find the multiarch lib dir (for example /lib/x86_64-linux-gnu)
multiarch_dir=$(ldd /usr/sbin/dhcpcd | sed -En 's;^.*/lib/([^/]+)/libc\.so\..*$;\1;p')
copy_exec "/usr/lib/${multiarch_dir}/dhcpcd/dev/udev.so"

View File

@ -19,14 +19,8 @@ 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
manual_add_modules "=drivers/char/agp" "=drivers/gpu" "=ubuntu/i915" \
fbcon vesafb vga16fb vboxvideo
for x in "${MODULESDIR}"/initrd/*; do
x=${x##*/}

View File

@ -76,6 +76,11 @@ if ! ischroot && [ -r /proc/swaps ]; then
report_verbose "Rejecting $resume_auto since it is zram"
ephemeral=true
;;
/dev/zd[0-9]*)
report_verbose "Rejecting $resume_auto since it is zvol"
ephemeral=true
;;
esac
$ephemeral || break

View File

@ -55,17 +55,11 @@ powerpc|ppc64)
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
manual_add_modules windfarm_core windfarm_cpufreq_clamp \
windfarm_lm75_sensor windfarm_max6690_sensor windfarm_pid \
windfarm_smu_controls windfarm_smu_sat windfarm_smu_sensors
;;
i386|amd64|ia64)
manual_add_modules fan
manual_add_modules thermal
manual_add_modules fan thermal
;;
esac

25
init
View File

@ -38,6 +38,13 @@ 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
mount -t devtmpfs -o nosuid,mode=0755 udev /dev
# Prepare the /dev directory
[ ! -h /dev/fd ] && ln -s /proc/self/fd /dev/fd
[ ! -h /dev/stdin ] && ln -s /proc/self/fd/0 /dev/stdin
[ ! -h /dev/stdout ] && ln -s /proc/self/fd/1 /dev/stdout
[ ! -h /dev/stderr ] && ln -s /proc/self/fd/2 /dev/stderr
mkdir /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
@ -247,7 +254,7 @@ mount -t tmpfs -o "nodev,noexec,nosuid,size=${RUNSIZE:-10%},mode=0755" tmpfs /ru
mkdir -m 0700 /run/initramfs
if [ -n "$log_output" ]; then
exec >$log_output 2>&1
exec >"$log_output" 2>&1
unset log_output
fi
@ -258,7 +265,7 @@ run_scripts /scripts/init-top
maybe_break modules
[ "$quiet" != "y" ] && log_begin_msg "Loading essential drivers"
[ -n "${netconsole}" ] && modprobe netconsole netconsole="${netconsole}"
[ -n "${netconsole}" ] && /sbin/modprobe netconsole netconsole="${netconsole}"
load_modules
[ "$quiet" != "y" ] && log_end_msg
@ -277,7 +284,7 @@ log_begin_msg "Mounting root file system"
# /usr, irrespective of the boot script used to mount the rootfs).
. /scripts/local
. /scripts/nfs
. /scripts/${BOOT}
. "/scripts/${BOOT}"
parse_numeric "${ROOT}"
maybe_break mountroot
mount_top
@ -296,6 +303,18 @@ mount_bottom
nfs_bottom
local_bottom
case "$IP" in
""|none|off)
case "$IP6" in
""|none|off) ;; # Do nothing
*)
configure_networking
esac
;;
*)
configure_networking
esac
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

View File

@ -56,6 +56,13 @@ Specifies the compression method used for the initramfs image.
will default to gzip if the kernel lacks support (CONFIG_RD) or the
corresponding userspace utility is not present.
.TP
\fB COMPRESSLEVEL
Specifies the compression level used for the initramfs image.
.B mkinitramfs
will default to 9 for lz4, 9 for zstd, and the builtin defaults for all
others.
.TP
\fB UMASK
Set the umask value of the generated initramfs file.

View File

@ -53,5 +53,6 @@ if [ "$#" -eq 0 ] ; then
fi
for initramfs in "$@" ; do
# shellcheck disable=SC2086
unmkinitramfs $umi_opts -- "$initramfs"
done

View File

@ -20,6 +20,7 @@ Usage: mkinitramfs [option]... -o outfile [version]
Options:
-c compress Override COMPRESS setting in initramfs.conf.
-d confdir Specify an alternative configuration directory.
-l level Override COMPRESSLEVEL setting in initramfs.conf.
-k Keep temporary directory used to make the image.
-o outfile Write to outfile.
-r root Override ROOT setting in initramfs.conf.
@ -35,7 +36,7 @@ usage_error()
exit 2
}
OPTIONS=$(getopt -o c:d:hko:r:v --long help -n "$0" -- "$@") || usage_error
OPTIONS=$(getopt -o c:d:hl:ko:r:v --long help -n "$0" -- "$@") || usage_error
eval set -- "$OPTIONS"
@ -57,6 +58,10 @@ while true; do
usage
exit 0
;;
-l)
compresslevel="$2"
shift 2
;;
-o)
outfile="$2"
shift 2
@ -179,10 +184,45 @@ fi
unset COMPRESS
if ! command -v "${compress}" >/dev/null 2>&1; then
echo "No ${compress} in ${PATH}, using gzip"
echo "W: No ${compress} in ${PATH}, using gzip" >&2
compress=gzip
fi
# Check that kernel supports selected compressor, and fall back to gzip.
# Exit if even gzip is not supported.
case "${compress}" in
gzip) kconfig_sym=CONFIG_RD_GZIP ;;
bzip2) kconfig_sym=CONFIG_RD_BZIP2 ;;
lzma) kconfig_sym=CONFIG_RD_LZMA ;;
xz) kconfig_sym=CONFIG_RD_XZ ;;
lzop) kconfig_sym=CONFIG_RD_LZO ;;
lz4) kconfig_sym=CONFIG_RD_LZ4 ;;
zstd) kconfig_sym=CONFIG_RD_ZSTD ;;
esac
while ! grep -q "^$kconfig_sym=y" "/boot/config-${version}"; do
if [ "${compress}" = gzip ]; then
echo "E: gzip compression ($kconfig_sym) not supported by kernel" >&2
exit 1
fi
echo "W: ${compress} compression ($kconfig_sym) not supported by kernel, using gzip" >&2
compress=gzip
kconfig_sym=CONFIG_RD_GZIP
done
if [ -z "${compresslevel:-}" ]; then
compresslevel=${COMPRESSLEVEL:-}
fi
case "${compress}" in
lz4) compresslevel="-${compresslevel:-2}" ;;
zstd) compresslevel="-${compresslevel:-1}" ;;
#gzip|xz|bzip2|lzma|lzop included
*)
# We're not using a compression level by default
compresslevel="${compresslevel:+-${compresslevel}}"
;;
esac
unset COMPRESSLEVEL
case "${compress}" in
gzip) # If we're doing a reproducible build, use gzip -n
if [ -n "${SOURCE_DATE_EPOCH}" ]; then
@ -191,15 +231,21 @@ gzip) # If we're doing a reproducible build, use gzip -n
elif command -v pigz >/dev/null; then
compress=pigz
fi
if [ -n "${compresslevel}" ]; then
compress="${compress} ${compresslevel}"
fi
;;
lz4) compress="lz4 -2 -l" ;;
zstd) compress="zstd -q -1 -T0" ;;
xz) compress="xz --check=crc32"
lz4) compress="lz4 ${compresslevel} -l" ;;
zstd) compress="zstd -q ${compresslevel}"
# If we're not doing a reproducible build, enable multithreading
test -z "${SOURCE_DATE_EPOCH}" && compress="$compress -T0"
;;
xz) compress="xz ${compresslevel} --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
compress="${compress} ${compresslevel}"
;;
*) echo "W: Unknown compression command ${compress}" >&2 ;;
esac
@ -221,17 +267,20 @@ fi
# Prepare to clean up temporary files on exit
DESTDIR=
__TMPMAINFILES=
__TMPUNCOMPRESSEDFILES=
__TMPCPIOGZ=
__TMPMAINCPIO=
__TMPEARLYCPIO=
# shellcheck disable=SC2317
clean_on_exit() {
if [ "${keep}" = "y" ]; then
echo "Working files in ${DESTDIR:-<not yet created>}," \
"early initramfs in ${__TMPEARLYCPIO:-<not yet created>}," \
"main initramfs in ${__TMPMAINCPIO:-<not yet created>} and" \
"list of files for main initramfs in ${__TMPMAINFILES:-<not yet created>}," \
"list of files for uncompressed initramfs in ${__TMPUNCOMPRESSEDFILES:-<not yet created>}," \
"early initramfs in ${__TMPEARLYCPIO:-<not yet created>} and" \
"overlay in ${__TMPCPIOGZ:-<not yet created>}"
else
for path in "${DESTDIR}" "${__TMPCPIOGZ}" "${__TMPMAINCPIO}" "${__TMPEARLYCPIO}"; do
for path in "${DESTDIR}" "${__TMPMAINFILES}" "${__TMPUNCOMPRESSEDFILES}" "${__TMPCPIOGZ}" "${__TMPEARLYCPIO}"; do
test -z "${path}" || rm -rf "${path}"
done
fi
@ -243,8 +292,9 @@ trap "exit 1" INT TERM # makes the EXIT trap effective even when killed
[ -n "${TMPDIR}" ] && [ ! -w "${TMPDIR}" ] && unset TMPDIR
DESTDIR="$(mktemp -d "${TMPDIR:-/var/tmp}/mkinitramfs_XXXXXX")" || exit 1
chmod 755 "${DESTDIR}"
__TMPMAINFILES="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-MAIN_files_XXXXXX")" || exit 1
__TMPUNCOMPRESSEDFILES="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-UNCOMPRESSED_files_XXXXXX")" || exit 1
__TMPCPIOGZ="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-OL_XXXXXX")" || exit 1
__TMPMAINCPIO="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-MAIN_XXXXXX")" || exit 1
__TMPEARLYCPIO="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-FW_XXXXXX")" || exit 1
DPKG_ARCH=$(dpkg --print-architecture)
@ -392,24 +442,6 @@ for b in $(cd "${DESTDIR}/scripts" && find . -mindepth 1 -type d); do
cache_run_scripts "${DESTDIR}" "/scripts/${b#./}"
done
# decompress modules for boot speed, if possible
find "${DESTDIR}/${MODULESDIR}" -name '*.ko.*' | while read -r ko; do
case "$ko" in
*.xz)
if ! command -v xz >/dev/null 2>&1; then
break
fi
xz -d "${ko}"
;;
*.zst)
if ! command -v zstd >/dev/null 2>&1; then
break
fi
zstd -q -d --rm "${ko}"
;;
esac
done
# generate module deps
depmod -a -b "${DESTDIR}" "${version}"
rm -f "${DESTDIR}/lib/modules/${version}"/modules.*map
@ -438,12 +470,12 @@ esac
# Remove any looping or broken symbolic links, since they break cpio.
[ "${verbose}" = y ] && xargs_verbose="-t"
# shellcheck disable=SC2086
(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"
(
# preserve permissions if root builds the image, see #633582
[ "$(id -ru)" != 0 ] && cpio_owner_root="-R 0:0"
@ -457,46 +489,70 @@ if [ -n "${SOURCE_DATE_EPOCH}" ]; then
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 >>"${outfile}" || exit 1
ec1=1
ec2=1
exec 3>&1
eval "$(
# http://cfaj.freeshell.org/shell/cus-faq-2.html
exec 4>&1 >&3 3>&-
cd "${DESTDIR}"
# Read list of files and echo them plus all leading directories.
# The same directories might be printed multiple times (even with sorted input)!
add_directories() {
local last_dir path dir
while read -r path; do
dir="${path%/*}"
parent="${dir}"
while [ "$parent" != "$last_dir" ] && [ "$parent" != "." ]; do
echo "$parent"
parent="${parent%/*}"
done
last_dir="$dir"
echo "$path"
done
if [ -n "$last_dir" ]; then
echo "."
fi
}
cd "${DESTDIR}" || exit 1
# work around lack of "set -o pipefail" for pipes.
# Write exit code to FD 3 in case of a failure to pass it through the pipes.
{
{
find . 4>&-; echo "ec1=$?;" >&4
} | {
LC_ALL=C sort
} | {
# shellcheck disable=SC2086
cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc 4>&- >"${__TMPMAINCPIO}"
echo "ec2=$?;" >&4
}
)"
if [ "$ec1" -ne 0 ]; then
echo "E: mkinitramfs failure find $ec1 cpio $ec2" >&2
exit "$ec1"
fi
if [ "$ec2" -ne 0 ]; then
echo "E: mkinitramfs failure cpio $ec2" >&2
exit "$ec2"
fi
) || exit 1
find . \( ! -type d ! -name '*.zst' ! -name '*.xz' \) -o \( -type d -empty \) ||
{ echo "E: mkinitramfs failure main find $?" >&2; echo 1 >&3; exit; }
} | add_directories | {
LC_ALL=C sort || { echo "E: mkinitramfs failure sort $?" >&2; echo 1 >&3; exit; }
} | uniq > "${__TMPMAINFILES}" || { echo "E: mkinitramfs failure uniq $?" >&2; echo 1 >&3; exit; }
} 3>&1 | { read -r exit_code; exit "${exit_code:-0}"; } || exit $?
{
if [ -s "${__TMPEARLYCPIO}" ]; then
cat "${__TMPEARLYCPIO}" || exit 1
fi
{
find . -name '*.zst' -o -name '*.xz' ||
{ echo "E: mkinitramfs failure uncompressed find $?" >&2; echo 1 >&3; exit; }
} | add_directories | {
LC_ALL=C sort || { echo "E: mkinitramfs failure sort $?" >&2; echo 1 >&3; exit; }
} | uniq > "${__TMPUNCOMPRESSEDFILES}" || { echo "E: mkinitramfs failure uniq $?" >&2; echo 1 >&3; exit; }
} 3>&1 | { read -r exit_code; exit "${exit_code:-0}"; } || exit $?
$compress -c "${__TMPMAINCPIO}" ||
{ echo "E: mkinitramfs failure $compress $?" >&2; exit 1; }
{
{
if [ -s "${__TMPEARLYCPIO}" ]; then
cat "${__TMPEARLYCPIO}" || { echo 1 >&3; exit; }
fi
if [ -s "${__TMPCPIOGZ}" ]; then
cat "${__TMPCPIOGZ}" || exit 1
fi
} >"${outfile}" || exit 1
if [ -s "${__TMPUNCOMPRESSEDFILES}" ]; then
# shellcheck disable=SC2086
cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc -D "${DESTDIR}" <"${__TMPUNCOMPRESSEDFILES}" ||
{ echo "E: mkinitramfs failure uncompressed cpio $?" >&2; echo 1 >&3; exit; }
fi
{
# shellcheck disable=SC2086
cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc -D "${DESTDIR}" <"${__TMPMAINFILES}" ||
{ echo "E: mkinitramfs failure cpio $?" >&2; echo 1 >&3; exit; }
} | $compress -c ||
{ echo "E: mkinitramfs failure $compress $?" >&2; echo 1 >&3; exit; }
if [ -s "${__TMPCPIOGZ}" ]; then
cat "${__TMPCPIOGZ}" || { echo 1 >&3; exit; }
fi
} >"${outfile}" || echo $? >&3
} 3>&1 | { read -r exit_code; exit "${exit_code:-0}"; } || exit $?
exit 0

View File

@ -48,6 +48,13 @@ Set an alternate configuration directory.
\fB\-k
Keep the temporary directory used to make the image.
.TP
\fB\-l \fI compresslevel
Override the
.B COMPRESSLEVEL
setting in
.IR initramfs.conf .
.TP
\fB\-o \fI outfile
Write the image to

View File

@ -107,13 +107,13 @@ maybe_break()
else
opts="-v"
fi
modprobe ${opts} -a i8042 atkbd ehci-pci ehci-orion \
/sbin/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}")"
/sbin/modprobe ${opts} -b "$(cat "${modalias}")"
fi
done
fi
@ -147,7 +147,7 @@ load_modules()
continue
fi
# shellcheck disable=SC2086
modprobe $m
/sbin/modprobe $m
done < /conf/modules
fi
}
@ -214,13 +214,11 @@ get_fstype ()
return 0
}
_handle_device_vs_ip()
_set_netdev_from_ip_param()
{
# 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
# If the ip= parameter is present and specifies a device, use
# that in preference to any device name we already have
local rc=1
local IFS=:
set -f
# shellcheck disable=SC2086
@ -228,71 +226,116 @@ _handle_device_vs_ip()
set +f
if [ -n "$6" ]; then
DEVICE="$6"
elif [ $# -ge 2 ] && [ -n "${DEVICE}" ]; then
rc=0
fi
case "$IP6" in
""|on|dhcp|any|none|off)
;;
*)
DEVICE6="$IP6"
rc=0
;;
esac
return $rc
}
_set_netdev_from_hw_address()
{
local want_address="$1"
local device
for device in /sys/class/net/*; do
if [ -f "$device/address" ] &&
[ "$(cat "$device/address")" = "$want_address" ]; then
DEVICE="${device##*/}"
DEVICE6="${device##*/}"
return 0
fi
done
return 1
}
_usable_netdev_exists()
{
# Look for a device with IFF_LOOPBACK clear and (IFF_BROADCAST
# or IFF_POINTTOPOINT) set. This is the same test the kernel
# and ipconfig apply to find a device.
local device
local flags
for device in /sys/class/net/*; do
if [ -f "${device}/flags" ]; then
flags="$(cat "${device}/flags")"
if [ "$((flags & 8))" -eq 0 ] &&
[ "$((flags & 0x12))" -ne 0 ]; then
return 0
fi
fi
done
return 1
}
_set_available_devices_to_up()
{
# Look for devices with (IFF_UP and IFF_LOOPBACK) clear and
# (IFF_BROADCAST or IFF_POINTTOPOINT) set. Bring those devices up.
# Skip any enslaved device (has "master" link attribute on it)
# if NETWORK_SKIP_ENSLAVED is set to a value different than "0".
local device
local flags
for device in /sys/class/net/*; do
if [ ! -f "${device}/flags" ]; then
continue
fi
flags="$(cat "${device}/flags")"
if [ "$((flags & 9))" -ne 0 ] ||
[ "$((flags & 0x12))" -eq 0 ]; then
continue
fi
if [ "${NETWORK_SKIP_ENSLAVED:-0}" != 0 ]; then
ip -o link show "${device##*/}" | grep -q -w master && continue
fi
echo "Setting ip link ${device##*/} up"
echo "$(( flags | 1 ))" > "${device}/flags"
done
}
_update_ip_param()
{
# If the ip= parameter is present, and is a colon-separated list,
# but does not specify a device, substitute in the device name
# we have
local IFS=:
set -f
# shellcheck disable=SC2086
set -- ${IP}
set +f
if [ -z "$6" ] && [ $# -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
local netdev_desc
# The order of precedence here is:
# 1. Device specified by ip= kernel parameter
# 2. Device matching MAC specified by BOOTIF= kernel parameter
# 3. Build-time DEVICE variable
# In case 2 we only discover the device name while waiting
# for a device.
if _set_netdev_from_ip_param; then
if [ -n "${DEVICE}" ] && [ -n "${DEVICE6}" ]; then
netdev_desc="${DEVICE} and ${DEVICE6}"
else
netdev_desc="${DEVICE:-$DEVICE6}"
fi
elif [ -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.
# network card used to PXE boot
# pxelinux sets BOOTIF to 01-$mac_address
# strip off the leading "01-", which isn't part of the mac
@ -311,29 +354,25 @@ configure_networking()
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
_set_netdev_from_hw_address "${bootif_mac}"
netdev_desc="device with address ${bootif_mac}"
elif [ -n "${DEVICE}${DEVICE6}" ]; then
if [ -n "${DEVICE}" ] && [ -n "${DEVICE6}" ]; then
netdev_desc="${DEVICE} and ${DEVICE6}"
else
netdev_desc="${DEVICE:-$DEVICE6}"
fi
else
netdev_desc="any network device"
fi
_handle_device_vs_ip
for v in $VLAN; do
VLAN_LINK="$VLAN_LINK ${v##*:}"
VLAN_NAMES="$VLAN_NAMES ${v%:*}"
done
# activate non-autoconfigured s390x devices
for dev in $DEVICE $DEVICE6 $IP6 $VLAN_LINK; do
for dev in $DEVICE $DEVICE6 $VLAN_LINK; do
# do not chzdev $dev if it is a not-yet-created vlan interface
for vlan_name in $VLAN_NAMES; do
if [ "$dev" = "$vlan_name" ]; then
@ -356,20 +395,25 @@ configure_networking()
ip link add name "$vname" link "$vlink" type vlan id "$vid"
done
if [ -n "${DEVICE}" ]; then
local netdevwait=180
log_begin_msg "Waiting up to ${netdevwait} secs for ${DEVICE} to become available"
while [ "$(time_elapsed)" -lt "$netdevwait" ]; do
if [ -e "/sys/class/net/${DEVICE}" ]; then
break
fi
sleep 1
done
if [ ! -e "/sys/class/net/${DEVICE}" ]; then
log_failure_msg "Interface ${DEVICE} did not appear in time"
local netdevwait=180
log_begin_msg "Waiting up to ${netdevwait} secs for ${netdev_desc} to become available"
while true; do
if [ "$(time_elapsed)" -ge "$netdevwait" ]; then
log_failure_msg "Network device did not appear in time"
break
fi
log_end_msg
fi
if [ -n "${DEVICE}" ]; then
[ -e "/sys/class/net/${DEVICE}" ] && break
elif [ -n "${bootif_mac}" ]; then
_set_netdev_from_hw_address "${bootif_mac}" && break
else
_usable_netdev_exists && break
fi
sleep 1
done
log_end_msg
_update_ip_param
wait_for_udev 10
@ -384,37 +428,35 @@ configure_networking()
# 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
IP="done"
break
fi
done
for x in /run/net6-"${DEVICE}".conf /run/net6-*.conf ; do
if [ -e "$x" ]; then
IP6=done
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
if [ "$IP" = "done" ] && [ "$IP6" = "done" ]; then
break
fi
if [ -z "${DEVICE}" ]; then
_set_available_devices_to_up
fi
case ${IP} in
none|done|off)
# Do nothing
IP=done
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
dhcpcd -1 -t $ROUNDTTT -4 ${DEVICE:+"${DEVICE}"}
;;
*)
ipconfig -t ${ROUNDTTT} -d "$IP"
@ -424,7 +466,7 @@ configure_networking()
case ${IP6} in
""|none|done|off)
# Do nothing
IP6=done
IP6="done"
;;
*)
# check the content of IP6 and if it is not on/dhcp/any use it as
@ -437,12 +479,7 @@ configure_networking()
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
dhcpcd -1 -t $ROUNDTTT -6 ${DEVICE6:+"${DEVICE6}"}
;;
esac
done
@ -482,7 +519,9 @@ netinfo_to_resolv_conf() {
. "$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
if [ -z "$n" ] || [ "$n" = "0.0.0.0" ]; then
continue
fi
# skip if 'n' already in list.
case " ${ns} " in
*\ $n\ *) continue;;
@ -534,7 +573,9 @@ _declare_sh_append_var() {
local name="$1" skip="$2" add="" n=""
shift 2
for n in "$@"; do
[ -n "$n" ] && [ "$n" != "$skip" ] || continue
if [ -z "$n" ] || [ "$n" = "$skip" ]; then
continue
fi
add="$add $n"
done
add=${add# }
@ -595,8 +636,12 @@ _render_netplan() {
echo " dhcp4: $dhcp4"
echo " dhcp-identifier: mac"
fi
[ -n "$dhcp6" ] && echo " dhcp6: $dhcp6" || true
[ -n "$dhcp4$dhcp6" ] && echo " critical: true" || true
if [ -n "$dhcp6" ]; then
echo " dhcp6: $dhcp6"
fi
if [ -n "$dhcp4$dhcp6" ]; then
echo " critical: true"
fi
if [ -n "$addrs" ]; then
echo " addresses:"
found=","
@ -607,8 +652,12 @@ _render_netplan() {
echo " - \"$n\""
done
fi
[ -n "$gateway4" ] && echo " gateway4: \"$gateway4\"" || true
[ -n "$gateway6" ] && echo " gateway6: \"$gateway6\"" || true
if [ -n "$gateway4" ]; then
echo " gateway4: \"$gateway4\""
fi
if [ -n "$gateway6" ]; then
echo " gateway6: \"$gateway6\""
fi
if [ -n "$ns_addrs" ]; then
local alist="[" slist=""
@ -630,7 +679,9 @@ _render_netplan() {
fi
echo " nameservers:"
echo " addresses: $alist"
[ -n "$slist" ] && echo " search: $slist" || true
if [ -n "$slist" ]; then
echo " search: $slist"
fi
fi
}
@ -891,7 +942,7 @@ _checkfs_once()
log_warning_msg "File system check failed but did not detect errors"
sleep 5
else
true > $FSCK_STAMPFILE
true >"$FSCK_STAMPFILE"
fi
return 0
}

View File

@ -17,11 +17,11 @@ esac
for x in $(cat /proc/cmdline); do
case ${x} in
all_generic_ide)
modprobe ata_generic all_generic_ide=1
/sbin/modprobe ata_generic all_generic_ide=1
;;
all_generic_ide=*)
if [ -n "${x#all_generic_ide=}" ]; then
modprobe ata_generic all_generic_ide=1
/sbin/modprobe ata_generic all_generic_ide=1
fi
;;
esac

View File

@ -91,9 +91,12 @@ if [ -n "${FB}" ]; then
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 ! [ -d /sys/class/graphics/fbcon ] \
|| ! [ -d /sys/class/graphics/fb0 ] \
|| ! [ -d /sys/class/drm/card0 ]
then
udevadm settle
fi
# If we still have no graphics device, fall back to vesafb like
# we do in the post-initramfs case in
@ -104,9 +107,12 @@ else
# 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
sleep 1
fi
if ! [ -d /sys/class/graphics/fbcon ] \
|| ! [ -d /sys/class/graphics/fb0 ] \

View File

@ -80,7 +80,7 @@ local_device_setup()
# 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"
/sbin/modprobe ubi "mtd=$UBIMTD"
DEV="${dev_id}"
return
fi

View File

@ -23,7 +23,7 @@ esac
BROKEN_CLOCK=""
ROOTDEV=""
# System partition is currently used by ubuntu touch only
# System partition is currently used by kylin touch only
SYSTEMPART=""
# shellcheck disable=SC2013

View File

@ -81,7 +81,7 @@ nfs_mount_root()
nfs_top
# For DHCP
modprobe af_packet
/sbin/modprobe af_packet
wait_for_udev 10
@ -130,7 +130,7 @@ nfs_mount_fs()
nfs_top
# For DHCP
modprobe af_packet
/sbin/modprobe af_packet
wait_for_udev 10

View File

@ -1,42 +0,0 @@
/*
* 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

View File

@ -1,250 +0,0 @@
/*
* 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;
}

View File

@ -95,7 +95,7 @@ splitinitramfs()
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 + 110))
end=$(((end + namesize + 3) & ~3))
end=$(((end + filesize + 3) & ~3))
done
@ -122,11 +122,11 @@ splitinitramfs()
start=$end
done
if [ $end -gt 0 ]; then
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 \
dd < "$initramfs" skip="$end" iflag=skip_bytes 2> /dev/null \
> "$subarchive"
# shellcheck disable=SC2030,SC2031
xcpio "$subarchive" "${dir:+$dir/main}" -i "$@"

View File

@ -11,7 +11,7 @@ set -e
[ -r ${CONF} ] && . ${CONF}
if [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] && [ $# = 1 ] && [ "$1" = '-u' ]; then
if [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] && [ $# = 1 ] && [ "$1" = -u ]; then
if dpkg-trigger --no-await update-initramfs; then
echo "update-initramfs: deferring update (trigger activated)"
exit 0
@ -102,7 +102,7 @@ backup_booted_initramfs()
# no backup yet
if [ ! -r "${initramfs}.bak" ]; then
mv -f ${initramfs_bak} "${initramfs}.bak"
mv -f "${initramfs_bak}" "${initramfs}.bak"
verbose "Backup ${initramfs}.bak"
return 0
fi
@ -119,7 +119,7 @@ backup_booted_initramfs()
return 0
fi
verbose "Removing current backup ${initramfs_bak}"
rm -f ${initramfs_bak}
rm -f "${initramfs_bak}"
}
# nuke generated copy