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) server-digest SHA256) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 1356C7A1FF for ; Thu, 6 May 2021 20:07:52 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id EE7F323611 for ; Thu, 6 May 2021 20:07:21 +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) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 39DDB23601 for ; Thu, 6 May 2021 20:07:20 +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 1686E464FF for ; Thu, 6 May 2021 20:07:20 +0200 (CEST) Message-ID: <27e28abc-d369-7555-c9b4-2aec01aca890@proxmox.com> Date: Thu, 6 May 2021 20:07:18 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Thunderbird/89.0 Content-Language: en-US To: Proxmox Backup Server development discussion , Stefan Reiter References: <20210506152624.12605-1-s.reiter@proxmox.com> <20210506152624.12605-10-s.reiter@proxmox.com> From: Thomas Lamprecht In-Reply-To: <20210506152624.12605-10-s.reiter@proxmox.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.143 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment NICE_REPLY_A -0.001 Looks like a legit reply (A) 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: Re: [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 18:07:52 -0000 On 06.05.21 17:26, Stefan Reiter wrote: > "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 > multiple source control files do not really make sense. There's only one source per d/control instance (normally per repo) for Debians POV... > 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(); > >