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 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: ... # 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 -- liushanwen <liushanwen@kylinos.cn> Thu, 12 Oct 2023 14:53:54 +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

11
debian/control vendored
View File

@ -2,13 +2,13 @@ Source: initramfs-tools
Section: utils Section: utils
Priority: optional Priority: optional
Uploaders: Michael Prokop <mika@debian.org>, Ben Hutchings <benh@debian.org> 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> 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 Rules-Requires-Root: no
Standards-Version: 4.1.5 Standards-Version: 4.1.5
Vcs-Browser: 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://gitee.com/openkylin/initramfs-tools.git 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-Browser: https://salsa.debian.org/kernel-team/initramfs-tools
X-Debian-Vcs-Git: https://salsa.debian.org/kernel-team/initramfs-tools.git 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 Package: initramfs-tools-core
Architecture: all Architecture: all
Multi-Arch: foreign 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 Suggests: bash-completion
Breaks: initramfs-tools (<< 0.121~), ${busybox:Breaks} Breaks: initramfs-tools (<< 0.121~), ${busybox:Breaks}
Replaces: initramfs-tools (<< 0.121~) 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 hooks usr/share/initramfs-tools
hook-functions usr/share/initramfs-tools hook-functions usr/share/initramfs-tools
conf/modules 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.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/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/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 # On Debian we can use either busybox or busybox-static, but on Ubuntu
# and derivatives only busybox-initramfs will work. # 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_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-4ok5~ BUSYBOX_MIN_VERSION := 1:1.30.1-4ubuntu5~
override_dh_gencontrol: override_dh_gencontrol:
echo >> debian/initramfs-tools-core.substvars "busybox:Breaks=$(wordlist 2,100,$(BUSYBOX_PACKAGES:%=, % (<< $(BUSYBOX_MIN_VERSION))))" 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: override_dh_auto_test:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
ifeq (,$(filter i386,$(DEB_HOST_ARCH))) 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') 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 endif
./tests/run-tests ./tests/run-tests
endif endif

18
debian/salsa-ci.yml vendored
View File

@ -4,3 +4,21 @@ include:
variables: variables:
RELEASE: 'unstable' 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 Test-Command: ./tests/run-tests
Depends: netplan.io Depends: netplan.io
Restrictions: allow-stderr Restrictions: allow-stderr
Features: test-name=unit-tests
Tests: net # Note: These tests need root on Ubuntu, because the kernel is only readable by root. See https://launchpad.net/bugs/759725
Depends: curl, Tests: qemu-klibc
initramfs-tools, Architecture: amd64 armhf s390x
isc-dhcp-client, Depends: genext2fs,
ipxe-qemu,
klibc-utils,
linux-image-generic, linux-image-generic,
lsb-release, qemu-efi-arm [armhf],
parted, 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, python3,
qemu-system qemu-efi-aarch64 [arm64],
Restrictions: needs-root, allow-stderr 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 #!/bin/sh -e
# Note: The qemu machines used on arm64, armhf, ppc64el, and s390x have no IDE
SUPPORTED_FLAVOURS='amd64 generic' SUPPORTED_FLAVOURS='amd64 generic'
ROOTDISK_QEMU_IF=ide ROOTDISK_QEMU_IF=ide
ROOTDISK_LINUX_NAME=sda ROOTDISK_LINUX_NAME=sda
@ -19,4 +20,5 @@ build_initramfs
build_rootfs_ext2 build_rootfs_ext2
run_qemu_amd64 run_qemu
check_no_network_configuration

View File

@ -1,6 +1,7 @@
#!/bin/sh -e #!/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 . debian/tests/test-common
cat >>"${CONFDIR}/initramfs.conf" <<EOF cat >>"${CONFDIR}/initramfs.conf" <<EOF
@ -13,7 +14,8 @@ lsinitramfs "${INITRAMFS}" | grep -qw busybox
build_rootfs_ext2 build_rootfs_ext2
run_qemu_amd64 run_qemu
check_no_network_configuration
# Check that fsck ran # Check that fsck ran
grep -q "^/dev/${ROOTDISK_LINUX_NAME}: clean," "${OUTPUT}" grep -q "^/dev/${ROOTDISK_LINUX_NAME}: clean," "${OUTPUT}"

View File

@ -1,6 +1,7 @@
#!/bin/sh -e #!/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 . debian/tests/test-common
cat >>"${CONFDIR}/initramfs.conf" <<EOF cat >>"${CONFDIR}/initramfs.conf" <<EOF
@ -13,7 +14,8 @@ build_initramfs
build_rootfs_ext2 build_rootfs_ext2
run_qemu_amd64 run_qemu
check_no_network_configuration
# Check that fsck ran # Check that fsck ran
grep -q "^/dev/${ROOTDISK_LINUX_NAME}: clean," "${OUTPUT}" 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 #!/bin/sh -e
SUPPORTED_FLAVOURS='amd64 generic' SUPPORTED_FLAVOURS='amd64 arm64 armmp powerpc64 s390x generic'
ROOTDISK_QEMU_IF=virtio ROOTDISK_QEMU_IF=virtio
ROOTDISK_LINUX_NAME=nonexistent ROOTDISK_LINUX_NAME=nonexistent
. debian/tests/test-common . debian/tests/test-common
@ -19,14 +19,17 @@ build_initramfs
build_rootfs_ext2 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 "ALERT! /dev/nonexistent does not exist. Dropping to a shell!" "${OUTPUT}"
grep -qF "(initramfs) " "${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 "Rebooting automatically due to panic= boot argument" "${OUTPUT}"
! grep -qF "(initramfs) " "${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 "Halting automatically due to panic= boot argument" "${OUTPUT}"
! grep -qF "(initramfs) " "${OUTPUT}" ! grep -qF "(initramfs) " "${OUTPUT}"

View File

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

View File

