core: add new ConditionArchitecture() that checks the architecture returned by uname()'s machine field.

This commit is contained in:
Lennart Poettering
2014-02-21 02:43:14 +01:00
parent a03c5fd2d8
commit 099524d7b0
9 changed files with 509 additions and 113 deletions
+159
View File
@@ -0,0 +1,159 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <sys/utsname.h>
#include "architecture.h"
Architecture uname_architecture(void) {
/* Return a sanitized 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 do not try to distuingish CPUs not CPU features, but
* actual architectures, i.e. that have genuinely different
* code. */
static const struct {
const char *machine;
Architecture arch;
} arch_map[] = {
#if defined(__x86_64__) || defined(__i386__)
{ "x86_64", ARCHITECTURE_X86_64 },
{ "i686", ARCHITECTURE_X86 },
{ "i586", ARCHITECTURE_X86 },
{ "i486", ARCHITECTURE_X86 },
{ "i386", ARCHITECTURE_X86 },
#elif defined(__powerpc__) || defined(__powerpc64__)
{ "ppc64", ARCHITECTURE_PPC64 },
{ "ppc", ARCHITECTURE_PPC },
#elif defined(__ia64__)
{ "ia64", ARCHITECTURE_IA64 },
#elif defined(__hppa__) || defined(__hppa64__)
{ "parisc64", ARCHITECTURE_PARISC64 },
{ "parisc", ARCHITECTURE_PARISC },
#elif defined(__s390__) || defined(__s390x__)
{ "s390x", ARCHITECTURE_S390X },
{ "s390", ARCHITECTURE_S390 },
#elif defined(__sparc__) || defined(__sparc64__)
{ "sparc64", ARCHITECTURE_SPARC64 },
{ "sparc", ARCHITECTURE_SPARC },
#elif defined(__mips__) || defined(__mips64__)
{ "mips64", ARCHITECTURE_MIPS64 },
{ "mips", ARCHITECTURE_MIPS },
#elif defined(__alpha__)
{ "alpha" , ARCHITECTURE_ALPHA },
#elif defined(__arm__) || defined(__aarch64__)
{ "aarch64", ARCHITECTURE_ARM64 },
{ "aarch64_be", ARCHITECTURE_ARM64_BE },
{ "armv4l", ARCHITECTURE_ARM },
{ "armv4b", ARCHITECTURE_ARM_BE },
{ "armv4tl", ARCHITECTURE_ARM },
{ "armv4tb", ARCHITECTURE_ARM_BE },
{ "armv5tl", ARCHITECTURE_ARM },
{ "armv5tb", ARCHITECTURE_ARM_BE },
{ "armv5tel", ARCHITECTURE_ARM },
{ "armv5teb" , ARCHITECTURE_ARM_BE },
{ "armv5tejl", ARCHITECTURE_ARM },
{ "armv5tejb", ARCHITECTURE_ARM_BE },
{ "armv6l", ARCHITECTURE_ARM },
{ "armv6b", ARCHITECTURE_ARM_BE },
{ "armv7l", ARCHITECTURE_ARM },
{ "armv7b", ARCHITECTURE_ARM_BE },
{ "armv7ml", ARCHITECTURE_ARM },
{ "armv7mb", ARCHITECTURE_ARM_BE },
{ "armv4l", ARCHITECTURE_ARM },
{ "armv4b", ARCHITECTURE_ARM_BE },
{ "armv4tl", ARCHITECTURE_ARM },
{ "armv4tb", ARCHITECTURE_ARM_BE },
{ "armv5tl", ARCHITECTURE_ARM },
{ "armv5tb", ARCHITECTURE_ARM_BE },
{ "armv5tel", ARCHITECTURE_ARM },
{ "armv5teb", ARCHITECTURE_ARM_BE },
{ "armv5tejl", ARCHITECTURE_ARM },
{ "armv5tejb", ARCHITECTURE_ARM_BE },
{ "armv6l", ARCHITECTURE_ARM },
{ "armv6b", ARCHITECTURE_ARM_BE },
{ "armv7l", ARCHITECTURE_ARM },
{ "armv7b", ARCHITECTURE_ARM_BE },
{ "armv7ml", ARCHITECTURE_ARM },
{ "armv7mb", ARCHITECTURE_ARM_BE },
{ "armv8l", ARCHITECTURE_ARM },
{ "armv8b", ARCHITECTURE_ARM_BE },
#elif defined(__sh__) || defined(__sh64__)
{ "sh64", ARCHITECTURE_SH64 },
{ "sh", ARCHITECTURE_SH },
#elif defined(__m68k__)
{ "m68k", ARCHITECTURE_M68K },
#else
#error "Please register your architecture here!"
#endif
};
static Architecture cached = _ARCHITECTURE_INVALID;
struct utsname u;
unsigned i;
if (cached != _ARCHITECTURE_INVALID)
return cached;
assert_se(uname(&u) >= 0);
for (i = 0; i < ELEMENTSOF(arch_map); i++)
if (streq(arch_map[i].machine, u.machine))
return cached = arch_map[i].arch;
assert_not_reached("Couldn't identify architecture. You need to patch systemd.");
return _ARCHITECTURE_INVALID;
}
static const char *const architecture_table[_ARCHITECTURE_MAX] = {
[ARCHITECTURE_X86] = "x86",
[ARCHITECTURE_X86_64] = "x86-64",
[ARCHITECTURE_PPC] = "ppc",
[ARCHITECTURE_PPC64] = "ppc64",
[ARCHITECTURE_IA64] = "ia64",
[ARCHITECTURE_PARISC] = "parisc",
[ARCHITECTURE_PARISC64] = "parisc64",
[ARCHITECTURE_S390] = "s390",
[ARCHITECTURE_S390X] = "s390x",
[ARCHITECTURE_SPARC] = "sparc",
[ARCHITECTURE_SPARC64] = "sparc64",
[ARCHITECTURE_MIPS] = "mips",
[ARCHITECTURE_MIPS64] = "mips64",
[ARCHITECTURE_ALPHA] = "alpha",
[ARCHITECTURE_ARM] = "arm",
[ARCHITECTURE_ARM_BE] = "arm-be",
[ARCHITECTURE_ARM64] = "arm64",
[ARCHITECTURE_ARM64_BE] = "arm64-be",
[ARCHITECTURE_SH] = "sh",
[ARCHITECTURE_SH64] = "sh64",
[ARCHITECTURE_M68K] = "m68k",
};
DEFINE_STRING_TABLE_LOOKUP(architecture, Architecture);
+105
View File
@@ -0,0 +1,105 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2014 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "util.h"
typedef enum Architecture {
ARCHITECTURE_X86 = 0,
ARCHITECTURE_X86_64,
ARCHITECTURE_PPC,
ARCHITECTURE_PPC64,
ARCHITECTURE_IA64,
ARCHITECTURE_PARISC,
ARCHITECTURE_PARISC64,
ARCHITECTURE_S390,
ARCHITECTURE_S390X,
ARCHITECTURE_SPARC,
ARCHITECTURE_SPARC64,
ARCHITECTURE_MIPS,
ARCHITECTURE_MIPS64,
ARCHITECTURE_ALPHA,
ARCHITECTURE_ARM,
ARCHITECTURE_ARM_BE,
ARCHITECTURE_ARM64,
ARCHITECTURE_ARM64_BE,
ARCHITECTURE_SH,
ARCHITECTURE_SH64,
ARCHITECTURE_M68K,
_ARCHITECTURE_MAX,
_ARCHITECTURE_INVALID = -1
} Architecture;
Architecture uname_architecture(void);
#if defined(__x86_64__)
# define native_architecture() ARCHITECTURE_X86_64
#elif defined(__i386__)
# define native_architecture() ARCHITECTURE_X86
#elif defined(__powerpc64__)
# define native_architecture() ARCHITECTURE_PPC64
#elif defined(__powerpc__)
# define native_architecture() ARCHITECTURE_PPC
#elif defined(__ia64__)
# define native_architecture() ARCHITECTURE_IA64
#elif defined(__hppa64__)
# define native_architecture() ARCHITECTURE_PARISC64
#elif defined(__hppa__)
# define native_architecture() ARCHITECTURE_PARISC
#elif defined(__s390x__)
# define native_architecture() ARCHITECTURE_S390X
#elif defined(__s390__)
# define native_architecture() ARCHITECTURE_S390
#elif defined(__sparc64__)
# define native_architecture() ARCHITECTURE_SPARC64
#elif defined(__sparc__)
# define native_architecture() ARCHITECTURE_SPARC
#elif defined(__mips64__)
# define native_architecture() ARCHITECTURE_MIPS64
#elif defined(__mips__)
# define native_architecture() ARCHITECTURE_MIPS
#elif defined(__alpha__)
# define native_architecture() ARCHITECTURE_ALPHA
#elif defined(__aarch64__)
# ifdef defined(WORDS_BIGENDIAN)
# define native_architecture() ARCHITECTURE_ARM64_BE
# else
# define native_architecture() ARCHITECTURE_ARM64
# endif
#elif defined(__arm__)
# ifdef defined(WORDS_BIGENDIAN)
# define native_architecture() ARCHITECTURE_ARM_BE
# else
# define native_architecture() ARCHITECTURE_ARM
# endif
#elif defined(__sh64__)
# define native_architecture() ARCHITECTURE_SH64
#elif defined(__sh__)
# define native_architecture() ARCHITECTURE_SH
#elif defined(__m68k__)
# define native_architecture() ARCHITECTURE_M68K
#else
#error "Please register your architecture here!"
#endif
const char *architecture_to_string(Architecture a) _const_;
Architecture architecture_from_string(const char *s) _pure_;
+25 -1
View File
@@ -33,6 +33,7 @@
#include "path-util.h"
#include "fileio.h"
#include "unit.h"
#include "architecture.h"
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
Condition *c;
@@ -154,6 +155,28 @@ bool condition_test_virtualization(Condition *c) {
return (v > 0 && streq(c->parameter, id)) == !c->negate;
}
bool condition_test_architecture(Condition *c) {
Architecture a, b;
assert(c);
assert(c->parameter);
assert(c->type == CONDITION_ARCHITECTURE);
a = uname_architecture();
if (a < 0)
return c->negate;
if (streq(c->parameter, "native"))
b = native_architecture();
else
b = architecture_from_string(c->parameter);
if (b < 0)
return c->negate;
return (a == b) == !c->negate;
}
bool condition_test_host(Condition *c) {
sd_id128_t x, y;
char *h;
@@ -170,7 +193,7 @@ bool condition_test_host(Condition *c) {
if (r < 0)
return c->negate;
return sd_id128_equal(x, y);
return sd_id128_equal(x, y) == !c->negate;
}
h = gethostname_malloc();
@@ -237,6 +260,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_CAPABILITY] = "ConditionCapability",
[CONDITION_HOST] = "ConditionHost",
[CONDITION_AC_POWER] = "ConditionACPower",
[CONDITION_ARCHITECTURE] = "ConditionArchitecture",
[CONDITION_NULL] = "ConditionNull"
};
+2
View File
@@ -43,6 +43,7 @@ typedef enum ConditionType {
CONDITION_CAPABILITY,
CONDITION_HOST,
CONDITION_AC_POWER,
CONDITION_ARCHITECTURE,
CONDITION_NULL,
_CONDITION_TYPE_MAX,
_CONDITION_TYPE_INVALID = -1
@@ -67,6 +68,7 @@ void condition_free_list(Condition *c);
bool condition_test_kernel_command_line(Condition *c);
bool condition_test_virtualization(Condition *c);
bool condition_test_architecture(Condition *c);
bool condition_test_host(Condition *c);
bool condition_test_ac_power(Condition *c);