mirror of
https://github.com/systemd/systemd
synced 2026-03-31 20:24:50 +02:00
Compare commits
27 Commits
00725c3c4f
...
a0d1dc662a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0d1dc662a | ||
|
|
3eabddbe9f | ||
|
|
aec0e63a4f | ||
|
|
be33b202e6 | ||
|
|
3db66ed388 | ||
|
|
1abe8dd9eb | ||
|
|
32d1bed50b | ||
|
|
59a81bbb80 | ||
|
|
dcf8bdf01d | ||
|
|
8bb6f4f164 | ||
|
|
0d91a204cb | ||
|
|
164fc38888 | ||
|
|
f5452477d4 | ||
|
|
dbc25d84ae | ||
|
|
40cb2aa4f8 | ||
|
|
ab69a04600 | ||
|
|
88e26303ce | ||
|
|
a580dd4e53 | ||
|
|
4b774c740b | ||
|
|
3866923a68 | ||
|
|
ebbc0ea7fd | ||
|
|
5bb9063505 | ||
|
|
397681405a | ||
|
|
58686034eb | ||
|
|
d3da74696b | ||
|
|
0d9e79d5ca | ||
|
|
7ca94ff4b1 |
@ -938,11 +938,12 @@ Defined-By: systemd
|
||||
Support: %SUPPORT_URL%
|
||||
Documentation: man:systemd(1)
|
||||
|
||||
A unit transaction was initiated that contains an ordering cycle, i.e. some
|
||||
unit that was requested to be started (either directly, or indirectly due to a
|
||||
requirement dependency such as Wants= or Requires=) is ordered before some
|
||||
other unit (via After=/Before=), but that latter unit is also ordered before
|
||||
the former by some dependency (either directly or indirectly).
|
||||
A unit transaction (with ID @TRANSACTION_ID@) was initiated that contains
|
||||
an ordering cycle, i.e. some unit that was requested to be started
|
||||
(either directly, or indirectly due to a requirement dependency such as
|
||||
Wants= or Requires=) is ordered before some other unit (via After=/Before=),
|
||||
but that latter unit is also ordered before the former by some dependency
|
||||
(either directly or indirectly).
|
||||
|
||||
Ordering cycles consist of at least two units, but might involve many
|
||||
more. They generally indicate a bug in the unit definitions, as a unit
|
||||
|
||||
@ -103,6 +103,9 @@ sensor:modalias:acpi:SMO8500:*:dmi:*Acer*:pnOneS1002:*
|
||||
sensor:modalias:acpi:KIOX0009*:dmi:*:svnAcer:pnOneS1003:*
|
||||
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
|
||||
|
||||
sensor:modalias:acpi:KIOX000A*:dmi:*:svnAcer:pnSwitchOneSW1-011:*
|
||||
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
|
||||
|
||||
sensor:modalias:acpi:BOSC0200*:dmi:*:svnAcer*:pnSwitchSW312-31:*
|
||||
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
|
||||
|
||||
|
||||
@ -413,6 +413,8 @@ node /org/freedesktop/systemd1 {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly u NFailedJobs = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly at TransactionsWithOrderingCycle = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly d Progress = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly as Environment = ['...', ...];
|
||||
@ -1103,6 +1105,8 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFailedJobs"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="TransactionsWithOrderingCycle"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Progress"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
|
||||
@ -1809,6 +1813,9 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<para><varname>NFailedJobs</varname> encodes how many jobs have ever failed in total.</para>
|
||||
|
||||
<para><varname>TransactionsWithOrderingCycle</varname> encodes IDs of transactions that encountered
|
||||
ordering cycle.</para>
|
||||
|
||||
<para><varname>Progress</varname> encodes boot progress as a floating point value between 0.0 and
|
||||
1.0. This value begins at 0.0 at early-boot and ends at 1.0 when boot is finished and is based on the
|
||||
number of executed and queued jobs. After startup, this field is always 1.0 indicating a finished
|
||||
@ -12465,6 +12472,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<para><varname>DefaultRestrictSUIDSGID</varname>,
|
||||
<function>RemoveSubgroupFromUnit()</function>, and
|
||||
<function>KillUnitSubgroup()</function> were added in version 258.</para>
|
||||
<para><varname>TransactionsWithOrderingCycle</varname> was added in version 259.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Unit Objects</title>
|
||||
|
||||
@ -225,8 +225,8 @@ Sun 2017-02-26 20:57:49 EST 2h 3min left Sun 2017-02-26 11:56:36 EST 6h ago
|
||||
|
||||
<listitem>
|
||||
<para>Check whether any of the specified units is in the "failed" state. If no unit is specified,
|
||||
check whether there are any failed units, which corresponds to the <literal>degraded</literal> state
|
||||
returned by <command>is-system-running</command>. Returns an exit code <constant>0</constant>
|
||||
check whether there are any failed units or ordering cycles, which corresponds to the <literal>degraded</literal>
|
||||
state returned by <command>is-system-running</command>. Returns an exit code <constant>0</constant>
|
||||
if at least one has failed, non-zero otherwise. Unless <option>--quiet</option> is specified, this
|
||||
will also print the current unit or system state to standard output.</para>
|
||||
|
||||
|
||||
@ -69,6 +69,15 @@
|
||||
<xi:include href="version-info.xml" xpointer="v251"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-q</option></term>
|
||||
<term><option>--quiet</option></term>
|
||||
|
||||
<listitem><para>Suppresses error logging on failure.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
|
||||
@ -34,11 +34,11 @@ static int get_runpath_from_dynamic(const ElfW(Dyn) *d, ElfW(Addr) bias, const c
|
||||
break;
|
||||
|
||||
case DT_STRTAB:
|
||||
/* On MIPS and RISC-V DT_STRTAB records an offset, not a valid address, so it has to be adjusted
|
||||
* using the bias calculated earlier. */
|
||||
/* On MIPS, RISC-V, or with musl, DT_STRTAB records an offset, not a valid address,
|
||||
* so it has to be adjusted using the bias calculated earlier. */
|
||||
if (d->d_un.d_val != 0)
|
||||
strtab = (const char *) ((uintptr_t) d->d_un.d_val
|
||||
#if defined(__mips__) || defined(__riscv)
|
||||
#if defined(__mips__) || defined(__riscv) || !defined(__GLIBC__)
|
||||
+ bias
|
||||
#endif
|
||||
);
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "io-util.h"
|
||||
#include "log.h"
|
||||
#include "memory-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
#include "time-util.h"
|
||||
#include "utf8.h"
|
||||
@ -32,6 +33,7 @@ int efi_get_variable(
|
||||
void **ret_value,
|
||||
size_t *ret_size) {
|
||||
|
||||
int r;
|
||||
usec_t begin = 0; /* Unnecessary initialization to appease gcc */
|
||||
|
||||
assert(variable);
|
||||
@ -66,13 +68,16 @@ int efi_get_variable(
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return log_debug_errno(errno, "fstat(\"%s\") failed: %m", p);
|
||||
if (st.st_size == 0)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||
"EFI variable %s is uncommitted", p);
|
||||
if (st.st_size < 4)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENODATA), "EFI variable %s is shorter than 4 bytes, refusing.", p);
|
||||
if (st.st_size > 4*1024*1024 + 4)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "EFI variable %s is ridiculously large, refusing.", p);
|
||||
r = stat_verify_regular(&st);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "EFI variable '%s' is not a regular file, refusing: %m", p);
|
||||
|
||||
if (st.st_size == 0) /* for uncommited variables, see below */
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOENT), "EFI variable '%s' is uncommitted", p);
|
||||
if ((uint64_t) st.st_size < sizeof(attr))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENODATA), "EFI variable '%s' is shorter than %zu bytes, refusing.", p, sizeof(attr));
|
||||
if ((uint64_t) st.st_size > sizeof(attr) + 4 * U64_MB)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "EFI variable '%s' is ridiculously large, refusing.", p);
|
||||
|
||||
if (!ret_attribute && !ret_value) {
|
||||
/* No need to read anything, return the reported size. */
|
||||
@ -81,31 +86,37 @@ int efi_get_variable(
|
||||
}
|
||||
|
||||
/* We want +1 for the read call, and +3 for the additional terminating bytes added below. */
|
||||
char *t = realloc(buf, (size_t) st.st_size + MAX(1, 3));
|
||||
if (!t)
|
||||
free(buf);
|
||||
buf = malloc((size_t) st.st_size - sizeof(attr) + CONST_MAX(1, 3));
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
buf = t;
|
||||
|
||||
const struct iovec iov[] = {
|
||||
struct iovec iov[] = {
|
||||
{ &attr, sizeof(attr) },
|
||||
{ buf, (size_t) st.st_size + 1 },
|
||||
{ buf, (size_t) st.st_size - sizeof(attr) + 1 },
|
||||
};
|
||||
|
||||
n = readv(fd, iov, 2);
|
||||
assert(n <= st.st_size + 1);
|
||||
if (n == st.st_size + 1)
|
||||
/* We need to try again with a bigger buffer. */
|
||||
continue;
|
||||
if (n >= 0)
|
||||
break;
|
||||
|
||||
log_debug_errno(errno, "Reading from \"%s\" failed: %m", p);
|
||||
if (n < 0) {
|
||||
if (errno != EINTR)
|
||||
return -errno;
|
||||
return log_debug_errno(errno, "Reading from '%s' failed: %m", p);
|
||||
|
||||
log_debug("Reading from '%s' failed with EINTR, retrying.", p);
|
||||
} else if ((size_t) n == sizeof(attr) + st.st_size + 1)
|
||||
/* We need to try again with a bigger buffer, the variable was apparently changed concurrently? */
|
||||
log_debug("EFI variable '%s' larger than expected, retrying.", p);
|
||||
else {
|
||||
assert((size_t) n < sizeof(attr) + st.st_size + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (try >= EFI_N_RETRIES_TOTAL)
|
||||
return -EBUSY;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBUSY), "Reading EFI variable '%s' failed even after %u tries, giving up.", p, try);
|
||||
if (try >= EFI_N_RETRIES_NO_DELAY)
|
||||
(void) usleep_safe(EFI_RETRY_DELAY);
|
||||
|
||||
/* Start from the beginning */
|
||||
(void) lseek(fd, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
/* Unfortunately kernel reports EOF if there's an inconsistency between efivarfs var list and
|
||||
@ -122,19 +133,21 @@ int efi_get_variable(
|
||||
if (n == 0)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||
"EFI variable %s is uncommitted", p);
|
||||
if (n < 4)
|
||||
if ((size_t) n < sizeof(attr))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Read %zi bytes from EFI variable %s, expected >= 4", n, p);
|
||||
"Read %zi bytes from EFI variable %s, expected >= %zu", n, p, sizeof(attr));
|
||||
size_t value_size = n - sizeof(attr);
|
||||
|
||||
if (ret_attribute)
|
||||
*ret_attribute = attr;
|
||||
|
||||
if (ret_value) {
|
||||
assert(buf);
|
||||
/* Always NUL-terminate (3 bytes, to properly protect UTF-16, even if truncated in
|
||||
* the middle of a character) */
|
||||
buf[n - 4] = 0;
|
||||
buf[n - 4 + 1] = 0;
|
||||
buf[n - 4 + 2] = 0;
|
||||
buf[value_size] = 0;
|
||||
buf[value_size + 1] = 0;
|
||||
buf[value_size + 2] = 0;
|
||||
*ret_value = TAKE_PTR(buf);
|
||||
}
|
||||
|
||||
@ -149,7 +162,7 @@ int efi_get_variable(
|
||||
* with a smaller value. */
|
||||
|
||||
if (ret_size)
|
||||
*ret_size = n - 4;
|
||||
*ret_size = value_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ assert_cc(sizeof(gid_t) == sizeof(uint32_t));
|
||||
# error Unknown timex member size
|
||||
#endif
|
||||
|
||||
#ifdef __GLIBC__
|
||||
# if SIZEOF_RLIM_T == 8
|
||||
# define RLIM_FMT "%" PRIu64
|
||||
# elif SIZEOF_RLIM_T == 4
|
||||
@ -46,6 +47,11 @@ assert_cc(sizeof(gid_t) == sizeof(uint32_t));
|
||||
# else
|
||||
# error Unknown rlim_t size
|
||||
# endif
|
||||
#else
|
||||
/* Assume musl, and it unconditionally uses unsigned long long. */
|
||||
assert_cc(SIZEOF_RLIM_T == 8);
|
||||
# define RLIM_FMT "%llu"
|
||||
#endif
|
||||
|
||||
#if SIZEOF_DEV_T == 8
|
||||
# define DEV_FMT "%" PRIu64
|
||||
|
||||
@ -94,8 +94,8 @@ bool hostname_is_valid(const char *s, ValidHostnameFlags flags) {
|
||||
if (hyphen)
|
||||
return false;
|
||||
|
||||
if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on Linux, but DNS allows domain names up to
|
||||
* 255 characters */
|
||||
/* Note that host name max is 64 on Linux, but DNS allows domain names up to 255 characters. */
|
||||
if (p - s > (ssize_t) LINUX_HOST_NAME_MAX)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -107,7 +107,7 @@ char* hostname_cleanup(char *s) {
|
||||
|
||||
assert(s);
|
||||
|
||||
for (p = s, d = s, dot = hyphen = true; *p && d - s < HOST_NAME_MAX; p++)
|
||||
for (p = s, d = s, dot = hyphen = true; *p && d - s < (ssize_t) LINUX_HOST_NAME_MAX; p++)
|
||||
if (*p == '.') {
|
||||
if (dot || hyphen)
|
||||
continue;
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
#include "basic-forward.h"
|
||||
#include "strv.h"
|
||||
|
||||
/* HOST_NAME_MAX should be 64 on linux, but musl uses the one by POSIX (255). */
|
||||
#define LINUX_HOST_NAME_MAX CONST_MIN((size_t) HOST_NAME_MAX, (size_t) 64)
|
||||
|
||||
char* get_default_hostname_raw(void);
|
||||
|
||||
bool valid_ldh_char(char c) _const_;
|
||||
|
||||
@ -410,12 +410,26 @@ TEST(startswith8) {
|
||||
ASSERT_NULL(startswith8(NULL, ""));
|
||||
}
|
||||
|
||||
#define TEST_FNMATCH_ONE(pattern, haystack, expect) \
|
||||
#define TEST_FNMATCH_ONE_FULL(pattern, haystack, expect, skip_libc) \
|
||||
({ \
|
||||
if (!skip_libc) \
|
||||
ASSERT_EQ(fnmatch(pattern, haystack, 0), expect ? 0 : FNM_NOMATCH); \
|
||||
ASSERT_EQ(efi_fnmatch(u##pattern, u##haystack), expect); \
|
||||
})
|
||||
|
||||
#define TEST_FNMATCH_ONE(pattern, haystack, expect) \
|
||||
TEST_FNMATCH_ONE_FULL(pattern, haystack, expect, false)
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#define TEST_FNMATCH_ONE_MAY_SKIP_LIBC(pattern, haystack, expect) \
|
||||
TEST_FNMATCH_ONE_FULL(pattern, haystack, expect, false)
|
||||
#else
|
||||
/* It seems musl is too strict in handling "[]" (or has a bug?). Anyway, let's skip some test cases when
|
||||
* built with musl. The behavior of efi_fnmatch() does not need to match musl's fnmatch(). */
|
||||
#define TEST_FNMATCH_ONE_MAY_SKIP_LIBC(pattern, haystack, expect) \
|
||||
TEST_FNMATCH_ONE_FULL(pattern, haystack, expect, true)
|
||||
#endif
|
||||
|
||||
TEST(efi_fnmatch) {
|
||||
TEST_FNMATCH_ONE("", "", true);
|
||||
TEST_FNMATCH_ONE("abc", "abc", true);
|
||||
@ -447,18 +461,18 @@ TEST(efi_fnmatch) {
|
||||
TEST_FNMATCH_ONE("[abc", "a", false);
|
||||
TEST_FNMATCH_ONE("[][!] [][!] [][!]", "[ ] !", true);
|
||||
TEST_FNMATCH_ONE("[]-] []-]", "] -", true);
|
||||
TEST_FNMATCH_ONE("[1\\]] [1\\]]", "1 ]", true);
|
||||
TEST_FNMATCH_ONE_MAY_SKIP_LIBC("[1\\]] [1\\]]", "1 ]", true);
|
||||
TEST_FNMATCH_ONE("[$-\\+]", "&", true);
|
||||
TEST_FNMATCH_ONE("[1-3A-C] [1-3A-C]", "2 B", true);
|
||||
TEST_FNMATCH_ONE("[3-5] [3-5] [3-5]", "3 4 5", true);
|
||||
TEST_FNMATCH_ONE("[f-h] [f-h] [f-h]", "f g h", true);
|
||||
TEST_FNMATCH_ONE("[a-c-f] [a-c-f] [a-c-f] [a-c-f] [a-c-f]", "a b c - f", true);
|
||||
TEST_FNMATCH_ONE("[a-c-f]", "e", false);
|
||||
TEST_FNMATCH_ONE_MAY_SKIP_LIBC("[a-c-f] [a-c-f] [a-c-f] [a-c-f] [a-c-f]", "a b c - f", true);
|
||||
TEST_FNMATCH_ONE_MAY_SKIP_LIBC("[a-c-f]", "e", false);
|
||||
TEST_FNMATCH_ONE("[--0] [--0] [--0]", "- . 0", true);
|
||||
TEST_FNMATCH_ONE("[+--] [+--] [+--]", "+ , -", true);
|
||||
TEST_FNMATCH_ONE("[f-l]", "m", false);
|
||||
TEST_FNMATCH_ONE("[b]", "z-a", false);
|
||||
TEST_FNMATCH_ONE("[a\\-z]", "b", false);
|
||||
TEST_FNMATCH_ONE_MAY_SKIP_LIBC("[a\\-z]", "b", false);
|
||||
TEST_FNMATCH_ONE("?a*b[.-0]c", "/a/b/c", true);
|
||||
TEST_FNMATCH_ONE("debian-*-*-*.*", "debian-jessie-2018-06-17-kernel-image-5.10.0-16-amd64.efi", true);
|
||||
|
||||
@ -674,8 +688,14 @@ TEST(xvasprintf_status) {
|
||||
test_printf_one("string");
|
||||
test_printf_one("%%-%%%%");
|
||||
|
||||
#ifdef __GLIBC__
|
||||
test_printf_one("%p %p %32p %*p %*p", NULL, (void *) 0xF, &errno, 0, &saved_argc, 20, &saved_argv);
|
||||
test_printf_one("%-10p %-32p %-*p %-*p", NULL, &errno, 0, &saved_argc, 20, &saved_argv);
|
||||
#else
|
||||
/* musl prints NULL as 0, while glibc and our implementation print it as (nil). */
|
||||
test_printf_one("%p %32p %*p %*p", (void *) 0xF, &errno, 0, &saved_argc, 20, &saved_argv);
|
||||
test_printf_one("%-32p %-*p %-*p", &errno, 0, &saved_argc, 20, &saved_argv);
|
||||
#endif
|
||||
|
||||
test_printf_one("%c %3c %*c %*c %-8c", '1', '!', 0, 'a', 9, '_', '>');
|
||||
|
||||
|
||||
@ -455,6 +455,35 @@ static int property_get_oom_score_adjust(
|
||||
return sd_bus_message_append(reply, "i", n);
|
||||
}
|
||||
|
||||
static int property_get_transactions_with_cycle(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "t");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
uint64_t *id;
|
||||
SET_FOREACH(id, m->transactions_with_cycle) {
|
||||
r = sd_bus_message_append_basic(reply, 't', id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static int bus_get_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
|
||||
Unit *u;
|
||||
int r;
|
||||
@ -2870,6 +2899,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("NJobs", "u", property_get_hashmap_size, offsetof(Manager, jobs), 0),
|
||||
SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
|
||||
SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
|
||||
SD_BUS_PROPERTY("TransactionsWithOrderingCycle", "at", property_get_transactions_with_cycle, 0, 0),
|
||||
SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
|
||||
SD_BUS_PROPERTY("Environment", "as", property_get_environment, 0, 0),
|
||||
SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
||||
@ -6633,7 +6633,7 @@ int config_parse_protect_hostname(
|
||||
|
||||
const char *colon = strchr(rvalue, ':');
|
||||
if (colon) {
|
||||
r = unit_full_printf_full(u, colon + 1, HOST_NAME_MAX, &h);
|
||||
r = unit_full_printf_full(u, colon + 1, LINUX_HOST_NAME_MAX, &h);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", colon + 1);
|
||||
|
||||
@ -92,6 +92,8 @@ int manager_serialize(
|
||||
|
||||
_cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
|
||||
|
||||
(void) serialize_item_format(f, "last-transaction-id", "%" PRIu64, m->last_transaction_id);
|
||||
|
||||
(void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
|
||||
(void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
|
||||
(void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
|
||||
@ -283,7 +285,7 @@ static void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
|
||||
|
||||
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
bool deserialize_varlink_sockets = false;
|
||||
int r = 0;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(f);
|
||||
@ -325,7 +327,15 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
if (r == 0) /* eof or end marker */
|
||||
break;
|
||||
|
||||
if ((val = startswith(l, "current-job-id="))) {
|
||||
if ((val = startswith(l, "last-transaction-id="))) {
|
||||
uint64_t id;
|
||||
|
||||
if (safe_atou64(val, &id) < 0)
|
||||
log_notice("Failed to parse last transaction id value '%s', ignoring.", val);
|
||||
else
|
||||
m->last_transaction_id = MAX(m->last_transaction_id, id);
|
||||
|
||||
} else if ((val = startswith(l, "current-job-id="))) {
|
||||
uint32_t id;
|
||||
|
||||
if (safe_atou32(val, &id) < 0)
|
||||
@ -350,22 +360,18 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
m->n_failed_jobs += n;
|
||||
|
||||
} else if ((val = startswith(l, "taint-logged="))) {
|
||||
int b;
|
||||
|
||||
b = parse_boolean(val);
|
||||
if (b < 0)
|
||||
r = parse_boolean(val);
|
||||
if (r < 0)
|
||||
log_notice("Failed to parse taint-logged flag '%s', ignoring.", val);
|
||||
else
|
||||
m->taint_logged = m->taint_logged || b;
|
||||
m->taint_logged = m->taint_logged || r;
|
||||
|
||||
} else if ((val = startswith(l, "service-watchdogs="))) {
|
||||
int b;
|
||||
|
||||
b = parse_boolean(val);
|
||||
if (b < 0)
|
||||
r = parse_boolean(val);
|
||||
if (r < 0)
|
||||
log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val);
|
||||
else
|
||||
m->service_watchdogs = b;
|
||||
m->service_watchdogs = r;
|
||||
|
||||
} else if ((val = startswith(l, "show-status-overridden="))) {
|
||||
ShowStatus s;
|
||||
|
||||
@ -526,8 +526,9 @@ static int manager_setup_signals(Manager *m) {
|
||||
|
||||
assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
|
||||
|
||||
/* We make liberal use of realtime signals here. On Linux/glibc we have 30 of them, between
|
||||
* SIGRTMIN+0 ... SIGRTMIN+30 (aka SIGRTMAX). */
|
||||
/* We make liberal use of realtime signals here. On Linux we have 29 of them, between
|
||||
* SIGRTMIN+0 ... SIGRTMIN+29. The glibc has one more (SIGRTMAX is SIGRTMIN+30),
|
||||
* but musl does not (SIGRTMAX is SIGRTMIN+29). */
|
||||
|
||||
assert_se(sigemptyset(&mask) == 0);
|
||||
sigset_add_many(&mask,
|
||||
@ -572,7 +573,7 @@ static int manager_setup_signals(Manager *m) {
|
||||
SIGRTMIN+28, /* systemd: set log target to kmsg */
|
||||
SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete) */
|
||||
|
||||
/* ... one free signal here SIGRTMIN+30 ... */
|
||||
/* ... one free signal here SIGRTMIN+30 (glibc only) ... */
|
||||
-1);
|
||||
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
|
||||
|
||||
@ -1659,6 +1660,8 @@ static void manager_clear_jobs_and_units(Manager *m) {
|
||||
m->n_running_jobs = 0;
|
||||
m->n_installed_jobs = 0;
|
||||
m->n_failed_jobs = 0;
|
||||
|
||||
m->transactions_with_cycle = set_free(m->transactions_with_cycle);
|
||||
}
|
||||
|
||||
Manager* manager_free(Manager *m) {
|
||||
@ -2153,14 +2156,16 @@ int manager_add_job_full(
|
||||
if (mode == JOB_RESTART_DEPENDENCIES && type != JOB_START)
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "--job-mode=restart-dependencies is only valid for start.");
|
||||
|
||||
tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY, ++m->last_transaction_id);
|
||||
if (!tr)
|
||||
return -ENOMEM;
|
||||
|
||||
LOG_CONTEXT_PUSHF("TRANSACTION_ID=%" PRIu64, tr->id);
|
||||
|
||||
log_unit_debug(unit, "Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode));
|
||||
|
||||
type = job_type_collapse(type, unit);
|
||||
|
||||
tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
|
||||
if (!tr)
|
||||
return -ENOMEM;
|
||||
|
||||
r = transaction_add_job_and_dependencies(
|
||||
tr,
|
||||
type,
|
||||
@ -2247,18 +2252,20 @@ int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name,
|
||||
}
|
||||
|
||||
int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e) {
|
||||
int r;
|
||||
_cleanup_(transaction_abort_and_freep) Transaction *tr = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(unit);
|
||||
assert(mode < _JOB_MODE_MAX);
|
||||
assert(mode != JOB_ISOLATE); /* Isolate is only valid for start */
|
||||
|
||||
tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
|
||||
tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY, ++m->last_transaction_id);
|
||||
if (!tr)
|
||||
return -ENOMEM;
|
||||
|
||||
LOG_CONTEXT_PUSHF("TRANSACTION_ID=%" PRIu64, tr->id);
|
||||
|
||||
/* We need an anchor job */
|
||||
r = transaction_add_job_and_dependencies(tr, JOB_NOP, unit, NULL, TRANSACTION_IGNORE_REQUIREMENTS|TRANSACTION_IGNORE_ORDER, e);
|
||||
if (r < 0)
|
||||
@ -3669,6 +3676,8 @@ void manager_reset_failed(Manager *m) {
|
||||
|
||||
HASHMAP_FOREACH(u, m->units)
|
||||
unit_reset_failed(u);
|
||||
|
||||
m->transactions_with_cycle = set_free(m->transactions_with_cycle);
|
||||
}
|
||||
|
||||
bool manager_unit_inactive_or_pending(Manager *m, const char *name) {
|
||||
@ -4617,8 +4626,8 @@ ManagerState manager_state(Manager *m) {
|
||||
return MANAGER_MAINTENANCE;
|
||||
}
|
||||
|
||||
/* Are there any failed units? If so, we are in degraded mode */
|
||||
if (!set_isempty(m->failed_units))
|
||||
/* Are there any failed units or ordering cycles? If so, we are in degraded mode */
|
||||
if (!set_isempty(m->failed_units) || !set_isempty(m->transactions_with_cycle))
|
||||
return MANAGER_DEGRADED;
|
||||
|
||||
return MANAGER_RUNNING;
|
||||
|
||||
@ -236,6 +236,11 @@ typedef struct Manager {
|
||||
/* A set which contains all currently failed units */
|
||||
Set *failed_units;
|
||||
|
||||
uint64_t last_transaction_id;
|
||||
|
||||
/* IDs of transactions that once encountered ordering cycle */
|
||||
Set *transactions_with_cycle;
|
||||
|
||||
sd_event_source *run_queue_event_source;
|
||||
|
||||
char *notify_socket;
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "bus-common-errors.h"
|
||||
#include "bus-error.h"
|
||||
#include "dbus-unit.h"
|
||||
#include "hash-funcs.h"
|
||||
#include "manager.h"
|
||||
#include "set.h"
|
||||
#include "slice.h"
|
||||
@ -15,6 +16,8 @@
|
||||
#include "strv.h"
|
||||
#include "transaction.h"
|
||||
|
||||
#define CYCLIC_TRANSACTIONS_MAX 4096U
|
||||
|
||||
static bool job_matters_to_anchor(Job *job);
|
||||
static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies);
|
||||
|
||||
@ -399,6 +402,16 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
|
||||
LOG_MESSAGE_ID(SD_MESSAGE_UNIT_ORDERING_CYCLE_STR),
|
||||
LOG_ITEM("%s", strempty(unit_ids)));
|
||||
|
||||
if (set_size(j->manager->transactions_with_cycle) >= CYCLIC_TRANSACTIONS_MAX)
|
||||
log_warning("Too many transactions with ordering cycle, suppressing record.");
|
||||
else {
|
||||
uint64_t *id_buf = newdup(uint64_t, &tr->id, 1);
|
||||
if (!id_buf)
|
||||
log_oom_warning();
|
||||
else
|
||||
(void) set_ensure_consume(&j->manager->transactions_with_cycle, &uint64_hash_ops_value_free, id_buf);
|
||||
}
|
||||
|
||||
if (delete) {
|
||||
const char *status;
|
||||
/* logging for j not k here to provide a consistent narrative */
|
||||
@ -1235,20 +1248,24 @@ int transaction_add_triggering_jobs(Transaction *tr, Unit *u) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Transaction* transaction_new(bool irreversible) {
|
||||
Transaction *tr;
|
||||
Transaction* transaction_new(bool irreversible, uint64_t id) {
|
||||
_cleanup_free_ Transaction *tr = NULL;
|
||||
|
||||
tr = new0(Transaction, 1);
|
||||
assert(id != 0);
|
||||
|
||||
tr = new(Transaction, 1);
|
||||
if (!tr)
|
||||
return NULL;
|
||||
|
||||
tr->jobs = hashmap_new(NULL);
|
||||
*tr = (Transaction) {
|
||||
.jobs = hashmap_new(NULL),
|
||||
.irreversible = irreversible,
|
||||
.id = id,
|
||||
};
|
||||
if (!tr->jobs)
|
||||
return mfree(tr);
|
||||
return NULL;
|
||||
|
||||
tr->irreversible = irreversible;
|
||||
|
||||
return tr;
|
||||
return TAKE_PTR(tr);
|
||||
}
|
||||
|
||||
Transaction* transaction_free(Transaction *tr) {
|
||||
|
||||
@ -8,9 +8,11 @@ typedef struct Transaction {
|
||||
Hashmap *jobs; /* Unit object => Job object list 1:1 */
|
||||
Job *anchor_job; /* The job the user asked for */
|
||||
bool irreversible;
|
||||
|
||||
uint64_t id;
|
||||
} Transaction;
|
||||
|
||||
Transaction* transaction_new(bool irreversible);
|
||||
Transaction* transaction_new(bool irreversible, uint64_t id);
|
||||
Transaction* transaction_free(Transaction *tr);
|
||||
Transaction* transaction_abort_and_free(Transaction *tr);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Transaction*, transaction_abort_and_free);
|
||||
|
||||
@ -112,6 +112,24 @@ static int manager_context_build_json(sd_json_variant **ret, const char *name, v
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("ControlGroup", m->cgroup_root));
|
||||
}
|
||||
|
||||
static int transactions_with_cycle_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
const Set *ids = userdata;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
uint64_t *id;
|
||||
SET_FOREACH(id, ids) {
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_UNSIGNED(*id));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int manager_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
dual_timestamp watchdog_last_ping;
|
||||
@ -154,6 +172,7 @@ static int manager_runtime_build_json(sd_json_variant **ret, const char *name, v
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("NJobs", hashmap_size(m->jobs)),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("NInstalledJobs", m->n_installed_jobs),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("NFailedJobs", m->n_failed_jobs),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("TransactionsWithOrderingCycle", transactions_with_cycle_build_json, m->transactions_with_cycle),
|
||||
SD_JSON_BUILD_PAIR_REAL("Progress", manager_get_progress(m)),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("WatchdogLastPingTimestamp", watchdog_get_last_ping_as_dual_timestamp(&watchdog_last_ping)),
|
||||
SD_JSON_BUILD_PAIR_STRING("SystemState", manager_state_to_string(manager_state(m))),
|
||||
|
||||
@ -127,7 +127,7 @@ static int add_cryptsetup(
|
||||
* assignment, under the assumption that people who are fine to use sd-stub with its PCR
|
||||
* assignments are also OK with our PCR 15 use here. */
|
||||
if (r > 0)
|
||||
if (!strextend_with_separator(&options, ",", "tpm2-measure-pcr=yes,tpm2-measure-slot-nvpcr=cryptsetup"))
|
||||
if (!strextend_with_separator(&options, ",", "tpm2-measure-pcr=yes,tpm2-measure-keyslot-nvpcr=cryptsetup"))
|
||||
return log_oom();
|
||||
if (r == 0)
|
||||
log_debug("Will not measure volume key of volume '%s', not booted via systemd-stub with measurements enabled.", id);
|
||||
|
||||
@ -570,7 +570,7 @@ static int home_parse_worker_stdout(int _fd, UserRecord **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lseek(fd, SEEK_SET, 0) < 0)
|
||||
if (lseek(fd, 0, SEEK_SET) < 0)
|
||||
return log_error_errno(errno, "Failed to seek to beginning of memfd: %m");
|
||||
|
||||
f = take_fdopen(&fd, "r");
|
||||
|
||||
@ -365,7 +365,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
|
||||
assert(i->raw_job->disk_fd >= 0);
|
||||
assert(i->offset == UINT64_MAX);
|
||||
|
||||
if (lseek(i->raw_job->disk_fd, SEEK_SET, 0) < 0)
|
||||
if (lseek(i->raw_job->disk_fd, 0, SEEK_SET) < 0)
|
||||
return log_error_errno(errno, "Failed to seek to beginning of vendor image: %m");
|
||||
}
|
||||
|
||||
|
||||
@ -186,12 +186,8 @@ int sd_lldp_tx_set_hostname(sd_lldp_tx *lldp_tx, const char *hostname) {
|
||||
assert_return(lldp_tx, -EINVAL);
|
||||
|
||||
/* An empty string unset the previously set hostname. */
|
||||
if (!isempty(hostname)) {
|
||||
assert_cc(HOST_NAME_MAX < 512);
|
||||
|
||||
if (!hostname_is_valid(hostname, 0))
|
||||
if (!isempty(hostname) && !hostname_is_valid(hostname, /* flags= */ 0))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return free_and_strdup(&lldp_tx->hostname, empty_to_null(hostname));
|
||||
}
|
||||
|
||||
@ -1623,14 +1623,20 @@ int bus_set_address_machine(sd_bus *b, RuntimeScope runtime_scope, const char *m
|
||||
if (!a)
|
||||
return -ENOMEM;
|
||||
|
||||
bool local = !eh || streq(eh, ".host");
|
||||
|
||||
/* Ideally we'd always use the "--user" and "--quiet" switches to systemd-stdio-bridge here,
|
||||
* but they're only available in recent systemd versions, meaning we can only use them if
|
||||
* we're not connecting to a container. Using the "-p" switch with an explicit path is a
|
||||
* working alternative for "--user", and is compatible with older versions, hence that's what
|
||||
* we use when connecting to a container. */
|
||||
|
||||
if (runtime_scope == RUNTIME_SCOPE_USER) {
|
||||
/* Ideally we'd use the "--user" switch to systemd-stdio-bridge here, but it's only
|
||||
* available in recent systemd versions. Using the "-p" switch with the explicit path
|
||||
* is a working alternative, and is compatible with older versions, hence that's what
|
||||
* we use here. */
|
||||
if (!strextend(&a, ",argv7=-punix:path%3d%24%7bXDG_RUNTIME_DIR%7d/bus"))
|
||||
if (!strextend(&a, local ? ",argv7=--user,argv8=--quiet" : ",argv7=-punix:path%3d%24%7bXDG_RUNTIME_DIR%7d/bus"))
|
||||
return -ENOMEM;
|
||||
} else if (local)
|
||||
if (!strextend(&a, ",argv7=--quiet"))
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
|
||||
|
||||
@ -570,8 +570,8 @@ int seat_read_active_vt(Seat *s) {
|
||||
if (!seat_has_vts(s))
|
||||
return 0;
|
||||
|
||||
if (lseek(s->manager->console_active_fd, SEEK_SET, 0) < 0)
|
||||
return log_error_errno(errno, "lseek on console_active_fd failed: %m");
|
||||
if (lseek(s->manager->console_active_fd, 0, SEEK_SET) < 0)
|
||||
return log_error_errno(errno, "lseek() on console_active_fd failed: %m");
|
||||
|
||||
errno = 0;
|
||||
k = read(s->manager->console_active_fd, t, sizeof(t)-1);
|
||||
|
||||
@ -161,7 +161,11 @@ static int bus_job_get_service_result(BusWaitForJobs *d, char **ret) {
|
||||
ret);
|
||||
}
|
||||
|
||||
static void log_job_error_with_service_result(const char* service, const char *result, const char* const* extra_args) {
|
||||
static void log_job_error_with_service_result(
|
||||
const char* service,
|
||||
const char *result,
|
||||
bool quiet,
|
||||
const char* const* extra_args) {
|
||||
|
||||
static const struct {
|
||||
const char *result, *explanation;
|
||||
@ -195,7 +199,8 @@ static void log_job_error_with_service_result(const char* service, const char *r
|
||||
if (!isempty(result))
|
||||
FOREACH_ELEMENT(i, explanations)
|
||||
if (streq(result, i->result)) {
|
||||
log_error("Job for %s failed because %s.\n"
|
||||
log_full(quiet ? LOG_DEBUG : LOG_ERR,
|
||||
"Job for %s failed because %s.\n"
|
||||
"See \"%s status %s\" and \"%s -xeu %s\" for details.\n",
|
||||
service, i->explanation,
|
||||
systemctl, service_shell_quoted ?: "<service>",
|
||||
@ -203,7 +208,8 @@ static void log_job_error_with_service_result(const char* service, const char *r
|
||||
goto extra;
|
||||
}
|
||||
|
||||
log_error("Job for %s failed.\n"
|
||||
log_full(quiet ? LOG_DEBUG : LOG_ERR,
|
||||
"Job for %s failed.\n"
|
||||
"See \"%s status %s\" and \"%s -xeu %s\" for details.\n",
|
||||
service,
|
||||
systemctl, service_shell_quoted ?: "<service>",
|
||||
@ -212,7 +218,8 @@ static void log_job_error_with_service_result(const char* service, const char *r
|
||||
extra:
|
||||
/* For some results maybe additional explanation is required */
|
||||
if (streq_ptr(result, "start-limit-hit"))
|
||||
log_info("To force a start use \"%1$s reset-failed %2$s\"\n"
|
||||
log_full(quiet ? LOG_DEBUG : LOG_INFO,
|
||||
"To force a start use \"%1$s reset-failed %2$s\"\n"
|
||||
"followed by \"%1$s start %2$s\" again.",
|
||||
systemctl,
|
||||
service_shell_quoted ?: "<service>");
|
||||
@ -226,38 +233,39 @@ static int check_wait_response(BusWaitForJobs *d, WaitJobsFlags flags, const cha
|
||||
assert(d->result);
|
||||
|
||||
if (streq(d->result, "done")) {
|
||||
if (FLAGS_SET(flags, BUS_WAIT_JOBS_LOG_SUCCESS))
|
||||
log_info("Job for %s finished.", d->name);
|
||||
log_full(FLAGS_SET(flags, BUS_WAIT_JOBS_LOG_SUCCESS) ? LOG_INFO : LOG_DEBUG,
|
||||
"Job for %s finished.", d->name);
|
||||
|
||||
return 0;
|
||||
} else if (streq(d->result, "skipped")) {
|
||||
if (FLAGS_SET(flags, BUS_WAIT_JOBS_LOG_SUCCESS))
|
||||
log_info("Job for %s was skipped.", d->name);
|
||||
log_full(FLAGS_SET(flags, BUS_WAIT_JOBS_LOG_SUCCESS) ? LOG_INFO : LOG_DEBUG,
|
||||
"Job for %s was skipped.", d->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, BUS_WAIT_JOBS_LOG_ERROR)) {
|
||||
int priority = FLAGS_SET(flags, BUS_WAIT_JOBS_LOG_ERROR) ? LOG_ERR : LOG_DEBUG;
|
||||
|
||||
if (streq(d->result, "canceled"))
|
||||
log_error("Job for %s canceled.", d->name);
|
||||
log_full(priority, "Job for %s canceled.", d->name);
|
||||
else if (streq(d->result, "timeout"))
|
||||
log_error("Job for %s timed out.", d->name);
|
||||
log_full(priority, "Job for %s timed out.", d->name);
|
||||
else if (streq(d->result, "dependency"))
|
||||
log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", d->name);
|
||||
log_full(priority, "A dependency job for %s failed. See 'journalctl -xe' for details.", d->name);
|
||||
else if (streq(d->result, "invalid"))
|
||||
log_error("%s is not active, cannot reload.", d->name);
|
||||
log_full(priority, "%s is not active, cannot reload.", d->name);
|
||||
else if (streq(d->result, "assert"))
|
||||
log_error("Assertion failed on job for %s.", d->name);
|
||||
log_full(priority, "Assertion failed on job for %s.", d->name);
|
||||
else if (streq(d->result, "unsupported"))
|
||||
log_error("Operation on or unit type of %s not supported on this system.", d->name);
|
||||
log_full(priority, "Operation on or unit type of %s not supported on this system.", d->name);
|
||||
else if (streq(d->result, "collected"))
|
||||
log_error("Queued job for %s was garbage collected.", d->name);
|
||||
log_full(priority, "Queued job for %s was garbage collected.", d->name);
|
||||
else if (streq(d->result, "once"))
|
||||
log_error("Unit %s was started already once and can't be started again.", d->name);
|
||||
log_full(priority, "Unit %s was started already once and can't be started again.", d->name);
|
||||
else if (streq(d->result, "frozen"))
|
||||
log_error("Cannot perform operation on frozen unit %s.", d->name);
|
||||
log_full(priority, "Cannot perform operation on frozen unit %s.", d->name);
|
||||
else if (streq(d->result, "concurrency"))
|
||||
log_error("Concurrency limit of a slice unit %s is contained in has been reached.", d->name);
|
||||
log_full(priority, "Concurrency limit of a slice unit %s is contained in has been reached.", d->name);
|
||||
else if (endswith(d->name, ".service")) {
|
||||
/* Job result is unknown. For services, let's also try Result property. */
|
||||
_cleanup_free_ char *result = NULL;
|
||||
@ -267,10 +275,9 @@ static int check_wait_response(BusWaitForJobs *d, WaitJobsFlags flags, const cha
|
||||
log_debug_errno(r, "Failed to get Result property of unit %s, ignoring: %m",
|
||||
d->name);
|
||||
|
||||
log_job_error_with_service_result(d->name, result, extra_args);
|
||||
log_job_error_with_service_result(d->name, result, priority, extra_args);
|
||||
} else /* Otherwise we just show a generic message. */
|
||||
log_error("Job failed. See \"journalctl -xe\" for details.");
|
||||
}
|
||||
log_full(priority, "Job failed. See \"journalctl -xe\" for details.");
|
||||
|
||||
if (STR_IN_SET(d->result, "canceled", "collected"))
|
||||
return -ECANCELED;
|
||||
|
||||
@ -96,9 +96,11 @@ char* cpu_set_to_mask_string(const CPUSet *c) {
|
||||
for (size_t i = c->allocated * 8; i > 0; ) {
|
||||
uint32_t m = 0;
|
||||
|
||||
for (int j = (i % 32 ?: 32) - 1; j >= 0; j--)
|
||||
if (CPU_ISSET_S(--i, c->allocated, c->set))
|
||||
for (int j = (i % 32 ?: 32) - 1; j >= 0; j--) {
|
||||
--i;
|
||||
if (CPU_ISSET_S(i, c->allocated, c->set))
|
||||
SET_BIT(m, j);
|
||||
}
|
||||
|
||||
if (!found_nonzero) {
|
||||
if (m == 0)
|
||||
|
||||
@ -51,7 +51,7 @@ int sethostname_idempotent(const char *s) {
|
||||
int shorten_overlong(const char *s, char **ret) {
|
||||
_cleanup_free_ char *h = NULL;
|
||||
|
||||
/* Shorten an overlong name to HOST_NAME_MAX or to the first dot,
|
||||
/* Shorten an overlong name to LINUX_HOST_NAME_MAX or to the first dot,
|
||||
* whatever comes earlier. */
|
||||
|
||||
assert(s);
|
||||
@ -70,7 +70,7 @@ int shorten_overlong(const char *s, char **ret) {
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
strshorten(h, HOST_NAME_MAX);
|
||||
strshorten(h, LINUX_HOST_NAME_MAX);
|
||||
|
||||
if (!hostname_is_valid(h, /* flags= */ 0))
|
||||
return -EDOM;
|
||||
@ -403,7 +403,7 @@ int pidref_gethostname_full(PidRef *pidref, GetHostnameFlags flags, char **ret)
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
char buf[HOST_NAME_MAX+1];
|
||||
char buf[LINUX_HOST_NAME_MAX+1];
|
||||
ssize_t n = loop_read(result_pipe[0], buf, sizeof(buf), /* do_poll = */ false);
|
||||
if (n < 0)
|
||||
return n;
|
||||
|
||||
@ -64,6 +64,7 @@ typedef struct Fido2HmacSalt Fido2HmacSalt;
|
||||
typedef struct GroupRecord GroupRecord;
|
||||
typedef struct Image Image;
|
||||
typedef struct ImagePolicy ImagePolicy;
|
||||
typedef struct InstallChange InstallChange;
|
||||
typedef struct InstallInfo InstallInfo;
|
||||
typedef struct LookupPaths LookupPaths;
|
||||
typedef struct LoopDevice LoopDevice;
|
||||
|
||||
@ -155,6 +155,8 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(NInstalledJobs, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The total amount of failed jobs"),
|
||||
SD_VARLINK_DEFINE_FIELD(NFailedJobs, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("IDs of transactions that encountered ordering cycle"),
|
||||
SD_VARLINK_DEFINE_FIELD(TransactionsWithOrderingCycle, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Boot progress as a floating point value between 0.0 and 1.0"),
|
||||
SD_VARLINK_DEFINE_FIELD(Progress, SD_VARLINK_FLOAT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the hardware watchdog was last pinged"),
|
||||
|
||||
@ -17,9 +17,10 @@
|
||||
#include "parse-argument.h"
|
||||
#include "time-util.h"
|
||||
|
||||
static const char *arg_bus_path = DEFAULT_SYSTEM_BUS_ADDRESS;
|
||||
static const char *arg_bus_path = NULL;
|
||||
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
|
||||
static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
|
||||
static bool arg_quiet = false;
|
||||
|
||||
static int help(void) {
|
||||
printf("%s [OPTIONS...]\n\n"
|
||||
@ -29,7 +30,8 @@ static int help(void) {
|
||||
" -p --bus-path=PATH Path to the bus address (default: %s)\n"
|
||||
" --system Connect to system bus\n"
|
||||
" --user Connect to user bus\n"
|
||||
" -M --machine=CONTAINER Name of local container to connect to\n",
|
||||
" -M --machine=CONTAINER Name of local container to connect to\n"
|
||||
" -q --quiet Fail silently instead of logging errors\n",
|
||||
program_invocation_short_name, DEFAULT_SYSTEM_BUS_ADDRESS);
|
||||
|
||||
return 0;
|
||||
@ -50,10 +52,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "user", no_argument, NULL, ARG_USER },
|
||||
{ "system", no_argument, NULL, ARG_SYSTEM },
|
||||
{ "machine", required_argument, NULL, 'M' },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{},
|
||||
};
|
||||
|
||||
int r, c;
|
||||
int c, r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
@ -86,6 +89,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return r;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
arg_quiet = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -94,18 +101,57 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
if (argc > optind)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
return log_full_errno(arg_quiet ? LOG_DEBUG : LOG_ERR, SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s takes no arguments.",
|
||||
program_invocation_short_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_set_address(
|
||||
sd_bus *bus,
|
||||
BusTransport transport,
|
||||
const char *bus_path,
|
||||
RuntimeScope runtime_scope) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
|
||||
switch (transport) {
|
||||
|
||||
case BUS_TRANSPORT_LOCAL:
|
||||
|
||||
if (bus_path)
|
||||
return sd_bus_set_address(bus, bus_path);
|
||||
|
||||
switch (runtime_scope) {
|
||||
|
||||
case RUNTIME_SCOPE_USER:
|
||||
return bus_set_address_user(bus);
|
||||
|
||||
case RUNTIME_SCOPE_SYSTEM:
|
||||
return bus_set_address_system(bus);
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
case BUS_TRANSPORT_MACHINE:
|
||||
return bus_set_address_machine(bus, runtime_scope, bus_path);
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *a = NULL, *b = NULL;
|
||||
sd_id128_t server_id;
|
||||
bool is_unix;
|
||||
int r, in_fd, out_fd;
|
||||
int in_fd, out_fd, r;
|
||||
|
||||
log_setup();
|
||||
|
||||
@ -113,6 +159,8 @@ static int run(int argc, char *argv[]) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
int priority = arg_quiet ? LOG_DEBUG : LOG_ERR;
|
||||
|
||||
r = sd_listen_fds(0);
|
||||
if (r == 0) {
|
||||
in_fd = STDIN_FILENO;
|
||||
@ -121,7 +169,8 @@ static int run(int argc, char *argv[]) {
|
||||
in_fd = SD_LISTEN_FDS_START;
|
||||
out_fd = SD_LISTEN_FDS_START;
|
||||
} else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "More than one file descriptor was passed.");
|
||||
return log_full_errno(priority, SYNTHETIC_ERRNO(EINVAL),
|
||||
"More than one file descriptor was passed.");
|
||||
|
||||
is_unix =
|
||||
sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
|
||||
@ -129,50 +178,47 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
r = sd_bus_new(&a);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate bus: %m");
|
||||
return log_full_errno(priority, r, "Failed to allocate bus: %m");
|
||||
|
||||
if (arg_transport == BUS_TRANSPORT_MACHINE)
|
||||
r = bus_set_address_machine(a, arg_runtime_scope, arg_bus_path);
|
||||
else
|
||||
r = sd_bus_set_address(a, arg_bus_path);
|
||||
r = bus_set_address(a, arg_transport, arg_bus_path, arg_runtime_scope);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set address to connect to: %m");
|
||||
return log_full_errno(priority, r, "Failed to set address to connect to: %m");
|
||||
|
||||
r = sd_bus_negotiate_fds(a, is_unix);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set FD negotiation: %m");
|
||||
return log_full_errno(priority, r, "Failed to set FD negotiation: %m");
|
||||
|
||||
r = sd_bus_start(a);
|
||||
if (r < 0)
|
||||
return bus_log_connect_error(r, arg_transport, arg_runtime_scope);
|
||||
return bus_log_connect_full(priority, r, arg_transport, arg_runtime_scope);
|
||||
|
||||
r = sd_bus_get_bus_id(a, &server_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get server ID: %m");
|
||||
return log_full_errno(priority, r, "Failed to get server ID: %m");
|
||||
|
||||
r = sd_bus_new(&b);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate bus: %m");
|
||||
return log_full_errno(priority, r, "Failed to allocate bus: %m");
|
||||
|
||||
r = sd_bus_set_fd(b, in_fd, out_fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set fds: %m");
|
||||
return log_full_errno(priority, r, "Failed to set fds: %m");
|
||||
|
||||
r = sd_bus_set_server(b, 1, server_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set server mode: %m");
|
||||
return log_full_errno(priority, r, "Failed to set server mode: %m");
|
||||
|
||||
r = sd_bus_negotiate_fds(b, is_unix);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set FD negotiation: %m");
|
||||
return log_full_errno(priority, r, "Failed to set FD negotiation: %m");
|
||||
|
||||
r = sd_bus_set_anonymous(b, true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set anonymous authentication: %m");
|
||||
return log_full_errno(priority, r, "Failed to set anonymous authentication: %m");
|
||||
|
||||
r = sd_bus_start(b);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to start bus forwarding server: %m");
|
||||
return log_full_errno(priority, r, "Failed to start bus forwarding server: %m");
|
||||
|
||||
for (;;) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||
@ -185,14 +231,14 @@ static int run(int argc, char *argv[]) {
|
||||
if (ERRNO_IS_NEG_DISCONNECT(r)) /* Treat 'connection reset by peer' as clean exit condition */
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to process bus a: %m");
|
||||
return log_full_errno(priority, r, "Failed to process bus a: %m");
|
||||
if (m) {
|
||||
if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected"))
|
||||
return 0;
|
||||
|
||||
r = sd_bus_send(b, m, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to send message: %m");
|
||||
return log_full_errno(priority, r, "Failed to send message: %m");
|
||||
}
|
||||
|
||||
if (r > 0)
|
||||
@ -202,14 +248,14 @@ static int run(int argc, char *argv[]) {
|
||||
if (ERRNO_IS_NEG_DISCONNECT(r)) /* Treat 'connection reset by peer' as clean exit condition */
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to process bus: %m");
|
||||
return log_full_errno(priority, r, "Failed to process bus: %m");
|
||||
if (m) {
|
||||
if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected"))
|
||||
return 0;
|
||||
|
||||
r = sd_bus_send(a, m, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to send message: %m");
|
||||
return log_full_errno(priority, r, "Failed to send message: %m");
|
||||
}
|
||||
|
||||
if (r > 0)
|
||||
@ -217,23 +263,23 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
fd = sd_bus_get_fd(a);
|
||||
if (fd < 0)
|
||||
return log_error_errno(fd, "Failed to get fd: %m");
|
||||
return log_full_errno(priority, fd, "Failed to get fd: %m");
|
||||
|
||||
events_a = sd_bus_get_events(a);
|
||||
if (events_a < 0)
|
||||
return log_error_errno(events_a, "Failed to get events mask: %m");
|
||||
return log_full_errno(priority, events_a, "Failed to get events mask: %m");
|
||||
|
||||
r = sd_bus_get_timeout(a, &timeout_a);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get timeout: %m");
|
||||
return log_full_errno(priority, r, "Failed to get timeout: %m");
|
||||
|
||||
events_b = sd_bus_get_events(b);
|
||||
if (events_b < 0)
|
||||
return log_error_errno(events_b, "Failed to get events mask: %m");
|
||||
return log_full_errno(priority, events_b, "Failed to get events mask: %m");
|
||||
|
||||
r = sd_bus_get_timeout(b, &timeout_b);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get timeout: %m");
|
||||
return log_full_errno(priority, r, "Failed to get timeout: %m");
|
||||
|
||||
t = usec_sub_unsigned(MIN(timeout_a, timeout_b), now(CLOCK_MONOTONIC));
|
||||
|
||||
@ -245,7 +291,7 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
r = ppoll_usec(p, ELEMENTSOF(p), t);
|
||||
if (r < 0 && !ERRNO_IS_TRANSIENT(r)) /* don't be bothered by signals, i.e. EINTR */
|
||||
return log_error_errno(r, "ppoll() failed: %m");
|
||||
return log_full_errno(priority, r, "ppoll() failed: %m");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ test_env = {
|
||||
'SYSTEMD_DEFAULT_LOCALE' : get_option('default-locale'),
|
||||
'SYSTEMD_SLOW_TESTS' : want_slow_tests ? '1' : '0',
|
||||
'PYTHONDONTWRITEBYTECODE' : '1',
|
||||
'SYSTEMD_LIBC' : get_option('libc'),
|
||||
}
|
||||
if conf.get('ENABLE_LOCALED') == 1
|
||||
test_env += {'SYSTEMD_LANGUAGE_FALLBACK_MAP' : language_fallback_map}
|
||||
|
||||
@ -124,7 +124,7 @@ TEST(copy_file_fd) {
|
||||
assert_se(write_string_file(in_fn, text, WRITE_STRING_FILE_CREATE) == 0);
|
||||
assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd, COPY_REFLINK) < 0);
|
||||
assert_se(copy_file_fd(in_fn, out_fd, COPY_REFLINK) >= 0);
|
||||
assert_se(lseek(out_fd, SEEK_SET, 0) == 0);
|
||||
assert_se(lseek(out_fd, 0, SEEK_SET) == 0);
|
||||
|
||||
assert_se(read(out_fd, buf, sizeof buf) == (ssize_t) strlen(text));
|
||||
ASSERT_STREQ(buf, text);
|
||||
|
||||
@ -127,7 +127,7 @@ TEST(os_release_support_ended) {
|
||||
|
||||
ASSERT_TRUE(os_release_support_ended("1999-01-01", false, NULL));
|
||||
ASSERT_FALSE(os_release_support_ended("2037-12-31", false, NULL));
|
||||
assert_se(os_release_support_ended("-1-1-1", true, NULL) == -EINVAL);
|
||||
ASSERT_ERROR(os_release_support_ended("1-1-1", true, NULL), ERANGE);
|
||||
|
||||
r = os_release_support_ended(NULL, false, NULL);
|
||||
if (r < 0)
|
||||
|
||||
@ -525,7 +525,7 @@ TEST(pid_get_cmdline_harder) {
|
||||
#define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'"
|
||||
#define EXPECT1v STRV_MAKE("foo", "'bar'", "\"bar$\"", "x y z", "!``")
|
||||
|
||||
ASSERT_OK_ZERO_ERRNO(lseek(fd, SEEK_SET, 0));
|
||||
ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
|
||||
ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE1, sizeof(CMDLINE1)), (ssize_t) sizeof(CMDLINE1));
|
||||
ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof(CMDLINE1)));
|
||||
|
||||
@ -550,7 +550,7 @@ TEST(pid_get_cmdline_harder) {
|
||||
#define EXPECT2p "foo $'\\001\\002\\003'"
|
||||
#define EXPECT2v STRV_MAKE("foo", "\1\2\3")
|
||||
|
||||
ASSERT_OK_ZERO_ERRNO(lseek(fd, SEEK_SET, 0));
|
||||
ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
|
||||
ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE2, sizeof(CMDLINE2)), (ssize_t) sizeof(CMDLINE2));
|
||||
ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof CMDLINE2));
|
||||
|
||||
|
||||
@ -559,7 +559,11 @@ TEST(memory_deny_write_execute_mmap) {
|
||||
p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch_lp64)
|
||||
assert_se(p == MAP_FAILED);
|
||||
assert_se(errno == EPERM);
|
||||
# ifdef __GLIBC__
|
||||
ASSERT_EQ(errno, EPERM);
|
||||
# else
|
||||
ASSERT_EQ(errno, ENOMEM); /* musl maps EPERM to ENOMEM. See src/mman/mmap.c in musl. */
|
||||
# endif
|
||||
#endif
|
||||
/* Depending on kernel, libseccomp, and glibc versions, other architectures
|
||||
* might fail or not. Let's not assert success. */
|
||||
|
||||
@ -13,8 +13,9 @@ TEST(rt_signals) {
|
||||
info(SIGRTMIN);
|
||||
info(SIGRTMAX);
|
||||
|
||||
/* We use signals SIGRTMIN+0 to SIGRTMIN+30 unconditionally */
|
||||
assert_se(SIGRTMAX - SIGRTMIN >= 30);
|
||||
/* We use signals SIGRTMIN+0 to SIGRTMIN+29 unconditionally. SIGRTMIN+30 can be used only when
|
||||
* built with glibc. */
|
||||
assert_se(SIGRTMAX - SIGRTMIN >= 29);
|
||||
}
|
||||
|
||||
static void test_signal_to_string_one(int val) {
|
||||
|
||||
@ -69,7 +69,7 @@ int probe_smart_media(int mtd_fd, mtd_info_t* info) {
|
||||
}
|
||||
|
||||
for (offset = 0; offset < block_size * spare_count; offset += sector_size) {
|
||||
(void) lseek(mtd_fd, SEEK_SET, offset);
|
||||
(void) lseek(mtd_fd, offset, SEEK_SET);
|
||||
|
||||
if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE) {
|
||||
cis_found = 1;
|
||||
|
||||
@ -13,6 +13,7 @@ if conf.get('ENABLE_SYSUSERS') == 1
|
||||
# https://github.com/mesonbuild/meson/issues/2681
|
||||
args : exe.full_path(),
|
||||
depends : exe,
|
||||
env : test_env,
|
||||
suite : 'sysusers')
|
||||
|
||||
if have_standalone_binaries
|
||||
@ -22,6 +23,7 @@ if conf.get('ENABLE_SYSUSERS') == 1
|
||||
# https://github.com/mesonbuild/meson/issues/2681
|
||||
args : exe.full_path(),
|
||||
depends : exe,
|
||||
env : test_env,
|
||||
suite : 'sysusers')
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -13,6 +13,12 @@ TESTDIR=$(mktemp --tmpdir --directory "test-sysusers.XXXXXXXXXX")
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$TESTDIR'" EXIT INT QUIT PIPE
|
||||
|
||||
skip_nis() {
|
||||
# musl seems to not support NIS entries. Let's skip the test case for NIS entries.
|
||||
local path=${1:?}
|
||||
[[ "${SYSTEMD_LIBC:-}" == musl && "${path##*/}" == "test-11.input" ]]
|
||||
}
|
||||
|
||||
prepare_testdir() {
|
||||
mkdir -p "$TESTDIR/etc/sysusers.d/"
|
||||
mkdir -p "$TESTDIR/usr/lib/sysusers.d/"
|
||||
@ -50,6 +56,7 @@ rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
|
||||
|
||||
# happy tests
|
||||
for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||
skip_nis "$f" && continue
|
||||
echo "*** Running $f"
|
||||
prepare_testdir "${f%.input}"
|
||||
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
||||
@ -59,6 +66,7 @@ for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||
done
|
||||
|
||||
for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||
skip_nis "$f" && continue
|
||||
echo "*** Running $f on stdin"
|
||||
prepare_testdir "${f%.input}"
|
||||
touch "$TESTDIR/etc/sysusers.d/test.conf"
|
||||
@ -68,6 +76,7 @@ for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||
done
|
||||
|
||||
for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||
skip_nis "$f" && continue
|
||||
echo "*** Running $f on stdin with --replace"
|
||||
prepare_testdir "${f%.input}"
|
||||
touch "$TESTDIR/etc/sysusers.d/test.conf"
|
||||
@ -133,6 +142,7 @@ SYS_GID_MAX999
|
||||
EOF
|
||||
|
||||
for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||
skip_nis "$f" && continue
|
||||
echo "*** Running $f (with login.defs)"
|
||||
prepare_testdir "${f%.input}"
|
||||
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
||||
@ -149,6 +159,7 @@ mv "$TESTDIR/etc/login.defs" "$TESTDIR/etc/login.defs.moved"
|
||||
ln -s ../../../../../etc/login.defs.moved "$TESTDIR/etc/login.defs"
|
||||
|
||||
for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||
skip_nis "$f" && continue
|
||||
echo "*** Running $f (with login.defs symlinked)"
|
||||
prepare_testdir "${f%.input}"
|
||||
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
||||
@ -161,13 +172,22 @@ done
|
||||
|
||||
rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
|
||||
|
||||
preprocess_error() {
|
||||
# Convert error message for ERANGE from glibc to musl.
|
||||
if [[ "${SYSTEMD_LIBC:-}" == musl ]]; then
|
||||
sed -e 's/Numerical result out of range/Result not representable/' "${1:?}"
|
||||
else
|
||||
cat "${1:?}"
|
||||
fi
|
||||
}
|
||||
|
||||
# tests for error conditions
|
||||
for f in $(find "$SOURCE"/unhappy-*.input | sort -V); do
|
||||
echo "*** Running test $f"
|
||||
prepare_testdir "${f%.input}"
|
||||
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
||||
SYSTEMD_LOG_LEVEL=info "$SYSUSERS" --root="$TESTDIR" 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >"$TESTDIR/err"
|
||||
if ! diff -u "$TESTDIR/err" "${f%.*}.expected-err" >&2; then
|
||||
if ! diff -u "$TESTDIR/err" <(preprocess_error "${f%.*}.expected-err") >&2; then
|
||||
echo >&2 "**** Unexpected error output for $f"
|
||||
cat >&2 "$TESTDIR/err"
|
||||
exit 1
|
||||
|
||||
@ -124,6 +124,13 @@ for i in {0..19}; do
|
||||
systemctl start "transaction-cycle$i.service"
|
||||
done
|
||||
|
||||
IDS_FILE="/tmp/TEST-03-JOBS-CYCLE-IDS-$RANDOM"
|
||||
varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Manager.Describe '{}' | jq '.runtime.TransactionsWithOrderingCycle' >"$IDS_FILE"
|
||||
[[ "$(jq length "$IDS_FILE")" -ge 20 ]]
|
||||
for i in {0..19}; do
|
||||
journalctl -b TRANSACTION_ID="$(jq -r ".[$i]" "$IDS_FILE")" --grep "cycle starting with"
|
||||
done
|
||||
|
||||
# Test PropagatesStopTo= when restart (issue #26839)
|
||||
systemctl start propagatestopto-and-pullin.target
|
||||
systemctl --quiet is-active propagatestopto-and-pullin.target
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user