@ -1,6 +1,6 @@
#!/bin/sh -e #!/bin/sh -e
SUPPORTED_FLAVOURS='amd64 generic' SUPPORTED_FLAVOURS='amd64 arm64 armmp powerpc64 s390x generic'
ROOTDISK_QEMU_IF=virtio ROOTDISK_QEMU_IF=virtio
ROOTDISK_LINUX_NAME=vda ROOTDISK_LINUX_NAME=vda
. debian/tests/test-common . debian/tests/test-common
@ -19,4 +19,5 @@ build_initramfs
build_rootfs_ext2 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 exit 2
fi 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}" export TMPDIR="${AUTOPKGTEST_TMP}"
fi fi
BASEDIR="$(mktemp -d -t initramfs-test.XXXXXXXXXX)"
# Skeleton configuration directory # Skeleton configuration directory
CONFDIR="$(mktemp -d)" CONFDIR="${BASEDIR}/config"
mkdir -p "${CONFDIR}"
cp conf/initramfs.conf "${CONFDIR}/initramfs.conf" cp conf/initramfs.conf "${CONFDIR}/initramfs.conf"
echo "RESUME=none" >>"${CONFDIR}/initramfs.conf" echo "RESUME=none" >>"${CONFDIR}/initramfs.conf"
mkdir "${CONFDIR}/hooks"
touch "${CONFDIR}/modules" touch "${CONFDIR}/modules"
mkdir "${CONFDIR}/scripts" mkdir "${CONFDIR}/scripts"
# initramfs image file # initramfs image file
INITRAMFS="$(mktemp)" INITRAMFS="${BASEDIR}/initrd.img"
# root disk image file # root disk image file
ROOTDISK="$(mktemp)" ROOTDISK="${BASEDIR}/rootdisk.raw"
# root disk interface type (for qemu) and device name (for Linux) # root disk interface type (for qemu) and device name (for Linux)
test -n "${ROOTDISK_QEMU_IF}" || ROOTDISK_QEMU_IF=virtio test -n "${ROOTDISK_QEMU_IF}" || ROOTDISK_QEMU_IF=virtio
test -n "${ROOTDISK_LINUX_NAME}" || ROOTDISK_LINUX_NAME=vda test -n "${ROOTDISK_LINUX_NAME}" || ROOTDISK_LINUX_NAME=vda
# Create a root fs with a trivial userspace # Create a root fs with a trivial userspace
ROOTDIR="$(mktemp -d)" ROOTDIR="${BASEDIR}/rootdir"
INIT_MESSAGE='root fs init system started successfully' INIT_MESSAGE='root fs init system started successfully'
for subdir in bin dev lib proc run sbin sys usr usr/bin; do for subdir in dev proc run sys usr usr/bin usr/lib/modules usr/lib64 usr/sbin; do
mkdir "${ROOTDIR}/${subdir}" mkdir -p "${ROOTDIR}/${subdir}"
done
for subdir in bin lib lib64 sbin; do
ln -s "usr/${subdir}" "${ROOTDIR}/${subdir}"
done done
cat >"${ROOTDIR}/sbin/init" <<EOF cat >"${ROOTDIR}/sbin/init" <<EOF
#!/bin/sh -e #!/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/" cp "$(dpkg -L libklibc | grep '^/lib/klibc.*\.so$')" "${ROOTDIR}/lib/"
# VM output file # 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() { build_initramfs() {
/usr/sbin/mkinitramfs -d "${CONFDIR}" -o "${INITRAMFS}" "${KVER}" /usr/sbin/mkinitramfs -d "${CONFDIR}" -o "${INITRAMFS}" "${KVER}"
@ -71,7 +148,7 @@ build_fs_ext2() {
local inodes="$(du --summarize --inodes "${dir}" | cut -f 1)" local inodes="$(du --summarize --inodes "${dir}" | cut -f 1)"
# Add fudge factor # Add fudge factor
blocks="$((blocks + 20 + blocks / 4))" blocks="$((blocks + 28 + blocks / 4))"
inodes="$((inodes + 10))" inodes="$((inodes + 10))"
# genext2fs writes status messages to stderr; hide that from # genext2fs writes status messages to stderr; hide that from
@ -83,18 +160,70 @@ build_rootfs_ext2() {
build_fs_ext2 "${ROOTDIR}" "${ROOTDISK}" build_fs_ext2 "${ROOTDIR}" "${ROOTDISK}"
} }
_run_qemu_amd64() { _run_qemu() {
local extra_params="$*" 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 # hide error messages from autopkgtest
_run_qemu_amd64 2>&1 "$@" _run_qemu "${1-}" 2>&1
} }
run_qemu_amd64() { run_qemu() {
_run_qemu_amd64 "panic=-1" _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}" 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) intelfb|i810fb|i915)
# Needs AGP driver loaded # Needs AGP driver loaded
modprobe intel-agp /sbin/modprobe intel-agp
;; ;;
uvesafb) uvesafb)
# v86d requires /dev/zero and dev/mem, but udev haven't been started yet # v86d requires /dev/zero and dev/mem, but udev haven't been started yet
@ -99,9 +99,9 @@ esac
if [ -n "${FB}" ]; then if [ -n "${FB}" ]; then
unset MODPROBE_OPTIONS unset MODPROBE_OPTIONS
modprobe -q fbcon /sbin/modprobe -q fbcon
# shellcheck disable=SC2086 # shellcheck disable=SC2086
modprobe -q ${FB} ${OPTS} /sbin/modprobe -q ${FB} ${OPTS}
fi fi
if [ -e /proc/fb ]; then if [ -e /proc/fb ]; then

View File

