This is an automated email from the git hooks/post-receive script. guillem pushed a commit to branch main in repository dpkg.
View the commit online: https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=25634a0099f388a4c72f689c66a7f5b9cfe1c6dd commit 25634a0099f388a4c72f689c66a7f5b9cfe1c6dd Author: Guillem Jover <[email protected]> AuthorDate: Sat Nov 18 13:39:46 2023 +0100 Add support for native arch definition for chroots When operating over a non-default root directory, we need to switch the native architecture and use the one from the dpkg installed in that chroot, instead of our current one. This information is available in the status database, but that would require parsing it and hardcoding the package name dpkg is shipped, which might not match the one used inside that chroot. We could also ship a file with the native architecture, that then we can load. But that implies hardcoding the pathname for a filesystem file (in contrast to the database pathname which we need anyway and can specify via --admindir), which is a distribution specific policy, and might end up not being loaded if the appropriate pathname is not passed, making the native architecture become out of sync with the one in the database. The approach selected as the better one is to generate a file in the database directory during package installation, so that we also cover cross-grades. In the future we might provide a new action or helper to populate a chroot directory for foreign installations, so that this does not need to be done by bootstrapping programs. Closes: #825385, #1020533 --- debian/dpkg.postinst | 8 ++++++++ lib/dpkg/arch.c | 37 +++++++++++++++++++++++++++++++++++++ lib/dpkg/arch.h | 1 + src/Makefile.am | 1 + src/at/dpkg-arch.at | 30 ++++++++++++++++++++++++++++++ src/at/testsuite.at | 2 ++ src/main/enquiry.c | 2 ++ 7 files changed, 81 insertions(+) diff --git a/debian/dpkg.postinst b/debian/dpkg.postinst index 5b3a248a0..b192d5021 100644 --- a/debian/dpkg.postinst +++ b/debian/dpkg.postinst @@ -7,6 +7,13 @@ PROGNAME=dpkg . /usr/share/dpkg/sh/dpkg-error.sh +create_db_native_arch() +{ + local admindir=${DPKG_ADMINDIR:-/var/lib/dpkg} + + echo "$DPKG_MAINTSCRIPT_ARCH" >$admindir/arch-native +} + setup_aliases() { local prog=start-stop-daemon @@ -20,6 +27,7 @@ setup_aliases() case "$1" in configure) + create_db_native_arch setup_aliases ;; abort-upgrade|abort-deconfigure|abort-remove) diff --git a/lib/dpkg/arch.c b/lib/dpkg/arch.c index 9409f5a5e..5ed758b40 100644 --- a/lib/dpkg/arch.c +++ b/lib/dpkg/arch.c @@ -35,10 +35,12 @@ #include <dpkg/dpkg.h> #include <dpkg/dpkg-db.h> #include <dpkg/dir.h> +#include <dpkg/fsys.h> #include <dpkg/varbuf.h> #include <dpkg/arch.h> #define DPKG_DB_ARCH_FILE "arch" +#define DPKG_DB_ARCH_NATIVE_FILE "arch-native" /** * Verify if the architecture name is valid. @@ -278,6 +280,39 @@ dpkg_arch_unmark(const struct dpkg_arch *arch_remove) } } +/** + * Load the native architecture name for a non-default root directory. + */ +void +dpkg_arch_load_native(void) +{ + struct varbuf arch_line = VARBUF_INIT; + struct dpkg_arch *arch; + char *archfile; + int rc; + + /* We only honor this file on chroots, for the non-chroot case + * the builtin arch is always honored. */ + if (str_is_unset(dpkg_fsys_get_dir())) + return; + + archfile = dpkg_db_get_path(DPKG_DB_ARCH_NATIVE_FILE); + rc = file_slurp(archfile, &arch_line, NULL); + free(archfile); + if (rc < 0) + return; + + if (arch_line.used == 0) + return; + + if (arch_line.buf[arch_line.used - 1] == '\n') + varbuf_trunc(&arch_line, arch_line.used - 1); + + /* Override the native architecture name. */ + arch = dpkg_arch_get(DPKG_ARCH_NATIVE); + arch->name = varbuf_detach(&arch_line); +} + /** * Load the architecture database. */ @@ -288,6 +323,8 @@ dpkg_arch_load_list(void) char *archfile; char archname[_POSIX2_LINE_MAX]; + dpkg_arch_load_native(); + archfile = dpkg_db_get_path(DPKG_DB_ARCH_FILE); fp = fopen(archfile, "r"); if (fp == NULL) { diff --git a/lib/dpkg/arch.h b/lib/dpkg/arch.h index 02ef06c94..e2b9abbcb 100644 --- a/lib/dpkg/arch.h +++ b/lib/dpkg/arch.h @@ -61,6 +61,7 @@ const char *dpkg_arch_describe(const struct dpkg_arch *arch); struct dpkg_arch *dpkg_arch_add(const char *name); void dpkg_arch_unmark(const struct dpkg_arch *arch); +void dpkg_arch_load_native(void); void dpkg_arch_load_list(void); void dpkg_arch_save_list(void); diff --git a/src/Makefile.am b/src/Makefile.am index abb1d96cf..f5152f83c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -162,6 +162,7 @@ TESTSUITE_AT += $(srcdir)/at/deb-split.at TESTSUITE_AT += $(srcdir)/at/realpath.at TESTSUITE_AT += $(srcdir)/at/divert.at TESTSUITE_AT += $(srcdir)/at/chdir.at +TESTSUITE_AT += $(srcdir)/at/dpkg-arch.at EXTRA_DIST += $(TESTSUITE_AT) TESTSUITE = $(srcdir)/at/testsuite diff --git a/src/at/dpkg-arch.at b/src/at/dpkg-arch.at new file mode 100644 index 000000000..6a8a935e7 --- /dev/null +++ b/src/at/dpkg-arch.at @@ -0,0 +1,30 @@ +m4_define([DPKG_ARCH], [dnl + dpkg DPKG_OPTIONS_COMMON --instdir=DPKG_DIR_INST dnl +]) + +AT_SETUP([dpkg native architecture support]) +AT_KEYWORDS([dpkg native arch]) + +DPKG_GEN_DB_FILE([arch], [arm64 +]) +DPKG_GEN_DB_FILE([arch-native], [arm64 +]) +AT_CHECK([DPKG_ARCH --print-architecture], [], [arm64 +]) +AT_CHECK([DPKG_ARCH --print-foreign-architectures], [], []) + +AT_CLEANUP + +AT_SETUP([dpkg foreign architecture support]) +AT_KEYWORDS([dpkg foreign arch]) + +DPKG_GEN_DB_FILE([arch], [arm64 +]) +DPKG_GEN_DB_FILE([arch-native], [riscv64 +]) +AT_CHECK([DPKG_ARCH --print-architecture], [], [riscv64 +]) +AT_CHECK([DPKG_ARCH --print-foreign-architectures], [], [arm64 +]) + +AT_CLEANUP diff --git a/src/at/testsuite.at b/src/at/testsuite.at index 86e2d37c0..f36c2f062 100644 --- a/src/at/testsuite.at +++ b/src/at/testsuite.at @@ -22,3 +22,5 @@ m4_include([divert.at]) AT_TESTED([dpkg]) AT_BANNER([Change directory options]) m4_include([chdir.at]) +AT_BANNER([Architecture support]) +m4_include([dpkg-arch.at]) diff --git a/src/main/enquiry.c b/src/main/enquiry.c index ddd11abe3..735f32e3f 100644 --- a/src/main/enquiry.c +++ b/src/main/enquiry.c @@ -594,6 +594,8 @@ printarch(const char *const *argv) if (*argv) badusage(_("--%s takes no arguments"), cipaction->olong); + dpkg_arch_load_native(); + printf("%s\n", dpkg_arch_get(DPKG_ARCH_NATIVE)->name); m_output(stdout, _("<standard output>")); -- Dpkg.Org's dpkg

