Compare commits

...

3 Commits

Author SHA1 Message Date
Luca Boccassi 58c57d640c
Merge dbb5891f8c into 7ac1ad90d0 2024-09-17 22:48:41 -07:00
Luca Boccassi dbb5891f8c vpick: ensure extension ABI matches the root's
Extensions can only run on the same ABI as the root image,
so if an ABI is specified, ensure the extensions match it
2024-07-22 11:58:04 +01:00
Luca Boccassi 56b16cb583 arch/gpt: check for userspace ABI instead of CPU family
For images, binaries, vendor trees and so on, what matters is
not the CPU family, but the userspace ABI. A vendor /usr/ tree
does not have a CPU family, it has an ABI triplet.

Add a separate enum and related bits to deal with ABI. Leave
the architecture enum and related bits for cases where comparing
CPU families is what's actually needed, which is the case when
calling qemu and when setting 'personality', and switch everything
else.

x32 is the native_architecture when uname is x86_64 and ILP32 is
defined, as it is a different userspace ABI with a different
lib triplet. Same for armel/armhf.
2024-07-22 11:58:04 +01:00
22 changed files with 822 additions and 254 deletions

View File

@ -18,7 +18,9 @@ Architecture uname_architecture(void) {
* clean it up and break down the confusion on x86 and arm in particular.
*
* We try to distinguish CPUs, not CPU features, i.e. actual architectures that
* have genuinely different code. */
* have genuinely different code. This does not include userspace ABI, so in most
* cases you do not want to use this, unless it is purely to compare CPUs (for
* example for QEMU), and instead use preferred_abi() below. */
static const struct {
const char *machine;
@ -176,3 +178,228 @@ static const char *const architecture_table[_ARCHITECTURE_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP(architecture, Architecture);
Abi preferred_abi(void) {
/* Return a usable enum identifying the architecture we are running on. This
* is based on uname(), and the user may hence control what this returns by using
* personality(). This puts the user in control on systems that can run binaries
* of multiple architectures.
*
* We do not translate the string returned by uname() 1:1. Instead we try to
* clean it up and break down the confusion on x86 and arm in particular.
*
* We try to distinguish CPUs, not CPU features, i.e. actual architectures that
* have genuinely different code. This includes different userspace ABI, as used
* for LIB_ARCH_TUPLE and defined in https://wiki.debian.org/Multiarch/Tuples as
* opposed to uname_architecture() above, which is solely and exclusively for CPU
* comparisons. In most cases, especially when comparing images, you want to use
* this instead of Architecture. */
static const struct {
const char *machine;
Abi abi;
} abi_map[] = {
#if defined(__aarch64__) || defined(__arm__)
{ "aarch64", ABI_ARM64 },
{ "aarch64_be", ABI_ARM64_BE },
# if defined(__ARM_EABI__)
# if defined(__ARM_PCS_VFP)
{ "armv8l", ABI_ARMHF },
{ "armv8b", ABI_ARMHF_BE },
{ "armv7ml", ABI_ARMHF },
{ "armv7mb", ABI_ARMHF_BE },
{ "armv7l", ABI_ARMHF },
{ "armv7b", ABI_ARMHF_BE },
{ "armv6l", ABI_ARMHF },
{ "armv6b", ABI_ARMHF_BE },
{ "armv5tl", ABI_ARMHF },
{ "armv5tel", ABI_ARMHF },
{ "armv5tejl", ABI_ARMHF },
{ "armv5tejb", ABI_ARMHF_BE },
{ "armv5teb", ABI_ARMHF_BE },
{ "armv5tb", ABI_ARMHF_BE },
{ "armv4tl", ABI_ARMHF },
{ "armv4tb", ABI_ARMHF_BE },
{ "armv4l", ABI_ARMHF },
{ "armv4b", ABI_ARMHF_BE },
# else
{ "armv8l", ABI_ARMEL },
{ "armv8b", ABI_ARMEL_BE },
{ "armv7ml", ABI_ARMEL },
{ "armv7mb", ABI_ARMEL_BE },
{ "armv7l", ABI_ARMEL },
{ "armv7b", ABI_ARMEL_BE },
{ "armv6l", ABI_ARMEL },
{ "armv6b", ABI_ARMEL_BE },
{ "armv5tl", ABI_ARMEL },
{ "armv5tel", ABI_ARMEL },
{ "armv5tejl", ABI_ARMEL },
{ "armv5tejb", ABI_ARMEL_BE },
{ "armv5teb", ABI_ARMEL_BE },
{ "armv5tb", ABI_ARMEL_BE },
{ "armv4tl", ABI_ARMEL },
{ "armv4tb", ABI_ARMEL_BE },
{ "armv4l", ABI_ARMEL },
{ "armv4b", ABI_ARMEL_BE },
# endif
# else
{ "armv8l", ABI_ARM },
{ "armv8b", ABI_ARM_BE },
{ "armv7ml", ABI_ARM },
{ "armv7mb", ABI_ARM_BE },
{ "armv7l", ABI_ARM },
{ "armv7b", ABI_ARM_BE },
{ "armv6l", ABI_ARM },
{ "armv6b", ABI_ARM_BE },
{ "armv5tl", ABI_ARM },
{ "armv5tel", ABI_ARM },
{ "armv5tejl", ABI_ARM },
{ "armv5tejb", ABI_ARM_BE },
{ "armv5teb", ABI_ARM_BE },
{ "armv5tb", ABI_ARM_BE },
{ "armv4tl", ABI_ARM },
{ "armv4tb", ABI_ARM_BE },
{ "armv4l", ABI_ARM },
{ "armv4b", ABI_ARM_BE },
# endif
#elif defined(__alpha__)
{ "alpha" , ABI_ALPHA },
#elif defined(__arc__)
{ "arc", ABI_ARC },
{ "arceb", ABI_ARC_BE },
#elif defined(__cris__)
{ "crisv32", ABI_CRIS },
#elif defined(__i386__) || defined(__x86_64__)
# if defined(__ILP32__)
{ "x86_64", ABI_X32 },
# else
{ "x86_64", ABI_X86_64 },
# endif
{ "i686", ABI_X86 },
{ "i586", ABI_X86 },
{ "i486", ABI_X86 },
{ "i386", ABI_X86 },
#elif defined(__ia64__)
{ "ia64", ABI_IA64 },
#elif defined(__hppa__) || defined(__hppa64__)
{ "parisc64", ABI_PARISC64 },
{ "parisc", ABI_PARISC },
#elif defined(__loongarch_lp64)
{ "loongarch64", ABI_LOONGARCH64 },
#elif defined(__m68k__)
{ "m68k", ABI_M68K },
#elif defined(__mips__) || defined(__mips64__)
{ "mips64", ABI_MIPS64 },
{ "mips", ABI_MIPS },
#elif defined(__nios2__)
{ "nios2", ABI_NIOS2 },
#elif defined(__powerpc__) || defined(__powerpc64__)
{ "ppc64le", ABI_PPC64_LE },
{ "ppc64", ABI_PPC64 },
{ "ppcle", ABI_PPC_LE },
{ "ppc", ABI_PPC },
#elif defined(__riscv)
{ "riscv64", ABI_RISCV64 },
{ "riscv32", ABI_RISCV32 },
# if __SIZEOF_POINTER__ == 4
{ "riscv", ABI_RISCV32 },
# elif __SIZEOF_POINTER__ == 8
{ "riscv", ABI_RISCV64 },
# endif
#elif defined(__s390__) || defined(__s390x__)
{ "s390x", ABI_S390X },
{ "s390", ABI_S390 },
#elif defined(__sh__) || defined(__sh64__)
{ "sh5", ABI_SH64 },
{ "sh4a", ABI_SH },
{ "sh4", ABI_SH },
{ "sh3", ABI_SH },
{ "sh2a", ABI_SH },
{ "sh2", ABI_SH },
#elif defined(__sparc__)
{ "sparc64", ABI_SPARC64 },
{ "sparc", ABI_SPARC },
#elif defined(__tilegx__)
{ "tilegx", ABI_TILEGX },
#else
# error "Please register your ABI here!"
#endif
};
static Abi cached = _ABI_INVALID;
struct utsname u;
if (cached != _ABI_INVALID)
return cached;
assert_se(uname(&u) >= 0);
for (size_t i = 0; i < ELEMENTSOF(abi_map); i++)
if (streq(abi_map[i].machine, u.machine))
return cached = abi_map[i].abi;
assert_not_reached();
return _ABI_INVALID;
}
/* Maintain same order and names as in the table above. */
static const char *const abi_table[_ABI_MAX] = {
[ABI_ARM64] = "arm64",
[ABI_ARM64_BE] = "arm64-be",
[ABI_ARM] = "arm",
[ABI_ARM_BE] = "arm-be",
[ABI_ARMEL] = "armel",
[ABI_ARMEL_BE] = "armel-be",
[ABI_ARMHF] = "armhf",
[ABI_ARMHF_BE] = "armhf-be",
[ABI_ALPHA] = "alpha",
[ABI_ARC] = "arc",
[ABI_ARC_BE] = "arc-be",
[ABI_CRIS] = "cris",
[ABI_X86_64] = "x86-64",
[ABI_X86] = "x86",
[ABI_X32] = "x32",
[ABI_IA64] = "ia64",
[ABI_LOONGARCH64] = "loongarch64",
[ABI_M68K] = "m68k",
[ABI_MIPS64_LE] = "mips64-le",
[ABI_MIPS64] = "mips64",
[ABI_MIPS_LE] = "mips-le",
[ABI_MIPS] = "mips",
[ABI_NIOS2] = "nios2",
[ABI_PARISC64] = "parisc64",
[ABI_PARISC] = "parisc",
[ABI_PPC64_LE] = "ppc64-le",
[ABI_PPC64] = "ppc64",
[ABI_PPC] = "ppc",
[ABI_PPC_LE] = "ppc-le",
[ABI_RISCV32] = "riscv32",
[ABI_RISCV64] = "riscv64",
[ABI_S390X] = "s390x",
[ABI_S390] = "s390",
[ABI_SH64] = "sh64",
[ABI_SH] = "sh",
[ABI_SPARC64] = "sparc64",
[ABI_SPARC] = "sparc",
[ABI_TILEGX] = "tilegx",
};
DEFINE_STRING_TABLE_LOOKUP(abi, Abi);

View File

@ -49,6 +49,54 @@ typedef enum {
Architecture uname_architecture(void);
/* CPU plus userspace ABI definitions. In most cases you'll want to use this, not Architecture, which is
* insufficient for every case apart from the very basics of comparing a running CPU with another. Never
* use Architecture when there is any connection with images, binaries, libraries, paths, etc. */
typedef enum {
ABI_ALPHA,
ABI_ARC,
ABI_ARC_BE,
ABI_ARM,
ABI_ARMEL,
ABI_ARMHF,
ABI_ARM64,
ABI_ARM64_BE,
ABI_ARM_BE,
ABI_ARMEL_BE,
ABI_ARMHF_BE,
ABI_CRIS,
ABI_IA64,
ABI_LOONGARCH64,
ABI_M68K,
ABI_MIPS,
ABI_MIPS64,
ABI_MIPS64_LE,
ABI_MIPS_LE,
ABI_NIOS2,
ABI_PARISC,
ABI_PARISC64,
ABI_PPC,
ABI_PPC64,
ABI_PPC64_LE,
ABI_PPC_LE,
ABI_RISCV32,
ABI_RISCV64,
ABI_S390,
ABI_S390X,
ABI_SH,
ABI_SH64,
ABI_SPARC,
ABI_SPARC64,
ABI_TILEGX,
ABI_X32,
ABI_X86,
ABI_X86_64,
_ABI_MAX,
_ABI_INVALID = -EINVAL,
} Abi;
Abi preferred_abi(void);
/*
* LIB_ARCH_TUPLE should resolve to the local library path
* architecture tuple systemd is built for, according to the Debian
@ -63,27 +111,38 @@ Architecture uname_architecture(void);
#if defined(__x86_64__)
# define native_architecture() ARCHITECTURE_X86_64
# if defined(__ILP32__)
# define native_abi() ABI_X32
# define ABI_SECONDARY ABI_X86
# define LIB_ARCH_TUPLE "x86_64-linux-gnux32"
# else
# define native_abi() ABI_X86_64
# define ABI_SECONDARY ABI_X32
# define ABI_TERTIARY ABI_X86
# define LIB_ARCH_TUPLE "x86_64-linux-gnu"
# endif
# define ARCHITECTURE_SECONDARY ARCHITECTURE_X86
#elif defined(__i386__)
# define native_architecture() ARCHITECTURE_X86
# define native_abi() ABI_X86
# define LIB_ARCH_TUPLE "i386-linux-gnu"
#elif defined(__powerpc64__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_PPC64
# define native_abi() ABI_PPC64
# define LIB_ARCH_TUPLE "ppc64-linux-gnu"
# define ARCHITECTURE_SECONDARY ARCHITECTURE_PPC
# define ABI_SECONDARY ABI_PPC
# else
# define native_architecture() ARCHITECTURE_PPC64_LE
# define native_abi() ABI_PPC64_LE
# define LIB_ARCH_TUPLE "powerpc64le-linux-gnu"
# define ARCHITECTURE_SECONDARY ARCHITECTURE_PPC_LE
# define ABI_SECONDARY ABI_PPC_LE
# endif
#elif defined(__powerpc__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_PPC
# define native_abi() ABI_PPC
# if defined(__NO_FPRS__)
# define LIB_ARCH_TUPLE "powerpc-linux-gnuspe"
# else
@ -91,95 +150,134 @@ Architecture uname_architecture(void);
# endif
# else
# define native_architecture() ARCHITECTURE_PPC_LE
# define native_abi() ABI_PPC_LE
# error "Missing LIB_ARCH_TUPLE for PPCLE"
# endif
#elif defined(__ia64__)
# define native_architecture() ARCHITECTURE_IA64
# define native_abi() ABI_IA64
# define LIB_ARCH_TUPLE "ia64-linux-gnu"
#elif defined(__hppa64__)
# define native_architecture() ARCHITECTURE_PARISC64
# define native_abi() ABI_PARISC64
# error "Missing LIB_ARCH_TUPLE for HPPA64"
#elif defined(__hppa__)
# define native_architecture() ARCHITECTURE_PARISC
# define native_abi() ABI_PARISC
# define LIB_ARCH_TUPLE "hppalinuxgnu"
#elif defined(__s390x__)
# define native_architecture() ARCHITECTURE_S390X
# define native_abi() ABI_S390X
# define LIB_ARCH_TUPLE "s390x-linux-gnu"
# define ARCHITECTURE_SECONDARY ARCHITECTURE_S390
# define ABI_SECONDARY ABI_S390
#elif defined(__s390__)
# define native_architecture() ARCHITECTURE_S390
# define native_abi() ABI_S390
# define LIB_ARCH_TUPLE "s390-linux-gnu"
#elif defined(__sparc__) && defined (__arch64__)
# define native_architecture() ARCHITECTURE_SPARC64
# define native_abi() ABI_SPARC64
# define LIB_ARCH_TUPLE "sparc64-linux-gnu"
#elif defined(__sparc__)
# define native_architecture() ARCHITECTURE_SPARC
# define native_abi() ABI_SPARC
# define LIB_ARCH_TUPLE "sparc-linux-gnu"
#elif defined(__mips64) && defined(__LP64__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_MIPS64
# define native_abi() ABI_MIPS64
# define LIB_ARCH_TUPLE "mips64-linux-gnuabi64"
# else
# define native_architecture() ARCHITECTURE_MIPS64_LE
# define native_abi() ABI_MIPS64_LE
# define LIB_ARCH_TUPLE "mips64el-linux-gnuabi64"
# endif
#elif defined(__mips64)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_MIPS64
# define native_abi() ABI_MIPS64
# define LIB_ARCH_TUPLE "mips64-linux-gnuabin32"
# else
# define native_architecture() ARCHITECTURE_MIPS64_LE
# define native_abi() ABI_MIPS64_LE
# define LIB_ARCH_TUPLE "mips64el-linux-gnuabin32"
# endif
#elif defined(__mips__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_MIPS
# define native_abi() ABI_MIPS
# define LIB_ARCH_TUPLE "mips-linux-gnu"
# else
# define native_architecture() ARCHITECTURE_MIPS_LE
# define native_abi() ABI_MIPS_LE
# define LIB_ARCH_TUPLE "mipsel-linux-gnu"
# endif
#elif defined(__alpha__)
# define native_architecture() ARCHITECTURE_ALPHA
# define native_abi() ABI_ALPHA
# define LIB_ARCH_TUPLE "alpha-linux-gnu"
#elif defined(__aarch64__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_ARM64_BE
# define native_abi() ABI_ARM64_BE
# define LIB_ARCH_TUPLE "aarch64_be-linux-gnu"
# define ARCHITECTURE_SECONDARY ARCHITECTURE_ARM_BE
# define ABI_SECONDARY ABI_ARMHF_BE
# define ABI_TERTIARY ABI_ARMEL_BE
# define ABI_QUATERNARY ABI_ARM_BE
# else
# define native_architecture() ARCHITECTURE_ARM64
# define native_abi() ABI_ARM64
# define LIB_ARCH_TUPLE "aarch64-linux-gnu"
# define ARCHITECTURE_SECONDARY ARCHITECTURE_ARM
# define ABI_SECONDARY ABI_ARMHF
# define ABI_TERTIARY ABI_ARMEL
# define ABI_QUATERNARY ABI_ARM
# endif
#elif defined(__arm__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_ARM_BE
# if defined(__ARM_EABI__)
# if defined(__ARM_PCS_VFP)
# define native_abi() ABI_ARMHF_BE
# define ABI_SECONDARY ABI_ARMEL_BE
# define ABI_TERIARY ABI_ARM_BE
# define LIB_ARCH_TUPLE "armeb-linux-gnueabihf"
# else
# define native_abi() ABI_ARMEL_BE
# define ABI_SECONDARY ABI_ARM_BE
# define LIB_ARCH_TUPLE "armeb-linux-gnueabi"
# endif
# else
# define native_abi() ABI_ARM_BE
# define LIB_ARCH_TUPLE "armeb-linux-gnu"
# endif
# else
# define native_architecture() ARCHITECTURE_ARM
# if defined(__ARM_EABI__)
# if defined(__ARM_PCS_VFP)
# define native_abi() ABI_ARMHF
# define ABI_SECONDARY ABI_ARMEL
# define ABI_TERIARY ABI_ARM
# define LIB_ARCH_TUPLE "arm-linux-gnueabihf"
# else
# define native_abi() ABI_ARMEL
# define ABI_SECONDARY ABI_ARM
# define LIB_ARCH_TUPLE "arm-linux-gnueabi"
# endif
# else
# define native_abi() ABI_ARM
# define LIB_ARCH_TUPLE "arm-linux-gnu"
# endif
# endif
#elif defined(__sh64__)
# define native_architecture() ARCHITECTURE_SH64
# define native_abi() ABI_SH64
# error "Missing LIB_ARCH_TUPLE for SH64"
#elif defined(__sh__)
# define native_architecture() ARCHITECTURE_SH
# define native_abi() ABI_SH
# if defined(__SH1__)
# define LIB_ARCH_TUPLE "sh1-linux-gnu"
# elif defined(__SH2__)
@ -199,6 +297,7 @@ Architecture uname_architecture(void);
# endif
#elif defined(__loongarch_lp64)
# define native_architecture() ARCHITECTURE_LOONGARCH64
# define native_abi() ABI_LOONGARCH64
# if defined(__loongarch_double_float)
# define LIB_ARCH_TUPLE "loongarch64-linux-gnu"
# elif defined(__loongarch_single_float)
@ -210,22 +309,28 @@ Architecture uname_architecture(void);
# endif
#elif defined(__m68k__)
# define native_architecture() ARCHITECTURE_M68K
# define native_abi() ABI_M68K
# define LIB_ARCH_TUPLE "m68k-linux-gnu"
#elif defined(__tilegx__)
# define native_architecture() ARCHITECTURE_TILEGX
# define native_abi() ABI_TILEGX
# define LIB_ARCH_TUPLE "tilegx-linux-gnu"
#elif defined(__cris__)
# define native_architecture() ARCHITECTURE_CRIS
# define native_abi() ABI_CRIS
# error "Missing LIB_ARCH_TUPLE for CRIS"
#elif defined(__nios2__)
# define native_architecture() ARCHITECTURE_NIOS2
# define native_abi() ABI_NIOS2
# define LIB_ARCH_TUPLE "nios2-linux-gnu"
#elif defined(__riscv)
# if __SIZEOF_POINTER__ == 4
# define native_architecture() ARCHITECTURE_RISCV32
# define native_abi() ABI_RISCV32
# define LIB_ARCH_TUPLE "riscv32-linux-gnu"
# elif __SIZEOF_POINTER__ == 8
# define native_architecture() ARCHITECTURE_RISCV64
# define native_abi() ABI_RISCV64
# define LIB_ARCH_TUPLE "riscv64-linux-gnu"
# else
# error "Unrecognized riscv architecture variant"
@ -233,9 +338,11 @@ Architecture uname_architecture(void);
#elif defined(__arc__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_ARC_BE
# define native_abi() ABI_ARC_BE
# define LIB_ARCH_TUPLE "arceb-linux"
# else
# define native_architecture() ARCHITECTURE_ARC
# define native_abi() ABI_ARC
# define LIB_ARCH_TUPLE "arc-linux"
# endif
#else
@ -244,3 +351,6 @@ Architecture uname_architecture(void);
const char* architecture_to_string(Architecture a) _const_;
Architecture architecture_from_string(const char *s) _pure_;
const char* abi_to_string(Abi a) _const_;
Abi abi_from_string(const char *s) _pure_;

View File

@ -2980,7 +2980,8 @@ static int pick_versions(
const ExecContext *context,
const ExecParameters *params,
char **ret_root_image,
char **ret_root_directory) {
char **ret_root_directory,
Abi *ret_root_abi) {
int r;
@ -2988,6 +2989,7 @@ static int pick_versions(
assert(params);
assert(ret_root_image);
assert(ret_root_directory);
assert(ret_root_abi);
if (context->root_image) {
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
@ -2996,7 +2998,7 @@ static int pick_versions(
/* toplevel_fd= */ AT_FDCWD,
context->root_image,
&pick_filter_image_raw,
PICK_ARCHITECTURE|PICK_TRIES|PICK_RESOLVE,
PICK_ABI|PICK_TRIES|PICK_RESOLVE,
&result);
if (r < 0)
return r;
@ -3006,6 +3008,7 @@ static int pick_versions(
*ret_root_image = TAKE_PTR(result.path);
*ret_root_directory = NULL;
*ret_root_abi = result.abi;
return r;
}
@ -3016,7 +3019,7 @@ static int pick_versions(
/* toplevel_fd= */ AT_FDCWD,
context->root_directory,
&pick_filter_image_dir,
PICK_ARCHITECTURE|PICK_TRIES|PICK_RESOLVE,
PICK_ABI|PICK_TRIES|PICK_RESOLVE,
&result);
if (r < 0)
return r;
@ -3026,10 +3029,12 @@ static int pick_versions(
*ret_root_image = NULL;
*ret_root_directory = TAKE_PTR(result.path);
*ret_root_abi = result.abi;
return r;
}
*ret_root_image = *ret_root_directory = NULL;
*ret_root_abi = _ABI_INVALID;
return 0;
}
@ -3052,6 +3057,7 @@ static int apply_mount_namespace(
bool setup_os_release_symlink;
BindMount *bind_mounts = NULL;
size_t n_bind_mounts = 0;
Abi root_abi = _ABI_INVALID;
int r;
assert(context);
@ -3063,7 +3069,8 @@ static int apply_mount_namespace(
context,
params,
&root_image,
&root_dir);
&root_dir,
&root_abi);
if (r < 0)
return r;
@ -3180,6 +3187,7 @@ static int apply_mount_namespace(
.root_image = root_image,
.root_image_options = context->root_image_options,
.root_image_policy = context->root_image_policy ?: &image_policy_service,
.root_abi = root_abi,
.read_write_paths = read_write_paths,
.read_only_paths = needs_sandboxing ? context->read_only_paths : NULL,

View File

@ -481,6 +481,7 @@ static int append_mount_images(MountList *ml, const MountImage *mount_images, si
static int append_extensions(
MountList *ml,
const char *root,
Abi root_abi,
const char *private_namespace_dir,
char **hierarchies,
const MountImage *mount_images,
@ -519,12 +520,15 @@ static int append_extensions(
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
_cleanup_free_ char *mount_point = NULL;
const MountImage *m = mount_images + i;
/* Ensure we pick extensions with the same ABI as the root */
PickFilter filter = pick_filter_image_raw;
filter.abi = root_abi;
r = path_pick(/* toplevel_path= */ NULL,
/* toplevel_fd= */ AT_FDCWD,
m->source,
&pick_filter_image_raw,
PICK_ARCHITECTURE|PICK_TRIES,
&filter,
PICK_ABI|PICK_TRIES,
&result);
if (r < 0)
return r;
@ -578,6 +582,9 @@ static int append_extensions(
_cleanup_free_ char *mount_point = NULL;
const char *e = *extension_directory;
bool ignore_enoent = false;
/* Ensure we pick extensions with the same ABI as the root */
PickFilter filter = pick_filter_image_dir;
filter.abi = root_abi;
/* Look for any prefixes */
if (startswith(e, "-")) {
@ -591,8 +598,8 @@ static int append_extensions(
r = path_pick(/* toplevel_path= */ NULL,
/* toplevel_fd= */ AT_FDCWD,
e,
&pick_filter_image_dir,
PICK_ARCHITECTURE|PICK_TRIES,
&filter,
PICK_ABI|PICK_TRIES,
&result);
if (r < 0)
return r;
@ -2425,7 +2432,7 @@ int setup_namespace(const NamespaceParameters *p, char **error_path) {
if (r < 0)
return r;
r = append_extensions(&ml, root, p->private_namespace_dir, hierarchies, p->extension_images, p->n_extension_images, p->extension_directories);
r = append_extensions(&ml, root, p->root_abi, p->private_namespace_dir, hierarchies, p->extension_images, p->n_extension_images, p->extension_directories);
if (r < 0)
return r;

View File

@ -107,6 +107,7 @@ struct NamespaceParameters {
const char *root_image;
const MountOptions *root_image_options;
const ImagePolicy *root_image_policy;
Abi root_abi;
char **read_write_paths;
char **read_only_paths;

View File

@ -888,7 +888,7 @@ static int action_dissect(
m->sector_size);
printf(" Arch.: %s\n",
strna(architecture_to_string(dissected_image_architecture(m))));
strna(abi_to_string(dissected_image_abi(m))));
putc('\n', stdout);
fflush(stdout);
@ -978,14 +978,14 @@ static int action_dissect(
if (r < 0)
return log_error_errno(r, "Failed to parse confext scopes: %m");
Architecture a = dissected_image_architecture(m);
Abi a = dissected_image_abi(m);
r = sd_json_buildo(
&v,
SD_JSON_BUILD_PAIR("name", SD_JSON_BUILD_STRING(bn)),
SD_JSON_BUILD_PAIR_CONDITION(size != UINT64_MAX, "size", SD_JSON_BUILD_INTEGER(size)),
SD_JSON_BUILD_PAIR("sectorSize", SD_JSON_BUILD_INTEGER(m->sector_size)),
SD_JSON_BUILD_PAIR_CONDITION(a >= 0, "architecture", SD_JSON_BUILD_STRING(architecture_to_string(a))),
SD_JSON_BUILD_PAIR_CONDITION(a >= 0, "architecture", SD_JSON_BUILD_STRING(abi_to_string(a))),
SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->image_uuid), "imageUuid", SD_JSON_BUILD_UUID(m->image_uuid)),
SD_JSON_BUILD_PAIR_CONDITION(!!m->hostname, "hostname", SD_JSON_BUILD_STRING(m->hostname)),
SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->machine_id), "machineId", SD_JSON_BUILD_ID128(m->machine_id)),
@ -1044,7 +1044,7 @@ static int action_dissect(
t,
TABLE_STRING, p->label,
TABLE_STRING, p->fstype,
TABLE_STRING, architecture_to_string(p->architecture));
TABLE_STRING, abi_to_string(p->abi));
if (r < 0)
return table_log_add_error(r);
@ -2030,7 +2030,7 @@ static int run(int argc, char *argv[]) {
r = path_pick_update_warn(
&arg_image,
&pick_filter_image_raw,
PICK_ARCHITECTURE|PICK_TRIES,
PICK_ABI|PICK_TRIES,
/* ret_result= */ NULL);
if (r < 0)
return r;

View File

@ -514,7 +514,7 @@ static int vl_method_mount_image(
SD_JSON_BUILD_PAIR("writable", SD_JSON_BUILD_BOOLEAN(pp->rw)),
SD_JSON_BUILD_PAIR("growFileSystem", SD_JSON_BUILD_BOOLEAN(pp->growfs)),
SD_JSON_BUILD_PAIR_CONDITION(pp->partno > 0, "partitionNumber", SD_JSON_BUILD_INTEGER(pp->partno)),
SD_JSON_BUILD_PAIR_CONDITION(pp->architecture > 0, "architecture", SD_JSON_BUILD_STRING(architecture_to_string(pp->architecture))),
SD_JSON_BUILD_PAIR_CONDITION(pp->abi > 0, "architecture", SD_JSON_BUILD_STRING(abi_to_string(pp->abi))),
SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(pp->uuid), "partitionUuid", SD_JSON_BUILD_UUID(pp->uuid)),
SD_JSON_BUILD_PAIR("fileSystemType", SD_JSON_BUILD_STRING(dissected_partition_fstype(pp))),
SD_JSON_BUILD_PAIR_CONDITION(!!pp->label, "partitionLabel", SD_JSON_BUILD_STRING(pp->label)),

View File

@ -231,7 +231,7 @@ static MachineCredentialContext arg_credentials = {};
static char **arg_bind_user = NULL;
static bool arg_suppress_sync = false;
static char *arg_settings_filename = NULL;
static Architecture arg_architecture = _ARCHITECTURE_INVALID;
static Abi arg_abi = _ABI_INVALID;
static ImagePolicy *arg_image_policy = NULL;
static char *arg_background = NULL;
static bool arg_privileged = false;
@ -3049,53 +3049,53 @@ static int pick_paths(void) {
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
PickFilter filter = pick_filter_image_dir;
filter.architecture = arg_architecture;
filter.abi = arg_abi;
r = path_pick_update_warn(
&arg_directory,
&filter,
PICK_ARCHITECTURE|PICK_TRIES,
PICK_ABI|PICK_TRIES,
&result);
if (r < 0) {
/* Accept ENOENT here so that the --template= logic can work */
if (r != -ENOENT)
return r;
} else
arg_architecture = result.architecture;
arg_abi = result.abi;
}
if (arg_image) {
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
PickFilter filter = pick_filter_image_raw;
filter.architecture = arg_architecture;
filter.abi = arg_abi;
r = path_pick_update_warn(
&arg_image,
&filter,
PICK_ARCHITECTURE|PICK_TRIES,
PICK_ABI|PICK_TRIES,
&result);
if (r < 0)
return r;
arg_architecture = result.architecture;
arg_abi = result.abi;
}
if (arg_template) {
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
PickFilter filter = pick_filter_image_dir;
filter.architecture = arg_architecture;
filter.abi = arg_abi;
r = path_pick_update_warn(
&arg_template,
&filter,
PICK_ARCHITECTURE,
PICK_ABI,
&result);
if (r < 0)
return r;
arg_architecture = result.architecture;
arg_abi = result.abi;
}
return 0;
@ -3507,16 +3507,28 @@ static int inner_child(
r = safe_personality(arg_personality);
if (r < 0)
return log_error_errno(r, "personality() failed: %m");
#ifdef ARCHITECTURE_SECONDARY
} else if (arg_architecture == ARCHITECTURE_SECONDARY) {
#ifdef ABI_SECONDARY
} else if (arg_abi == ABI_SECONDARY) {
r = safe_personality(PER_LINUX32);
if (r < 0)
return log_error_errno(r, "personality() failed: %m");
#endif
} else if (!arg_quiet && arg_architecture >= 0 && arg_architecture != native_architecture())
#ifdef ABI_TERTIARY
} else if (arg_abi == ABI_TERTIARY) {
r = safe_personality(PER_LINUX32);
if (r < 0)
return log_error_errno(r, "personality() failed: %m");
#endif
#ifdef ABI_QUATERNARY
} else if (arg_abi == ABI_QUATERNARY) {
r = safe_personality(PER_LINUX32);
if (r < 0)
return log_error_errno(r, "personality() failed: %m");
#endif
} else if (!arg_quiet && arg_abi >= 0 && arg_abi != native_abi())
log_notice("Selected architecture '%s' not supported natively on the local CPU, assuming "
"invocation with qemu userspace emulator (or equivalent) in effect.",
architecture_to_string(arg_architecture));
abi_to_string(arg_abi));
r = setrlimit_closest_all((const struct rlimit *const*) arg_rlimit, &which_failed);
if (r < 0)
@ -6328,8 +6340,8 @@ static int run(int argc, char *argv[]) {
if (remove_image && unlink(arg_image) >= 0)
remove_image = false;
if (arg_architecture < 0)
arg_architecture = dissected_image_architecture(dissected_image);
if (arg_abi < 0)
arg_abi = dissected_image_abi(dissected_image);
}
r = custom_mount_prepare_all(arg_directory, arg_custom_mounts, arg_n_custom_mounts);

View File

@ -169,7 +169,7 @@ static GptPartitionType *arg_defer_partitions = NULL;
static size_t arg_n_defer_partitions = 0;
static uint64_t arg_sector_size = 0;
static ImagePolicy *arg_image_policy = NULL;
static Architecture arg_architecture = _ARCHITECTURE_INVALID;
static Abi arg_abi = _ABI_INVALID;
static int arg_offline = -1;
static char **arg_copy_from = NULL;
static char *arg_copy_source = NULL;
@ -1469,8 +1469,8 @@ static int config_parse_type(
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse partition type: %s", rvalue);
if (arg_architecture >= 0)
*type = gpt_partition_type_override_architecture(*type, arg_architecture);
if (arg_abi >= 0)
*type = gpt_partition_type_override_abi(*type, arg_abi);
return 0;
}
@ -7703,7 +7703,7 @@ static int help(void) {
" --offline=BOOL Whether to build the image offline\n"
" --discard=BOOL Whether to discard backing blocks for new partitions\n"
" --sector-size=SIZE Set the logical sector size for the image\n"
" --architecture=ARCH Set the generic architecture for the image\n"
" --architecture=ABI Set the generic ABI for the image\n"
" --size=BYTES Grow loopback file to specified size\n"
" --seed=UUID 128-bit seed UUID to derive all UUIDs from\n"
" --split=BOOL Whether to generate split artifacts\n"
@ -8180,11 +8180,11 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_ARCHITECTURE:
r = architecture_from_string(optarg);
r = abi_from_string(optarg);
if (r < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid architecture '%s'.", optarg);
arg_architecture = r;
arg_abi = r;
break;
case ARG_OFFLINE:
@ -8391,12 +8391,12 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_pretty < 0 && isatty_safe(STDOUT_FILENO))
arg_pretty = true;
if (arg_architecture >= 0) {
if (arg_abi >= 0) {
FOREACH_ARRAY(p, arg_filter_partitions, arg_n_filter_partitions)
*p = gpt_partition_type_override_architecture(*p, arg_architecture);
*p = gpt_partition_type_override_abi(*p, arg_abi);
FOREACH_ARRAY(p, arg_defer_partitions, arg_n_defer_partitions)
*p = gpt_partition_type_override_architecture(*p, arg_architecture);
*p = gpt_partition_type_override_abi(*p, arg_abi);
}
if (private_key && arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {

View File

@ -581,7 +581,7 @@ static int extract_image_and_extensions(
/* toplevel_fd= */ AT_FDCWD,
name_or_path,
&pick_filter_image_any,
PICK_ARCHITECTURE|PICK_TRIES|PICK_RESOLVE,
PICK_ABI|PICK_TRIES|PICK_RESOLVE,
&result);
if (r < 0)
return r;
@ -615,11 +615,15 @@ static int extract_image_and_extensions(
const char *path = *p;
if (path_is_absolute(*p)) {
/* Ensure we pick extensions with the same ABI as the root */
PickFilter filter = pick_filter_image_any;
filter.abi = result.abi;
r = path_pick(/* toplevel_path= */ NULL,
/* toplevel_fd= */ AT_FDCWD,
*p,
&pick_filter_image_any,
PICK_ARCHITECTURE|PICK_TRIES|PICK_RESOLVE,
&filter,
PICK_ABI|PICK_TRIES|PICK_RESOLVE,
&ext_result);
if (r < 0)
return r;
@ -1765,7 +1769,7 @@ static bool marker_matches_images(const char *marker, const char *name_or_path,
/* toplevel_fd= */ AT_FDCWD,
*image_name_or_path,
&pick_filter_image_any,
PICK_ARCHITECTURE|PICK_TRIES|PICK_RESOLVE,
PICK_ABI|PICK_TRIES|PICK_RESOLVE,
&result);
if (r < 0)
return r;

View File

@ -664,7 +664,7 @@ int image_find(ImageClass class,
PickFilter filter = {
.type_mask = endswith(suffix, ".raw") ? (UINT32_C(1) << DT_REG) | (UINT32_C(1) << DT_BLK) : (UINT32_C(1) << DT_DIR),
.basename = name,
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.suffix = STRV_MAKE(suffix),
};
@ -673,7 +673,7 @@ int image_find(ImageClass class,
/* toplevel_fd= */ AT_FDCWD,
vp,
&filter,
PICK_ARCHITECTURE|PICK_TRIES,
PICK_ABI|PICK_TRIES,
&result);
if (r < 0) {
log_debug_errno(r, "Failed to pick versioned image on '%s', skipping: %m", vp);
@ -832,7 +832,7 @@ int image_discover(
PickFilter filter = {
.type_mask = endswith(suffix, ".raw") ? (UINT32_C(1) << DT_REG) | (UINT32_C(1) << DT_BLK) : (UINT32_C(1) << DT_DIR),
.basename = pretty,
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.suffix = STRV_MAKE(suffix),
};
@ -841,7 +841,7 @@ int image_discover(
/* toplevel_fd= */ AT_FDCWD,
vp,
&filter,
PICK_ARCHITECTURE|PICK_TRIES,
PICK_ABI|PICK_TRIES,
&result);
if (r < 0) {
log_debug_errno(r, "Failed to pick versioned image on '%s', skipping: %m", vp);

View File

@ -647,21 +647,37 @@ static int open_partition(
return TAKE_FD(fd);
}
static int compare_arch(Architecture a, Architecture b) {
static int compare_abi(Abi a, Abi b) {
if (a == b)
return 0;
if (a == native_architecture())
if (a == native_abi())
return 1;
if (b == native_architecture())
if (b == native_abi())
return -1;
#ifdef ARCHITECTURE_SECONDARY
if (a == ARCHITECTURE_SECONDARY)
#ifdef ABI_SECONDARY
if (a == ABI_SECONDARY)
return 1;
if (b == ARCHITECTURE_SECONDARY)
if (b == ABI_SECONDARY)
return -1;
#endif
#ifdef ABI_TERTIARY
if (a == ABI_TERTIARY)
return 1;
if (b == ABI_TERTIARY)
return -1;
#endif
#ifdef ABI_QUATERNARY
if (a == ABI_QUATERNARY)
return 1;
if (b == ABI_QUATERNARY)
return -1;
#endif
@ -862,7 +878,7 @@ static int dissect_image(
.found = true,
.rw = !m->verity_ready && !fstype_is_ro(fstype),
.partno = -1,
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.fstype = TAKE_PTR(t),
.node = TAKE_PTR(n),
.mount_options = TAKE_PTR(o),
@ -1230,7 +1246,7 @@ static int dissect_image(
* let the newest version win. This permits a simple A/B versioning
* scheme in OS images. */
c = compare_arch(type.arch, m->partitions[type.designator].architecture);
c = compare_abi(type.abi, m->partitions[type.designator].abi);
if (c < 0) /* the arch we already found is better than the one we found now */
continue;
if (c == 0 && /* same arch? then go by version in label */
@ -1276,7 +1292,7 @@ static int dissect_image(
.partno = nr,
.rw = rw,
.growfs = growfs,
.architecture = type.arch,
.abi = type.abi,
.node = TAKE_PTR(n),
.fstype = TAKE_PTR(t),
.label = TAKE_PTR(l),
@ -1354,7 +1370,7 @@ static int dissect_image(
.partno = nr,
.rw = true,
.growfs = false,
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.node = TAKE_PTR(n),
.uuid = id,
.mount_options = TAKE_PTR(o),
@ -1387,12 +1403,12 @@ static int dissect_image(
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
return -EADDRNOTAVAIL;
/* If root and /usr are combined then insist that the architecture matches */
/* If root and /usr are combined then insist that the abi matches */
if (m->partitions[PARTITION_ROOT].found &&
m->partitions[PARTITION_USR].found &&
(m->partitions[PARTITION_ROOT].architecture >= 0 &&
m->partitions[PARTITION_USR].architecture >= 0 &&
m->partitions[PARTITION_ROOT].architecture != m->partitions[PARTITION_USR].architecture))
(m->partitions[PARTITION_ROOT].abi >= 0 &&
m->partitions[PARTITION_USR].abi >= 0 &&
m->partitions[PARTITION_ROOT].abi != m->partitions[PARTITION_USR].abi))
return -EADDRNOTAVAIL;
if (!m->partitions[PARTITION_ROOT].found &&
@ -1445,7 +1461,7 @@ static int dissect_image(
.rw = generic_rw,
.growfs = generic_growfs,
.partno = generic_nr,
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.node = TAKE_PTR(n),
.uuid = generic_uuid,
.mount_options = TAKE_PTR(o),
@ -3768,18 +3784,18 @@ finish:
return r;
}
Architecture dissected_image_architecture(DissectedImage *img) {
Abi dissected_image_abi(DissectedImage *img) {
assert(img);
if (img->partitions[PARTITION_ROOT].found &&
img->partitions[PARTITION_ROOT].architecture >= 0)
return img->partitions[PARTITION_ROOT].architecture;
img->partitions[PARTITION_ROOT].abi >= 0)
return img->partitions[PARTITION_ROOT].abi;
if (img->partitions[PARTITION_USR].found &&
img->partitions[PARTITION_USR].architecture >= 0)
return img->partitions[PARTITION_USR].architecture;
img->partitions[PARTITION_USR].abi >= 0)
return img->partitions[PARTITION_USR].abi;
return _ARCHITECTURE_INVALID;
return _ABI_INVALID;
}
int dissect_loop_device(
@ -4204,7 +4220,7 @@ int get_common_dissect_directory(char **ret) {
#if HAVE_BLKID
static JSON_DISPATCH_ENUM_DEFINE(dispatch_architecture, Architecture, architecture_from_string);
static JSON_DISPATCH_ENUM_DEFINE(dispatch_abi, Abi, abi_from_string);
static JSON_DISPATCH_ENUM_DEFINE(dispatch_partition_designator, PartitionDesignator, partition_designator_from_string);
typedef struct PartitionFields {
@ -4212,7 +4228,7 @@ typedef struct PartitionFields {
bool rw;
bool growfs;
unsigned partno;
Architecture architecture;
Abi abi;
sd_id128_t uuid;
char *fstype;
char *label;
@ -4336,7 +4352,7 @@ int mountfsd_mount_image(
_cleanup_(partition_fields_done) PartitionFields pp = {
.designator = _PARTITION_DESIGNATOR_INVALID,
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.size = UINT64_MAX,
.offset = UINT64_MAX,
.fsmount_fd_idx = UINT_MAX,
@ -4347,7 +4363,7 @@ int mountfsd_mount_image(
{ "writable", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(struct PartitionFields, rw), SD_JSON_MANDATORY },
{ "growFileSystem", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(struct PartitionFields, growfs), SD_JSON_MANDATORY },
{ "partitionNumber", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, offsetof(struct PartitionFields, partno), 0 },
{ "architecture", SD_JSON_VARIANT_STRING, dispatch_architecture, offsetof(struct PartitionFields, architecture), 0 },
{ "architecture", SD_JSON_VARIANT_STRING, dispatch_abi, offsetof(struct PartitionFields, abi), 0 },
{ "partitionUuid", SD_JSON_VARIANT_STRING, sd_json_dispatch_id128, offsetof(struct PartitionFields, uuid), 0 },
{ "fileSystemType", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(struct PartitionFields, fstype), SD_JSON_MANDATORY },
{ "partitionLabel", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(struct PartitionFields, label), 0 },
@ -4386,7 +4402,7 @@ int mountfsd_mount_image(
.rw = pp.rw,
.growfs = pp.growfs,
.partno = pp.partno,
.architecture = pp.architecture,
.abi = pp.abi,
.uuid = pp.uuid,
.fstype = TAKE_PTR(pp.fstype),
.label = TAKE_PTR(pp.label),

View File

@ -26,7 +26,7 @@ struct DissectedPartition {
bool rw:1;
bool growfs:1;
int partno; /* -1 if there was no partition and the images contains a file system directly */
Architecture architecture; /* Intended architecture: either native, secondary or unset ARCHITECTURE_INVALID. */
Abi abi; /* Intended architecture: either native, secondary or unset ABI_INVALID. */
sd_id128_t uuid; /* Partition entry UUID as reported by the GPT */
char *fstype;
char *node;
@ -44,7 +44,7 @@ struct DissectedPartition {
#define DISSECTED_PARTITION_NULL \
((DissectedPartition) { \
.partno = -1, \
.architecture = _ARCHITECTURE_INVALID, \
.abi = _ABI_INVALID, \
.mount_node_fd = -EBADF, \
.fsmount_fd = -EBADF, \
})
@ -175,7 +175,7 @@ int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t u
int dissected_image_acquire_metadata(DissectedImage *m, int userns_fd, DissectImageFlags extra_flags);
Architecture dissected_image_architecture(DissectedImage *m);
Abi dissected_image_abi(DissectedImage *m);
static inline bool dissected_image_is_bootable_os(DissectedImage *m) {
return m && m->has_init_system > 0;

View File

@ -5,14 +5,14 @@
#include "string-util.h"
#include "utf8.h"
/* Gently push people towards defining GPT type UUIDs for all architectures we know */
/* Gently push people towards defining GPT type UUIDs for all abis we know */
#if !defined(SD_GPT_ROOT_NATIVE) || \
!defined(SD_GPT_ROOT_NATIVE_VERITY) || \
!defined(SD_GPT_ROOT_NATIVE_VERITY_SIG) || \
!defined(SD_GPT_USR_NATIVE) || \
!defined(SD_GPT_USR_NATIVE_VERITY) || \
!defined(SD_GPT_USR_NATIVE_VERITY_SIG)
#pragma message "Please define GPT partition types for your architecture."
#pragma message "Please define GPT partition types for your abi."
#endif
bool partition_designator_is_versioned(PartitionDesignator d) {
@ -118,16 +118,16 @@ static const char *const partition_mountpoint_table[_PARTITION_DESIGNATOR_MAX] =
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(partition_mountpoint, PartitionDesignator);
#define _GPT_ARCH_SEXTET(arch, name) \
{ SD_GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .designator = PARTITION_ROOT }, \
{ SD_GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_VERITY }, \
{ SD_GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_VERITY_SIG }, \
{ SD_GPT_USR_##arch, "usr-" name, ARCHITECTURE_##arch, .designator = PARTITION_USR }, \
{ SD_GPT_USR_##arch##_VERITY, "usr-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_USR_VERITY }, \
{ SD_GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_USR_VERITY_SIG }
{ SD_GPT_ROOT_##arch, "root-" name, ABI_##arch, .designator = PARTITION_ROOT }, \
{ SD_GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ABI_##arch, .designator = PARTITION_ROOT_VERITY }, \
{ SD_GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig", ABI_##arch, .designator = PARTITION_ROOT_VERITY_SIG }, \
{ SD_GPT_USR_##arch, "usr-" name, ABI_##arch, .designator = PARTITION_USR }, \
{ SD_GPT_USR_##arch##_VERITY, "usr-" name "-verity", ABI_##arch, .designator = PARTITION_USR_VERITY }, \
{ SD_GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ABI_##arch, .designator = PARTITION_USR_VERITY_SIG }
/* Two special cases: alias aarch64 to arm64, and amd64 to x86-64. The DSP mixes debianisms and CPUisms: for
* x86, it uses x86 and x86_64, but for aarch64 it uses arm64. This is confusing, and leads to issues for
* callers that have to know which -ism to use for which architecture. But we also don't really want to
* callers that have to know which -ism to use for which abi. But we also don't really want to
* change the spec and add new partition labels, so add a user-friendly aliasing here, so that both are
* accepted but the end result on disk (ie: the partition label).
* So always list the canonical name FIRST, and then any aliases later, so that we can match on aliases,
@ -141,9 +141,12 @@ const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(ARM, "armv7l"), /* Alias: must be listed after arm */
_GPT_ARCH_SEXTET(ARM64, "arm64"),
_GPT_ARCH_SEXTET(ARM64, "aarch64"), /* Alias: must be listed after arm64 */
_GPT_ARCH_SEXTET(ARMEL, "armel"),
_GPT_ARCH_SEXTET(ARMHF, "armhf"),
_GPT_ARCH_SEXTET(IA64, "ia64"),
_GPT_ARCH_SEXTET(LOONGARCH64, "loongarch64"),
_GPT_ARCH_SEXTET(LOONGARCH64, "loong64"), /* Alias: must be listed after loongarch64 */
_GPT_ARCH_SEXTET(M68K, "m68k"),
_GPT_ARCH_SEXTET(MIPS, "mips"),
_GPT_ARCH_SEXTET(MIPS64, "mips64"),
_GPT_ARCH_SEXTET(MIPS_LE, "mips-le"),
@ -161,7 +164,10 @@ const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(RISCV64, "riscv64"),
_GPT_ARCH_SEXTET(S390, "s390"),
_GPT_ARCH_SEXTET(S390X, "s390x"),
_GPT_ARCH_SEXTET(SPARC64, "sparc64"),
_GPT_ARCH_SEXTET(SH, "sh4"),
_GPT_ARCH_SEXTET(TILEGX, "tilegx"),
_GPT_ARCH_SEXTET(X32, "x32"),
_GPT_ARCH_SEXTET(X86, "x86"),
_GPT_ARCH_SEXTET(X86, "i386"), /* Alias: must be listed after x86 */
_GPT_ARCH_SEXTET(X86, "i486"), /* Alias: must be listed after x86 */
@ -171,31 +177,47 @@ const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(X86_64, "x86_64"), /* Alias: must be listed after x86-64 */
_GPT_ARCH_SEXTET(X86_64, "amd64"), /* Alias: must be listed after x86-64 */
#ifdef SD_GPT_ROOT_NATIVE
{ SD_GPT_ROOT_NATIVE, "root", native_architecture(), .designator = PARTITION_ROOT },
{ SD_GPT_ROOT_NATIVE_VERITY, "root-verity", native_architecture(), .designator = PARTITION_ROOT_VERITY },
{ SD_GPT_ROOT_NATIVE_VERITY_SIG, "root-verity-sig", native_architecture(), .designator = PARTITION_ROOT_VERITY_SIG },
{ SD_GPT_USR_NATIVE, "usr", native_architecture(), .designator = PARTITION_USR },
{ SD_GPT_USR_NATIVE_VERITY, "usr-verity", native_architecture(), .designator = PARTITION_USR_VERITY },
{ SD_GPT_USR_NATIVE_VERITY_SIG, "usr-verity-sig", native_architecture(), .designator = PARTITION_USR_VERITY_SIG },
{ SD_GPT_ROOT_NATIVE, "root", native_abi(), .designator = PARTITION_ROOT },
{ SD_GPT_ROOT_NATIVE_VERITY, "root-verity", native_abi(), .designator = PARTITION_ROOT_VERITY },
{ SD_GPT_ROOT_NATIVE_VERITY_SIG, "root-verity-sig", native_abi(), .designator = PARTITION_ROOT_VERITY_SIG },
{ SD_GPT_USR_NATIVE, "usr", native_abi(), .designator = PARTITION_USR },
{ SD_GPT_USR_NATIVE_VERITY, "usr-verity", native_abi(), .designator = PARTITION_USR_VERITY },
{ SD_GPT_USR_NATIVE_VERITY_SIG, "usr-verity-sig", native_abi(), .designator = PARTITION_USR_VERITY_SIG },
#endif
#ifdef SD_GPT_ROOT_SECONDARY
{ SD_GPT_ROOT_SECONDARY, "root-secondary", ARCHITECTURE_SECONDARY, .designator = PARTITION_ROOT },
{ SD_GPT_ROOT_SECONDARY_VERITY, "root-secondary-verity", ARCHITECTURE_SECONDARY, .designator = PARTITION_ROOT_VERITY },
{ SD_GPT_ROOT_SECONDARY_VERITY_SIG, "root-secondary-verity-sig", ARCHITECTURE_SECONDARY, .designator = PARTITION_ROOT_VERITY_SIG },
{ SD_GPT_USR_SECONDARY, "usr-secondary", ARCHITECTURE_SECONDARY, .designator = PARTITION_USR },
{ SD_GPT_USR_SECONDARY_VERITY, "usr-secondary-verity", ARCHITECTURE_SECONDARY, .designator = PARTITION_USR_VERITY },
{ SD_GPT_USR_SECONDARY_VERITY_SIG, "usr-secondary-verity-sig", ARCHITECTURE_SECONDARY, .designator = PARTITION_USR_VERITY_SIG },
{ SD_GPT_ROOT_SECONDARY, "root-secondary", ABI_SECONDARY, .designator = PARTITION_ROOT },
{ SD_GPT_ROOT_SECONDARY_VERITY, "root-secondary-verity", ABI_SECONDARY, .designator = PARTITION_ROOT_VERITY },
{ SD_GPT_ROOT_SECONDARY_VERITY_SIG, "root-secondary-verity-sig", ABI_SECONDARY, .designator = PARTITION_ROOT_VERITY_SIG },
{ SD_GPT_USR_SECONDARY, "usr-secondary", ABI_SECONDARY, .designator = PARTITION_USR },
{ SD_GPT_USR_SECONDARY_VERITY, "usr-secondary-verity", ABI_SECONDARY, .designator = PARTITION_USR_VERITY },
{ SD_GPT_USR_SECONDARY_VERITY_SIG, "usr-secondary-verity-sig", ABI_SECONDARY, .designator = PARTITION_USR_VERITY_SIG },
#endif
#ifdef SD_GPT_ROOT_TERTIARY
{ SD_GPT_ROOT_TERTIARY, "root-tertiary", ABI_TERTIARY, .designator = PARTITION_ROOT },
{ SD_GPT_ROOT_TERTIARY_VERITY, "root-tertiary-verity", ABI_TERTIARY, .designator = PARTITION_ROOT_VERITY },
{ SD_GPT_ROOT_TERTIARY_VERITY_SIG, "root-tertiary-verity-sig", ABI_TERTIARY, .designator = PARTITION_ROOT_VERITY_SIG },
{ SD_GPT_USR_TERTIARY, "usr-tertiary", ABI_TERTIARY, .designator = PARTITION_USR },
{ SD_GPT_USR_TERTIARY_VERITY, "usr-tertiary-verity", ABI_TERTIARY, .designator = PARTITION_USR_VERITY },
{ SD_GPT_USR_TERTIARY_VERITY_SIG, "usr-tertiary-verity-sig", ABI_TERTIARY, .designator = PARTITION_USR_VERITY_SIG },
#endif
#ifdef SD_GPT_ROOT_QUATERNARY
{ SD_GPT_ROOT_QUATERNARY, "root-quaternary", ABI_QUATERNARY, .designator = PARTITION_ROOT },
{ SD_GPT_ROOT_QUATERNARY_VERITY, "root-quaternary-verity", ABI_QUATERNARY, .designator = PARTITION_ROOT_VERITY },
{ SD_GPT_ROOT_QUATERNARY_VERITY_SIG, "root-quaternary-verity-sig", ABI_QUATERNARY, .designator = PARTITION_ROOT_VERITY_SIG },
{ SD_GPT_USR_QUATERNARY, "usr-quaternary", ABI_QUATERNARY, .designator = PARTITION_USR },
{ SD_GPT_USR_QUATERNARY_VERITY, "usr-quaternary-verity", ABI_QUATERNARY, .designator = PARTITION_USR_VERITY },
{ SD_GPT_USR_QUATERNARY_VERITY_SIG, "usr-quaternary-verity-sig", ABI_QUATERNARY, .designator = PARTITION_USR_VERITY_SIG },
#endif
{ SD_GPT_ESP, "esp", _ARCHITECTURE_INVALID, .designator = PARTITION_ESP },
{ SD_GPT_XBOOTLDR, "xbootldr", _ARCHITECTURE_INVALID, .designator = PARTITION_XBOOTLDR },
{ SD_GPT_SWAP, "swap", _ARCHITECTURE_INVALID, .designator = PARTITION_SWAP },
{ SD_GPT_HOME, "home", _ARCHITECTURE_INVALID, .designator = PARTITION_HOME },
{ SD_GPT_SRV, "srv", _ARCHITECTURE_INVALID, .designator = PARTITION_SRV },
{ SD_GPT_VAR, "var", _ARCHITECTURE_INVALID, .designator = PARTITION_VAR },
{ SD_GPT_TMP, "tmp", _ARCHITECTURE_INVALID, .designator = PARTITION_TMP },
{ SD_GPT_USER_HOME, "user-home", _ARCHITECTURE_INVALID, .designator = _PARTITION_DESIGNATOR_INVALID },
{ SD_GPT_LINUX_GENERIC, "linux-generic", _ARCHITECTURE_INVALID, .designator = _PARTITION_DESIGNATOR_INVALID },
{ SD_GPT_ESP, "esp", _ABI_INVALID, .designator = PARTITION_ESP },
{ SD_GPT_XBOOTLDR, "xbootldr", _ABI_INVALID, .designator = PARTITION_XBOOTLDR },
{ SD_GPT_SWAP, "swap", _ABI_INVALID, .designator = PARTITION_SWAP },
{ SD_GPT_HOME, "home", _ABI_INVALID, .designator = PARTITION_HOME },
{ SD_GPT_SRV, "srv", _ABI_INVALID, .designator = PARTITION_SRV },
{ SD_GPT_VAR, "var", _ABI_INVALID, .designator = PARTITION_VAR },
{ SD_GPT_TMP, "tmp", _ABI_INVALID, .designator = PARTITION_TMP },
{ SD_GPT_USER_HOME, "user-home", _ABI_INVALID, .designator = _PARTITION_DESIGNATOR_INVALID },
{ SD_GPT_LINUX_GENERIC, "linux-generic", _ABI_INVALID, .designator = _PARTITION_DESIGNATOR_INVALID },
{}
};
@ -259,26 +281,26 @@ int gpt_partition_type_from_string(const char *s, GptPartitionType *ret) {
return 0;
}
GptPartitionType gpt_partition_type_override_architecture(GptPartitionType type, Architecture arch) {
assert(arch >= 0);
GptPartitionType gpt_partition_type_override_abi(GptPartitionType type, Abi abi) {
assert(abi >= 0);
FOREACH_ARRAY(t, gpt_partition_type_table, ELEMENTSOF(gpt_partition_type_table) - 1)
if (t->designator == type.designator && t->arch == arch)
if (t->designator == type.designator && t->abi == abi)
return *t;
/* If we can't find an entry with the same designator and the requested architecture, just return the
/* If we can't find an entry with the same designator and the requested abi, just return the
* original partition type. */
return type;
}
Architecture gpt_partition_type_uuid_to_arch(sd_id128_t id) {
Abi gpt_partition_type_uuid_to_abi(sd_id128_t id) {
const GptPartitionType *pt;
pt = gpt_partition_type_find_by_uuid(id);
if (!pt)
return _ARCHITECTURE_INVALID;
return _ABI_INVALID;
return pt->arch;
return pt->abi;
}
int gpt_partition_label_valid(const char *s) {
@ -300,7 +322,7 @@ GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id) {
return (GptPartitionType) {
.uuid = id,
.arch = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.designator = _PARTITION_DESIGNATOR_INVALID,
};
}

View File

@ -49,12 +49,12 @@ const char* gpt_partition_type_uuid_to_string_harder(
#define GPT_PARTITION_TYPE_UUID_TO_STRING_HARDER(id) \
gpt_partition_type_uuid_to_string_harder((id), (char[SD_ID128_UUID_STRING_MAX]) {})
Architecture gpt_partition_type_uuid_to_arch(sd_id128_t id);
Abi gpt_partition_type_uuid_to_abi(sd_id128_t id);
typedef struct GptPartitionType {
sd_id128_t uuid;
const char *name;
Architecture arch;
Abi abi;
PartitionDesignator designator;
} GptPartitionType;
@ -65,7 +65,7 @@ int gpt_partition_label_valid(const char *s);
GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id);
int gpt_partition_type_from_string(const char *s, GptPartitionType *ret);
GptPartitionType gpt_partition_type_override_architecture(GptPartitionType type, Architecture arch);
GptPartitionType gpt_partition_type_override_abi(GptPartitionType type, Abi abi);
const char* gpt_partition_type_mountpoint_nulstr(GptPartitionType type);

View File

@ -43,9 +43,9 @@ static int format_fname(
* or:
* <basename>_<version><suffix>
* or:
* <basename>_<version>_<architecture><suffix>
* <basename>_<version>_<abi><suffix>
* or:
* <basename>_<architecture><suffix>
* <basename>_<abi><suffix>
*
* (Note that basename can be empty, in which case the leading "_" is suppressed)
*
@ -57,9 +57,9 @@ static int format_fname(
* fields).
*
* This is very close to Debian's way to name packages, but allows arbitrary suffixes, and makes the
* architecture field redundant.
* abi field redundant.
*
* Compare with RPM's "NEVRA" concept. Here we have "BVAS" (basename, version, architecture, suffix).
* Compare with RPM's "NEVRA" concept. Here we have "BVAS" (basename, version, abi, suffix).
*/
if (filter->basename) {
@ -77,8 +77,8 @@ static int format_fname(
return -ENOMEM;
}
if (FLAGS_SET(flags, PICK_ARCHITECTURE) && filter->architecture >= 0) {
const char *as = ASSERT_PTR(architecture_to_string(filter->architecture));
if (FLAGS_SET(flags, PICK_ABI) && filter->abi >= 0) {
const char *as = ASSERT_PTR(abi_to_string(filter->abi));
if (isempty(fn)) {
r = free_and_strdup(&fn, as);
if (r < 0)
@ -174,7 +174,7 @@ static int pin_choice(
_cleanup_(pick_result_done) PickResult result = {
.fd = TAKE_FD(inode_fd),
.st = st,
.architecture = filter->architecture,
.abi = filter->abi,
.tries_left = tries_left,
.tries_done = tries_done,
};
@ -251,21 +251,27 @@ static int make_choice(
PickFlags flags,
PickResult *ret) {
static const Architecture local_architectures[] = {
static const Abi local_abis[] = {
/* In order of preference */
native_architecture(),
#ifdef ARCHITECTURE_SECONDARY
ARCHITECTURE_SECONDARY,
native_abi(),
#ifdef ABI_SECONDARY
ABI_SECONDARY,
#endif
_ARCHITECTURE_INVALID, /* accept any arch, as last resort */
#ifdef ABI_TERTIARY
ABI_TERTIARY,
#endif
#ifdef ABI_QUATERNARY
ABI_QUATERNARY,
#endif
_ABI_INVALID, /* accept any arch, as last resort */
};
_cleanup_free_ DirectoryEntries *de = NULL;
_cleanup_free_ char *best_version = NULL, *best_filename = NULL, *p = NULL, *j = NULL;
_cleanup_close_ int dir_fd = -EBADF, object_fd = -EBADF, inode_fd = TAKE_FD(_inode_fd);
const Architecture *architectures;
const Abi *abis;
unsigned best_tries_left = UINT_MAX, best_tries_done = UINT_MAX;
size_t n_architectures, best_architecture_index = SIZE_MAX;
size_t n_abis, best_abi_index = SIZE_MAX;
int r;
assert(toplevel_fd >= 0 || toplevel_fd == AT_FDCWD);
@ -322,18 +328,18 @@ static int make_choice(
if (r < 0)
return log_debug_errno(r, "Failed to read directory '%s': %m", prefix_roota(toplevel_path, inode_path));
if (filter->architecture < 0) {
architectures = local_architectures;
n_architectures = ELEMENTSOF(local_architectures);
if (filter->abi < 0) {
abis = local_abis;
n_abis = ELEMENTSOF(local_abis);
} else {
architectures = &filter->architecture;
n_architectures = 1;
abis = &filter->abi;
n_abis = 1;
}
FOREACH_ARRAY(entry, de->entries, de->n_entries) {
unsigned found_tries_done = UINT_MAX, found_tries_left = UINT_MAX;
_cleanup_free_ char *dname = NULL;
size_t found_architecture_index = SIZE_MAX;
size_t found_abi_index = SIZE_MAX;
const char *e;
dname = strdup((*entry)->d_name);
@ -371,24 +377,24 @@ static int make_choice(
}
}
if (FLAGS_SET(flags, PICK_ARCHITECTURE)) {
if (FLAGS_SET(flags, PICK_ABI)) {
char *underscore = strrchr(e, '_');
Architecture a;
Abi a;
a = underscore ? architecture_from_string(underscore + 1) : _ARCHITECTURE_INVALID;
a = underscore ? abi_from_string(underscore + 1) : _ABI_INVALID;
for (size_t i = 0; i < n_architectures; i++)
if (architectures[i] == a) {
found_architecture_index = i;
for (size_t i = 0; i < n_abis; i++)
if (abis[i] == a) {
found_abi_index = i;
break;
}
if (found_architecture_index == SIZE_MAX) { /* No matching arch found */
log_debug("Found entry with architecture '%s' which is not what we are looking for, ignoring entry.", a < 0 ? "any" : architecture_to_string(a));
if (found_abi_index == SIZE_MAX) { /* No matching arch found */
log_debug("Found entry with abi '%s' which is not what we are looking for, ignoring entry.", a < 0 ? "any" : abi_to_string(a));
continue;
}
/* Chop off architecture from string */
/* Chop off abi from string */
if (underscore)
*underscore = 0;
}
@ -414,11 +420,11 @@ static int make_choice(
if (d == 0)
d = strverscmp_improved(e, best_version);
/* Third, prefer native architectures over secondary architectures */
/* Third, prefer native abis over secondary abis */
if (d == 0 &&
FLAGS_SET(flags, PICK_ARCHITECTURE) &&
found_architecture_index != SIZE_MAX && best_architecture_index != SIZE_MAX)
d = -CMP(found_architecture_index, best_architecture_index);
FLAGS_SET(flags, PICK_ABI) &&
found_abi_index != SIZE_MAX && best_abi_index != SIZE_MAX)
d = -CMP(found_abi_index, best_abi_index);
/* Fourth, prefer entries with more tries left */
if (FLAGS_SET(flags, PICK_TRIES)) {
@ -448,7 +454,7 @@ static int make_choice(
if (r < 0)
return r;
best_architecture_index = found_architecture_index;
best_abi_index = found_abi_index;
best_tries_left = found_tries_left;
best_tries_done = found_tries_done;
}
@ -477,7 +483,7 @@ static int make_choice(
.type_mask = filter->type_mask,
.basename = filter->basename,
.version = empty_to_null(best_version),
.architecture = best_architecture_index != SIZE_MAX ? architectures[best_architecture_index] : _ARCHITECTURE_INVALID,
.abi = best_abi_index != SIZE_MAX ? abis[best_abi_index] : _ABI_INVALID,
.suffix = filter->suffix,
},
flags,
@ -614,7 +620,7 @@ int path_pick(
.type_mask = filter_type_mask,
.basename = filter_bname,
.version = filter->version,
.architecture = filter->architecture,
.abi = filter->abi,
.suffix = filter_suffix_strv ?: STRV_MAKE(filter_suffix),
},
flags,
@ -683,17 +689,17 @@ int path_pick_update_warn(
const PickFilter pick_filter_image_raw = {
.type_mask = (UINT32_C(1) << DT_REG) | (UINT32_C(1) << DT_BLK),
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.suffix = STRV_MAKE(".raw"),
};
const PickFilter pick_filter_image_dir = {
.type_mask = UINT32_C(1) << DT_DIR,
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
};
const PickFilter pick_filter_image_any = {
.type_mask = (UINT32_C(1) << DT_REG) | (UINT32_C(1) << DT_BLK) | (UINT32_C(1) << DT_DIR),
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.suffix = STRV_MAKE(".raw", ""),
};

View File

@ -6,16 +6,16 @@
#include "architecture.h"
typedef enum PickFlags {
PICK_ARCHITECTURE = 1 << 0, /* Look for an architecture suffix */
PICK_TRIES = 1 << 1, /* Look for tries left/tries done counters */
PICK_RESOLVE = 1 << 2, /* Return the fully resolved (chased) path, rather than the path to the entry */
PICK_ABI = 1 << 0, /* Look for an abi suffix */
PICK_TRIES = 1 << 1, /* Look for tries left/tries done counters */
PICK_RESOLVE = 1 << 2, /* Return the fully resolved (chased) path, rather than the path to the entry */
} PickFlags;
typedef struct PickFilter {
uint32_t type_mask; /* A mask of 1U << DT_REG, 1U << DT_DIR, … */
const char *basename; /* Can be overridden by search pattern */
const char *version;
Architecture architecture;
Abi abi;
char * const *suffix; /* Can be overridden by search pattern */
} PickFilter;
@ -24,7 +24,7 @@ typedef struct PickResult {
int fd; /* O_PATH */
struct stat st;
char *version;
Architecture architecture;
Abi abi;
unsigned tries_left;
unsigned tries_done;
} PickResult;
@ -33,7 +33,7 @@ typedef struct PickResult {
(const PickResult) { \
.fd = -EBADF, \
.st.st_mode = MODE_INVALID, \
.architecture = _ARCHITECTURE_INVALID, \
.abi = _ABI_INVALID, \
.tries_left = UINT_MAX, \
.tries_done = UINT_MAX, \
}

View File

@ -26,9 +26,12 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_ROOT_ALPHA SD_ID128_MAKE(65,23,f8,ae,3e,b1,4e,2a,a0,5a,18,b6,95,ae,65,6f)
#define SD_GPT_ROOT_ARC SD_ID128_MAKE(d2,7f,46,ed,29,19,4c,b8,bd,25,95,31,f3,c1,65,34)
#define SD_GPT_ROOT_ARM SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3)
#define SD_GPT_ROOT_ARMEL SD_ID128_MAKE(60,cc,41,29,60,ea,4c,d8,a5,02,d7,a0,1b,67,31,b1)
#define SD_GPT_ROOT_ARMHF SD_ID128_MAKE(86,f3,e6,77,80,fe,4f,9e,b4,66,0d,2d,56,3d,4e,5e)
#define SD_GPT_ROOT_ARM64 SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae)
#define SD_GPT_ROOT_IA64 SD_ID128_MAKE(99,3d,8d,3d,f8,0e,42,25,85,5a,9d,af,8e,d7,ea,97)
#define SD_GPT_ROOT_LOONGARCH64 SD_ID128_MAKE(77,05,58,00,79,2c,4f,94,b3,9a,98,c9,1b,76,2b,b6)
#define SD_GPT_ROOT_M68K SD_ID128_MAKE(0c,f1,91,c8,3b,54,43,3a,b7,15,68,c6,fa,40,86,de)
#define SD_GPT_ROOT_MIPS SD_ID128_MAKE(e9,43,45,44,6e,2c,47,cc,ba,e2,12,d6,de,af,b4,4c)
#define SD_GPT_ROOT_MIPS64 SD_ID128_MAKE(d1,13,af,76,80,ef,41,b4,bd,b6,0c,ff,4d,3d,4a,25)
#define SD_GPT_ROOT_MIPS_LE SD_ID128_MAKE(37,c5,8c,8a,d9,13,41,56,a2,5f,48,b1,b6,4e,07,f0)
@ -41,15 +44,21 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_ROOT_RISCV64 SD_ID128_MAKE(72,ec,70,a6,cf,74,40,e6,bd,49,4b,da,08,e8,f2,24)
#define SD_GPT_ROOT_S390 SD_ID128_MAKE(08,a7,ac,ea,62,4c,4a,20,91,e8,6e,0f,a6,7d,23,f9)
#define SD_GPT_ROOT_S390X SD_ID128_MAKE(5e,ea,d9,a9,fe,09,4a,1e,a1,d7,52,0d,00,53,13,06)
#define SD_GPT_ROOT_SH SD_ID128_MAKE(7b,8f,86,b1,39,7a,4e,1c,9e,b0,85,09,83,ba,ed,c4)
#define SD_GPT_ROOT_SPARC64 SD_ID128_MAKE(f7,b4,d1,67,1e,51,42,a9,81,51,ec,96,c2,e9,94,78)
#define SD_GPT_ROOT_TILEGX SD_ID128_MAKE(c5,0c,dd,70,38,62,4c,c3,90,e1,80,9a,8c,93,ee,2c)
#define SD_GPT_ROOT_X32 SD_ID128_MAKE(63,59,52,25,06,a8,43,f5,a6,7a,ca,4a,57,f9,75,5c)
#define SD_GPT_ROOT_X86 SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a)
#define SD_GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
#define SD_GPT_USR_ALPHA SD_ID128_MAKE(e1,8c,f0,8c,33,ec,4c,0d,82,46,c6,c6,fb,3d,a0,24)
#define SD_GPT_USR_ARC SD_ID128_MAKE(79,78,a6,83,63,16,49,22,bb,ee,38,bf,f5,a2,fe,cc)
#define SD_GPT_USR_ARM SD_ID128_MAKE(7d,03,59,a3,02,b3,4f,0a,86,5c,65,44,03,e7,06,25)
#define SD_GPT_USR_ARMHF SD_ID128_MAKE(33,f1,c8,10,41,8b,4f,68,ab,dd,72,32,ed,97,16,a9)
#define SD_GPT_USR_ARMEL SD_ID128_MAKE(9f,c0,a0,1b,c5,8a,40,d3,9a,4b,7a,23,aa,0b,5d,b7)
#define SD_GPT_USR_ARM64 SD_ID128_MAKE(b0,e0,10,50,ee,5f,43,90,94,9a,91,01,b1,71,04,e9)
#define SD_GPT_USR_IA64 SD_ID128_MAKE(43,01,d2,a6,4e,3b,4b,2a,bb,94,9e,0b,2c,42,25,ea)
#define SD_GPT_USR_LOONGARCH64 SD_ID128_MAKE(e6,11,c7,02,57,5c,4c,be,9a,46,43,4f,a0,bf,7e,3f)
#define SD_GPT_USR_M68K SD_ID128_MAKE(a6,39,b8,10,a0,2d,44,bc,b5,79,d2,3e,7b,ff,de,de)
#define SD_GPT_USR_MIPS SD_ID128_MAKE(77,3b,2a,bc,2a,99,43,98,8b,f5,03,ba,ac,40,d0,2b)
#define SD_GPT_USR_MIPS64 SD_ID128_MAKE(57,e1,39,58,73,31,43,65,8e,6e,35,ee,ee,17,c6,1b)
#define SD_GPT_USR_MIPS_LE SD_ID128_MAKE(0f,48,68,e9,99,52,47,06,97,9f,3e,d3,a4,73,e9,47)
@ -62,7 +71,10 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_USR_RISCV64 SD_ID128_MAKE(be,ae,c3,4b,84,42,43,9b,a4,0b,98,43,81,ed,09,7d)
#define SD_GPT_USR_S390 SD_ID128_MAKE(cd,0f,86,9b,d0,fb,4c,a0,b1,41,9e,a8,7c,c7,8d,66)
#define SD_GPT_USR_S390X SD_ID128_MAKE(8a,4f,57,70,50,aa,4e,d3,87,4a,99,b7,10,db,6f,ea)
#define SD_GPT_USR_SH SD_ID128_MAKE(0b,6d,8f,08,15,48,41,83,a6,fa,22,fe,95,bc,54,22)
#define SD_GPT_USR_SPARC64 SD_ID128_MAKE(db,8c,e3,99,78,7c,46,0a,80,e3,69,10,4c,1c,e3,75)
#define SD_GPT_USR_TILEGX SD_ID128_MAKE(55,49,70,29,c7,c1,44,cc,aa,39,81,5e,d1,55,86,30)
#define SD_GPT_USR_X32 SD_ID128_MAKE(89,2c,7c,79,6d,60,4d,69,9a,c4,45,66,e8,b5,c8,78)
#define SD_GPT_USR_X86 SD_ID128_MAKE(75,25,0d,76,8c,c6,45,8e,bd,66,bd,47,cc,81,a8,12)
#define SD_GPT_USR_X86_64 SD_ID128_MAKE(84,84,68,0c,95,21,48,c6,9c,11,b0,72,06,56,f6,9e)
@ -71,9 +83,12 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_ROOT_ALPHA_VERITY SD_ID128_MAKE(fc,56,d9,e9,e6,e5,4c,06,be,32,e7,44,07,ce,09,a5)
#define SD_GPT_ROOT_ARC_VERITY SD_ID128_MAKE(24,b2,d9,75,0f,97,45,21,af,a1,cd,53,1e,42,1b,8d)
#define SD_GPT_ROOT_ARM_VERITY SD_ID128_MAKE(73,86,cd,f2,20,3c,47,a9,a4,98,f2,ec,ce,45,a2,d6)
#define SD_GPT_ROOT_ARMEL_VERITY SD_ID128_MAKE(77,1a,d3,e9,a3,f0,49,07,b1,e1,05,d8,93,7a,7e,42)
#define SD_GPT_ROOT_ARMHF_VERITY SD_ID128_MAKE(6a,af,1f,da,f0,e7,49,d9,80,17,52,5a,66,34,3b,e3)
#define SD_GPT_ROOT_ARM64_VERITY SD_ID128_MAKE(df,33,00,ce,d6,9f,4c,92,97,8c,9b,fb,0f,38,d8,20)
#define SD_GPT_ROOT_IA64_VERITY SD_ID128_MAKE(86,ed,10,d5,b6,07,45,bb,89,57,d3,50,f2,3d,05,71)
#define SD_GPT_ROOT_LOONGARCH64_VERITY SD_ID128_MAKE(f3,39,3b,22,e9,af,46,13,a9,48,9d,3b,fb,d0,c5,35)
#define SD_GPT_ROOT_M68K_VERITY SD_ID128_MAKE(84,3e,63,a4,c1,ff,47,6e,a8,a4,1b,72,e3,99,47,5f)
#define SD_GPT_ROOT_MIPS_VERITY SD_ID128_MAKE(7a,43,07,99,f7,11,4c,7e,8e,5b,1d,68,5b,d4,86,07)
#define SD_GPT_ROOT_MIPS64_VERITY SD_ID128_MAKE(57,95,36,f8,6a,33,40,55,a9,5a,df,2d,5e,2c,42,a8)
#define SD_GPT_ROOT_MIPS_LE_VERITY SD_ID128_MAKE(d7,d1,50,d2,2a,04,4a,33,8f,12,16,65,12,05,ff,7b)
@ -86,15 +101,21 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_ROOT_RISCV64_VERITY SD_ID128_MAKE(b6,ed,55,82,44,0b,42,09,b8,da,5f,f7,c4,19,ea,3d)
#define SD_GPT_ROOT_S390_VERITY SD_ID128_MAKE(7a,c6,3b,47,b2,5c,46,3b,8d,f8,b4,a9,4e,6c,90,e1)
#define SD_GPT_ROOT_S390X_VERITY SD_ID128_MAKE(b3,25,bf,be,c7,be,4a,b8,83,57,13,9e,65,2d,2f,6b)
#define SD_GPT_ROOT_SH_VERITY SD_ID128_MAKE(4a,6c,2f,25,be,67,45,c5,95,ac,25,54,24,f9,4f,89)
#define SD_GPT_ROOT_SPARC64_VERITY SD_ID128_MAKE(4a,42,d3,da,9a,55,49,73,be,ff,17,34,96,de,e7,6f)
#define SD_GPT_ROOT_TILEGX_VERITY SD_ID128_MAKE(96,60,61,ec,28,e4,4b,2e,b4,a5,1f,0a,82,5a,1d,84)
#define SD_GPT_ROOT_X32_VERITY SD_ID128_MAKE(f3,ca,c7,6c,ae,97,49,7e,a9,8e,4d,be,38,64,b8,cd)
#define SD_GPT_ROOT_X86_64_VERITY SD_ID128_MAKE(2c,73,57,ed,eb,d2,46,d9,ae,c1,23,d4,37,ec,2b,f5)
#define SD_GPT_ROOT_X86_VERITY SD_ID128_MAKE(d1,3c,5d,3b,b5,d1,42,2a,b2,9f,94,54,fd,c8,9d,76)
#define SD_GPT_USR_ALPHA_VERITY SD_ID128_MAKE(8c,ce,0d,25,c0,d0,4a,44,bd,87,46,33,1b,f1,df,67)
#define SD_GPT_USR_ARC_VERITY SD_ID128_MAKE(fc,a0,59,8c,d8,80,45,91,8c,16,4e,da,05,c7,34,7c)
#define SD_GPT_USR_ARM_VERITY SD_ID128_MAKE(c2,15,d7,51,7b,cd,46,49,be,90,66,27,49,0a,4c,05)
#define SD_GPT_USR_ARMHF_VERITY SD_ID128_MAKE(bc,18,e0,b0,c0,98,47,40,8d,4c,4a,99,02,73,85,b1)
#define SD_GPT_USR_ARMEL_VERITY SD_ID128_MAKE(2f,54,bb,1b,5d,b1,48,88,95,04,5f,86,24,be,4d,3a)
#define SD_GPT_USR_ARM64_VERITY SD_ID128_MAKE(6e,11,a4,e7,fb,ca,4d,ed,b9,e9,e1,a5,12,bb,66,4e)
#define SD_GPT_USR_IA64_VERITY SD_ID128_MAKE(6a,49,1e,03,3b,e7,45,45,8e,38,83,32,0e,0e,a8,80)
#define SD_GPT_USR_LOONGARCH64_VERITY SD_ID128_MAKE(f4,6b,2c,26,59,ae,48,f0,91,06,c5,0e,d4,7f,67,3d)
#define SD_GPT_USR_M68K_VERITY SD_ID128_MAKE(26,7d,a0,76,7f,71,44,5b,96,1f,f9,7b,81,7d,fd,11)
#define SD_GPT_USR_MIPS_VERITY SD_ID128_MAKE(6e,5a,1b,c8,d2,23,49,b7,bc,a8,37,a5,fc,ce,b9,96)
#define SD_GPT_USR_MIPS64_VERITY SD_ID128_MAKE(81,cf,9d,90,74,58,4d,f4,8d,cf,c8,a3,a4,04,f0,9b)
#define SD_GPT_USR_MIPS_LE_VERITY SD_ID128_MAKE(46,b9,8d,8d,b5,5c,4e,8f,aa,b3,37,fc,a7,f8,07,52)
@ -107,7 +128,10 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_USR_RISCV64_VERITY SD_ID128_MAKE(8f,10,56,be,9b,05,47,c4,81,d6,be,53,12,8e,5b,54)
#define SD_GPT_USR_S390_VERITY SD_ID128_MAKE(b6,63,c6,18,e7,bc,4d,6d,90,aa,11,b7,56,bb,17,97)
#define SD_GPT_USR_S390X_VERITY SD_ID128_MAKE(31,74,1c,c4,1a,2a,41,11,a5,81,e0,0b,44,7d,2d,06)
#define SD_GPT_USR_SH_VERITY SD_ID128_MAKE(7d,d6,26,a2,f8,a9,4e,38,b8,aa,8c,ed,fe,f0,f0,ee)
#define SD_GPT_USR_SPARC64_VERITY SD_ID128_MAKE(c9,4c,dd,d2,69,4d,4c,e1,bf,7b,8b,6f,29,ba,fe,b1)
#define SD_GPT_USR_TILEGX_VERITY SD_ID128_MAKE(2f,b4,bf,56,07,fa,42,da,81,32,6b,13,9f,20,26,ae)
#define SD_GPT_USR_X32_VERITY SD_ID128_MAKE(46,bf,87,4f,d8,0c,41,41,81,4e,e1,48,2a,88,16,36)
#define SD_GPT_USR_X86_64_VERITY SD_ID128_MAKE(77,ff,5f,63,e7,b6,46,33,ac,f4,15,65,b8,64,c0,e6)
#define SD_GPT_USR_X86_VERITY SD_ID128_MAKE(8f,46,1b,0d,14,ee,4e,81,9a,a9,04,9b,6f,b9,7a,bd)
@ -115,9 +139,12 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_ROOT_ALPHA_VERITY_SIG SD_ID128_MAKE(d4,64,95,b7,a0,53,41,4f,80,f7,70,0c,99,92,1e,f8)
#define SD_GPT_ROOT_ARC_VERITY_SIG SD_ID128_MAKE(14,3a,70,ba,cb,d3,4f,06,91,9f,6c,05,68,3a,78,bc)
#define SD_GPT_ROOT_ARM_VERITY_SIG SD_ID128_MAKE(42,b0,45,5f,eb,11,49,1d,98,d3,56,14,5b,a9,d0,37)
#define SD_GPT_ROOT_ARMEL_VERITY_SIG SD_ID128_MAKE(9a,74,20,89,40,fa,41,12,b2,7e,1c,ce,25,ff,d2,5e)
#define SD_GPT_ROOT_ARMHF_VERITY_SIG SD_ID128_MAKE(52,ec,e4,e6,04,9f,43,98,b7,bb,d9,cd,9d,72,cc,3b)
#define SD_GPT_ROOT_ARM64_VERITY_SIG SD_ID128_MAKE(6d,b6,9d,e6,29,f4,47,58,a7,a5,96,21,90,f0,0c,e3)
#define SD_GPT_ROOT_IA64_VERITY_SIG SD_ID128_MAKE(e9,8b,36,ee,32,ba,48,82,9b,12,0c,e1,46,55,f4,6a)
#define SD_GPT_ROOT_LOONGARCH64_VERITY_SIG SD_ID128_MAKE(5a,fb,67,eb,ec,c8,4f,85,ae,8e,ac,1e,7c,50,e7,d0)
#define SD_GPT_ROOT_M68K_VERITY_SIG SD_ID128_MAKE(d6,e4,b0,ae,10,f8,46,d9,9f,36,d8,fd,1a,14,b5,1f)
#define SD_GPT_ROOT_MIPS_VERITY_SIG SD_ID128_MAKE(bb,a2,10,a2,9c,5d,45,ee,9e,87,ff,2c,cb,d0,02,d0)
#define SD_GPT_ROOT_MIPS64_VERITY_SIG SD_ID128_MAKE(43,ce,94,d4,0f,3d,49,99,82,50,b9,de,af,d9,8e,6e)
#define SD_GPT_ROOT_MIPS_LE_VERITY_SIG SD_ID128_MAKE(c9,19,cc,1f,44,56,4e,ff,91,8c,f7,5e,94,52,5c,a5)
@ -130,15 +157,21 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_ROOT_RISCV64_VERITY_SIG SD_ID128_MAKE(ef,e0,f0,87,ea,8d,44,69,82,1a,4c,2a,96,a8,38,6a)
#define SD_GPT_ROOT_S390_VERITY_SIG SD_ID128_MAKE(34,82,38,8e,42,54,43,5a,a2,41,76,6a,06,5f,99,60)
#define SD_GPT_ROOT_S390X_VERITY_SIG SD_ID128_MAKE(c8,01,87,a5,73,a3,49,1a,90,1a,01,7c,3f,a9,53,e9)
#define SD_GPT_ROOT_SH_VERITY_SIG SD_ID128_MAKE(c6,28,47,16,c0,b3,4c,93,b3,49,a3,86,d6,bd,ee,62)
#define SD_GPT_ROOT_SPARC64_VERITY_SIG SD_ID128_MAKE(79,5c,f8,0b,dc,bf,49,52,9c,7b,4f,d4,72,9d,fd,97)
#define SD_GPT_ROOT_TILEGX_VERITY_SIG SD_ID128_MAKE(b3,67,14,39,97,b0,4a,53,90,f7,2d,5a,8f,3a,d4,7b)
#define SD_GPT_ROOT_X32_VERITY_SIG SD_ID128_MAKE(8d,26,6d,5f,d2,4d,40,70,9c,f6,38,f6,14,73,76,2c)
#define SD_GPT_ROOT_X86_64_VERITY_SIG SD_ID128_MAKE(41,09,2b,05,9f,c8,45,23,99,4f,2d,ef,04,08,b1,76)
#define SD_GPT_ROOT_X86_VERITY_SIG SD_ID128_MAKE(59,96,fc,05,10,9c,48,de,80,8b,23,fa,08,30,b6,76)
#define SD_GPT_USR_ALPHA_VERITY_SIG SD_ID128_MAKE(5c,6e,1c,76,07,6a,45,7a,a0,fe,f3,b4,cd,21,ce,6e)
#define SD_GPT_USR_ARC_VERITY_SIG SD_ID128_MAKE(94,f9,a9,a1,99,71,42,7a,a4,00,50,cb,29,7f,0f,35)
#define SD_GPT_USR_ARM_VERITY_SIG SD_ID128_MAKE(d7,ff,81,2f,37,d1,49,02,a8,10,d7,6b,a5,7b,97,5a)
#define SD_GPT_USR_ARMHF_VERITY_SIG SD_ID128_MAKE(13,ac,23,2f,bf,21,4b,b0,b3,45,ed,c4,94,d7,d1,4b)
#define SD_GPT_USR_ARMEL_VERITY_SIG SD_ID128_MAKE(b3,06,63,5f,fd,da,4d,5c,8a,38,ac,61,fe,7a,0e,68)
#define SD_GPT_USR_ARM64_VERITY_SIG SD_ID128_MAKE(c2,3c,e4,ff,44,bd,4b,00,b2,d4,b4,1b,34,19,e0,2a)
#define SD_GPT_USR_IA64_VERITY_SIG SD_ID128_MAKE(8d,e5,8b,c2,2a,43,46,0d,b1,4e,a7,6e,4a,17,b4,7f)
#define SD_GPT_USR_LOONGARCH64_VERITY_SIG SD_ID128_MAKE(b0,24,f3,15,d3,30,44,4c,84,61,44,bb,de,52,4e,99)
#define SD_GPT_USR_M68K_VERITY_SIG SD_ID128_MAKE(3b,93,56,77,dd,33,4d,7d,8b,30,e6,02,e3,16,49,9e)
#define SD_GPT_USR_MIPS_VERITY_SIG SD_ID128_MAKE(97,ae,15,8d,f2,16,49,7b,80,57,f7,f9,05,77,0f,54)
#define SD_GPT_USR_MIPS64_VERITY_SIG SD_ID128_MAKE(05,81,6c,e2,dd,40,4a,c6,a6,1d,37,d3,2d,c1,ba,7d)
#define SD_GPT_USR_MIPS_LE_VERITY_SIG SD_ID128_MAKE(3e,23,ca,0b,a4,bc,4b,4e,80,87,5a,b6,a2,6a,a8,a9)
@ -151,7 +184,10 @@ _SD_BEGIN_DECLARATIONS;
#define SD_GPT_USR_RISCV64_VERITY_SIG SD_ID128_MAKE(d2,f9,00,0a,7a,18,45,3f,b5,cd,4d,32,f7,7a,7b,32)
#define SD_GPT_USR_S390_VERITY_SIG SD_ID128_MAKE(17,44,0e,4f,a8,d0,46,7f,a4,6e,39,12,ae,6e,f2,c5)
#define SD_GPT_USR_S390X_VERITY_SIG SD_ID128_MAKE(3f,32,48,16,66,7b,46,ae,86,ee,9b,0c,0c,6c,11,b4)
#define SD_GPT_USR_SH_VERITY_SIG SD_ID128_MAKE(71,bb,ee,31,fc,3c,4b,a4,80,50,0b,75,ed,32,b4,66)
#define SD_GPT_USR_SPARC64_VERITY_SIG SD_ID128_MAKE(0b,eb,c1,10,9e,89,4e,17,9e,52,6f,39,73,88,9b,2b)
#define SD_GPT_USR_TILEGX_VERITY_SIG SD_ID128_MAKE(4e,de,75,e2,6c,cc,4c,c8,b9,c7,70,33,4b,08,75,10)
#define SD_GPT_USR_X32_VERITY_SIG SD_ID128_MAKE(c4,75,3c,76,e5,1c,4b,bc,b1,50,3e,db,af,b9,03,c3)
#define SD_GPT_USR_X86_64_VERITY_SIG SD_ID128_MAKE(e7,bb,33,fb,06,cf,4e,81,82,73,e5,43,b4,13,e2,e2)
#define SD_GPT_USR_X86_VERITY_SIG SD_ID128_MAKE(97,4a,71,c0,de,41,43,c3,be,5d,5c,5c,cd,1a,d2,c0)
@ -193,24 +229,72 @@ _SD_BEGIN_DECLARATIONS;
#elif defined(__aarch64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ARM64
# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_ARM
# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_ARMHF
# define SD_GPT_ROOT_TERTIARY SD_GPT_ROOT_ARMEL
# define SD_GPT_ROOT_QUATERNARY SD_GPT_ROOT_ARM
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ARM64_VERITY
# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_ARM_VERITY
# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_ARMHF_VERITY
# define SD_GPT_ROOT_TERTIARY_VERITY SD_GPT_ROOT_ARMEL_VERITY
# define SD_GPT_ROOT_QUATERNARY_VERITY SD_GPT_ROOT_ARM_VERITY
# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ARM64_VERITY_SIG
# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_ARM_VERITY_SIG
# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_ARMHF_VERITY_SIG
# define SD_GPT_ROOT_TERTIARY_VERITY_SIG SD_GPT_ROOT_ARMEL_VERITY_SIG
# define SD_GPT_ROOT_QUATERNARY_VERITY_SIG SD_GPT_ROOT_ARM_VERITY_SIG
# define SD_GPT_USR_NATIVE SD_GPT_USR_ARM64
# define SD_GPT_USR_SECONDARY SD_GPT_USR_ARM
# define SD_GPT_USR_SECONDARY SD_GPT_USR_ARMHF
# define SD_GPT_USR_TERTIARY SD_GPT_USR_ARMEL
# define SD_GPT_USR_QUATERNARY SD_GPT_USR_ARM
# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ARM64_VERITY
# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_ARM_VERITY
# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_ARMHF_VERITY
# define SD_GPT_USR_TERTIARY_VERITY SD_GPT_USR_ARMEL_VERITY
# define SD_GPT_USR_QUATERNARY_VERITY SD_GPT_USR_ARM_VERITY
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ARM64_VERITY_SIG
# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_ARM_VERITY_SIG
# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_ARMHF_VERITY_SIG
# define SD_GPT_USR_TERTIARY_VERITY_SIG SD_GPT_USR_ARMEL_VERITY_SIG
# define SD_GPT_USR_QUATERNARY_VERITY_SIG SD_GPT_USR_ARM_VERITY_SIG
#elif defined(__arm__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ARM
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ARM_VERITY
# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ARM_VERITY_SIG
# define SD_GPT_USR_NATIVE SD_GPT_USR_ARM
# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ARM_VERITY
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ARM_VERITY_SIG
# if defined(__ARM_EABI__)
# if defined(__ARM_PCS_VFP)
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ARMHF
# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_ARMEL
# define SD_GPT_ROOT_TERTIARY SD_GPT_ROOT_ARM
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ARMHF_VERITY
# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_ARMEL_VERITY
# define SD_GPT_ROOT_TERTIARY_VERITY SD_GPT_ROOT_ARM_VERITY
# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ARMHF_VERITY_SIG
# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_ARMEL_VERITY_SIG
# define SD_GPT_ROOT_TERTIARY_VERITY_SIG SD_GPT_ROOT_ARM_VERITY_SIG
# define SD_GPT_USR_NATIVE SD_GPT_USR_ARMHF
# define SD_GPT_USR_SECONDARY SD_GPT_USR_ARMEL
# define SD_GPT_USR_TERTIARY SD_GPT_USR_ARM
# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ARMHF_VERITY
# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_ARMEL_VERITY
# define SD_GPT_USR_TERTIARY_VERITY SD_GPT_USR_ARM_VERITY
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ARMHF_VERITY_SIG
# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_ARMEL_VERITY_SIG
# define SD_GPT_USR_TERTIARY_VERITY_SIG SD_GPT_USR_ARM_VERITY_SIG
# else
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ARMEL
# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_ARM
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ARMEL_VERITY
# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_ARM_VERITY
# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ARMEL_VERITY_SIG
# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_ARM_VERITY_SIG
# define SD_GPT_USR_NATIVE SD_GPT_USR_ARMEL
# define SD_GPT_USR_SECONDARY SD_GPT_USR_ARM
# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ARMEL_VERITY
# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_ARM_VERITY
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ARMEL_VERITY_SIG
# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_ARM_VERITY_SIG
# endif
# else
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ARM
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ARM_VERITY
# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ARM_VERITY_SIG
# define SD_GPT_USR_NATIVE SD_GPT_USR_ARM
# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ARM_VERITY
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ARM_VERITY_SIG
# endif
#elif defined(__ia64__)
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_IA64
@ -328,18 +412,39 @@ _SD_BEGIN_DECLARATIONS;
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_TILEGX_VERITY_SIG
#elif defined(__x86_64__)
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_X86_64
# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_X86
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_X86_64_VERITY
# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_X86_VERITY
# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_X86_64_VERITY_SIG
# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_X86_VERITY_SIG
# define SD_GPT_USR_NATIVE SD_GPT_USR_X86_64
# define SD_GPT_USR_SECONDARY SD_GPT_USR_X86
# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_X86_64_VERITY
# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_X86_VERITY
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_X86_64_VERITY_SIG
# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_X86_VERITY_SIG
# if defined(__ILP32__)
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_X32
# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_X86
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_X32_VERITY
# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_X86_VERITY
# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_X32_VERITY_SIG
# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_X86_VERITY_SIG
# define SD_GPT_USR_NATIVE SD_GPT_USR_X32
# define SD_GPT_USR_SECONDARY SD_GPT_USR_X86
# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_X32_VERITY
# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_X86_VERITY
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_X32_VERITY_SIG
# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_X86_VERITY_SIG
# else
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_X86_64
# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_X32
# define SD_GPT_ROOT_TERTIARY SD_GPT_ROOT_X86
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_X86_64_VERITY
# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_X32_VERITY
# define SD_GPT_ROOT_TERTIARY_VERITY SD_GPT_ROOT_X86_VERITY
# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_X86_64_VERITY_SIG
# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_X32_VERITY_SIG
# define SD_GPT_ROOT_TERTIARY_VERITY_SIG SD_GPT_ROOT_X86_VERITY_SIG
# define SD_GPT_USR_NATIVE SD_GPT_USR_X86_64
# define SD_GPT_USR_SECONDARY SD_GPT_USR_X32
# define SD_GPT_USR_TERTIARY SD_GPT_USR_X86
# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_X86_64_VERITY
# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_X32_VERITY
# define SD_GPT_USR_TERTIARY_VERITY SD_GPT_USR_X86_VERITY
# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_X86_64_VERITY_SIG
# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_X32_VERITY_SIG
# define SD_GPT_USR_TERTIARY_VERITY_SIG SD_GPT_USR_X86_VERITY_SIG
# endif
#elif defined(__i386__)
# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_X86
# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_X86_VERITY

View File

@ -10,6 +10,7 @@
int main(int argc, char *argv[]) {
Virtualization v;
Architecture a;
Abi abi;
const char *p;
test_setup_logging(LOG_INFO);
@ -21,6 +22,13 @@ int main(int argc, char *argv[]) {
ASSERT_EQ(architecture_from_string(architecture_to_string(0)), 0);
ASSERT_EQ(architecture_from_string(architecture_to_string(1)), 1);
ASSERT_LT(abi_from_string(""), 0);
ASSERT_LT(abi_from_string(NULL), 0);
ASSERT_LT(abi_from_string("hoge"), 0);
ASSERT_NULL(abi_to_string(-1));
ASSERT_EQ(abi_from_string(abi_to_string(0)), 0);
ASSERT_EQ(abi_from_string(abi_to_string(1)), 1);
v = detect_virtualization();
if (ERRNO_IS_NEG_PRIVILEGE(v))
return log_tests_skipped("Cannot detect virtualization");
@ -62,5 +70,35 @@ int main(int argc, char *argv[]) {
log_info("Good for inclusion in .v/ filenames: %s", n);
}
abi = preferred_abi();
ASSERT_OK(abi);
p = abi_to_string(abi);
assert_se(p);
log_info("uname abi=%s", p);
ASSERT_EQ(abi_from_string(p), abi);
abi = native_abi();
ASSERT_OK(abi);
p = abi_to_string(abi);
assert_se(p);
log_info("native architecture=%s", p);
ASSERT_EQ(abi_from_string(p), abi);
log_info("primary library abi=" LIB_ARCH_TUPLE);
for (Abi i = 0; i < _ABI_MAX; i++) {
const char *n = ASSERT_PTR(abi_to_string(i));
/* Let's validate that all ABI names we define are good for inclusion in .v/
* filename patterns which use "." and "_" as field separators in the filenames. */
assert(filename_part_is_valid(n));
assert(!strchr(n, '_'));
assert(!strchr(n, '.'));
log_info("Good for inclusion in .v/ filenames: %s", n);
}
return 0;
}

View File

@ -9,19 +9,19 @@
#include "terminal-util.h"
#include "tests.h"
TEST(gpt_types_against_architectures) {
TEST(gpt_types_against_abis) {
int r;
/* Dumps a table indicating for which architectures we know we have matching GPT partition
/* Dumps a table indicating for which abis we know we have matching GPT partition
* types. Also validates whether we can properly categorize the entries. */
FOREACH_STRING(prefix, "root-", "usr-")
for (Architecture a = 0; a < _ARCHITECTURE_MAX; a++)
for (Abi a = 0; a < _ABI_MAX; a++)
FOREACH_STRING(suffix, "", "-verity", "-verity-sig") {
_cleanup_free_ char *joined = NULL;
GptPartitionType type;
joined = strjoin(prefix, architecture_to_string(a), suffix);
joined = strjoin(prefix, abi_to_string(a), suffix);
if (!joined)
return (void) log_oom();
@ -42,7 +42,7 @@ TEST(gpt_types_against_architectures) {
if (streq(prefix, "usr-") && streq(suffix, "-verity"))
ASSERT_EQ(type.designator, PARTITION_USR_VERITY);
ASSERT_EQ(type.arch, a);
ASSERT_EQ(type.abi, a);
}
}
@ -74,35 +74,35 @@ TEST(type_alias_same) {
x = gpt_partition_type_from_uuid(t->uuid); /* search first by uuid */
ASSERT_GE(gpt_partition_type_from_string(t->name, &y), 0); /* search first by name */
ASSERT_EQ(t->arch, x.arch);
ASSERT_EQ(t->arch, y.arch);
ASSERT_EQ(t->abi, x.abi);
ASSERT_EQ(t->abi, y.abi);
ASSERT_EQ(t->designator, x.designator);
ASSERT_EQ(t->designator, y.designator);
}
}
TEST(override_architecture) {
TEST(override_abi) {
GptPartitionType x, y;
ASSERT_GE(gpt_partition_type_from_string("root-x86-64", &x), 0);
ASSERT_EQ(x.arch, ARCHITECTURE_X86_64);
ASSERT_EQ(x.abi, ABI_X86_64);
ASSERT_GE(gpt_partition_type_from_string("root-arm64", &y), 0);
ASSERT_EQ(y.arch, ARCHITECTURE_ARM64);
ASSERT_EQ(y.abi, ABI_ARM64);
x = gpt_partition_type_override_architecture(x, ARCHITECTURE_ARM64);
ASSERT_EQ(x.arch, y.arch);
x = gpt_partition_type_override_abi(x, ABI_ARM64);
ASSERT_EQ(x.abi, y.abi);
ASSERT_EQ(x.designator, y.designator);
assert_se(sd_id128_equal(x.uuid, y.uuid));
ASSERT_STREQ(x.name, y.name);
/* If the partition type does not have an architecture, nothing should change. */
/* If the partition type does not have an abi, nothing should change. */
ASSERT_GE(gpt_partition_type_from_string("esp", &x), 0);
y = x;
x = gpt_partition_type_override_architecture(x, ARCHITECTURE_ARM64);
ASSERT_EQ(x.arch, y.arch);
x = gpt_partition_type_override_abi(x, ABI_ARM64);
ASSERT_EQ(x.abi, y.abi);
ASSERT_EQ(x.designator, y.designator);
assert_se(sd_id128_equal(x.uuid, y.uuid));
ASSERT_STREQ(x.name, y.name);

View File

@ -32,7 +32,7 @@ TEST(path_pick) {
/* Let's add an entry for sparc (which is a valid arch, but almost certainly not what we test
* on). This entry should hence always be ignored */
if (native_architecture() != ARCHITECTURE_SPARC)
if (native_abi() != ABI_SPARC)
assert_se(write_string_file_at(sub_dfd, "foo_100_sparc.raw", "100 sparc", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "quux_1_s390.raw", "waldo1", WRITE_STRING_FILE_CREATE) >= 0);
@ -46,76 +46,76 @@ TEST(path_pick) {
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
PickFilter filter = {
.architecture = _ARCHITECTURE_INVALID,
.abi = _ABI_INVALID,
.suffix = STRV_MAKE(".raw"),
};
if (IN_SET(native_architecture(), ARCHITECTURE_X86, ARCHITECTURE_X86_64)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
if (IN_SET(native_abi(), ABI_X86, ABI_X86_64)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
ASSERT_STREQ(result.version, "99");
assert_se(result.architecture == ARCHITECTURE_X86);
assert_se(result.abi == ABI_X86);
assert_se(endswith(result.path, "/foo_99_x86.raw"));
pick_result_done(&result);
}
filter.architecture = ARCHITECTURE_X86_64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
filter.abi = ABI_X86_64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
ASSERT_STREQ(result.version, "55");
assert_se(result.architecture == ARCHITECTURE_X86_64);
assert_se(result.abi == ABI_X86_64);
assert_se(endswith(result.path, "/foo_55_x86-64.raw"));
pick_result_done(&result);
filter.architecture = ARCHITECTURE_IA64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
filter.abi = ABI_IA64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
ASSERT_STREQ(result.version, "5");
assert_se(result.architecture == ARCHITECTURE_IA64);
assert_se(result.abi == ABI_IA64);
assert_se(endswith(result.path, "/foo_5_ia64.raw"));
pick_result_done(&result);
filter.architecture = _ARCHITECTURE_INVALID;
filter.abi = _ABI_INVALID;
filter.version = "5";
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
ASSERT_STREQ(result.version, "5");
if (native_architecture() != ARCHITECTURE_IA64) {
assert_se(result.architecture == _ARCHITECTURE_INVALID);
if (native_abi() != ABI_IA64) {
assert_se(result.abi == _ABI_INVALID);
assert_se(endswith(result.path, "/foo_5.raw"));
}
pick_result_done(&result);
filter.architecture = ARCHITECTURE_IA64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
filter.abi = ABI_IA64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
ASSERT_STREQ(result.version, "5");
assert_se(result.architecture == ARCHITECTURE_IA64);
assert_se(result.abi == ABI_IA64);
assert_se(endswith(result.path, "/foo_5_ia64.raw"));
pick_result_done(&result);
filter.architecture = ARCHITECTURE_CRIS;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) == 0);
filter.abi = ABI_CRIS;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) == 0);
assert_se(result.st.st_mode == MODE_INVALID);
assert_se(!result.version);
assert_se(result.architecture < 0);
assert_se(result.abi < 0);
assert_se(!result.path);
assert_se(unlinkat(sub_dfd, "foo_99_x86.raw", 0) >= 0);
filter.architecture = _ARCHITECTURE_INVALID;
filter.abi = _ABI_INVALID;
filter.version = NULL;
if (IN_SET(native_architecture(), ARCHITECTURE_X86_64, ARCHITECTURE_X86)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
if (IN_SET(native_abi(), ABI_X86_64, ABI_X86)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
ASSERT_STREQ(result.version, "55");
if (native_architecture() == ARCHITECTURE_X86_64) {
assert_se(result.architecture == ARCHITECTURE_X86_64);
if (native_abi() == ABI_X86_64) {
assert_se(result.abi == ABI_X86_64);
assert_se(endswith(result.path, "/foo_55_x86-64.raw"));
} else {
assert_se(result.architecture == ARCHITECTURE_X86);
assert_se(result.abi == ABI_X86);
assert_se(endswith(result.path, "/foo_55_x86.raw"));
}
pick_result_done(&result);
@ -126,11 +126,11 @@ TEST(path_pick) {
pp = path_join(p, "foo.v/foo___.raw");
assert_se(pp);
if (IN_SET(native_architecture(), ARCHITECTURE_X86, ARCHITECTURE_X86_64)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
if (IN_SET(native_abi(), ABI_X86, ABI_X86_64)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
ASSERT_STREQ(result.version, "55");
assert_se(result.architecture == native_architecture());
assert_se(result.abi == native_abi());
assert_se(endswith(result.path, ".raw"));
assert_se(strrstr(result.path, "/foo_55_x86"));
pick_result_done(&result);
@ -142,13 +142,13 @@ TEST(path_pick) {
assert_se(pp);
filter.type_mask = UINT32_C(1) << DT_DIR;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) == -ENOTDIR);
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) == -ENOTDIR);
filter.type_mask = UINT32_C(1) << DT_REG;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(!result.version);
assert_se(result.architecture == _ARCHITECTURE_INVALID);
assert_se(result.abi == _ABI_INVALID);
assert_se(path_equal(result.path, pp));
pick_result_done(&result);
@ -156,16 +156,16 @@ TEST(path_pick) {
pp = path_join(p, "foo.v");
assert_se(pp);
filter.architecture = ARCHITECTURE_S390;
filter.abi = ABI_S390;
filter.basename = "quux";
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ABI|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
ASSERT_STREQ(result.version, "2");
assert_se(result.tries_left == 4);
assert_se(result.tries_done == 6);
assert_se(endswith(result.path, "quux_2_s390+4-6.raw"));
assert_se(result.architecture == ARCHITECTURE_S390);
assert_se(result.abi == ABI_S390);
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -18,7 +18,7 @@
static char *arg_filter_basename = NULL;
static char *arg_filter_version = NULL;
static Architecture arg_filter_architecture = _ARCHITECTURE_INVALID;
static Abi arg_filter_abi = _ABI_INVALID;
static char *arg_filter_suffix = NULL;
static uint32_t arg_filter_type_mask = 0;
static enum {
@ -31,7 +31,7 @@ static enum {
PRINT_ALL,
_PRINT_INVALID = -EINVAL,
} arg_print = _PRINT_INVALID;
static PickFlags arg_flags = PICK_ARCHITECTURE|PICK_TRIES;
static PickFlags arg_flags = PICK_ABI|PICK_TRIES;
STATIC_DESTRUCTOR_REGISTER(arg_filter_basename, freep);
STATIC_DESTRUCTOR_REGISTER(arg_filter_version, freep);
@ -128,21 +128,33 @@ static int parse_argv(int argc, char *argv[]) {
case 'A':
if (streq(optarg, "native"))
arg_filter_architecture = native_architecture();
arg_filter_abi = native_abi();
else if (streq(optarg, "secondary")) {
#ifdef ARCHITECTURE_SECONDARY
arg_filter_architecture = ARCHITECTURE_SECONDARY;
#ifdef ABI_SECONDARY
arg_filter_abi = ABI_SECONDARY;
#else
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Local architecture has no secondary architecture.");
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Local abi has no secondary abi.");
#endif
} else if (streq(optarg, "tertiary")) {
#ifdef ABI_TERTIARY
arg_filter_abi = ABI_TERTIARY;
#else
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Local abi has no tertiary abi.");
#endif
} else if (streq(optarg, "quaternary")) {
#ifdef ABI_QUATERNARY
arg_filter_abi = ABI_QUATERNARY;
#else
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Local abi has no tertiary abi.");
#endif
} else if (streq(optarg, "uname"))
arg_filter_architecture = uname_architecture();
arg_filter_abi = preferred_abi();
else if (streq(optarg, "auto"))
arg_filter_architecture = _ARCHITECTURE_INVALID;
arg_filter_abi = _ABI_INVALID;
else {
arg_filter_architecture = architecture_from_string(optarg);
if (arg_filter_architecture < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown architecture: %s", optarg);
arg_filter_abi = abi_from_string(optarg);
if (arg_filter_abi < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown abi: %s", optarg);
}
break;
@ -238,7 +250,7 @@ static int run(int argc, char *argv[]) {
&(PickFilter) {
.basename = arg_filter_basename,
.version = arg_filter_version,
.architecture = arg_filter_architecture,
.abi = arg_filter_abi,
.suffix = STRV_MAKE(arg_filter_suffix),
.type_mask = arg_filter_type_mask,
},
@ -284,10 +296,10 @@ static int run(int argc, char *argv[]) {
break;
case PRINT_ARCHITECTURE:
if (result.architecture < 0)
if (result.abi < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No architecture information discovered.");
puts(architecture_to_string(result.architecture));
puts(abi_to_string(result.abi));
break;
case PRINT_TRIES:
@ -315,7 +327,7 @@ static int run(int argc, char *argv[]) {
TABLE_FIELD, "Type",
TABLE_STRING, result.st.st_mode == MODE_INVALID ? NULL : inode_type_to_string(result.st.st_mode),
TABLE_FIELD, "Architecture",
TABLE_STRING, result.architecture < 0 ? NULL : architecture_to_string(result.architecture));
TABLE_STRING, result.abi < 0 ? NULL : abi_to_string(result.abi));
if (r < 0)
return table_log_add_error(r);