From 652f2a99887f48e03d64da5aa5a7d7d22b702b13 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Tue, 29 Aug 2023 19:34:59 +0000 Subject: [PATCH] arch: Teach Pakfire to run a different arch effectively This is useful to let Pakfire think it is running in "noarch" mode, when we of course actually have to install some binary packages. This might also become useful when bootstrapping the distribution for a new architecture. Signed-off-by: Michael Tremer --- src/libpakfire/arch.c | 23 ++++++++++++--- src/libpakfire/db.c | 4 +-- src/libpakfire/dist.c | 12 ++++---- src/libpakfire/include/pakfire/arch.h | 2 +- src/libpakfire/include/pakfire/pakfire.h | 2 ++ src/libpakfire/jail.c | 4 +-- src/libpakfire/mount.c | 2 +- src/libpakfire/pakfire.c | 37 +++++++++++++++++------- src/libpakfire/repo.c | 2 +- 9 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/libpakfire/arch.c b/src/libpakfire/arch.c index b6e963378..dda1538f0 100644 --- a/src/libpakfire/arch.c +++ b/src/libpakfire/arch.c @@ -199,14 +199,29 @@ int pakfire_arch_is_compatible(const char* name, const char* compatible_arch) { return 0; } -int pakfire_arch_supported_by_host(const char* name) { - if (!name) - return -EINVAL; +/* + This function figures out which architecture the build environment has - + which might not be the same as the requested architecture. +*/ +const char* pakfire_arch_supported_by_host(const char* name) { + if (!name) { + errno = EINVAL; + return NULL; + } const char* native_arch = pakfire_arch_native(); + // All hosts support noarch natively + if (strcmp(name, "noarch") == 0) + return native_arch; + // Check if those two architectures are compatible - return pakfire_arch_is_compatible(native_arch, name); + if (pakfire_arch_is_compatible(native_arch, name)) + return name; + + // Not supported + errno = ENOTSUP; + return NULL; } static char* find_interpreter(DIR* dir, const char* path, const char* magic) { diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c index 9d17ce9a0..8e5d441a8 100644 --- a/src/libpakfire/db.c +++ b/src/libpakfire/db.c @@ -461,7 +461,7 @@ static int pakfire_db_create_schema(struct pakfire_db* db) { if (r) return 1; - const char* arch = pakfire_get_arch(db->pakfire); + const char* arch = pakfire_get_effective_arch(db->pakfire); // Set architecture r = pakfire_db_set_string(db, "arch", arch); @@ -545,7 +545,7 @@ static int pakfire_db_check_arch(struct pakfire_db* db) { } // Fetch the running architecture - const char* arch = pakfire_get_arch(db->pakfire); + const char* arch = pakfire_get_effective_arch(db->pakfire); if (!arch) goto ERROR; diff --git a/src/libpakfire/dist.c b/src/libpakfire/dist.c index 8905cd873..b67a5e193 100644 --- a/src/libpakfire/dist.c +++ b/src/libpakfire/dist.c @@ -105,22 +105,22 @@ static int pakfire_makefile_set_defaults(struct pakfire* pakfire, pakfire_parser_set(parser, NULL, "DISTRO_VENDOR", vendor, 0); // Set DISTRO_ARCH - const char* arch = pakfire_get_arch(pakfire); - if (arch) { - pakfire_parser_set(parser, NULL, "DISTRO_ARCH", arch, 0); + const char* effective_arch = pakfire_get_effective_arch(pakfire); + if (effective_arch) { + pakfire_parser_set(parser, NULL, "DISTRO_ARCH", effective_arch, 0); - const char* platform = pakfire_arch_platform(arch); + const char* platform = pakfire_arch_platform(effective_arch); if (platform) pakfire_parser_set(parser, NULL, "DISTRO_PLATFORM", platform, 0); if (vendor) { // Set DISTRO_MACHINE - r = pakfire_arch_machine(buffer, arch, vendor); + r = pakfire_arch_machine(buffer, effective_arch, vendor); if (!r) pakfire_parser_set(parser, NULL, "DISTRO_MACHINE", buffer, 0); // Set DISTRO_BUILDTARGET - r = pakfire_arch_buildtarget(buffer, arch, vendor); + r = pakfire_arch_buildtarget(buffer, effective_arch, vendor); if (!r) pakfire_parser_set(parser, NULL, "DISTRO_BUILDTARGET", buffer, 0); } diff --git a/src/libpakfire/include/pakfire/arch.h b/src/libpakfire/include/pakfire/arch.h index 84ff0387a..f09f777c3 100644 --- a/src/libpakfire/include/pakfire/arch.h +++ b/src/libpakfire/include/pakfire/arch.h @@ -40,7 +40,7 @@ int __pakfire_arch_buildtarget(char* buffer, size_t length, const char* arch, co const char* pakfire_arch_platform(const char* name); int pakfire_arch_is_compatible(const char* name, const char* compatible_arch); -int pakfire_arch_supported_by_host(const char* name); +const char* pakfire_arch_supported_by_host(const char* name); char* pakfire_arch_find_interpreter(const char* name); #endif diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index 094a2a2fc..7423d6644 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -125,6 +125,8 @@ int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags, int* chan #include #include +const char* pakfire_get_effective_arch(struct pakfire* pakfire); + int pakfire_on_root(struct pakfire* pakfire); uid_t pakfire_uid(struct pakfire* pakfire); diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index 1adbda033..e22feeca5 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -254,7 +254,7 @@ static int pakfire_jail_setup_interactive_env(struct pakfire_jail* jail) { PAKFIRE_EXPORT int pakfire_jail_create(struct pakfire_jail** jail, struct pakfire* pakfire) { int r; - const char* arch = pakfire_get_arch(pakfire); + const char* arch = pakfire_get_effective_arch(pakfire); // Allocate a new jail struct pakfire_jail* j = calloc(1, sizeof(*j)); @@ -1642,7 +1642,7 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe } const char* root = pakfire_get_path(jail->pakfire); - const char* arch = pakfire_get_arch(jail->pakfire); + const char* arch = pakfire_get_effective_arch(jail->pakfire); // Change mount propagation to slave to receive anything from the parent namespace r = pakfire_mount_change_propagation(jail->pakfire, MS_SLAVE, "/"); diff --git a/src/libpakfire/mount.c b/src/libpakfire/mount.c index 264781044..fc7781f6f 100644 --- a/src/libpakfire/mount.c +++ b/src/libpakfire/mount.c @@ -361,7 +361,7 @@ static int pakfire_mount_interpreter(struct pakfire* pakfire) { char target[PATH_MAX]; // Fetch the target architecture - const char* arch = pakfire_get_arch(pakfire); + const char* arch = pakfire_get_effective_arch(pakfire); // Can we emulate this architecture? char* interpreter = pakfire_arch_find_interpreter(arch); diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index e03f2c1d3..e3f392dd7 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -70,7 +70,11 @@ struct pakfire { char path[PATH_MAX]; char lock_path[PATH_MAX]; char cache_path[PATH_MAX]; - char arch[ARCH_MAX]; + + struct pakfire_arches { + char nominal[ARCH_MAX]; + const char* effective; + } arches; int flags; @@ -297,6 +301,8 @@ static int pakfire_populate_pool(struct pakfire* pakfire) { struct pakfire_repo* system = NULL; int r; + const char* arch = pakfire_get_effective_arch(pakfire); + // Initialize the pool Pool* pool = pakfire->pool = pool_create(); pool_setdisttype(pool, DISTTYPE_RPM); @@ -307,7 +313,7 @@ static int pakfire_populate_pool(struct pakfire* pakfire) { #endif // Set architecture of the pool - pool_setarch(pool, pakfire->arch); + pool_setarch(pool, arch); // Set path pool_set_rootdir(pool, pakfire->path); @@ -740,6 +746,8 @@ static int pakfire_set_cache_path(struct pakfire* pakfire) { char basepath[PATH_MAX]; int r; + const char* arch = pakfire_get_effective_arch(pakfire); + // Fetch the path from the configuration file const char* path = pakfire_config_get(pakfire->config, "general", "cache_path", NULL); if (!path) { @@ -754,7 +762,7 @@ static int pakfire_set_cache_path(struct pakfire* pakfire) { // Format the final path return pakfire_string_format(pakfire->cache_path, "%s/%s/%s/%s", - path, pakfire->distro.id, pakfire->distro.version_id, pakfire->arch); + path, pakfire->distro.id, pakfire->distro.version_id, arch); } static int pakfire_setup_user(struct pakfire* pakfire) { @@ -852,16 +860,19 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path, pakfire_log_set_priority(p, log_priority(env)); } - // Check if the architecture is supported by this host - if (!pakfire_arch_supported_by_host(arch)) { + // Store the nominal architecture + r = pakfire_string_set(p->arches.nominal, arch); + if (r) + goto ERROR; + + // Determine the effective architecture + p->arches.effective = pakfire_arch_supported_by_host(arch); + if (!p->arches.effective) { ERROR(p, "Unsupported architecture: %s\n", arch); - r = -EINVAL; + r = errno; goto ERROR; } - // Set architecture - pakfire_string_set(p->arch, arch); - // Path must be absolute if (path && !pakfire_string_startswith(path, "/")) { ERROR(p, "Invalid path: %s\n", path); @@ -907,7 +918,7 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path, DEBUG(p, "Pakfire initialized at %p\n", p); DEBUG(p, " user = %s (%d)\n", p->user.name, p->user.uid); DEBUG(p, " group = %s (%d)\n", p->group.name, p->group.gid); - DEBUG(p, " arch = %s\n", pakfire_get_arch(p)); + DEBUG(p, " arch = %s (%s)\n", pakfire_get_arch(p), pakfire_get_effective_arch(p)); DEBUG(p, " path = %s\n", pakfire_get_path(p)); if (p->user.subuids.id) DEBUG(p, " subuid = %d (%zu)\n", p->user.subuids.id, p->user.subuids.length); @@ -1314,7 +1325,11 @@ PAKFIRE_EXPORT int pakfire_copy_out(struct pakfire* pakfire, const char* src, co } PAKFIRE_EXPORT const char* pakfire_get_arch(struct pakfire* pakfire) { - return pakfire->arch; + return pakfire->arches.nominal; +} + +const char* pakfire_get_effective_arch(struct pakfire* pakfire) { + return pakfire->arches.effective; } PAKFIRE_EXPORT int pakfire_version_compare(struct pakfire* pakfire, const char* evr1, const char* evr2) { diff --git a/src/libpakfire/repo.c b/src/libpakfire/repo.c index 10ccde02a..77ca4aa67 100644 --- a/src/libpakfire/repo.c +++ b/src/libpakfire/repo.c @@ -765,7 +765,7 @@ static char* pakfire_repo_url_replace(struct pakfire_repo* repo, const char* url const char* replacement; } replacements[] = { { "%{name}", pakfire_repo_get_name(repo) }, - { "%{arch}", pakfire_get_arch(repo->pakfire) }, + { "%{arch}", pakfire_get_effective_arch(repo->pakfire) }, { "%{distro}", pakfire_get_distro_id(repo->pakfire) }, { "%{version}", pakfire_get_distro_version_id(repo->pakfire) }, { NULL, NULL }, -- 2.39.5