从 jessie 升级到拉伸后,update-initramfs 失败

Ste*_*fen 5 ssh debian initramfs

我最近更新了我的一个 Debian 机器以使用拉伸运行,但不幸的是,当涉及到 initramfs 映像的重新生成时,我遇到了一个问题。

它似乎没有认识到我需要/root/.ssh/在引导时目录及其内容存在。我试图寻找一个配置选项来强制 update-initramfs 获取 /etc/initramfs-tools/root 中的内容 - 我在它无法生成映像后手动创建的 - 但没有任何运气。最后,我从 sysresccd 进行了 debootstrap 安装,以确保它不是我这边的配置失败,但这也失败了。

下面是我尝试更新 initramfs 映像时得到的输出:

root@sysresccd:/etc/initramfs-tools# update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-4.3.0-1-amd64
/etc/initramfs-tools/hooks/mount_cryptroot: 21: /etc/initramfs-tools/hooks/mount_cryptroot: cannot create /var/tmp/mkinitramfs_uIC6Q0/root/mount_cryptroot.sh: Directory nonexistent
chmod: cannot access /var/tmp/mkinitramfs_uIC6Q0/root/mount_cryptroot.sh: No such file or directory
/etc/initramfs-tools/hooks/mount_cryptroot: 36: /etc/initramfs-tools/hooks/mount_cryptroot: cannot create /var/tmp/mkinitramfs_uIC6Q0/root/.profile: Directory nonexistent
/etc/initramfs-tools/hooks/mount_cryptroot: 21: /etc/initramfs-tools/hooks/mount_cryptroot: cannot create /var/tmp/mkinitramfs_uIC6Q0/root/mount_cryptroot.sh: Directory nonexistent
chmod: cannot access /var/tmp/mkinitramfs_uIC6Q0/root/mount_cryptroot.sh: No such file or directory
/etc/initramfs-tools/hooks/mount_cryptroot: 36: /etc/initramfs-tools/hooks/mount_cryptroot: cannot create /var/tmp/mkinitramfs_uIC6Q0/root/.profile: Directory nonexistent
E: /etc/initramfs-tools/hooks/mount_cryptroot failed with return 2.
update-initramfs: failed for /boot/initrd.img-4.3.0-1-amd64 with 2.
Run Code Online (Sandbox Code Playgroud)

实际上,我现在没有想法,如果有人能帮助我解决这个问题,我将非常感激。

一些背景信息:
我使用 本指南来安装我的系统,对于 jessie 来说,它运行良好,但由于上述原因,它在拉伸时失败了。

小智 4

今天我也遇到了同样的问题,只能在网上找到这个问题。于是我尝试自己调试一下...

该脚本/etc/initramfs-tools/hooks/mount_cryptroot(第 21 行)尝试将文件放入/var/tmp/mkinitramfs_uIC6Q0/root/目录中。根据错误消息,该目录恰好丢失。脚本的相关部分是:

SCRIPT="${DESTDIR}/root/mount_cryptroot.sh"
cat > "${SCRIPT}" << 'EOF'
Run Code Online (Sandbox Code Playgroud)

/var/tmp/mkinitramfs_uIC6Q0/目录是一个临时目录,其中收集了新 initrd 的内容。我的猜测是 initrd 不再有根子目录了。于是我看了一下现有的initrd镜像的内容:

# mkdir initrd
# cd initrd
# gunzip -c /boot/initrd.img-4.9.0-3-amd64 | cpio -i
125955 blocks
# ls
bin  conf  etc  init  lib  lib64  root-aBcDeF  run  sbin  scripts
#
Run Code Online (Sandbox Code Playgroud)

root目录的后缀为 6 个随机字母/数字(此处更改为aBcDeF)。这可能是出于安全原因。我发现每次生成initrd的后缀都不一样。

因此,解决方案是扩展/etc/initramfs-tools/hooks/mount_cryptroot脚本以找出根目录的真实名称(包括后缀)并使用它而不仅仅是root.

这可以通过插入来完成

ROOTDIR="$(cd "${DESTDIR}"; echo root-*)"
Run Code Online (Sandbox Code Playgroud)

在故障线路之前并将故障线路更改为

SCRIPT="${DESTDIR}/${ROOTDIR}/mount_cryptroot.sh"
cat > "${SCRIPT}" << 'EOF'
Run Code Online (Sandbox Code Playgroud)

。还有两行root不包含后缀。这些必须改为

cat > "${DESTDIR}/${ROOTDIR}/.profile" << EOF
Run Code Online (Sandbox Code Playgroud)

/${ROOTDIR}/mount_cryptroot.sh && exit 1 || echo "Run ./mount_cryptroot.sh to try unlocking again"
Run Code Online (Sandbox Code Playgroud)

。这为我解决了这个问题

update-initramfs -u -k all
Run Code Online (Sandbox Code Playgroud)

以及在启动时通过 SSH 输入密码再次起作用。

/etc/initramfs-tools/hooks/mount_cryptroot改编后的整个脚本:

#!/bin/sh

# Author: http://www.dont-panic.cc/capi/2012/10/24/fully-encrypted-vserver-with-ubuntu-12-04/
# This script generates two scripts in the initramfs output,
# /root-xxxxxx/mount_cryptroot.sh and /root-xxxxxx/.profile
ALLOW_SHELL=1
# Set this to 1 before running update-initramfs if you want
# to allow authorized users to type Ctrl-C to drop to a
# root shell (useful for debugging, potential for abuse.)
#
# (Note that even with ALLOW_SHELL=0 it may still be possible
# to achieve a root shell.)
#

if [ -z ${DESTDIR} ]; then
exit
fi

ROOTDIR="$(cd "${DESTDIR}"; echo root-*)"

SCRIPT="${DESTDIR}/${ROOTDIR}/mount_cryptroot.sh"
cat > "${SCRIPT}" << 'EOF'
#!/bin/sh
CMD=
while [ -z "$CMD" -o -z "`pidof askpass plymouth`" ]; do
CMD=`ps -o args | grep 'open --type luks' | grep -v grep`
sleep 0.1
done
while [ -n "`pidof askpass plymouth`" ]; do
$CMD && kill -9 `pidof askpass plymouth` && echo "Success"
done
EOF

chmod +x "${SCRIPT}"

# Run mount_cryptroot by default and close the login session afterwards
# If ALLOW_SHELL is set to 1, you can press Ctrl-C to get to an interactive prompt
cat > "${DESTDIR}/${ROOTDIR}/.profile" << EOF
ctrl_c_exit() {
exit 1
}
ctrl_c_shell() {
# Ctrl-C during .profile appears to mangle terminal settings
reset
}
if [ "$ALLOW_SHELL" == "1" ]; then
echo "Unlocking rootfs... Type Ctrl-C for a shell."
trap ctrl_c_shell INT
else
echo "Unlocking rootfs..."
trap ctrl_c_exit INT
fi
/${ROOTDIR}/mount_cryptroot.sh && exit 1 || echo "Run ./mount_cryptroot.sh to try unlocking again"
trap INT
EOF
Run Code Online (Sandbox Code Playgroud)