#!/bin/bash # $Id$ COPY_BINARIES=false CPIO_ARGS="--quiet --null -o -H newc --owner root:root --force-local" # The copy_binaries function is explicitly released under the CC0 license to # encourage wide adoption and re-use. That means: # - You may use the code of copy_binaries() as CC0 outside of genkernel # - Contributions to this function are licensed under CC0 as well. # - If you change it outside of genkernel, please consider sending your # modifications back to genkernel@gentoo.org. # # On a side note: "Both public domain works and the simple license provided by # CC0 are compatible with the GNU GPL." # (from https://www.gnu.org/licenses/license-list.html#CC0) # # Written by: # - Sebastian Pipping (error checking) # - Robin H. Johnson (complete rewrite) # - Richard Yao (original concept) # Usage: # copy_binaries DESTDIR BINARIES... copy_binaries() { local destdir=${1} shift if [ ! -f "${TEMP}/.binaries_copied" ] then touch "${TEMP}/.binaries_copied" \ || gen_die "Failed to set '${TEMP}/.binaries_copied' marker!" fi local binary for binary in "$@" do [[ -e "${binary}" ]] \ || gen_die "Binary ${binary} could not be found" if "${LDDTREE_COMMAND}" "${binary}" 2>&1 | grep -F -q 'not found' then gen_die "Binary ${binary} is linked to missing libraries and may need to be re-built" fi done # This must be OUTSIDE the for loop, we only want to run lddtree etc ONCE. # lddtree does not have the -V (version) nor the -l (list) options prior to version 1.18 ( if "${LDDTREE_COMMAND}" -V > /dev/null 2>&1 then "${LDDTREE_COMMAND}" -l "$@" \ || gen_die "Binary '${binary}' or some of its library dependencies could not be copied!" else "${LDDTREE_COMMAND}" "$@" \ | tr ')(' '\n' \ | awk '/=>/{ if($3 ~ /^\//){print $3}}' \ || gen_die "Binary '${binary}' or some of its library dependencies could not be copied!" fi ) \ | sort \ | uniq \ | "${CPIO_COMMAND}" -p --make-directories --dereference --quiet "${destdir}" \ || gen_die "Binary '${binary}' or some of its library dependencies could not be copied!" } # @FUNCTION: copy_system_binaries # @USAGE: # @DESCRIPTION: # Copies system binaries into dest dir. # # Difference to copy_binaries() is, that copy_system_binaries() does NOT # try to recreate directory structure. Any system binary to copy will be # placed into same DESTination DIRectory. # Because we focus on *system* binaries, it's safe to assume that everything # belongs to the same directory. This assumption will allow us to copy from # crossdev environments (i.e. /usr/$CHOST). copy_system_binaries() { [[ ${#} -lt 2 ]] \ && gen_die "$(get_useful_function_stack "${FUNCNAME}")Invalid usage of ${FUNCNAME}(): Function takes at least two arguments (${#} given)!" local destdir=${1} shift [[ ! -d "${destdir}" ]] \ && gen_die "$(get_useful_function_stack "${FUNCNAME}")Invalid usage of ${FUNCNAME}(): Destdir '${destdir}' does NOT exist!" if [ ! -f "${TEMP}/.system_binaries_copied" ] then touch "${TEMP}/.system_binaries_copied" \ || gen_die "Failed to set '${TEMP}/.system_binaries_copied' marker!" fi local binary binary_realpath binary_basename base_dir local binary_dependency binary_dependency_basename for binary in "$@" do [[ -e "${binary}" ]] \ || gen_die "$(get_useful_function_stack)System binary '${binary}' could not be found!" print_info 5 "System binary '${binary}' should be copied to '${destdir}' ..." binary_basename=$(basename "${binary}") if [[ -z "${binary_basename}" ]] then gen_die "$(get_useful_function_stack)Failed to determine basename of '${binary}'!" else print_info 5 "System binary's basename is '${binary_basename}'." fi if [[ -e "${destdir}/${binary_basename}" ]] then print_info 5 "System binary '${binary_basename}' already exists in '${destdir}'; Skipping ..." continue fi if [[ -L "${binary}" ]] then binary_realpath=$(realpath "${binary}") if [[ -z "${binary_realpath}" ]] then gen_die "$(get_useful_function_stack)Failed to resolve path to '${binary}'!" elif [[ ! -e "${binary_realpath}" ]] then gen_die "$(get_useful_function_stack)System binary '${binary}' was resolved to '${binary_realpath}' but file does NOT exist!" else print_info 5 "System binary '${binary}' resolved to '${binary_realpath}'." binary=${binary_realpath} fi fi base_dir=$(dirname "${binary}") if [[ -z "${base_dir}" ]] then gen_die "$(get_useful_function_stack)Failed to determine directory of '${binary}'!" else print_info 5 "System binary dirname set to '${base_dir}'." fi local is_first=1 while IFS= read -r -u 3 binary_dependency do binary_dependency_basename=$(basename "${binary_dependency}") if [[ -z "${binary_dependency_basename}" ]] then gen_die "$(get_useful_function_stack)Failed to determine basename of '${binary_dependency}'!" fi if [[ ${is_first} -eq 1 ]] then # `lddtree -l` first line is always the binary itself print_info 5 "Copying '${base_dir}/${binary_dependency_basename}' to '${destdir}/' ..." cp -aL "${base_dir}/${binary_dependency_basename}" "${destdir}/${binary_basename}" \ || gen_die "$(get_useful_function_stack)Failed to copy '${base_dir}/${binary_dependency_basename}' to '${destdir}'!" is_first=0 elif [[ -e "${destdir}/${binary_dependency_basename}" ]] then print_info 5 "System binary '${binary_basename}' already exists in '${destdir}'; Skipping ..." continue else print_info 5 "Need to copy dependency '${base_dir}/${binary_dependency_basename}' ..." "${FUNCNAME}" "${destdir}" "${base_dir}/${binary_dependency_basename}" fi done 3< <("${LDDTREE_COMMAND}" -l "${binary}" 2>/dev/null) IFS="${GK_DEFAULT_IFS}" done } log_future_cpio_content() { local dir_size=$(get_du "${PWD}") if [ -n "${dir_size}" ] then dir_size=" (${dir_size})" fi print_info 3 "=================================================================" 1 0 1 print_info 3 "About to add these files${dir_size} from '${PWD}' to cpio archive:" 1 0 1 print_info 3 "$(find . -print0 | xargs --null ls -ald)" 1 0 1 print_info 3 "=================================================================" 1 0 1 } append_devicemanager() { local PN="lvm" local TDIR="${TEMP}/initramfs-dm-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" # Delete unneeded files rm -rf \ sbin/lvm \ usr/include \ usr/lib/device-mapper \ usr/lib/pkgconfig \ usr/lib/lib* \ usr/sbin/lvm \ usr/share log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append bcache to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_devices() { if isTrue "${BUSYBOX}" then local TDIR="${TEMP}/initramfs-devices-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir -p "${TDIR}/dev" || gen_die "Failed to create '${TDIR}/dev'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" chmod 0755 dev || gen_die "Failed to chmod of '${TDIR}/dev' to 0755!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append devices to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi else local TFILE="${TEMP}/initramfs-base-temp.devices" if [ -f "${TFILE}" ] then rm "${TFILE}" || gen_die "Failed to clean out existing '${TFILE}'!" fi if [[ ! -x "${KERNEL_OUTPUTDIR}/usr/gen_init_cpio" ]]; then compile_gen_init_cpio fi # WARNING, does NOT support appending to cpio! cat >"${TFILE}" <<-EOF dir /dev 0755 0 0 nod /dev/console 660 0 0 c 5 1 nod /dev/null 666 0 0 c 1 3 nod /dev/random 600 0 0 c 1 8 nod /dev/tty0 600 0 0 c 4 0 nod /dev/tty1 600 0 0 c 4 1 nod /dev/ttyS0 600 0 0 c 4 64 nod /dev/ttyS1 600 0 0 c 4 65 nod /dev/urandom 600 0 0 c 1 9 nod /dev/zero 666 0 0 c 1 5 EOF print_info 3 "=================================================================" 1 0 1 print_info 3 "Adding the following devices to cpio:" 1 0 1 print_info 3 "$(cat "${TFILE}")" 1 0 1 print_info 3 "=================================================================" 1 0 1 "${KERNEL_OUTPUTDIR}"/usr/gen_init_cpio "${TFILE}" >"${CPIO_ARCHIVE}" \ || gen_die "Failed to append devices to cpio!" fi } append_base_layout() { local TDIR="${TEMP}/initramfs-base-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" local mydir= for mydir in \ .initrd \ bin \ dev \ etc \ lib \ lib/console \ lib/dracut \ mnt \ proc \ run \ sbin \ sys \ tmp \ usr \ usr/bin \ usr/lib \ usr/sbin \ var/empty \ var/log \ var/run/lock \ ; do mkdir -p "${TDIR}"/${mydir} || gen_die "Failed to create '${TDIR}/${mydir}'!" done chmod 1777 "${TDIR}"/tmp || gen_die "Failed to chmod of '${TDIR}/tmp' to 1777!" # In general, we don't really need lib{32,64} anymore because we now # compile most stuff on our own and therefore don't have to deal with # multilib anymore. However, when copy_binaries() was used to copy # binaries from a multilib-enabled system, this could be a problem. # So let's keep symlinks to ensure that all libraries will land in # /lib. local myliblink for myliblink in \ lib32 \ lib64 \ usr/lib32 \ usr/lib64 \ ; do ln -s lib ${myliblink} || gen_die "Failed to create symlink '${TDIR}/${myliblink}' to '${TDIR}/lib'!" done print_info 2 "$(get_indent 2)>> Populating '/etc/fstab' ..." echo "/dev/ram0 / ext2 defaults 0 0" > "${TDIR}"/etc/fstab \ || gen_die "Failed to add /dev/ram0 to '${TDIR}/etc/fstab'!" echo "proc /proc proc defaults 0 0" >> "${TDIR}"/etc/fstab \ || gen_die "Failed to add proc to '${TDIR}/etc/fstab'!" print_info 2 "$(get_indent 2)>> Adding /etc/{group,passwd,shadow} ..." cat >"${TDIR}"/etc/group <<-EOF root:x:0:root bin:x:1:root,bin,daemon daemon:x:2:root,bin,daemon sys:x:3:root,bin,adm adm:x:4:root,adm,daemon tty:x:5: disk:x:6:root,adm lp:x:7:lp mem:x:8: kmem:x:9: wheel:x:10:root floppy:x:11:root news:x:13:news uucp:x:14:uucp console:x:17: audio:x:18: cdrom:x:19: dialout:x:20: tape:x:26:root video:x:27:root render:x:28: rpc:x:32: kvm:x:78: usb:x:85: input:x:97: utmp:x:406: nogroup:x:65533: nobody:x:65534: EOF chmod 0644 "${TDIR}"/etc/group \ || gen_die "Failed to chmod of '${TDIR}/etc/group'!" cat >"${TDIR}"/etc/passwd <<-EOF root:x:0:0:root:/root:/usr/bin/login-remote.sh nobody:x:65534:65534:nobody:/var/empty:/bin/false EOF chmod 0644 "${TDIR}"/etc/passwd \ || gen_die "Failed to chmod of '${TDIR}/etc/passwd'!" echo "root:!:0:0:99999:7:::" > "${TDIR}"/etc/shadow \ || gen_die "Failed to create '/etc/shadow'!" chmod 0640 "${TDIR}"/etc/shadow \ || gen_die "Failed to chmod of '${TDIR}/etc/shadow'!" print_info 2 "$(get_indent 2)>> Adding /etc/nsswitch.conf ..." cat >"${TDIR}"/etc/nsswitch.conf <<-EOF # /etc/nsswitch.conf generated by genkernel passwd: files shadow: files group: files EOF print_info 2 "$(get_indent 2)>> Adding /etc/ld.so.conf ..." cat >"${TDIR}"/etc/ld.so.conf <<-EOF # ld.so.conf generated by genkernel include ld.so.conf.d/*.conf /lib /usr/lib EOF print_info 2 "$(get_indent 2)>> Adding misc files ..." date -u '+%Y-%m-%d %H:%M:%S UTC' > "${TDIR}"/etc/build_date \ || gen_die "Failed to create '${TDIR}/etc/build_date'!" echo "Genkernel ${GK_V}" > "${TDIR}"/etc/build_id \ || gen_die "Failed to create '${TDIR}/etc/build_id'!" cat >"${TDIR}"/etc/initrd-release <<-EOF NAME="genkernel" VERSION="genkernel-${GK_V}" ID=genkernel VERSION_ID=${GK_V} PRETTY_NAME="Gentoo/Linux genkernel-${GK_V} (Initramfs)" ANSI_COLOR="0;34" EOF cp -a "${GK_SHARE}"/defaults/gksosreport.sh "${TDIR}"/usr/sbin/gksosreport \ || gen_die "Failed to copy '${GK_SHARE}/defaults/gksosreport.sh' to '${TDIR}/usr/sbin/gksosreport'" chmod 0755 "${TDIR}"/usr/sbin/gksosreport \ || gen_die "Failed to chmod of '${TDIR}/usr/sbin/gksosreport'!" ln -s /proc/self/mounts "${TDIR}"/etc/mtab \ || gen_die "Failed to symlink '/etc/mtab' to '/proc/self/mounts'!" # Allow lsinitrd from dracut to process our initramfs echo "$(cat "${TDIR}/etc/build_id") ($(cat "${TDIR}/etc/build_date"))" > "${TDIR}"/lib/dracut/dracut-gk-version.info \ || gen_die "Failed to create '${TDIR}/lib/dracut/dracut-gk-version.info'!" if [[ "${CMD_BOOTFONT}" == "none" ]] then print_info 3 "$(get_indent 2)>> --boot-font=none set; Not embedding console font ..." else local BOOTFONT_FILE="${TDIR}/lib/console/font" if [[ "${CMD_BOOTFONT}" == "current" ]] then print_info 2 "$(get_indent 2)>> Embedding current active console font ..." local -a setfont_cmd=( "${SETFONT_COMMAND}" ) setfont_cmd+=( "-O ${BOOTFONT_FILE}" ) print_info 3 "COMMAND: ${setfont_cmd[*]}" 1 0 1 eval "${setfont_cmd[@]}" || gen_die "Failed to dump current active console font!" if ! isTrue $(is_psf_file "${BOOTFONT_FILE}") then gen_die "Sanity check failed: Dumped current active console font does NOT look like a valid PC Screen Font (PSF) file!" fi else print_info 2 "$(get_indent 2)>> Embedding '${BOOTFONT}' as console font ..." # Already validated in determine_real_args() cp -aL "${BOOTFONT}" "${BOOTFONT_FILE}" \ || gen_die "Failed to copy '${BOOTFONT}' to '${BOOTFONT_FILE}'!" fi fi local -a build_parameters build_parameters+=( --boot-font=${CMD_BOOTFONT} ) if isTrue "${KEYMAP}" then build_parameters+=( --keymap ) isTrue "${DOKEYMAPAUTO}" && build_parameters+=( --do-keymap-auto ) else build_parameters+=( --no-keymap ) fi isTrue "${COMPRESS_INITRD}" && build_parameters+=( --compress-initramfs ) || build_parameters+=( --no-compress-initramfs ) isTrue "${MICROCODE_INITRAMFS}" && build_parameters+=( --microcode-initramfs ) || build_parameters+=( --no-microcode-initramfs ) isTrue "${RAMDISKMODULES}" && build_parameters+=( --ramdisk-modules ) || build_parameters+=( --no-ramdisk-modules ) isTrue "${BUSYBOX}" && build_parameters+=( --busybox ) || build_parameters+=( --no-busybox ) isTrue "${BCACHE}" && build_parameters+=( --bcache ) || build_parameters+=( --no-bcache ) isTrue "${B2SUM}" && build_parameters+=( --b2sum ) || build_parameters+=( --no-b2sum ) isTrue "${BTRFS}" && build_parameters+=( --btrfs ) || build_parameters+=( --no-btrfs ) isTrue "${ISCSI}" && build_parameters+=( --iscsi ) || build_parameters+=( --no-iscsi ) isTrue "${MULTIPATH}" && build_parameters+=( --multipath ) || build_parameters+=( --no-multipath ) isTrue "${DMRAID}" && build_parameters+=( --dmraid ) || build_parameters+=( --no-dmraid ) isTrue "${MDADM}" && build_parameters+=( --mdadm ) || build_parameters+=( --no-mdadm ) isTrue "${LVM}" && build_parameters+=( --lvm ) || build_parameters+=( --no-lvm ) isTrue "${UNIONFS}" && build_parameters+=( --unionfs ) || build_parameters+=( --no-unionfs ) isTrue "${ZFS}" && build_parameters+=( --zfs ) || build_parameters+=( --no-zfs ) isTrue "${SPLASH}" && build_parameters+=( --splash ) || build_parameters+=( --no-splash ) isTrue "${STRACE}" && build_parameters+=( --strace ) || build_parameters+=( --no-strace ) isTrue "${KEYCTL}" && build_parameters+=( --keyctl ) || build_parameters+=( --no-keyctl ) isTrue "${GPG}" && build_parameters+=( --gpg ) || build_parameters+=( --no-gpg ) isTrue "${LUKS}" && build_parameters+=( --luks ) || build_parameters+=( --no-luks ) isTrue "${FIRMWARE}" && build_parameters+=( --firmware ) || build_parameters+=( --no-firmware ) [ -n "${FIRMWARE_DIR}" ] && build_parameters+=( --firmware-dir="${FIRMWARE_DIR}" ) [ -n "${FIRMWARE_FILES}" ] && build_parameters+=( --firmware-files="${FIRMWARE_FILES}" ) isTrue "${SSH}" && build_parameters+=( --ssh ) || build_parameters+=( --no-ssh ) isTrue "${E2FSPROGS}" && build_parameters+=( --e2fsprogs ) || build_parameters+=( --no-e2fsprogs ) isTrue "${XFSPROGS}" && build_parameters+=( --xfsprogs ) || build_parameters+=( --no-xfsprogs ) echo "${build_parameters[@]}" > "${TDIR}"/lib/dracut/build-parameter.txt \ || gen_die "Failed to create '${TDIR}/lib/dracut/build-parameter.txt'!" dd if=/dev/zero of="${TDIR}/var/log/lastlog" bs=1 count=0 seek=0 &>/dev/null \ || die "Failed to create '${TDIR}/var/log/lastlog'!" dd if=/dev/zero of="${TDIR}/var/log/wtmp" bs=1 count=0 seek=0 &>/dev/null \ || die "Failed to create '${TDIR}/var/log/wtmp'!" dd if=/dev/zero of="${TDIR}/var/run/utmp" bs=1 count=0 seek=0 &>/dev/null \ || die "Failed to create '${TDIR}/var/run/utmp'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append baselayout to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_busybox() { local PN=busybox local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" # Delete unneeded files rm -rf configs/ mkdir -p "${TDIR}"/usr/share/udhcpc || gen_die "Failed to create '${TDIR}/usr/share/udhcpc'!" cp -a "${GK_SHARE}"/defaults/udhcpc.scripts usr/share/udhcpc/default.script 2>/dev/null \ || gen_die "Failed to copy '${GK_SHARE}/defaults/udhcpc.scripts' to '${TDIR}/usr/share/udhcpc/default.script'!" local myfile= for myfile in \ bin/busybox \ usr/share/udhcpc/default.script \ ; do chmod +x "${TDIR}"/${myfile} || gen_die "Failed to chmod of '${TDIR}/${myfile}'!" done # Set up a few default symlinks local required_applets='[ ash sh mkdir mknod mount uname echo chmod cut cat touch' local required_applet= for required_applet in ${required_applets} do ln -s busybox "${TDIR}"/bin/${required_applet} \ || gen_die "Failed to create Busybox symlink for '${required_applet}' applet!" done # allow for DNS resolution if isTrue "$(is_glibc)" then local libdir=$(get_chost_libdir) local libnss_dns="${libdir}/libnss_dns.so" # NSS dns module was moved into libc in >=glibc-2.34 # but when this file exists we are probably dealing with older glibc # and need to manually copy the module. if [[ -f "${libnss_dns}" ]] then mkdir -p "${TDIR}"/lib || gen_die "Failed to create '${TDIR}/lib'!" copy_system_binaries "${TDIR}"/lib "${libnss_dns}" fi fi log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_e2fsprogs() { local PN=e2fsprogs local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_eudev() { local PN=eudev local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} populate_binpkg hwids mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" unpack "$(get_gkpkg_binpkg hwids)" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" if isTrue "$(can_run_programs_compiled_by_genkernel)" then print_info 2 "$(get_indent 2)${PN}: >> Pre-generating initramfs' /etc/udev/hwdb.bin ..." local gen_hwdb_cmd=( "${TDIR}/usr/bin/udevadm" ) gen_hwdb_cmd+=( hwdb --update --root "${TDIR}" ) print_info 3 "COMMAND: ${gen_hwdb_cmd[*]}" 1 0 1 eval "${gen_hwdb_cmd[@]}" 2>&1 | tee -a "${LOGFILE}" \ || gen_die "Failed to pre-generate initramfs' /etc/udev/hwdb.bin!" # Now that we have a pre-generated hwdb in initramfs # we can delete source files rm -rf usr/lib/udev/hwdb.d/ fi # Delete unneeded files rm -rf usr/include \ usr/lib/libu* \ usr/lib/pkgconfig \ usr/share # Disable predictable network interface names in initramfs echo "" > usr/lib/udev/rules.d/80-net-name-slot.rules \ || gen_die "Failed to disable predictable network interface naming rule" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_b2sum() { local PN="coreutils" local TDIR="${TEMP}/initramfs-b2sum-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append b2sum to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_bcache() { local PN="bcache-tools" local TDIR="${TEMP}/initramfs-bcache-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append bcache to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_unionfs_fuse() { local PN=unionfs-fuse local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_util-linux() { local PN="util-linux" local TDIR="${TEMP}/initramfs-util-linux-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" # Delete unneeded files rm -rf usr/ log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_multipath() { local PN=multipath-tools local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir -p "${TDIR}"/etc || gen_die "Failed to create '${TDIR}/etc'!" mkdir -p "${TDIR}"/usr/lib/udev/rules.d || gen_die "Failed to create '${TDIR}/usr/lib/udev/rules.d'!" local libdir=$(get_chost_libdir) if [[ "${libdir}" =~ ^/usr ]] then libdir=${libdir/\/usr/} fi copy_binaries \ "${TDIR}" \ /sbin/multipath \ /sbin/kpartx \ /sbin/mpathpersist \ ${libdir}/multipath/lib*.so local udevdir=$(get_udevdir) local udevdir_initramfs="/usr/lib/udev" local udev_files=( $(qlist -e sys-fs/multipath-tools:0 \ | grep -E -- "^${udevdir}") ) if [ ${#udev_files[@]} -eq 0 ] then gen_die "Something went wrong: Did not found any udev-related files for sys-fs/multipath-tools!" fi local udev_files for udev_file in "${udev_files[@]}" do local dest_file="${TDIR%/}${udev_file/${udevdir}/${udevdir_initramfs}}" cp -aL "${udev_file}" "${dest_file}" \ || gen_die "Failed to copy '${udev_file}' to '${dest_file}'" done cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" cp -aL /etc/multipath.conf "${TDIR}"/etc/multipath.conf 2>/dev/null \ || gen_die "Failed to copy '/etc/multipath.conf'!" # /etc/scsi_id.config does not exist in newer udevs # copy it optionally. if [ -f /etc/scsi_id.config ] then cp -aL /etc/scsi_id.config "${TDIR}"/etc/scsi_id.config 2>/dev/null \ || gen_die "Failed to copy '/etc/scsi_id.config'!" fi cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_dmraid() { local PN=dmraid local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" # Delete unneeded files rm -rf \ usr/lib \ usr/share \ usr/include log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append dmraid to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_iscsi() { local PN=open-iscsi local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append iscsi to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_keyutils() { local PN=keyutils local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_lvm() { local PN=lvm local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} populate_binpkg thin-provisioning-tools mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" unpack "$(get_gkpkg_binpkg "thin-provisioning-tools")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" local mydir= for mydir in \ etc/lvm/cache \ sbin \ ; do mkdir -p ${mydir} || gen_die "Failed to create '${TDIR}/${mydir}'!" done # Delete unneeded files rm -rf \ usr/lib/device-mapper \ usr/lib/pkgconfig \ usr/lib/lib* \ usr/sbin/dm* \ usr/share \ usr/include # Include the LVM config if [ -x /sbin/lvm -o -x /bin/lvm ] then local ABORT_ON_ERRORS=$(kconfig_get_opt "/etc/lvm/lvm.conf" "abort_on_errors") if isTrue "${ABORT_ON_ERRORS}" && [[ ${CBUILD} == ${CHOST} ]] then # Make sure the LVM binary we created is able to handle # system's lvm.conf "${TDIR}"/sbin/lvm dumpconfig 1>"${TDIR}"/etc/lvm/lvm.conf 2>/dev/null \ || gen_die "Bundled LVM version does NOT support system's lvm.conf!" # Sanity check if [ ! -s "${TDIR}/etc/lvm/lvm.conf" ] then gen_die "Sanity check failed: '${TDIR}/etc/lvm/lvm.conf' looks empty?!" fi else cp -aL /etc/lvm/lvm.conf "${TDIR}"/etc/lvm/lvm.conf 2>/dev/null \ || gen_die "Failed to copy '/etc/lvm/lvm.conf'!" fi # Some LVM config options need changing, because the functionality is # not compiled in: sed -r -i \ -e '/^[[:space:]]*obtain_device_list_from_udev/s,=.*,= 1,g' \ -e '/^[[:space:]]*udev_sync/s,=.*,= 1,g' \ -e '/^[[:space:]]*use_lvmetad/s,=.*,= 0,g' \ -e '/^[[:space:]]*use_lvmlockd/s,=.*,= 0,g' \ -e '/^[[:space:]]*use_lvmpolld/s,=.*,= 0,g' \ -e '/^[[:space:]]*monitoring/s,=.*,= 0,g' \ -e '/^[[:space:]]*external_device_info_source/s,=.*,= "none",g' \ -e '/^[[:space:]]*units/s,=.*"r",= "h",g' \ -e '/^[[:space:]]*thin_repair_executable/s,=.*,= /usr/sbin/thin_repair,g' \ -e '/^[[:space:]]*thin_dump_executable/s,=.*,= /usr/sbin/thin_dump,g' \ -e '/^[[:space:]]*thin_check_executable/s,=.*,= /usr/sbin/thin_check,g' \ "${TDIR}"/etc/lvm/lvm.conf \ || gen_die 'Could not sed lvm.conf!' fi log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append lvm to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_mdadm() { local PN=mdadm local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" local mydir= for mydir in \ etc \ sbin \ ; do mkdir -p "${TDIR}"/${mydir} || gen_die "Failed to create '${TDIR}/${mydir}'!" done unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" if [ -n "${MDADM_CONFIG}" ] then print_info 2 "$(get_indent 2)${PN}: >> Adding '${MDADM_CONFIG}' ..." if [ -f "${MDADM_CONFIG}" ] then cp -aL "${MDADM_CONFIG}" "${TDIR}"/etc/mdadm.conf 2>/dev/null \ || gen_die "Failed to copy '${MDADM_CONFIG}'!" else gen_die "Specified '${MDADM_CONFIG}' does not exist!" fi else print_info 2 "$(get_indent 2)${PN}: >> --mdadm-config not set; Skipping inclusion of mdadm.conf ..." fi cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_xfsprogs() { local PN=xfsprogs local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_zfs() { local PN=zfs local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" mkdir -p "${TDIR}"/etc/zfs || gen_die "Failed to create '${TDIR}/etc/zfs'!" # Copy files to /etc/zfs local i for i in vdev_id.conf zdev.conf zpool.cache do if [ -f /etc/zfs/${i} ] then print_info 2 "$(get_indent 2)${PN}: >> Including ${i}" cp -aL "/etc/zfs/${i}" "${TDIR}/etc/zfs/${i}" 2>/dev/null \ || gen_die "Could not copy file '/etc/zfs/${i}' for ZFS" fi done if [ -f "/etc/hostid" ] then local _hostid=$(hostid 2>/dev/null) print_info 2 "$(get_indent 2)${PN}: >> Embedding hostid '${_hostid}' into initramfs ..." cp -aL /etc/hostid "${TDIR}"/etc/hostid 2>/dev/null \ || gen_die "Failed to copy /etc/hostid" echo "${_hostid}" > "${TEMP}"/.embedded_hostid \ || gen_die "Failed to record system's hostid!" else print_warning 1 "$(get_indent 2)${PN}: /etc/hostid not found; You must use 'spl_hostid' kernel command-line parameter!" fi copy_binaries "${TDIR}" /sbin/{mount.zfs,zdb,zfs,zpool} local udevdir=$(get_udevdir) local udevdir_initramfs="/usr/lib/udev" local udev_files=( $(qlist -e sys-fs/zfs:0 \ | grep -E -- "^${udevdir}") ) if [ ${#udev_files[@]} -eq 0 ] then gen_die "Something went wrong: Did not found any udev-related files for sys-fs/zfs!" fi mkdir -p "${TDIR}"/usr/lib/udev/rules.d || gen_die "Failed to create '${TDIR}/usr/lib/udev/rules.d'!" local udev_files for udev_file in "${udev_files[@]}" do local dest_file="${TDIR%/}${udev_file/${udevdir}/${udevdir_initramfs}}" cp -aL "${udev_file}" "${dest_file}" \ || gen_die "Failed to copy '${udev_file}' to '${dest_file}'" if [[ "${dest_file}" == *.rules ]] then print_info 5 "Updating UDEV dir in '${dest_file}' ..." sed -i \ -e "s|${udevdir}|${udevdir_initramfs}|g" \ "${dest_file}" \ || gen_die "Failed to update UDEV dir in '${dest_file}'" fi done cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_btrfs() { local PN=btrfs-progs local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_libgcc_s() { local TDIR="${TEMP}/initramfs-libgcc_s-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" # Include libgcc_s.so.1: # - workaround for zfsonlinux/zfs#4749 # - required for LUKS2 (libargon2 uses pthread_cancel) local libgccpath if type gcc-config 2>&1 1>/dev/null; then libgccpath="/usr/lib/gcc/$(s=$(gcc-config -c); echo ${s%-*}/${s##*-})/libgcc_s.so.1" fi if [[ ! -f ${libgccpath} ]]; then libgccpath="/usr/lib/gcc/*/*/libgcc_s.so.1" fi copy_binaries "${TDIR}" ${libgccpath} cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append libgcc_s to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_linker() { local TDIR="${TEMP}/initramfs-linker-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" mkdir -p "${TDIR}"/etc || gen_die "Failed to create '${TDIR}/etc'!" if isTrue "$(tc-is-cross-compiler)" then # We cannot copy ld files from host because they could be # incompatible with CHOST. Instead, add ldconfig to allow # initramfs to regenerate on its own (default /etc/ld.so.conf # for initramfs was added via append_base_layout()). mkdir -p "${TDIR}"/sbin || gen_die "Failed to create '${TDIR}/sbin'!" local libdir=$(get_chost_libdir) copy_system_binaries "${TDIR}/sbin" "${libdir%/usr\/*}/sbin/ldconfig" else # Only copy /etc/ld.so.conf.d -- /etc/ld.so.conf was already # added to CPIO via append_base_layout() and because we only # append to CPIO, that file wouldn't be used at all. if [ -d "/etc/ld.so.conf.d" ] then mkdir -p "${TDIR}"/etc/ld.so.conf.d || gen_die "Failed to create '${TDIR}/etc/ld.so.conf.d'!" cp -arL "/etc/ld.so.conf.d" "${TDIR}"/etc \ || gen_die "Failed to copy '/etc/ld.so.conf.d'!" fi if [ -e "/etc/ld.so.cache" ] then cp -aL "/etc/ld.so.cache" "${TDIR}"/etc/ld.so.cache \ || gen_die "Failed to copy '/etc/ld.so.cache'!" fi fi cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append linker to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_splash() { local TDIR="${TEMP}/initramfs-splash-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" if [ -z "${SPLASH_THEME}" -a -e /etc/conf.d/splash ] then source /etc/conf.d/splash &>/dev/null || gen_die "Failed to source '/etc/conf.d/splash'!" fi if [ -z "${SPLASH_THEME}" ] then SPLASH_THEME=default fi print_info 1 "$(get_indent 1)>> Installing splash [ using the ${SPLASH_THEME} theme ] ..." local res_param="" [ -n "${SPLASH_RES}" ] && res_param="-r ${SPLASH_RES}" splash_geninitramfs -c "${TDIR}" ${res_param} ${SPLASH_THEME} \ || gen_die "Failed to build splash cpio archive" if [ -e "/usr/share/splashutils/initrd.splash" ] then mkdir -p "${TDIR}"/etc || gen_die "Failed to create '${TDIR}/etc'!" cp -f /usr/share/splashutils/initrd.splash "${TDIR}"/etc/ 2>/dev/null \ gen_die "Failed to copy '/usr/share/splashutils/initrd.splash'!" fi cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append splash to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_strace() { local PN=strace local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_overlay() { cd "${INITRAMFS_OVERLAY}" || gen_die "Failed to chdir to '${INITRAMFS_OVERLAY}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append overlay to cpio!" } append_luks() { local PN=cryptsetup local TDIR="${TEMP}/initramfs-luks-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" # Delete unneeded files rm -rf usr/ log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append luks to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_dropbear() { local PN=dropbear local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi local dropbear_command= if ! isTrue "$(is_valid_ssh_host_keys_parameter_value "${SSH_HOST_KEYS}")" then gen_die "--ssh-host-keys value '${SSH_HOST_KEYS}' is unsupported!" elif [[ "${SSH_HOST_KEYS}" == 'create' ]] then dropbear_command=dropbearkey else dropbear_command=dropbearconvert fi if [ -z "${DROPBEAR_AUTHORIZED_KEYS_FILE}" ] then gen_die "Something went wrong: DROPBEAR_AUTHORIZED_KEYS_FILE should already been set but is missing!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" if [[ "${SSH_HOST_KEYS}" == 'runtime' ]] then print_info 2 "$(get_indent 2)${PN}: >> No SSH host key embedded due to --ssh-host-key=runtime; Dropbear will generate required host key(s) at runtime!" else if ! hash ssh-keygen &>/dev/null then gen_die "'ssh-keygen' program is required but missing!" fi local initramfs_dropbear_dir="${TDIR}/etc/dropbear" if [[ "${SSH_HOST_KEYS}" == 'create-from-host' ]] then print_info 3 "$(get_indent 2)${PN}: >> Checking for existence of all SSH host keys ..." local missing_ssh_host_keys=no if [ ! -f "/etc/ssh/ssh_host_rsa_key" ] then print_info 3 "$(get_indent 2)${PN}: >> SSH host key '/etc/ssh/ssh_host_rsa_key' is missing!" missing_ssh_host_keys=yes fi if [ ! -f "/etc/ssh/ssh_host_ecdsa_key" ] then print_info 3 "$(get_indent 2)${PN}: >> SSH host key '/etc/ssh/ssh_host_ecdsa_key' is missing!" missing_ssh_host_keys=yes fi if [ ! -f "/etc/ssh/ssh_host_ed25519_key" ] then print_info 3 "$(get_indent 2)${PN}: >> SSH host key '/etc/ssh/ssh_host_ed25519_key' is missing!" missing_ssh_host_keys=yes fi if isTrue "${missing_ssh_host_keys}" then # Should only happen when installing a new system ... print_info 3 "$(get_indent 2)${PN}: >> Creating missing SSH host key(s) ..." ssh-keygen -A || gen_die "Failed to generate host's SSH host key(s) using 'ssh-keygen -A'!" fi fi local -a required_dropbear_host_keys=( /etc/dropbear/dropbear_ecdsa_host_key /etc/dropbear/dropbear_ed25519_host_key /etc/dropbear/dropbear_rsa_host_key ) local i=0 local n_required_dropbear_keys=${#required_dropbear_host_keys[@]} local required_key= while [[ ${i} < ${n_required_dropbear_keys} ]] do required_key=${required_dropbear_host_keys[${i}]} print_info 3 "$(get_indent 2)${PN}: >> Checking for existence of dropbear host key '${required_key}' ..." if [[ -f "${required_key}" ]] then if [[ ! -s "${required_key}" ]] then print_info 1 "$(get_indent 2)${PN}: >> Dropbear host key '${required_key}' exists but is empty; Removing ..." rm "${required_key}" || gen_die "Failed to remove invalid '${required_key}' null byte file!" elif [[ "${SSH_HOST_KEYS}" == 'create-from-host' ]] \ && [[ "${required_key}" == *_rsa_* ]] \ && [[ "${required_key}" -ot "/etc/ssh/ssh_host_rsa_key" ]] then print_info 1 "$(get_indent 2)${PN}: >> Dropbear host key '${required_key}' exists but is older than '/etc/ssh/ssh_host_rsa_key'; Removing to force update due to --ssh-host-key=create-from-host ..." rm "${required_key}" || gen_die "Failed to remove outdated '${required_key}' file!" elif [[ "${SSH_HOST_KEYS}" == 'create-from-host' ]] \ && [[ "${required_key}" == *_ecdsa_* ]] \ && [[ "${required_key}" -ot "/etc/ssh/ssh_host_ecdsa_key" ]] then print_info 1 "$(get_indent 2)${PN}: >> Dropbear host key '${required_key}' exists but is older than '/etc/ssh/ssh_host_ecdsa_key'; Removing to force update due to --ssh-host-key=create-from-host ..." rm "${required_key}" || gen_die "Failed to remove outdated '${required_key}' file!" elif [[ "${SSH_HOST_KEYS}" == 'create-from-host' ]] \ && [[ "${required_key}" == *_ed25519_* ]] \ && [[ "${required_key}" -ot "/etc/ssh/ssh_host_ed25519_key" ]] then print_info 1 "$(get_indent 2)${PN}: >> Dropbear host key '${required_key}' exists but is older than '/etc/ssh/ssh_host_ed25519_key'; Removing to force update due to --ssh-host-key=create-from-host ..." rm "${required_key}" || gen_die "Failed to remove outdated '${required_key}' file!" else print_info 3 "$(get_indent 2)${PN}: >> Dropbear host key '${required_key}' exists!" unset required_dropbear_host_keys[${i}] fi else print_info 3 "$(get_indent 2)${PN}: >> Dropbear host key '${required_key}' is missing! Will create ..." fi i=$((i + 1)) done if [[ ${#required_dropbear_host_keys[@]} -gt 0 ]] then if isTrue "$(can_run_programs_compiled_by_genkernel)" then dropbear_command="${TDIR}/usr/bin/${dropbear_command}" print_info 3 "$(get_indent 2)${PN}: >> Will use '${dropbear_command}' to create missing keys ..." elif hash ${dropbear_command} &>/dev/null then print_info 3 "$(get_indent 2)${PN}: >> Will use existing '${dropbear_command}' program from path to create missing keys ..." else local error_msg="Need to generate '${required_dropbear_host_keys[*]}' but '${dropbear_command}'" error_msg+=" program is missing. Please install net-misc/dropbear and re-run genkernel!" gen_die "${error_msg}" fi local missing_key= for missing_key in ${required_dropbear_host_keys[@]} do dropbear_create_key "${missing_key}" "${dropbear_command}" # just in case ... if [ -f "${missing_key}" ] then print_info 3 "$(get_indent 2)${PN}: >> Dropbear host key '${missing_key}' successfully created!" else gen_die "Sanity check failed: '${missing_key}' should exist at this stage but does NOT." fi done else print_info 2 "$(get_indent 2)${PN}: >> Using existing dropbear host keys from /etc/dropbear ..." fi cp -aL --target-directory "${initramfs_dropbear_dir}" /etc/dropbear/dropbear_{rsa,ecdsa,ed25519}_host_key \ || gen_die "Failed to copy '/etc/dropbear/dropbear_{rsa,ecdsa,ed25519}_host_key'" # Try to show embedded dropbear host key details for security reasons. # We do it that complicated to get common used formats. local -a key_info_files=() local -a missing_key_info_files=() local host_key_file= host_key_file_checksum= host_key_info_file= while IFS= read -r -u 3 -d $'\0' host_key_file do host_key_file_checksum=$(sha256sum "${host_key_file}" 2>/dev/null | awk '{print $1}') if [ -z "${host_key_file_checksum}" ] then gen_die "Failed to generate SHA256 checksum of '${host_key_file}'!" fi host_key_info_file="${GK_V_CACHEDIR}/$(basename "${host_key_file}").${host_key_file_checksum:0:10}.info" if [ ! -s "${host_key_info_file}" ] then missing_key_info_files+=( ${host_key_info_file} ) else key_info_files+=( ${host_key_info_file} ) fi done 3< <(find "${initramfs_dropbear_dir}" -type f -name '*_key' -print0 2>/dev/null) unset host_key_file host_key_file_checksum host_key_info_file IFS="${GK_DEFAULT_IFS}" if [[ ${#missing_key_info_files[@]} -ne 0 ]] then dropbear_command= if isTrue "$(can_run_programs_compiled_by_genkernel)" then dropbear_command="${TDIR}/usr/bin/dropbearconvert" print_info 3 "$(get_indent 2)${PN}: >> Will use '${dropbear_command}' to extract embedded host key information ..." elif hash dropbearconvert &>/dev/null then dropbear_command=dropbearconvert print_info 3 "$(get_indent 2)${PN}: >> Will use existing '${dropbear_command}' program to extract embedded host key information ..." else print_warning 2 "$(get_indent 2)${PN}: >> 'dropbearconvert' program not available; Cannot generate missing key information for ${#missing_key_info_files[@]} key(s)!" fi if [[ -n "${dropbear_command}" ]] then # We are missing at least information for one embedded key # but looks like we are able to generate the missing information ... local missing_key_info_file= for missing_key_info_file in "${missing_key_info_files[@]}" do dropbear_generate_key_info_file "${dropbear_command}" "${missing_key_info_file}" "${initramfs_dropbear_dir}" key_info_files+=( ${missing_key_info_file} ) done unset missing_key_info_file fi fi if [[ ${#key_info_files[@]} -gt 0 ]] then # We have at least information about one embedded key ... print_info 1 "=================================================================" 1 0 1 print_info 1 "This initramfs' sshd will use the following host key(s):" 1 0 1 local key_info_file= for key_info_file in "${key_info_files[@]}" do print_info 1 "$(cat "${key_info_file}")" 1 0 1 done unset key_info_file if [ ${LOGLEVEL} -lt 3 ] then # Don't clash with output from log_future_cpio_content print_info 1 "=================================================================" 1 0 1 fi else print_warning 2 "$(get_indent 2)${PN}: >> No information about embedded SSH host key(s) available." fi fi if isTrue "$(is_glibc)" then local libdir=$(get_chost_libdir) local libnss_files="${libdir}/libnss_files.so" # NSS files module was moved into libc in >=glibc-2.34 # but when this file exists we are probably dealing with older glibc # and need to manually copy the module. if [[ -f "${libnss_files}" ]] then mkdir -p "${TDIR}"/lib || gen_die "Failed to create '${TDIR}/lib'!" copy_system_binaries "${TDIR}"/lib "${libnss_files}" fi fi cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" cp -a "${GK_SHARE}"/defaults/login-remote.sh "${TDIR}"/usr/bin/ \ || gen_die "Failed to copy '${GK_SHARE}/defaults/login-remote.sh'" cp -a "${GK_SHARE}"/defaults/resume-boot.sh "${TDIR}"/usr/sbin/resume-boot \ || gen_die "Failed to copy '${GK_SHARE}/defaults/resume-boot.sh' to '${TDIR}/usr/sbin/resume-boot'" cp -a "${GK_SHARE}"/defaults/unlock-luks.sh "${TDIR}"/usr/sbin/unlock-luks \ || gen_die "Failed to copy '${GK_SHARE}/defaults/unlock-luks.sh' to '${TDIR}/usr/sbin/unlock-luks'" cp -a "${GK_SHARE}"/defaults/unlock-zfs.sh "${TDIR}"/usr/sbin/unlock-zfs \ || gen_die "Failed to copy '${GK_SHARE}/defaults/unlock-zfs.sh' to '${TDIR}/usr/sbin/unlock-zfs'" cp -aL "${DROPBEAR_AUTHORIZED_KEYS_FILE}" "${TDIR}"/root/.ssh/ \ || gen_die "Failed to copy '${DROPBEAR_AUTHORIZED_KEYS_FILE}'!" cp -aL /etc/localtime "${TDIR}"/etc/ \ || gen_die "Failed to copy '/etc/localtime'. Please set system's timezone!" echo "/usr/bin/login-remote.sh" > "${TDIR}"/etc/shells \ || gen_die "Failed to create '/etc/shells'!" chmod 0755 "${TDIR}"/usr/bin/login-remote.sh \ || gen_die "Failed to chmod of '${TDIR}/usr/bin/login-remote.sh'!" chmod 0755 "${TDIR}"/usr/sbin/resume-boot \ || gen_die "Failed to chmod of '${TDIR}/usr/sbin/resume-boot'!" chmod 0755 "${TDIR}"/usr/sbin/unlock-luks \ || gen_die "Failed to chmod of '${TDIR}/usr/sbin/unlock-luks'!" chmod 0755 "${TDIR}"/usr/sbin/unlock-zfs \ || gen_die "Failed to chmod of '${TDIR}/usr/sbin/unlock-zfs'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_firmware() { local TDIR="${TEMP}/initramfs-firmware-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" if [ ! -d "${FIRMWARE_DIR}" ] then gen_die "Specified firmware directory '${FIRMWARE_DIR}' does not exist!" fi mkdir -p "${TDIR}"/lib/firmware || gen_die "Failed to create '${TDIR}/lib/firmware'!" if [ ${#FIRMWARE_FILES[@]} -gt 0 ] then pushd "${FIRMWARE_DIR}" &>/dev/null || gen_die "Failed to chdir to '${FIRMWARE_DIR}'!" cp -rL --parents --target-directory="${TDIR}/lib/firmware" "${FIRMWARE_FILES[@]}" 2>/dev/null \ || gen_die "Failed to copy firmware files (${FIRMWARE_FILES}) to '${TDIR}/lib/firmware'!" popd &>/dev/null || gen_die "Failed to chdir!" else cp -a "${FIRMWARE_DIR}"/* "${TDIR}"/lib/firmware/ 2>/dev/null \ || gen_die "Failed to copy firmware files to '${TDIR}/lib/firmware'!" fi cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append firmware to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_gpg() { local PN=gnupg local TDIR="${TEMP}/initramfs-${PN}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg ${PN} mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg "${PN}")" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append ${PN} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } print_list() { local x for x in ${*} do echo ${x} done } append_modules() { local TDIR="${TEMP}/initramfs-modules-${KV}-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi populate_binpkg kmod mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" unpack "$(get_gkpkg_binpkg kmod)" "${TDIR}" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" # Delete unneeded files rm -rf \ usr/include \ usr/lib local mydir= for mydir in \ etc/modules \ lib/modules/${KV} \ ; do mkdir -p "${TDIR}"/${mydir} || gen_die "Failed to create '${TDIR}/${mydir}'!" done local modules_dstdir="${TDIR}/lib/modules/${KV}" local modules_srcdir="/lib/modules/${KV}" if [ -n "${KERNEL_MODULES_PREFIX}" ] then modules_srcdir="${KERNEL_MODULES_PREFIX%/}${modules_srcdir}" fi if [ ! -d "${modules_srcdir}" ] then error_message="'${modules_srcdir}' does not exist! Did you forget" error_message+=" to compile kernel before building initramfs?" error_message+=" If you know what you are doing please set '--no-ramdisk-modules'." gen_die "${error_message}" fi determine_KEXT cd "${modules_srcdir}" || gen_die "Failed to chdir to '${modules_srcdir}'!" print_info 2 "$(get_indent 2)modules: >> Copying modules from '${modules_srcdir}' to initramfs ..." local i= mymod= local n_copied_modules=0 for i in $(gen_dep_list) do mymod=$(find . -name "${i}${KEXT}" 2>/dev/null | head -n 1) if [ -z "${mymod}" ] then print_warning 3 "$(get_indent 3) - ${i}${KEXT} not found; Skipping ..." continue; fi print_info 3 "$(get_indent 3) - Copying ${i}${KEXT} ..." cp -ax --parents --target-directory "${modules_dstdir}" "${mymod}" 2>/dev/null \ || gen_die "Failed to copy '${modules_srcdir}/${mymod}' to '${modules_dstdir}'!" n_copied_modules=$[$n_copied_modules+1] done if [ ${n_copied_modules} -eq 0 ] then print_warning 1 "$(get_indent 2)modules: ${n_copied_modules} modules copied. Is that correct?" else print_info 2 "$(get_indent 2)modules: ${n_copied_modules} modules copied!" fi cp -ax --parents --target-directory "${modules_dstdir}" modules* 2>/dev/null \ || gen_die "Failed to copy '${modules_srcdir}/modules*' to '${modules_dstdir}'!" print_info 2 "$(get_indent 2)modules: Updating modules.dep ..." local depmod_cmd=( depmod -a -b "${TDIR}" ${KV} ) print_info 3 "COMMAND: ${depmod_cmd[*]}" 1 0 1 eval "${depmod_cmd[@]}" || gen_die "Failed to run '${depmod_cmd[*]}'!" local group_modules= group= for group_modules in ${!MODULES_*} do group="$(echo ${group_modules} | cut -d_ -f2- | tr "[:upper:]" "[:lower:]")" print_list ${!group_modules} > "${TDIR}"/etc/modules/${group} \ || gen_die "Failed to create '${TDIR}/etc/modules/${group}'!" done cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append modules-${KV} to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_modprobed() { local TDIR="${TEMP}/initramfs-modprobe.d-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" local modprobe_dir for modprobe_dir in /etc/modprobe.d /lib/modprobe.d do if [[ ! -e "${modprobe_dir}" ]]; then print_info 5 "'${modprobe_dir}' does not exist; Skipping ..." continue fi mkdir -p "${TDIR}${modprobe_dir}" || gen_die "Failed to create '${TDIR}${modprobe_dir}'!" cp -aL "${modprobe_dir}"/. "${TDIR}${modprobe_dir}" 2>/dev/null \ || gen_die "Failed to copy '${modprobe_dir}'!" done cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append modprobe.d to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_auxiliary() { local TDIR="${TEMP}/initramfs-aux-temp" if [ -d "${TDIR}" ] then rm -r "${TDIR}" || gen_die "Failed to clean out existing '${TDIR}'!" fi mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" local mydir= for mydir in \ etc \ sbin \ ; do mkdir -p "${TDIR}"/${mydir} || gen_die "Failed to create '${TDIR}/${mydir}'!" done local mylinuxrc= if [ -n "${LINUXRC}" ] then mylinuxrc="${LINUXRC}" print_info 2 "$(get_indent 2)>> Copying user specified linuxrc '${mylinuxrc}' to '/init' ..." elif isTrue "${NETBOOT}" then mylinuxrc="${GK_SHARE}/netboot/linuxrc.x" print_info 2 "$(get_indent 2)>> Copying netboot specific linuxrc '${mylinuxrc}' to '/init' ..." else if [ -f "${GK_SHARE}/arch/${ARCH}/linuxrc" ] then mylinuxrc="${GK_SHARE}/arch/${ARCH}/linuxrc" else mylinuxrc="${GK_SHARE}/defaults/linuxrc" fi print_info 2 "$(get_indent 2)>> Copying '${mylinuxrc}' to '/init' ..." fi cp -aL "${mylinuxrc}" "${TDIR}"/init 2>/dev/null \ || gen_die "Failed to copy '${mylinuxrc}' to '${TDIR}/init'!" # Make sure it's executable chmod 0755 "${TDIR}"/init || gen_die "Failed to chmod of '${TDIR}/init' to 0755!" # Make a symlink to init .. in case we are bundled inside the kernel as one # big cpio. pushd "${TDIR}" &>/dev/null || gen_die "Failed to chdir to '${TDIR}'!" ln -s init linuxrc || gen_die "Failed to create symlink 'linuxrc' to 'init'!" popd &>/dev/null || gen_die "Failed to chdir!" local myinitrd_script= if [ -f "${GK_SHARE}/arch/${ARCH}/initrd.scripts" ] then myinitrd_script="${GK_SHARE}/arch/${ARCH}/initrd.scripts" else myinitrd_script="${GK_SHARE}/defaults/initrd.scripts" fi print_info 2 "$(get_indent 2)>> Copying '${myinitrd_script}' to '/etc/initrd.scripts' ..." cp -aL "${myinitrd_script}" "${TDIR}"/etc/initrd.scripts 2>/dev/null \ || gen_die "Failed to copy '${myinitrd_script}' to '${TDIR}/etc/initrd.scripts'!" local myinitrd_default= if [ -f "${GK_SHARE}/arch/${ARCH}/initrd.defaults" ] then myinitrd_default="${GK_SHARE}/arch/${ARCH}/initrd.defaults" else myinitrd_default="${GK_SHARE}/defaults/initrd.defaults" fi print_info 2 "$(get_indent 2)>> Copying '${myinitrd_default}' to '/etc/initrd.defaults' ..." cp -aL "${myinitrd_default}" "${TDIR}"/etc/initrd.defaults 2>/dev/null \ || gen_die "Failed to copy '${myinitrd_default}' to '${TDIR}/etc/initrd.defaults'!" if [ -n "${REAL_ROOT}" ] then print_info 2 "$(get_indent 2)>> Setting REAL_ROOT to '${REAL_ROOT}' in '/etc/initrd.defaults' ..." sed -i "s:^REAL_ROOT=.*$:REAL_ROOT='${REAL_ROOT}':" \ "${TDIR}"/etc/initrd.defaults \ || gen_die "Failed to set REAL_ROOT in '${TDIR}/etc/initrd.defaults'!" fi printf "%s" 'HWOPTS="$HWOPTS ' >> "${TDIR}"/etc/initrd.defaults \ || gen_die "Failed to add HWOPTS to '${TDIR}/etc/initrd.defaults'!" local group_modules group for group_modules in ${!MODULES_*}; do group="$(echo ${group_modules} | cut -d_ -f2 | tr "[:upper:]" "[:lower:]")" printf "%s" "${group} " >> "${TDIR}"/etc/initrd.defaults \ || gen_die "Failed to add MODULES_* to '${TDIR}/etc/initrd.defaults'!" done echo '"' >> "${TDIR}"/etc/initrd.defaults \ || gen_die "Failed to add closing '\"' to '${TDIR}/etc/initrd.defaults'!" if isTrue "${CMD_KEYMAP}" then print_info 2 "$(get_indent 2)>> Copying keymaps ..." mkdir -p "${TDIR}"/lib || gen_die "Failed to create '${TDIR}/lib'!" cp -R "${GK_SHARE}/defaults/keymaps" "${TDIR}"/lib/ 2>/dev/null \ || gen_die "Failed to copy '${GK_SHARE}/defaults/keymaps' to '${TDIR}/lib'!" if isTrue "${CMD_DOKEYMAPAUTO}" then print_info 2 "$(get_indent 2)>> Forcing keymap selection in initrd script due to DOKEYMAPAUTO setting ..." echo 'MY_HWOPTS="${MY_HWOPTS} keymap"' >> "${TDIR}"/etc/initrd.defaults \ || gen_die "Failed to add keymap to MY_HWOPTS in '${TDIR}/etc/initrd.defaults'!" fi fi pushd "${TDIR}"/sbin &>/dev/null || gen_die "Failed to chdir to '${TDIR}/sbin'!" ln -s ../init init || gen_die "Failed to create symlink 'init' to '../init'!" popd &>/dev/null || gen_die "Failed to chdir!" if isTrue "${NETBOOT}" then pushd "${GK_SHARE}/netboot/misc" &>/dev/null || gen_die "Failed to chdir to '${GK_SHARE}/netboot/misc'!" cp -pPRf * "${TDIR}"/ 2>/dev/null \ || gen_die "Failed to copy '${GK_SHARE}/netboot/misc' to '${TDIR}'!" popd &>/dev/null || gen_die "Failed to chdir!" fi cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" ${CPIO_ARGS} --append -F "${CPIO_ARCHIVE}" \ || gen_die "Failed to append auxiliary to cpio!" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi } append_data() { [ $# -eq 0 ] && gen_die "append_data() called with zero arguments" local name=$1 local func="append_${name}" shift if [ $# -eq 0 ] || anyTrue "$@" then print_info 1 "$(get_indent 1)>> Appending ${name} cpio data ..." ${func} || gen_die "${func}() failed!" fi } create_initramfs() { print_info 1 "initramfs: >> Initializing ..." if ! isTrue "${BUILD_KERNEL}" then # Check early for suitable kmod determine_KEXT if ! isTrue "$(is_kext_supported_by_kmod "${KEXT}")" then gen_die "${KMOD_CMD} does not support chosen module compression algorithm. Please re-emerge sys-apps/kmod with USE=$(get_kext_kmod_use_flag "${KEXT}") enabled or adjust CONFIG_MODULE_COMPRESS_* kernel option!" fi fi # Create empty cpio CPIO_ARCHIVE="${TMPDIR}/${GK_FILENAME_TEMP_INITRAMFS}" append_data 'devices' # WARNING, must be first! append_data 'base_layout' append_data 'util-linux' append_data 'eudev' append_data 'devicemanager' "${DMRAID}" "${LVM}" "${LUKS}" "${MULTIPATH}" append_data 'auxiliary' "${BUSYBOX}" append_data 'busybox' "${BUSYBOX}" append_data 'b2sum' "${B2SUM}" append_data 'btrfs' "${BTRFS}" append_data 'dmraid' "${DMRAID}" append_data 'dropbear' "${SSH}" append_data 'e2fsprogs' "${E2FSPROGS}" append_data 'gpg' "${GPG}" append_data 'iscsi' "${ISCSI}" append_data 'keyutils' "${KEYCTL}" append_data 'luks' "${LUKS}" append_data 'lvm' "${LVM}" append_data 'bcache' "${BCACHE}" append_data 'mdadm' "${MDADM}" append_data 'modprobed' append_data 'multipath' "${MULTIPATH}" append_data 'splash' "${SPLASH}" append_data 'strace' "${STRACE}" append_data 'unionfs_fuse' "${UNIONFS}" append_data 'xfsprogs' "${XFSPROGS}" append_data 'zfs' "${ZFS}" if isTrue "${ZFS}" then append_data 'libgcc_s' fi if isTrue "${FIRMWARE}" && [ -n "${FIRMWARE_DIR}" ] then append_data 'firmware' fi if isTrue "${RAMDISKMODULES}" then append_data 'modules' else print_info 1 "$(get_indent 1)>> Not copying modules due to --no-ramdisk-modules ..." fi # This should always be appended last if [ -n "${INITRAMFS_OVERLAY}" ] then append_data 'overlay' fi if [[ -f "${TEMP}/.binaries_copied" || -f "${TEMP}/.system_binaries_copied" ]] then append_data 'linker' else print_info 2 "$(get_indent 1)>> Not appending linker because no binaries have been copied ..." fi # Finalize cpio by removing duplicate files # TODO: maybe replace this with: # http://search.cpan.org/~pixel/Archive-Cpio-0.07/lib/Archive/Cpio.pm # as then we can dedupe ourselves... if isTrue "${BUSYBOX}" || [[ ${UID} -eq 0 ]] then print_info 1 "$(get_indent 1)>> Deduping cpio ..." local TDIR="${TEMP}/initramfs-final" mkdir -p "${TDIR}" || gen_die "Failed to create '${TDIR}'!" cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!" "${CPIO_COMMAND}" --quiet -i -F "${CPIO_ARCHIVE}" 2>/dev/null \ || gen_die "Failed to extract cpio '${CPIO_ARCHIVE}' for dedupe" if ! isTrue "$(tc-is-cross-compiler)" then # We can generate or update /etc/ld.so.cache which was copied from host # to actually match initramfs' content. print_info 1 "$(get_indent 1)>> Pre-generating initramfs' /etc/ld.so.cache ..." # Need to disable sandbox which doesn't understand chroot(), bug #431038 SANDBOX_ON=0 ldconfig -f /etc/ld.so.conf -r "${TDIR}" 2>/dev/null \ || print_warning 1 "Failed to pre-generate '${TDIR}/etc/ld.so.cache'! Probably due to sandbox/permission problem; Ignoring ..." fi find . -print0 | sort -z | "${CPIO_COMMAND}" ${CPIO_ARGS} --reproducible -F "${CPIO_ARCHIVE}" 2>/dev/null \ || gen_die "rebuilding cpio for dedupe" cd "${TEMP}" || die "Failed to chdir to '${TEMP}'!" if isTrue "${CLEANUP}" then rm -rf "${TDIR}" fi else print_info 1 "$(get_indent 1)>> Cannot deduping cpio contents without root; Skipping ..." fi cd "${TEMP}" || gen_die "Failed to chdir to '${TEMP}'" local kconfig_file_used="${KERNEL_CONFIG}" if isTrue "${BUILD_KERNEL}" then kconfig_file_used="${KERNEL_OUTPUTDIR}/.config" fi if isTrue "$(is_gzipped "${kconfig_file_used}")" then print_info 5 "Compressed kernel config '${kconfig_file_used}' found; Must decompress to temporary file ..." local kconfig_file_tmp="${TEMP}/current_kernel.config" zcat "${kconfig_file_used}" > "${kconfig_file_tmp}" \ || gen_die "Failed to decompress '${kconfig_file_used}' to '${kconfig_file_tmp}'!" kconfig_file_used="${kconfig_file_tmp}" fi if isTrue "${INTEGRATED_INITRAMFS}" then # Explicitly do not compress if we are integrating into the kernel. # The kernel will do a better job of it than us. mv "${CPIO_ARCHIVE}" "${CPIO_ARCHIVE}.cpio" print_info 1 "$(get_indent 1)>> --integrated-initramfs is set; Setting CONFIG_INITRAMFS_* options ..." [ -f "${KCONFIG_MODIFIED_MARKER}" ] && rm "${KCONFIG_MODIFIED_MARKER}" [ -f "${KCONFIG_REQUIRED_OPTIONS}" ] && rm "${KCONFIG_REQUIRED_OPTIONS}" kconfig_set_opt "${kconfig_file_used}" "CONFIG_BLK_DEV_INITRD" "y" kconfig_set_opt "${kconfig_file_used}" "CONFIG_INITRAMFS_SOURCE" "\"${CPIO_ARCHIVE}.cpio\"" kconfig_set_opt "${kconfig_file_used}" "CONFIG_INITRAMFS_ROOT_UID" "0" kconfig_set_opt "${kconfig_file_used}" "CONFIG_INITRAMFS_ROOT_GID" "0" set_initramfs_compression_method "${kconfig_file_used}" if [ -f "${KCONFIG_MODIFIED_MARKER}" ] then print_info 1 "$(get_indent 1)>> Running 'make olddefconfig' due to changed kernel options ..." pushd "${KERNEL_DIR}" &>/dev/null || gen_die "Failed to chdir to '${KERNEL_DIR}'!" compile_generic olddefconfig kernel 2>/dev/null popd &>/dev/null || gen_die "Failed to chdir!" fi else if isTrue "${COMPRESS_INITRD}" then if ! isTrue "${BUILD_KERNEL}" || isTrue "${KERNCACHE_IS_VALID}" then # We need to initialize COMPRESS_INITRD_TYPE in case it was set # to best/fastest and validate if used kernel config can decompress # set COMPRESS_INITRD_TYPE at all. set_initramfs_compression_method "${kconfig_file_used}" fi print_info 1 "$(get_indent 1)>> Compressing cpio data (${GKICM_LOOKUP_TABLE_EXT[${COMPRESS_INITRD_TYPE}]}) ..." print_info 3 "COMMAND: ${GKICM_LOOKUP_TABLE_CMD[${COMPRESS_INITRD_TYPE}]} ${CPIO_ARCHIVE}" 1 0 1 ${GKICM_LOOKUP_TABLE_CMD[${COMPRESS_INITRD_TYPE}]} "${CPIO_ARCHIVE}" || gen_die "Initramfs compression using '${GKICM_LOOKUP_TABLE_CMD[${COMPRESS_INITRD_TYPE}]}' failed" mv -f "${CPIO_ARCHIVE}${GKICM_LOOKUP_TABLE_EXT[${COMPRESS_INITRD_TYPE}]}" "${CPIO_ARCHIVE}" || gen_die "Rename failed" else print_info 3 "$(get_indent 1)>> --no-compress-initramfs is set; Skipping compression of initramfs ..." fi ## To early load microcode we need to follow some pretty specific steps ## mostly laid out in linux/Documentation/x86/early-microcode.txt ## It only loads monolithic ucode from an uncompressed cpio, which MUST ## be before the other cpio archives in the stream. if isTrue "${MICROCODE_INITRAMFS}" then local cfg_CONFIG_MICROCODE=$(kconfig_get_opt "${kconfig_file_used}" CONFIG_MICROCODE) local cfg_CONFIG_MICROCODE_INTEL=$(kconfig_get_opt "${kconfig_file_used}" CONFIG_MICROCODE_INTEL) local cfg_CONFIG_MICROCODE_AMD=$(kconfig_get_opt "${kconfig_file_used}" CONFIG_MICROCODE_AMD) print_info 1 "$(get_indent 1)>> Adding early-microcode support ..." local UCODEDIR="${TEMP}/ucode_tmp/kernel/x86/microcode/" mkdir -p "${UCODEDIR}" || gen_die "Failed to create '${UCODEDIR}'!" echo 1 > "${TEMP}/ucode_tmp/early_cpio" if [ "${cfg_CONFIG_MICROCODE}" != "y" ] then print_warning 1 "$(get_indent 2)early-microcode: Will add microcode(s) like requested but kernel has set CONFIG_MICROCODE=n" fi if [[ "${MICROCODE}" == 'all' || "${MICROCODE}" == 'intel' ]] then if [[ "${cfg_CONFIG_MICROCODE_INTEL}" != "y" ]] then print_warning 1 "$(get_indent 2)early-microcode: Will add Intel microcode(s) like requested (--microcode=${MICROCODE}) but kernel has set CONFIG_MICROCODE_INTEL=n" fi if [ -d /lib/firmware/intel-ucode ] then print_info 1 "$(get_indent 2)early-microcode: Adding GenuineIntel.bin ..." cat /lib/firmware/intel-ucode/* > "${UCODEDIR}/GenuineIntel.bin" || gen_die "Failed to concat intel cpu ucode" else print_warning 1 "$(get_indent 2)early-microcode: Unable to add Intel microcode like requested (--microcode=${MICROCODE}); No ucode is available." print_warning 1 "$(get_indent 2) Is sys-firmware/intel-microcode[split-ucode] installed?" fi fi if [[ "${MICROCODE}" == 'all' || "${MICROCODE}" == 'amd' ]] then if [[ "${cfg_CONFIG_MICROCODE_AMD}" != "y" ]] then print_warning 1 "$(get_indent 2)early-microcode: Will add AMD microcode(s) like requested (--microcode=${MICROCODE}) but kernel has set CONFIG_MICROCODE_AMD=n" fi if [ -d /lib/firmware/amd-ucode ] then print_info 1 "$(get_indent 2)early-microcode: Adding AuthenticAMD.bin ..." cat /lib/firmware/amd-ucode/*.bin > "${UCODEDIR}/AuthenticAMD.bin" || gen_dir "Failed to concat amd cpu ucode" else print_warning 1 "$(get_indent 2)early-microcode: Unable to add AMD microcode like requested (--microcode=${MICROCODE}); No ucode is available." print_warning 1 "$(get_indent 2) Is sys-firmware/linux-firmware installed?" fi fi if [ -f "${UCODEDIR}/AuthenticAMD.bin" -o -f "${UCODEDIR}/GenuineIntel.bin" ] then print_info 1 "$(get_indent 2)early-microcode: Creating cpio ..." pushd "${TEMP}/ucode_tmp" &>/dev/null || gen_die "Failed to chdir to '${TEMP}/ucode_tmp'!" log_future_cpio_content find . -print0 | "${CPIO_COMMAND}" --quiet --null -o -H newc > ../ucode.cpio || gen_die "Failed to create cpu microcode cpio" popd &>/dev/null || gen_die "Failed to chdir!" print_info 1 "$(get_indent 2)early-microcode: Prepending early-microcode to initramfs ..." cat "${TEMP}/ucode.cpio" "${CPIO_ARCHIVE}" > "${CPIO_ARCHIVE}.early-microcode" || gen_die "Failed to prepend early-microcode to initramfs" mv -f "${CPIO_ARCHIVE}.early-microcode" "${CPIO_ARCHIVE}" || gen_die "Rename failed" else print_warning 1 "$(get_indent 2)early-microcode: No microcode found; Will not prepend any microcode to initramfs ..." print_info 1 "$(get_indent 2) ${BOLD}Note:${NORMAL} You can set --no-microcode-initramfs if you load microcode on your own" fi if ! isTrue "${WRAP_INITRD}" then print_info 1 '' print_info 1 "${BOLD}Note:${NORMAL}" print_info 1 '--microcode-initramfs option is enabled by default for backward compatability.' print_info 1 'If your bootloader can load multiple initramfs it is recommended to load' print_info 1 '/boot/{amd,intel}-uc.img instead of embedding microcode into initramfs so you' print_info 1 'can update microcode via package update independently of initramfs updates.' fi else print_info 3 "$(get_indent 1)>> --no-microcode-initramfs is set; Skipping early-microcode support ..." fi if isTrue "${WRAP_INITRD}" then local mkimage_cmd=$(type -p mkimage) [[ -z ${mkimage_cmd} ]] && gen_die "mkimage is not available. Please install package 'dev-embedded/u-boot-tools'." local mkimage_args="-A ${ARCH} -O linux -T ramdisk -C ${compression:-none} -a 0x00000000 -e 0x00000000" print_info 1 "$(get_indent 1)>> Wrapping initramfs using mkimage ..." print_info 2 "$(get_indent 1)${mkimage_cmd} ${mkimage_args} -n ${GK_FILENAME_TEMP_INITRAMFS} -d ${CPIO_ARCHIVE} ${CPIO_ARCHIVE}.uboot" ${mkimage_cmd} ${mkimage_args} -n "${GK_FILENAME_TEMP_INITRAMFS}" -d "${CPIO_ARCHIVE}" "${CPIO_ARCHIVE}.uboot" >> ${LOGFILE} 2>&1 || gen_die "Wrapping initramfs using mkimage failed" mv -f "${CPIO_ARCHIVE}.uboot" "${CPIO_ARCHIVE}" || gen_die "Rename failed" fi fi if isTrue "${CMD_INSTALL}" then if ! isTrue "${INTEGRATED_INITRAMFS}" then copy_image_with_preserve \ "${GK_FILENAME_INITRAMFS_SYMLINK}" \ "${CPIO_ARCHIVE}" \ "${GK_FILENAME_INITRAMFS}" fi fi }