From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 5B7397A1ED for ; Thu, 6 May 2021 17:28:06 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 53ED222DE0 for ; Thu, 6 May 2021 17:27:09 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 84A0D22D4E for ; Thu, 6 May 2021 17:27:05 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 5FC1B464F5 for ; Thu, 6 May 2021 17:27:05 +0200 (CEST) From: Stefan Reiter To: pbs-devel@lists.proxmox.com Date: Thu, 6 May 2021 17:26:24 +0200 Message-Id: <20210506152624.12605-10-s.reiter@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210506152624.12605-1-s.reiter@proxmox.com> References: <20210506152624.12605-1-s.reiter@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.137 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [pkg-info.mk, architecture.mk, main.rs] Subject: [pbs-devel] [PATCH proxmox-backup-restore-image 9/9] add debug initramfs as seperate package X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 May 2021 15:28:06 -0000 "proxmox-backup-restore-image-debug", containing only the debug initramfs, so depends on the base "proxmox-backup-restore-image" for the kernel. Adapt the init-shim to start an agetty on ttyS1, which the host can use to connect to a root shell for debugging, and use create_dir_all, since some debug packages seem to create /sys and /proc as empty dirs already. The build_initramfs.sh script is modified to include dependency resolution via apt-rdepends, so debug packages like agetty (util-linux), busybox and gdb can easily be added. This now builds both the regular and the debug binary at once, to avoid downloading shared packages twice. Signed-off-by: Stefan Reiter --- The updated build_initramfs script should also make further additions to the initrd easier, e.g. adding lvm and zfs tooling if necessary. Makefile | 13 +++-- debian/control | 10 +++- ...proxmox-backup-restore-image-debug.install | 1 + ...ckup-restore-image-debug.lintian-overrides | 2 + ...roxmox-backup-restore-image-debug.triggers | 1 + src/Makefile | 5 +- src/build_initramfs.sh | 55 +++++++++++++------ src/init-shim-rs/src/main.rs | 46 +++++++++++++++- 8 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 debian/proxmox-backup-restore-image-debug.install create mode 100644 debian/proxmox-backup-restore-image-debug.lintian-overrides create mode 100644 debian/proxmox-backup-restore-image-debug.triggers diff --git a/Makefile b/Makefile index d11ac3e..92aa791 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,14 @@ include /usr/share/dpkg/pkg-info.mk include /usr/share/dpkg/architecture.mk PACKAGE=proxmox-backup-restore-image +PACKAGE_DBG=proxmox-backup-restore-image-debug BUILDDIR=${PACKAGE}-${DEB_VERSION_UPSTREAM_REVISION} DEB=${PACKAGE}_${DEB_VERSION}_${DEB_BUILD_ARCH}.deb DSC=${PACKAGE}_${DEB_VERSION}.dsc +DEB_DBG=${PACKAGE_DBG}_${DEB_VERSION}_${DEB_BUILD_ARCH}.deb +DSC_DBG=${PACKAGE_DBG}_${DEB_VERSION}.dsc all: deb @@ -32,21 +35,23 @@ ${BUILDDIR}: submodules.prepared deb: ${DEB} ${DEB}: ${BUILDDIR} cd ${BUILDDIR}; dpkg-buildpackage -b -us -uc - lintian ${DEB} + lintian ${DEB} ${DEB_DBG} +${DEB_DBG}: ${DEB} .PHONY: dsc dsc: ${DSC} ${DSC}: ${BUILDDIR} cd ${BUILDDIR}; dpkg-buildpackage -S -us -uc -d - lintian ${DSC} + lintian ${DSC} ${DSC_DBG} +${DSC_DBG}: ${DSC} .PHONY: dinstall dinstall: deb - dpkg -i ${DEB} + dpkg -i ${DEB} ${DEB_DBG} .PHONY: upload upload: ${DEB} - tar cf - ${DEB} | ssh -X repoman@repo.proxmox.com upload --product pbs,pve --dist buster + tar cf - ${DEB} ${DEB_DBG} | ssh -X repoman@repo.proxmox.com upload --product pbs,pve --dist buster .PHONY: clean clean: diff --git a/debian/control b/debian/control index 5b50392..b87c903 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,8 @@ Source: proxmox-backup-restore-image Section: admin Priority: optional Maintainer: Proxmox Support Team -Build-Depends: asciidoc-base, +Build-Depends: apt-rdepends, + asciidoc-base, automake, bc, bison, @@ -34,3 +35,10 @@ Description: Kernel/initramfs images for Proxmox Backup single-file restore. Preconfigured images used as base for single file restore of Proxmox Backup Server snapshots. Not really useful on their own, so best used together with the proxmox-backup-file-restore package, which provide the actual tools. + +Package: proxmox-backup-restore-image-debug +Architecture: amd64 +Depends: proxmox-backup-restore-image +Description: Debug initramfs image for Proxmox Backup single-file restore. + Not required for production use, only useful for manual inspection of file + restore VMs. Includes busybox and gdb. diff --git a/debian/proxmox-backup-restore-image-debug.install b/debian/proxmox-backup-restore-image-debug.install new file mode 100644 index 0000000..02ffb49 --- /dev/null +++ b/debian/proxmox-backup-restore-image-debug.install @@ -0,0 +1 @@ +build/initramfs/initramfs-debug.img /usr/lib/x86_64-linux-gnu/proxmox-backup/file-restore/ diff --git a/debian/proxmox-backup-restore-image-debug.lintian-overrides b/debian/proxmox-backup-restore-image-debug.lintian-overrides new file mode 100644 index 0000000..ad59aad --- /dev/null +++ b/debian/proxmox-backup-restore-image-debug.lintian-overrides @@ -0,0 +1,2 @@ +missing-depends-on-sensible-utils +uses-dpkg-database-directly diff --git a/debian/proxmox-backup-restore-image-debug.triggers b/debian/proxmox-backup-restore-image-debug.triggers new file mode 100644 index 0000000..948d898 --- /dev/null +++ b/debian/proxmox-backup-restore-image-debug.triggers @@ -0,0 +1 @@ +activate-noawait proxmox-backup-restore-image-update diff --git a/src/Makefile b/src/Makefile index 37f385f..a398ea1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,12 +9,13 @@ SHIM_DIR=init-shim-rs KERNEL_IMG=${BUILDDIR}/bzImage INITRAMFS_IMG=${INITRAMFS_BUILDDIR}/initramfs.img +INITRAMFS_IMG_DBG=${INITRAMFS_BUILDDIR}/initramfs-debug.img CONFIG=config-base RUST_SRC=$(wildcard ${SHIM_DIR}/**/*.rs) ${SHIM_DIR}/Cargo.toml -all: ${KERNEL_IMG} ${INITRAMFS_IMG} +all: ${KERNEL_IMG} ${INITRAMFS_IMG_DBG} ${BUILDDIR}.prepared: ${CONFIG} rm -rf ${BUILDDIR} @@ -54,6 +55,8 @@ ${INITRAMFS_IMG}: ${BUILDDIR}.prepared ${RUST_SRC} build_initramfs.sh cd ${SHIM_DIR}; cargo build --release sh build_initramfs.sh +${INITRAMFS_IMG_DBG}: ${INITRAMFS_IMG} + .PHONY: test-run test-run: ${KERNEL_IMG} ${INITRAMFS_IMG} # note: this will always fail since /proxmox-restore-daemon is not diff --git a/src/build_initramfs.sh b/src/build_initramfs.sh index 4efa29b..c4ee95c 100755 --- a/src/build_initramfs.sh +++ b/src/build_initramfs.sh @@ -6,29 +6,36 @@ ROOT="root" BUILDDIR="build/initramfs" INIT="../../init-shim-rs/target/release/init-shim-rs" -PKGS=" \ - libc6:amd64 \ - libgcc1:amd64 \ - libstdc++6:amd64 \ - libssl1.1:amd64 \ - libattr1:amd64 \ - libacl1:amd64 -" - echo "Using build dir: $BUILDDIR" rm -rf "$BUILDDIR" mkdir -p "$BUILDDIR" cd "$BUILDDIR" mkdir "$ROOT" -# add necessary packages to initramfs -for pkg in $PKGS; do - apt-get download "$pkg" - dpkg-deb -x ./*.deb "$ROOT" +# adds necessary packages to initramfs build root folder +add_pkgs() { + DEPS="" + for pkg in $1; do + LOCAL_DEPS=$(apt-rdepends -f Depends -s Depends "$pkg" | grep -v '^ ') + DEPS="$DEPS $LOCAL_DEPS" + done + # debconf and gcc are unnecessary + DEPS=$(echo "$DEPS" |\ + sed -E 's/debconf(-2\.0)?//' |\ + sed -E 's/gcc-.{1,2}-base//') + apt-get download $DEPS + for deb in ./*.deb; do + dpkg-deb -x "$deb" "$ROOT" + done rm ./*.deb -done +} -rm -rf ${ROOT:?}/usr/share # contains only docs and debian stuff +make_cpio() { + fakeroot -- sh -c " + cd '$ROOT'; + find . -print0 | cpio --null -oV --format=newc -F ../$1 + " +} cp $INIT "$ROOT/init" chmod a+x "$ROOT/init" # just to be sure @@ -36,7 +43,19 @@ chmod a+x "$ROOT/init" # just to be sure # tell daemon it's running in the correct environment touch "$ROOT/restore-vm-marker" -fakeroot -- sh -c " - cd '$ROOT'; - find . -print0 | cpio --null -oV --format=newc -F ../initramfs.img +add_pkgs " + libstdc++6:amd64 \ + libssl1.1:amd64 \ + libacl1:amd64 \ " +rm -rf ${ROOT:?}/usr/share # contains only docs and debian stuff +make_cpio "initramfs.img" + +# add debug helpers for debug initramfs, packages from above are included too +add_pkgs " + util-linux:amd64 \ + busybox-static:amd64 \ + gdb:amd64 \ +" +# leave /usr/share here, it contains necessary stuff for gdb +make_cpio "initramfs-debug.img" diff --git a/src/init-shim-rs/src/main.rs b/src/init-shim-rs/src/main.rs index 89aff7b..641218f 100644 --- a/src/init-shim-rs/src/main.rs +++ b/src/init-shim-rs/src/main.rs @@ -1,6 +1,8 @@ -use anyhow::Error; +use anyhow::{bail, Error}; use std::ffi::CStr; use std::fs; +use std::path::PathBuf; +use std::process::Command; const URANDOM_MAJ: u64 = 1; const URANDOM_MIN: u64 = 9; @@ -21,15 +23,54 @@ fn main() { do_mknod("/dev/urandom", URANDOM_MAJ, URANDOM_MIN) }); + if let Err(err) = run_agetty() { + // not fatal + println!("[init-shim] debug: agetty start failed: {}", err); + } + let uptime = read_uptime(); println!("[init-shim] reached daemon start after {:.2}s", uptime); do_run("/proxmox-restore-daemon"); } +fn run_agetty() -> Result<(), Error> { + use nix::unistd::{fork, ForkResult}; + + if !PathBuf::from("/sbin/agetty").exists() { + bail!("/sbin/agetty not found, probably not running debug mode and safe to ignore"); + } + + if !PathBuf::from("/sys/class/tty/ttyS1/device/driver/serial8250").exists() { + bail!("ttyS1 device does not exist or is not a 8250"); + } + + let dev = fs::read_to_string("/sys/class/tty/ttyS1/dev")?; + let (tty_maj, tty_min) = dev.trim().split_at(dev.find(':').unwrap_or(1)); + do_mknod("/dev/ttyS1", tty_maj.parse()?, tty_min[1..].parse()?)?; + + match unsafe { fork() } { + Ok(ForkResult::Parent { .. }) => {} + Ok(ForkResult::Child) => loop { + // continue to restart agetty if it exits, this runs in a forked process + println!("[init-shim] Spawning new agetty"); + let res = Command::new("/sbin/agetty") + .args(&["-a", "root", "-l", "/bin/busybox", "-o", "sh", "115200", "ttyS1"]) + .spawn() + .unwrap() + .wait() + .unwrap(); + println!("[init-shim] agetty exited: {}", res.code().unwrap_or(-1)); + }, + Err(err) => println!("fork failed: {}", err), + } + + Ok(()) +} + fn do_mount(target: &str, fstype: &str) -> Result<(), Error> { use nix::mount::{mount, MsFlags}; - fs::create_dir(target)?; + fs::create_dir_all(target)?; let none_type: Option<&CStr> = None; mount( none_type, @@ -63,7 +104,6 @@ fn read_uptime() -> f32 { fn do_run(cmd: &str) -> ! { use std::io::ErrorKind; - use std::process::Command; let spawn_res = Command::new(cmd).env("RUST_BACKTRACE", "1").spawn(); -- 2.20.1