@ -57,85 +57,47 @@ add_modules_from_file()
# whether a warning should be printed in that case.) # whether a warning should be printed in that case.)
add_firmware() add_firmware()
{ {
local firmware fwloc local ext firmware found_fwloc fwloc path
firmware="${1}" firmware="${1}"
if [ -e "${DESTDIR}/lib/firmware/updates/${version?}/${firmware}" ] \ for path in "updates/${version?}" "updates" "${version}" ""; do
|| [ -e "${DESTDIR}/lib/firmware/updates/${version?}/${firmware}.xz" ] \ for ext in ".xz" ".zst" ""; do
|| [ -e "${DESTDIR}/lib/firmware/updates/${firmware}" ] \ fwloc="/lib/firmware${path:+/}${path}/${firmware}${ext}"
|| [ -e "${DESTDIR}/lib/firmware/updates/${firmware}.xz" ] \ if [ -e "${DESTDIR}${fwloc}" ]; then
|| [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ] \ # DESTDIR already contains a matching firmware file.
|| [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}.xz" ] \ return 0
|| [ -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"
fi fi
return 0 if [ -z "${found_fwloc}" ] && [ -e "${fwloc}" ]; then
fi found_fwloc="$fwloc"
fi
done
done done
# We can't figure out where to get that firmware from. if [ -z "${found_fwloc}" ]; then
return 1 # We can't figure out where to get that firmware from.
return 1
fi
copy_file firmware "${found_fwloc}"
} }
# Add dependent modules + eventual firmware # Add dependent modules + eventual firmware
manual_add_modules() manual_add_modules()
{ {
local prefix kmod options firmware local dracut_verbose
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
return return
fi fi
# modprobe --ignore-install inhibits processing of 'install' if [ "${verbose?}" = "y" ]; then
# configuration lines, so that instead we will see 'insmod dracut_verbose=-v
# module.ko' as we want. However it also means that 'softdep' fi
# configuration lines and embedded softdep information is not
# processed. So we run twice, with and without this option.
# shellcheck disable=SC2034
{ modprobe --all --set-version="${version?}" --ignore-install --quiet --show-depends "$@";
modprobe --all --set-version="${version}" --quiet --show-depends "$@"; } |
while read -r prefix kmod options ; do
if [ "${prefix}" != "insmod" ]; then
continue
fi
copy_file module "${kmod}" || continue /usr/lib/dracut/dracut-install -D "$DESTDIR" --kerneldir "/lib/modules/${version?}" \
--firmwaredirs "/lib/firmware/updates/${version?}:/lib/firmware/updates:/lib/firmware/${version?}:/lib/firmware" \
# Add required firmware ${dracut_verbose-} -o -m "$@"
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
} }
# manual_add_modules() takes care of adding firmware for things that were built # 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" modules="$modules virtio_pci virtio_mmio"
fi 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 if [ -e /sys/bus/ps3_system_bus/ ]; then
modules="$modules ps3disk ps3rom ps3-gelic ps3_sys_manager" modules="$modules ps3disk ps3rom ps3-gelic ps3_sys_manager"
fi fi
@ -636,13 +593,23 @@ dep_add_modules()
# The modules "most" classes added per default to the initramfs # The modules "most" classes added per default to the initramfs
auto_add_modules() auto_add_modules()
{ {
local arg local arg blockfuncs exclude exclude_dir
local modules= local modules=
if [ "$#" -eq 0 ] ; then 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 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 for arg in "$@" ; do
case "$arg" in case "$arg" in
base) base)
@ -655,120 +622,125 @@ auto_add_modules()
modules="$modules vfat nls_cp437 nls_iso8859-1" modules="$modules vfat nls_cp437 nls_iso8859-1"
# Include most USB host and dual-role drivers # Include most USB host and dual-role drivers
copy_modules_dir kernel/drivers/usb/host \ modules="$modules ehci-hcd ehci-pci ehci-platform ohci-hcd ohci-pci"
hwa-hc.ko sl811_cs.ko sl811-hcd.ko \ modules="$modules uhci-hcd usbhid xhci-hcd xhci-pci xhci-plat-hcd"
u132-hcd.ko whci-hcd.ko modules="$modules =drivers/usb/typec"
copy_modules_dir kernel/drivers/usb/c67x00 modules="$modules =drivers/usb/c67x00"
copy_modules_dir kernel/drivers/usb/chipidea modules="$modules =drivers/usb/renesas_usbhs"
copy_modules_dir kernel/drivers/usb/dwc2
copy_modules_dir kernel/drivers/usb/dwc3
copy_modules_dir kernel/drivers/usb/isp1760
copy_modules_dir kernel/drivers/usb/musb
copy_modules_dir kernel/drivers/usb/renesas_usbhs
# and any extcon drivers for USB # and any extcon drivers for USB
modules="$modules extcon-usb-gpio extcon-usbc-cros-ec" 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 # Include all keyboard drivers and all HID drivers
# unless we're sure they don't support keyboards. # unless we're sure they don't support keyboards.
# hid-*ff covers various game controllers with # hid-*ff covers various game controllers with
# force feedback. # force feedback.
copy_modules_dir kernel/drivers/input/keyboard modules="$modules =drivers/input/keyboard"
copy_modules_dir kernel/drivers/hid \ exclude="a4tech|cypress|dr|elecom|gyration|icade|kensington"
'hid-*ff.ko' hid-a4tech.ko hid-cypress.ko \ exclude="${exclude}|kye|lcpower|magicmouse|multitouch|ntrig"
hid-dr.ko hid-elecom.ko hid-gyration.ko \ exclude="${exclude}|petalynx|picolcd|pl|ps3remote|quanta"
hid-icade.ko hid-kensington.ko hid-kye.ko \ exclude="${exclude}|roccat-ko.*|roccat-pyra|saitek|sensor-hub|sony"
hid-lcpower.ko hid-magicmouse.ko \ exclude="${exclude}|speedlink|tivo|twinhan|uclogic|wacom|waltop"
hid-multitouch.ko hid-ntrig.ko \ exclude="${exclude}|wiimote|zydacron|.*ff"
hid-petalynx.ko hid-picolcd.ko hid-pl.ko \ manual_add_modules -P "/hid-(${exclude})\.ko" =drivers/hid
hid-ps3remote.ko hid-quanta.ko \
'hid-roccat-ko*.ko' hid-roccat-pyra.ko \
hid-saitek.ko hid-sensor-hub.ko hid-sony.ko \
hid-speedlink.ko hid-tivo.ko hid-twinhan.ko \
hid-uclogic.ko hid-wacom.ko hid-waltop.ko \
hid-wiimote.ko hid-zydacron.ko
# needed to access keyboard on some ChromeOS devices # needed to access keyboard on some ChromeOS devices
modules="$modules cros_ec_spi" modules="$modules cros_ec_spi"
# Any of these might be needed by other drivers # For Linux console access
copy_modules_dir kernel/drivers/bus modules="$modules =drivers/tty/serial"
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
# Needed for periodic fsck # Any of these might be needed by other drivers
copy_modules_dir kernel/drivers/rtc 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) hw_random)
copy_modules_dir kernel/drivers/char/hw_random modules="$modules =drivers/char/hw_random"
;; ;;
net) net)
copy_modules_dir kernel/drivers/net \ exclude="cdc_mbim|ipheth|qmi_wwan|sierra_net|veth|xen-netback"
appletalk arcnet bonding can dummy.ko \ exclude_dir="isdn|net/ethernet|net/phy|net/team|uwb|wan|wireless"
hamradio hippi ifb.ko irda macvlan.ko \ manual_add_modules -P "/((${exclude})\.ko|(${exclude_dir})/)" \
macvtap.ko pcmcia sb1000.ko team tokenring \ -s "eth_type_trans|register_virtio_device|usbnet_open" \
tun.ko veth.ko wan wimax wireless \ "=drivers/net"
cdc_mbim.ko cdc-phonet.ko hso.ko huawei_cdc_ncm.ko ipheth.ko kalmia.ko \ modules="$modules =drivers/net/ethernet =drivers/net/mdio"
lg-vl600.ko qmi_wwan.ko sierra_net.ko cdc_subset.ko gl620a.ko \ modules="$modules =drivers/net/phy 8021q ipvlan"
net1080.ko plusb.ko cx82310_eth.ko zaurus.ko \
xen-netback.ko # Required to initialize Ethernet (FEC) on ARM64 iMX8M
modules="$modules 8021q" # devices.
modules="$modules nvmem-imx-ocotp"
;; ;;
ide) ide)
copy_modules_dir kernel/drivers/ide modules="$modules =drivers/ide"
;; ;;
mmc) mmc)
copy_modules_dir kernel/drivers/mmc modules="$modules =drivers/mmc"
;; ;;
scsi) 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" modules="$modules mptfc mptsas mptscsih mptspi zfcp"
# scsi_transport_srp should have been pulled in by =drivers/scsi
modules="$modules scsi_transport_srp"
;; ;;
ata) ata)
copy_modules_dir kernel/drivers/ata manual_add_modules -s "${blockfuncs}" "=drivers/ata"
;; ;;
block) block)
copy_modules_dir kernel/drivers/block manual_add_modules -s "${blockfuncs}" "=drivers/block" \
copy_modules_dir kernel/drivers/nvme "=drivers/nvme" "=drivers/dax" vmd
copy_modules_dir kernel/drivers/nvdimm manual_add_modules -s nvdimm_bus_register "=drivers/nvdimm" "=drivers/acpi"
copy_modules_dir kernel/drivers/dax
copy_modules_dir kernel/drivers/acpi/nfit
modules="$modules vmd"
;; ;;
ubi) ubi)
modules="$modules deflate zlib lzo ubi ubifs" modules="$modules deflate zlib lzo ubi ubifs"
;; ;;
ieee1394)
modules="$modules ohci1394 sbp2"
;;
firewire) firewire)
modules="$modules firewire-ohci firewire-sbp2" modules="$modules firewire-ohci firewire-sbp2"
;; ;;
i2o)
modules="$modules i2o_block"
;;
dasd) dasd)
modules="$modules dasd_diag_mod dasd_eckd_mod dasd_fba_mod" modules="$modules dasd_diag_mod dasd_eckd_mod dasd_fba_mod"
;; ;;
usb_storage) usb_storage)
copy_modules_dir kernel/drivers/usb/storage modules="$modules =drivers/usb/storage"
;; ;;
fb) fb)
# For machines that don't have a generic framebuffer device. # For machines that don't have a generic framebuffer device.
modules="$modules rockchipdrm pwm-cros-ec pwm_bl panel-simple" modules="$modules rockchipdrm pwm-cros-ec pwm_bl pwm-rockchip panel-simple"
modules="$modules analogix-anx6345 pwm-sun4i sun4i-drm sun8i-mixer" 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) virtual)
# Hyper-V # Hyper-V
@ -833,7 +805,7 @@ hidden_dep_add_modules()
echo pl330 echo pl330
;; ;;
dw_mmc-rockchip) dw_mmc-rockchip)
echo rockchip-io-domain echo rockchip-io-domain io-domain
;; ;;
esac esac
done done
@ -862,7 +834,7 @@ set_initlist()
[ "${si_x}" = "${initdir}/*" ] && return [ "${si_x}" = "${initdir}/*" ] && return
# only allow variable name chars # only allow variable name chars
case ${si_x#"${initdir}"/} in case "${si_x#"${initdir}"/}" in
*[![:alnum:]\._-]*) *[![:alnum:]\._-]*)
[ "${verbose}" = "y" ] \ [ "${verbose}" = "y" ] \
&& echo "$si_x ignored: not alphanumeric or '_' file" >&2 && echo "$si_x ignored: not alphanumeric or '_' file" >&2
@ -947,7 +919,7 @@ call_scripts()
if [ "$ec" -ne 0 ]; then if [ "$ec" -ne 0 ]; then
echo "E: ${initdir}/${cs_x} failed with return $ec." >&2 echo "E: ${initdir}/${cs_x} failed with return $ec." >&2
# only errexit on mkinitramfs # only errexit on mkinitramfs
[ -n "${version}" ] && exit $ec [ -n "${version}" ] && exit "$ec"
fi fi
# allow boot scripts to modify exported boot parameters # allow boot scripts to modify exported boot parameters
if [ -e /conf/param.conf ]; then if [ -e /conf/param.conf ]; then
@ -974,13 +946,9 @@ run_scripts_optional()
} }
add_dns() { 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) # find the multiarch lib dir (for example /lib/x86_64-linux-gnu)
# by finding a directory with libc.so.6. libdir=$(ldd /bin/sh | sed -En 's;^.*\s(\S+)/libc\.so\..*$;\1;p')
for d in /lib/* /lib; do
for f in "$d"/libc.so.?; do [ -f "$f" ] && break; done
[ -f "$f" ] && libdir="$d" && break
done
if [ -z "$libdir" ]; then if [ -z "$libdir" ]; then
echo "WARNING: no libdir found for adding dns." 1>&2 echo "WARNING: no libdir found for adding dns." 1>&2
return 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 . /usr/share/initramfs-tools/hook-functions
copy_modules_dir kernel/drivers/char/agp manual_add_modules "=drivers/char/agp" "=drivers/gpu" "=ubuntu/i915" \
copy_modules_dir kernel/drivers/gpu fbcon vesafb vga16fb vboxvideo
copy_modules_dir kernel/ubuntu/i915
manual_add_modules fbcon
manual_add_modules vesafb
manual_add_modules vga16fb
manual_add_modules vboxvideo
for x in "${MODULESDIR}"/initrd/*; do for x in "${MODULESDIR}"/initrd/*; do
x=${x##*/} x=${x##*/}

View File

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

View File

@ -55,17 +55,11 @@ powerpc|ppc64)
exit 0 exit 0
;; ;;
esac esac
manual_add_modules windfarm_core manual_add_modules windfarm_core windfarm_cpufreq_clamp \
manual_add_modules windfarm_cpufreq_clamp windfarm_lm75_sensor windfarm_max6690_sensor windfarm_pid \
manual_add_modules windfarm_lm75_sensor windfarm_smu_controls windfarm_smu_sat windfarm_smu_sensors
manual_add_modules windfarm_max6690_sensor
manual_add_modules windfarm_pid
manual_add_modules windfarm_smu_controls
manual_add_modules windfarm_smu_sat
manual_add_modules windfarm_smu_sensors
;; ;;
i386|amd64|ia64) i386|amd64|ia64)
manual_add_modules fan manual_add_modules fan thermal
manual_add_modules thermal
;; ;;
esac 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 # 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 # are used; which they will be, but it's worth pointing out
mount -t devtmpfs -o nosuid,mode=0755 udev /dev 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 mkdir /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true 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 mkdir -m 0700 /run/initramfs
if [ -n "$log_output" ]; then if [ -n "$log_output" ]; then
exec >$log_output 2>&1 exec >"$log_output" 2>&1
unset log_output unset log_output
fi fi
@ -258,7 +265,7 @@ run_scripts /scripts/init-top
maybe_break modules maybe_break modules
[ "$quiet" != "y" ] && log_begin_msg "Loading essential drivers" [ "$quiet" != "y" ] && log_begin_msg "Loading essential drivers"
[ -n "${netconsole}" ] && modprobe netconsole netconsole="${netconsole}" [ -n "${netconsole}" ] && /sbin/modprobe netconsole netconsole="${netconsole}"
load_modules load_modules
[ "$quiet" != "y" ] && log_end_msg [ "$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). # /usr, irrespective of the boot script used to mount the rootfs).
. /scripts/local . /scripts/local
. /scripts/nfs . /scripts/nfs
. /scripts/${BOOT} . "/scripts/${BOOT}"
parse_numeric "${ROOT}" parse_numeric "${ROOT}"
maybe_break mountroot maybe_break mountroot
mount_top mount_top
@ -296,6 +303,18 @@ mount_bottom
nfs_bottom nfs_bottom
local_bottom local_bottom
case "$IP" in
""|none|off)
case "$IP6" in
""|none|off) ;; # Do nothing
*)
configure_networking
esac
;;
*)
configure_networking
esac
maybe_break bottom maybe_break bottom
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-bottom" [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-bottom"
# We expect udev's init-bottom script to move /dev to ${rootmnt}/dev # 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 will default to gzip if the kernel lacks support (CONFIG_RD) or the
corresponding userspace utility is not present. 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 .TP
\fB UMASK \fB UMASK
Set the umask value of the generated initramfs file. Set the umask value of the generated initramfs file.

View File

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

View File

@ -20,6 +20,7 @@ Usage: mkinitramfs [option]... -o outfile [version]
Options: Options:
-c compress Override COMPRESS setting in initramfs.conf. -c compress Override COMPRESS setting in initramfs.conf.
-d confdir Specify an alternative configuration directory. -d confdir Specify an alternative configuration directory.
-l level Override COMPRESSLEVEL setting in initramfs.conf.
-k Keep temporary directory used to make the image. -k Keep temporary directory used to make the image.
-o outfile Write to outfile. -o outfile Write to outfile.
-r root Override ROOT setting in initramfs.conf. -r root Override ROOT setting in initramfs.conf.
@ -35,7 +36,7 @@ usage_error()
exit 2 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" eval set -- "$OPTIONS"
@ -57,6 +58,10 @@ while true; do
usage usage
exit 0 exit 0
;; ;;
-l)
compresslevel="$2"
shift 2
;;
-o) -o)
outfile="$2" outfile="$2"
shift 2 shift 2
@ -179,10 +184,45 @@ fi
unset COMPRESS unset COMPRESS
if ! command -v "${compress}" >/dev/null 2>&1; then 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 compress=gzip
fi 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 case "${compress}" in
gzip) # If we're doing a reproducible build, use gzip -n gzip) # If we're doing a reproducible build, use gzip -n
if [ -n "${SOURCE_DATE_EPOCH}" ]; then 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 elif command -v pigz >/dev/null; then
compress=pigz compress=pigz
fi fi
if [ -n "${compresslevel}" ]; then
compress="${compress} ${compresslevel}"
fi
;; ;;
lz4) compress="lz4 -2 -l" ;; lz4) compress="lz4 ${compresslevel} -l" ;;
zstd) compress="zstd -q -1 -T0" ;; zstd) compress="zstd -q ${compresslevel}"
xz) compress="xz --check=crc32" # 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 # If we're not doing a reproducible build, enable multithreading
test -z "${SOURCE_DATE_EPOCH}" && compress="$compress --threads=0" test -z "${SOURCE_DATE_EPOCH}" && compress="$compress --threads=0"
;; ;;
bzip2|lzma|lzop) bzip2|lzma|lzop)
# no parameters needed compress="${compress} ${compresslevel}"
;; ;;
*) echo "W: Unknown compression command ${compress}" >&2 ;; *) echo "W: Unknown compression command ${compress}" >&2 ;;
esac esac
@ -221,17 +267,20 @@ fi
# Prepare to clean up temporary files on exit # Prepare to clean up temporary files on exit
DESTDIR= DESTDIR=
__TMPMAINFILES=
__TMPUNCOMPRESSEDFILES=
__TMPCPIOGZ= __TMPCPIOGZ=
__TMPMAINCPIO=
__TMPEARLYCPIO= __TMPEARLYCPIO=
# shellcheck disable=SC2317
clean_on_exit() { clean_on_exit() {
if [ "${keep}" = "y" ]; then if [ "${keep}" = "y" ]; then
echo "Working files in ${DESTDIR:-<not yet created>}," \ echo "Working files in ${DESTDIR:-<not yet created>}," \
"early initramfs in ${__TMPEARLYCPIO:-<not yet created>}," \ "list of files for main initramfs in ${__TMPMAINFILES:-<not yet created>}," \
"main initramfs in ${__TMPMAINCPIO:-<not yet created>} and" \ "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>}" "overlay in ${__TMPCPIOGZ:-<not yet created>}"
else else
for path in "${DESTDIR}" "${__TMPCPIOGZ}" "${__TMPMAINCPIO}" "${__TMPEARLYCPIO}"; do for path in "${DESTDIR}" "${__TMPMAINFILES}" "${__TMPUNCOMPRESSEDFILES}" "${__TMPCPIOGZ}" "${__TMPEARLYCPIO}"; do
test -z "${path}" || rm -rf "${path}" test -z "${path}" || rm -rf "${path}"
done done
fi fi
@ -243,8 +292,9 @@ trap "exit 1" INT TERM # makes the EXIT trap effective even when killed
[ -n "${TMPDIR}" ] && [ ! -w "${TMPDIR}" ] && unset TMPDIR [ -n "${TMPDIR}" ] && [ ! -w "${TMPDIR}" ] && unset TMPDIR
DESTDIR="$(mktemp -d "${TMPDIR:-/var/tmp}/mkinitramfs_XXXXXX")" || exit 1 DESTDIR="$(mktemp -d "${TMPDIR:-/var/tmp}/mkinitramfs_XXXXXX")" || exit 1
chmod 755 "${DESTDIR}" 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 __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 __TMPEARLYCPIO="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-FW_XXXXXX")" || exit 1
DPKG_ARCH=$(dpkg --print-architecture) 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#./}" cache_run_scripts "${DESTDIR}" "/scripts/${b#./}"
done 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 # generate module deps
depmod -a -b "${DESTDIR}" "${version}" depmod -a -b "${DESTDIR}" "${version}"
rm -f "${DESTDIR}/lib/modules/${version}"/modules.*map rm -f "${DESTDIR}/lib/modules/${version}"/modules.*map
@ -438,12 +470,12 @@ esac
# Remove any looping or broken symbolic links, since they break cpio. # Remove any looping or broken symbolic links, since they break cpio.
[ "${verbose}" = y ] && xargs_verbose="-t" [ "${verbose}" = y ] && xargs_verbose="-t"
# shellcheck disable=SC2086
(cd "${DESTDIR}" && find . -type l -printf '%p %Y\n' | sed -n 's/ [LN]$//p' \ (cd "${DESTDIR}" && find . -type l -printf '%p %Y\n' | sed -n 's/ [LN]$//p' \
| xargs ${xargs_verbose:-} -rL1 rm -f) | xargs ${xargs_verbose:-} -rL1 rm -f)
[ "${verbose}" = y ] && echo "Building cpio ${outfile} initramfs" [ "${verbose}" = y ] && echo "Building cpio ${outfile} initramfs"
(
# preserve permissions if root builds the image, see #633582 # preserve permissions if root builds the image, see #633582
[ "$(id -ru)" != 0 ] && cpio_owner_root="-R 0:0" [ "$(id -ru)" != 0 ] && cpio_owner_root="-R 0:0"
@ -457,46 +489,70 @@ if [ -n "${SOURCE_DATE_EPOCH}" ]; then
cpio_reproducible="--reproducible" cpio_reproducible="--reproducible"
fi fi
# work around lack of "set -o pipefail" for the following pipe: # Read list of files and echo them plus all leading directories.
# cd "${DESTDIR}" && find . | LC_ALL=C sort | cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc >>"${outfile}" || exit 1 # The same directories might be printed multiple times (even with sorted input)!
ec1=1 add_directories() {
ec2=1 local last_dir path dir
exec 3>&1 while read -r path; do
eval "$( dir="${path%/*}"
# http://cfaj.freeshell.org/shell/cus-faq-2.html parent="${dir}"
exec 4>&1 >&3 3>&- while [ "$parent" != "$last_dir" ] && [ "$parent" != "." ]; do
cd "${DESTDIR}" 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 find . \( ! -type d ! -name '*.zst' ! -name '*.xz' \) -o \( -type d -empty \) ||
} | { { echo "E: mkinitramfs failure main find $?" >&2; echo 1 >&3; exit; }
LC_ALL=C sort } | add_directories | {
} | { LC_ALL=C sort || { echo "E: mkinitramfs failure sort $?" >&2; echo 1 >&3; exit; }
# shellcheck disable=SC2086 } | uniq > "${__TMPMAINFILES}" || { echo "E: mkinitramfs failure uniq $?" >&2; echo 1 >&3; exit; }
cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc 4>&- >"${__TMPMAINCPIO}" } 3>&1 | { read -r exit_code; exit "${exit_code:-0}"; } || exit $?
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
{ {
if [ -s "${__TMPEARLYCPIO}" ]; then {
cat "${__TMPEARLYCPIO}" || exit 1 find . -name '*.zst' -o -name '*.xz' ||
fi { 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 if [ -s "${__TMPUNCOMPRESSEDFILES}" ]; then
cat "${__TMPCPIOGZ}" || exit 1 # shellcheck disable=SC2086
fi cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc -D "${DESTDIR}" <"${__TMPUNCOMPRESSEDFILES}" ||
} >"${outfile}" || exit 1 { 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 exit 0

View File

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

View File

@ -107,13 +107,13 @@ maybe_break()
else else
opts="-v" opts="-v"
fi 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 \ ehci-hcd ohci-hcd ohci-pci uhci-hcd usbhid xhci \
xhci-pci xhci-hcd xhci-pci xhci-hcd
sleep 2 sleep 2
for modalias in /sys/bus/hid/devices/*/modalias; do for modalias in /sys/bus/hid/devices/*/modalias; do
if [ -f "${modalias}" ]; then if [ -f "${modalias}" ]; then
modprobe ${opts} -b "$(cat "${modalias}")" /sbin/modprobe ${opts} -b "$(cat "${modalias}")"
fi fi
done done
fi fi
@ -147,7 +147,7 @@ load_modules()
continue continue
fi fi
# shellcheck disable=SC2086 # shellcheck disable=SC2086
modprobe $m /sbin/modprobe $m
done < /conf/modules done < /conf/modules
fi fi
} }
@ -214,13 +214,11 @@ get_fstype ()
return 0 return 0
} }
_handle_device_vs_ip() _set_netdev_from_ip_param()
{ {
# If the ip= parameter is present and is a colon-separated list, # If the ip= parameter is present and specifies a device, use
# then: # that in preference to any device name we already have
# - If it specifies a device, use that in preference to any local rc=1
# device name we already have
# - Otherwise, substitute in any device name we already have
local IFS=: local IFS=:
set -f set -f
# shellcheck disable=SC2086 # shellcheck disable=SC2086
@ -228,71 +226,116 @@ _handle_device_vs_ip()
set +f set +f
if [ -n "$6" ]; then if [ -n "$6" ]; then
DEVICE="$6" 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}" IP="$1:$2:$3:$4:$5:${DEVICE}"
shift 6 || shift $# shift 6 || shift $#
IP="${IP}:$*" IP="${IP}:$*"
fi 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() 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 # 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 # network card used to PXE boot
# than a hard-coded device name from initramfs.conf. this facilitates
# network booting when machines may have multiple network cards.
# pxelinux sets BOOTIF to 01-$mac_address # pxelinux sets BOOTIF to 01-$mac_address
# strip off the leading "01-", which isn't part of the mac # strip off the leading "01-", which isn't part of the mac
@ -311,29 +354,25 @@ configure_networking()
done done
unset IFS unset IFS
# look for devices with matching mac address, and set DEVICE to _set_netdev_from_hw_address "${bootif_mac}"
# appropriate value if match is found. netdev_desc="device with address ${bootif_mac}"
for device in /sys/class/net/* ; do elif [ -n "${DEVICE}${DEVICE6}" ]; then
if [ -f "$device/address" ]; then if [ -n "${DEVICE}" ] && [ -n "${DEVICE6}" ]; then
current_mac=$(cat "$device/address") netdev_desc="${DEVICE} and ${DEVICE6}"
if [ "$bootif_mac" = "$current_mac" ]; then else
DEVICE=${device##*/} netdev_desc="${DEVICE:-$DEVICE6}"
DEVICE6=${device##*/} fi
break else
fi netdev_desc="any network device"
fi
done
fi fi
_handle_device_vs_ip
for v in $VLAN; do for v in $VLAN; do
VLAN_LINK="$VLAN_LINK ${v##*:}" VLAN_LINK="$VLAN_LINK ${v##*:}"
VLAN_NAMES="$VLAN_NAMES ${v%:*}" VLAN_NAMES="$VLAN_NAMES ${v%:*}"
done done
# activate non-autoconfigured s390x devices # 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 # do not chzdev $dev if it is a not-yet-created vlan interface
for vlan_name in $VLAN_NAMES; do for vlan_name in $VLAN_NAMES; do
if [ "$dev" = "$vlan_name" ]; then if [ "$dev" = "$vlan_name" ]; then
@ -356,20 +395,25 @@ configure_networking()
ip link add name "$vname" link "$vlink" type vlan id "$vid" ip link add name "$vname" link "$vlink" type vlan id "$vid"
done done
if [ -n "${DEVICE}" ]; then local netdevwait=180
local netdevwait=180 log_begin_msg "Waiting up to ${netdevwait} secs for ${netdev_desc} to become available"
log_begin_msg "Waiting up to ${netdevwait} secs for ${DEVICE} to become available" while true; do
while [ "$(time_elapsed)" -lt "$netdevwait" ]; do if [ "$(time_elapsed)" -ge "$netdevwait" ]; then
if [ -e "/sys/class/net/${DEVICE}" ]; then log_failure_msg "Network device did not appear in time"
break break
fi
sleep 1
done
if [ ! -e "/sys/class/net/${DEVICE}" ]; then
log_failure_msg "Interface ${DEVICE} did not appear in time"
fi fi
log_end_msg if [ -n "${DEVICE}" ]; then
fi [ -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 wait_for_udev 10
@ -384,37 +428,35 @@ configure_networking()
# creating the file, ipconfig is not run again. # creating the file, ipconfig is not run again.
for x in /run/net-"${DEVICE}".conf /run/net-*.conf ; do for x in /run/net-"${DEVICE}".conf /run/net-*.conf ; do
if [ -e "$x" ]; then if [ -e "$x" ]; then
IP=done IP="done"
break break
fi fi
done done
for x in /run/net6-"${DEVICE}".conf /run/net6-*.conf ; do for x in /run/net6-"${DEVICE}".conf /run/net6-*.conf ; do
if [ -e "$x" ]; then if [ -e "$x" ]; then
IP6=done IP6="done"
break break
fi fi
done done
# if we've reached a point where both IP and IP6 are "done", # if we've reached a point where both IP and IP6 are "done",
# then we're finished with network configuration. # then we're finished with network configuration.
if [ "$IP" = done ] && [ "$IP6" = done ]; then if [ "$IP" = "done" ] && [ "$IP6" = "done" ]; then
break break
fi fi
if [ -z "${DEVICE}" ]; then
_set_available_devices_to_up
fi
case ${IP} in case ${IP} in
none|done|off) none|done|off)
# Do nothing # Do nothing
IP=done IP="done"
;; ;;
""|on|any|dhcp|bootp|both) ""|on|any|dhcp|bootp|both)
if [ "${NETWORK_SKIP_ENSLAVED:-0}" = 0 ] || [ -n "${DEVICE}" ]; then dhcpcd -1 -t $ROUNDTTT -4 ${DEVICE:+"${DEVICE}"}
run_dhclient $ROUNDTTT -4 ${DEVICE:+"${DEVICE}"}
else
# shellcheck disable=SC2046
run_dhclient $ROUNDTTT -4 $(all_non_enslaved_devices)
fi
;; ;;
*) *)
ipconfig -t ${ROUNDTTT} -d "$IP" ipconfig -t ${ROUNDTTT} -d "$IP"
@ -424,7 +466,7 @@ configure_networking()
case ${IP6} in case ${IP6} in
""|none|done|off) ""|none|done|off)
# Do nothing # Do nothing
IP6=done IP6="done"
;; ;;
*) *)
# check the content of IP6 and if it is not on/dhcp/any use it as # check the content of IP6 and if it is not on/dhcp/any use it as
@ -437,12 +479,7 @@ configure_networking()
DEVICE6="$IP6" ;; DEVICE6="$IP6" ;;
esac esac
if [ "${NETWORK_SKIP_ENSLAVED:-0}" = 0 ] || [ -n "${DEVICE6}" ]; then dhcpcd -1 -t $ROUNDTTT -6 ${DEVICE6:+"${DEVICE6}"}
run_dhclient $ROUNDTTT -6 ${DEVICE6:+"${DEVICE6}"}
else
# shellcheck disable=SC2046
run_dhclient $ROUNDTTT -6 $(all_non_enslaved_devices)
fi
;; ;;
esac esac
done done
@ -482,7 +519,9 @@ netinfo_to_resolv_conf() {
. "$f" || { echo "WARN: failed '. \"$f\"'" 1>&2; return 1; } . "$f" || { echo "WARN: failed '. \"$f\"'" 1>&2; return 1; }
for n in "${IPV4DNS0}" "${IPV4DNS1}" \ for n in "${IPV4DNS0}" "${IPV4DNS1}" \
"${IPV6DNS0}" "${IPV6DNS1}"; do "${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. # skip if 'n' already in list.
case " ${ns} " in case " ${ns} " in
*\ $n\ *) continue;; *\ $n\ *) continue;;
@ -534,7 +573,9 @@ _declare_sh_append_var() {
local name="$1" skip="$2" add="" n="" local name="$1" skip="$2" add="" n=""
shift 2 shift 2
for n in "$@"; do for n in "$@"; do
[ -n "$n" ] && [ "$n" != "$skip" ] || continue if [ -z "$n" ] || [ "$n" = "$skip" ]; then
continue
fi
add="$add $n" add="$add $n"
done done
add=${add# } add=${add# }
@ -595,8 +636,12 @@ _render_netplan() {
echo " dhcp4: $dhcp4" echo " dhcp4: $dhcp4"
echo " dhcp-identifier: mac" echo " dhcp-identifier: mac"
fi fi
[ -n "$dhcp6" ] && echo " dhcp6: $dhcp6" || true if [ -n "$dhcp6" ]; then
[ -n "$dhcp4$dhcp6" ] && echo " critical: true" || true echo " dhcp6: $dhcp6"
fi
if [ -n "$dhcp4$dhcp6" ]; then
echo " critical: true"
fi
if [ -n "$addrs" ]; then if [ -n "$addrs" ]; then
echo " addresses:" echo " addresses:"
found="," found=","
@ -607,8 +652,12 @@ _render_netplan() {
echo " - \"$n\"" echo " - \"$n\""
done done
fi fi
[ -n "$gateway4" ] && echo " gateway4: \"$gateway4\"" || true if [ -n "$gateway4" ]; then
[ -n "$gateway6" ] && echo " gateway6: \"$gateway6\"" || true echo " gateway4: \"$gateway4\""
fi
if [ -n "$gateway6" ]; then
echo " gateway6: \"$gateway6\""
fi
if [ -n "$ns_addrs" ]; then if [ -n "$ns_addrs" ]; then
local alist="[" slist="" local alist="[" slist=""
@ -630,7 +679,9 @@ _render_netplan() {
fi fi
echo " nameservers:" echo " nameservers:"
echo " addresses: $alist" echo " addresses: $alist"
[ -n "$slist" ] && echo " search: $slist" || true if [ -n "$slist" ]; then
echo " search: $slist"
fi
fi fi
} }
@ -891,7 +942,7 @@ _checkfs_once()
log_warning_msg "File system check failed but did not detect errors" log_warning_msg "File system check failed but did not detect errors"
sleep 5 sleep 5
else else
true > $FSCK_STAMPFILE true >"$FSCK_STAMPFILE"
fi fi
return 0 return 0
} }

View File

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

View File

@ -91,9 +91,12 @@ if [ -n "${FB}" ]; then
udevadm settle udevadm settle
else else
# If we have no graphics devices yet, wait for udev to settle # If we have no graphics devices yet, wait for udev to settle
[ -d /sys/class/graphics/fbcon ] && \ if ! [ -d /sys/class/graphics/fbcon ] \
[ -d /sys/class/graphics/fb0 ] && \ || ! [ -d /sys/class/graphics/fb0 ] \
[ -d /sys/class/drm/card0 ] || udevadm settle || ! [ -d /sys/class/drm/card0 ]
then
udevadm settle
fi
# If we still have no graphics device, fall back to vesafb like # If we still have no graphics device, fall back to vesafb like
# we do in the post-initramfs case in # 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 # 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) # 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. # which seems to be enough time to let the drm interface get loaded.
[ -d /sys/class/graphics/fbcon ] && \ if ! [ -d /sys/class/graphics/fbcon ] \
[ -d /sys/class/graphics/fb0 ] && \ || ! [ -d /sys/class/graphics/fb0 ] \
[ -d /sys/class/drm/card0 ] || sleep 1 || ! [ -d /sys/class/drm/card0 ]
then
sleep 1
fi
if ! [ -d /sys/class/graphics/fbcon ] \ if ! [ -d /sys/class/graphics/fbcon ] \
|| ! [ -d /sys/class/graphics/fb0 ] \ || ! [ -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 # Load ubi with the correct MTD partition and return since fstype
# doesn't work with a char device like ubi. # doesn't work with a char device like ubi.
if [ -n "$UBIMTD" ]; then if [ -n "$UBIMTD" ]; then
modprobe ubi "mtd=$UBIMTD" /sbin/modprobe ubi "mtd=$UBIMTD"
DEV="${dev_id}" DEV="${dev_id}"
return return
fi fi

View File

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

View File

@ -81,7 +81,7 @@ nfs_mount_root()
nfs_top nfs_top
# For DHCP # For DHCP
modprobe af_packet /sbin/modprobe af_packet
wait_for_udev 10 wait_for_udev 10
@ -130,7 +130,7 @@ nfs_mount_fs()
nfs_top nfs_top
# For DHCP # For DHCP
modprobe af_packet /sbin/modprobe af_packet
wait_for_udev 10 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 test "$magic" = 070701 || test "$magic" = 070702 || break
namesize=0x$(readhex "$initramfs" $((end + 94)) 8) namesize=0x$(readhex "$initramfs" $((end + 94)) 8)
filesize=0x$(readhex "$initramfs" $((end + 54)) 8) filesize=0x$(readhex "$initramfs" $((end + 54)) 8)
end=$(((end + 110))) end=$((end + 110))
end=$(((end + namesize + 3) & ~3)) end=$(((end + namesize + 3) & ~3))
end=$(((end + filesize + 3) & ~3)) end=$(((end + filesize + 3) & ~3))
done done
@ -122,11 +122,11 @@ splitinitramfs()
start=$end start=$end
done done
if [ $end -gt 0 ]; then if [ "$end" -gt 0 ]; then
# Extract to main subdirectory # Extract to main subdirectory
subarchive=$(mktemp "${TMPDIR:-/var/tmp}/unmkinitramfs_XXXXXX") subarchive=$(mktemp "${TMPDIR:-/var/tmp}/unmkinitramfs_XXXXXX")
trap 'rm -f "$subarchive"' EXIT 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" > "$subarchive"
# shellcheck disable=SC2030,SC2031 # shellcheck disable=SC2030,SC2031
xcpio "$subarchive" "${dir:+$dir/main}" -i "$@" xcpio "$subarchive" "${dir:+$dir/main}" -i "$@"

View File

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