Compare commits

..

10 Commits

Author SHA1 Message Date
Lennart Poettering 5895a9d600
Merge pull request #16874 from poettering/analyze-cap
introduce "systemd-analyze capability" command for dumping locally defined caps
2020-08-28 21:01:56 +02:00
Daniel Mack 5170afbc55 clock-util: read timestamp from /usr/lib/clock-epoch
On systems without an RTC, systemd currently sets the clock to a
compile-time epoch value, derived from the NEWS file in the
repository. This is not ideal as the initial clock hence depends
on the last time systemd was built, not when the image was compiled.

Let's provide a different way here and look at `/usr/lib/clock-epoch`.
If that file exists, it's timestamp for the last modification will be
used instead of the compile-time default.
2020-08-28 18:58:22 +02:00
Kyle Russell dd05042039 units: add missing usb-gadget.target 2020-08-28 18:57:58 +02:00
Lennart Poettering b2af819b22 analyze: add 'capability' verb for dumping all known and unknown caps 2020-08-28 18:52:48 +02:00
Lennart Poettering 0f849d0af9 analyze: fix error handling in one case 2020-08-28 18:14:53 +02:00
Lennart Poettering 524bdc95e7 basic: make sure we include inttypes.h when we use its types 2020-08-28 18:14:35 +02:00
Lennart Poettering 3c719357dc man: extend on the usec/sec discrepancy
Let's document the discrepancy between the Sec and USec suffixing of
unit files and D-Bus properties at three places: in "systemctl show"
(where it already was briefly mentioned), in the D-Bus interface
description (at one place at least, i.e. the most prominent of
properties that encapsulate time values, there are many more) and in the
general man page explaining time values.

By documenting this at all three places I think we now do as much as we
can do about this highlighting the discrepancy of the naming and the
reasons behind it.

Fixes: #2047
2020-08-28 18:01:17 +02:00
fangxiuning c53aafb7b5
tree-wide: drop pointless zero initialization (#16884)
tree-wide: drop pointless zero initialization
2020-08-28 17:45:54 +02:00
Lennart Poettering cd17bb6e71 networkd: consider any uevent other than "remove" sufficient for the network device to be ready 2020-08-28 17:45:05 +02:00
Ikey Doherty 97207ac85c login/logind: Include sys/stat.h for struct stat usage
We need to include `<sys/stat.h>` for usage of the `struct stat` in
the Manager struct, much as we already include `<stdbool.h>` for C99
booleans.

This helps alleviate another minor build failure on non-glibc systems.
2020-08-28 17:44:39 +02:00
19 changed files with 163 additions and 44 deletions

View File

@ -2720,12 +2720,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--property RestartUSec is not documented!-->
<!--property TimeoutStartUSec is not documented!-->
<!--property TimeoutStopUSec is not documented!-->
<!--property TimeoutAbortUSec is not documented!-->
<!--property TimeoutStartFailureMode is not documented!-->
<!--property TimeoutStopFailureMode is not documented!-->
@ -3772,6 +3766,18 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<para>Most properties of the Service interface map directly to the corresponding settings in service
unit files. For the sake of brevity, here's a list of all exceptions only:</para>
<para><varname>TimeoutStartUSec</varname>, <varname>TimeoutStopUSec</varname> and
<varname>TimeoutAbortUSec</varname> contain the start, stop and abort timeouts, in microseconds. Note
the slight difference in naming when compared to the matching unit file settings (see
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>7</manvolnum></citerefentry>):
these bus properties strictly use microseconds (and thus are suffixed <varname>…USec</varname>) while
the unit file settings default to a time unit of seconds (and thus are suffixed
<varname>…Sec</varname>), unless a different unit is explicitly specified. This reflects that fact that
internally the service manager deals in microsecond units only, and the bus properties are a relatively
low-level (binary) concept exposing this. The unit file settings on the other hand are relatively
high-level (string-based) concepts and thus support more user friendly time specifications which
default to second time units but allow other units too, if specified.</para>
<para><varname>WatchdogTimestamp</varname> and <varname>WatchdogTimestampMonotonic</varname> contain
<constant>CLOCK_REALTIME</constant>/<constant>CLOCK_MONOTONIC</constant> microsecond timestamps of the
last watchdog ping received from the service, or 0 if none was ever received.</para>
@ -9238,8 +9244,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
<!--method AttachProcesses is not documented!-->
<!--property TimeoutStopUSec is not documented!-->
<!--property RuntimeMaxUSec is not documented!-->
<!--property Slice is not documented!-->

View File

@ -446,7 +446,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
current main process identifier as <literal>MainPID</literal> (which is runtime state), and time settings
are always exposed as properties ending in the <literal>…USec</literal> suffix even if a matching
configuration options end in <literal>…Sec</literal>, because microseconds is the normalized time unit used
by the system and service manager.</para>
internally by the system and service manager.</para>
<para>For details about many of these properties, see the documentation of the D-Bus interface
backing these properties, see
<citerefentry><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -70,6 +70,12 @@
<arg choice="plain">exit-status</arg>
<arg choice="opt" rep="repeat"><replaceable>STATUS</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-analyze</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">capability</arg>
<arg choice="opt" rep="repeat"><replaceable>CAPABILITY</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-analyze</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
@ -345,6 +351,30 @@ DATAERR 65 BSD
</example>
</refsect2>
<refsect2>
<title><command>systemd-analyze capability <optional><replaceable>CAPABILITY</replaceable>...</optional></command></title>
<para>This command prints a list of Linux capabilities along with their numeric IDs. See <citerefentry
project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for details. If no argument is specified the full list of capabilities known to the service manager and
the kernel is shown. Capabilities defined by the kernel but not known to the service manager are shown
as <literal>cap_???</literal>. Optionally, if arguments are specified they may refer to specific
cabilities by name or numeric ID, in which case only the indicated capabilities are shown in the
table.</para>
<example>
<title><command>Show some example capability names</command></title>
<programlisting>$ systemd-analyze capability 0 1 {30..32}
NAME NUMBER
cap_chown 0
cap_dac_override 1
cap_audit_control 30
cap_setfcap 31
cap_mac_override 32</programlisting>
</example>
</refsect2>
<refsect2>
<title><command>systemd-analyze condition <replaceable>CONDITION</replaceable>...</command></title>

View File

@ -544,22 +544,28 @@
<varlistentry>
<term><varname>CapabilityBoundingSet=</varname></term>
<listitem><para>Controls which capabilities to include in the capability bounding set for the executed
process. See <citerefentry
project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
details. Takes a whitespace-separated list of capability names, e.g. <constant>CAP_SYS_ADMIN</constant>,
<constant>CAP_DAC_OVERRIDE</constant>, <constant>CAP_SYS_PTRACE</constant>. Capabilities listed will be
included in the bounding set, all others are removed. If the list of capabilities is prefixed with
<literal>~</literal>, all but the listed capabilities will be included, the effect of the assignment
inverted. Note that this option also affects the respective capabilities in the effective, permitted and
inheritable capability sets. If this option is not used, the capability bounding set is not modified on process
execution, hence no limits on the capabilities of the process are enforced. This option may appear more than
once, in which case the bounding sets are merged by <constant>OR</constant>, or by <constant>AND</constant> if
the lines are prefixed with <literal>~</literal> (see below). If the empty string is assigned to this option,
the bounding set is reset to the empty capability set, and all prior settings have no effect. If set to
<literal>~</literal> (without any further argument), the bounding set is reset to the full set of available
capabilities, also undoing any previous settings. This does not affect commands prefixed with
<literal>+</literal>.</para>
<listitem><para>Controls which capabilities to include in the capability bounding set for the
executed process. See <citerefentry
project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for details. Takes a whitespace-separated list of capability names,
e.g. <constant>CAP_SYS_ADMIN</constant>, <constant>CAP_DAC_OVERRIDE</constant>,
<constant>CAP_SYS_PTRACE</constant>. Capabilities listed will be included in the bounding set, all
others are removed. If the list of capabilities is prefixed with <literal>~</literal>, all but the
listed capabilities will be included, the effect of the assignment inverted. Note that this option
also affects the respective capabilities in the effective, permitted and inheritable capability
sets. If this option is not used, the capability bounding set is not modified on process execution,
hence no limits on the capabilities of the process are enforced. This option may appear more than
once, in which case the bounding sets are merged by <constant>OR</constant>, or by
<constant>AND</constant> if the lines are prefixed with <literal>~</literal> (see below). If the
empty string is assigned to this option, the bounding set is reset to the empty capability set, and
all prior settings have no effect. If set to <literal>~</literal> (without any further argument),
the bounding set is reset to the full set of available capabilities, also undoing any previous
settings. This does not affect commands prefixed with <literal>+</literal>.</para>
<para>Use
<citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<command>capability</command> command to retrieve a list of capabilities defined on the local
system.</para>
<para>Example: if a unit has the following,
<programlisting>CapabilityBoundingSet=CAP_A CAP_B

View File

@ -75,6 +75,16 @@
<para>One can use the <command>timespan</command> command of
<citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>
to normalise a textual time span for testing and validation purposes.</para>
<para>Internally, systemd generally operates with microsecond time granularity, while the default time
unit in user-configurable time spans is usually seconds (see above). This disparity becomes visible when
comparing the same settings in the (high-level) unit file syntax with the matching (more low-level) D-Bus
properties (which are what
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<command>show</command> command displays). The former typically are suffixed with <literal>…Sec</literal>
to indicate the default unit of seconds, the latter are typically suffixed with <literal>…USec</literal>
to indicate the underlying low-level time unit, even if they both encapsulate the very same
settings.</para>
</refsect1>
<refsect1>

View File

@ -21,6 +21,8 @@
#include "bus-map-properties.h"
#include "bus-unit-util.h"
#include "calendarspec.h"
#include "cap-list.h"
#include "capability-util.h"
#include "conf-files.h"
#include "copy.h"
#include "def.h"
@ -1576,7 +1578,7 @@ static int dump_exit_status(int argc, char *argv[], void *userdata) {
status = exit_status_from_string(argv[i]);
if (status < 0)
return log_error_errno(r, "Invalid exit status \"%s\": %m", argv[i]);
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid exit status \"%s\".", argv[i]);
assert(status >= 0 && (size_t) status < ELEMENTSOF(exit_status_mappings));
r = table_add_many(table,
@ -1592,6 +1594,51 @@ static int dump_exit_status(int argc, char *argv[], void *userdata) {
return table_print(table, NULL);
}
static int dump_capabilities(int argc, char *argv[], void *userdata) {
_cleanup_(table_unrefp) Table *table = NULL;
unsigned last_cap;
int r;
table = table_new("name", "number");
if (!table)
return log_oom();
(void) table_set_align_percent(table, table_get_cell(table, 0, 1), 100);
/* Determine the maximum of the last cap known by the kernel and by us */
last_cap = MAX((unsigned) CAP_LAST_CAP, cap_last_cap());
if (strv_isempty(strv_skip(argv, 1)))
for (unsigned c = 0; c <= last_cap; c++) {
r = table_add_many(table,
TABLE_STRING, capability_to_name(c) ?: "cap_???",
TABLE_UINT, c);
if (r < 0)
return table_log_add_error(r);
}
else {
for (int i = 1; i < argc; i++) {
int c;
c = capability_from_name(argv[i]);
if (c < 0 || (unsigned) c > last_cap)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Capability \"%s\" not known.", argv[i]);
r = table_add_many(table,
TABLE_STRING, capability_to_name(c) ?: "cap_???",
TABLE_UINT, (unsigned) c);
if (r < 0)
return table_log_add_error(r);
}
(void) table_set_sort(table, (size_t) 1, (size_t) -1);
}
(void) pager_open(arg_pager_flags);
return table_print(table, NULL);
}
#if HAVE_SECCOMP
static int load_kernel_syscalls(Set **ret) {
@ -2126,6 +2173,7 @@ static int help(int argc, char *argv[], void *userdata) {
" unit-files List files and symlinks for units\n"
" unit-paths List load directories for units\n"
" exit-status [STATUS...] List exit status definitions\n"
" capability [CAP...] List capability definitions\n"
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
" condition CONDITION... Evaluate conditions and asserts\n"
" verify FILE... Check unit files for correctness\n"
@ -2363,6 +2411,7 @@ static int run(int argc, char *argv[]) {
{ "unit-paths", 1, 1, 0, dump_unit_paths },
{ "exit-status", VERB_ANY, VERB_ANY, 0, dump_exit_status },
{ "syscall-filter", VERB_ANY, VERB_ANY, 0, dump_syscall_filters },
{ "capability", VERB_ANY, VERB_ANY, 0, dump_capabilities },
{ "condition", 2, VERB_ANY, 0, do_condition },
{ "verify", 2, VERB_ANY, 0, do_verify },
{ "calendar", 2, VERB_ANY, 0, test_calendar },

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <inttypes.h>
const char *capability_to_name(int id);
int capability_from_name(const char *name);
int capability_list_length(void);

View File

@ -106,7 +106,7 @@ int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
int mac_smack_apply_pid(pid_t pid, const char *label) {
const char *p;
int r = 0;
int r;
assert(label);
@ -232,7 +232,7 @@ int mac_smack_fix_container(const char *path, const char *inside_path, LabelFixF
}
int mac_smack_copy(const char *dest, const char *src) {
int r = 0;
int r;
_cleanup_free_ char *label = NULL;
assert(dest);

View File

@ -118,7 +118,7 @@ static int get_file_version(int fd, char **v) {
char *buf;
const char *s, *e;
char *x = NULL;
int r = 0;
int r;
assert(fd >= 0);
assert(v);
@ -248,7 +248,7 @@ static int print_efi_option(uint16_t id, bool in_order) {
_cleanup_free_ char *path = NULL;
sd_id128_t partition;
bool active;
int r = 0;
int r;
r = efi_get_boot_option(id, &title, &partition, &path, &active);
if (r < 0)

View File

@ -532,7 +532,7 @@ static int tree_one(sd_bus *bus, const char *service) {
static int tree(int argc, char **argv, void *userdata) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
char **i;
int r = 0;
int r;
/* Do superficial verification of arguments before even opening the bus */
STRV_FOREACH(i, strv_skip(argv, 1))

View File

@ -340,7 +340,7 @@ static int bus_job_allocate_bus_track(Job *j) {
}
int bus_job_coldplug_bus_track(Job *j) {
int r = 0;
int r;
_cleanup_strv_free_ char **deserialized_clients = NULL;
assert(j);

View File

@ -1149,7 +1149,7 @@ void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
}
int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l) {
int r = 0;
int r;
assert(m);
assert(t);

View File

@ -1425,7 +1425,7 @@ int swap_process_device_new(Manager *m, sd_device *dev) {
_cleanup_free_ char *e = NULL;
const char *dn, *devlink;
Unit *u;
int r = 0;
int r;
assert(m);
assert(dev);
@ -1463,7 +1463,7 @@ int swap_process_device_new(Manager *m, sd_device *dev) {
int swap_process_device_remove(Manager *m, sd_device *dev) {
const char *dn;
int r = 0;
int r;
Swap *s;
r = sd_device_get_devname(dev, &dn);

View File

@ -607,7 +607,7 @@ static int get_process_ns(pid_t pid, const char *namespace, ino_t *ns) {
static int get_mount_namespace_leader(pid_t pid, pid_t *container_pid) {
pid_t cpid = pid, ppid = 0;
ino_t proc_mntns;
int r = 0;
int r;
r = get_process_ns(pid, "mnt", &proc_mntns);
if (r < 0)

View File

@ -2,6 +2,7 @@
#pragma once
#include <stdbool.h>
#include <sys/stat.h>
#include "sd-bus.h"
#include "sd-device.h"

View File

@ -223,14 +223,16 @@ static int manager_udev_process_link(sd_device_monitor *monitor, sd_device *devi
return 0;
}
if (!IN_SET(action, DEVICE_ACTION_ADD, DEVICE_ACTION_CHANGE, DEVICE_ACTION_MOVE)) {
log_device_debug(device, "Ignoring udev %s event for device.", device_action_to_string(action));
/* Ignore the "remove" uevent — let's remove a device only if rtnetlink says so. All other uevents
* are "positive" events in some form, i.e. inform us about a changed or new network interface, that
* still exists and we are interested in that. */
if (action == DEVICE_ACTION_REMOVE)
return 0;
}
r = sd_device_get_ifindex(device, &ifindex);
if (r < 0) {
log_device_debug_errno(device, r, "Ignoring udev ADD event for device without ifindex or with invalid ifindex: %m");
log_device_debug_errno(device, r, "Ignoring udev %s event for device without ifindex or with invalid ifindex: %m",
device_action_to_string(action));
return 0;
}

View File

@ -166,7 +166,7 @@ static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct
int cg_trim(const char *controller, const char *path, bool delete_root) {
_cleanup_free_ char *fs = NULL;
int r = 0, q;
int r, q;
assert(path);

View File

@ -142,15 +142,25 @@ int clock_reset_timewarp(void) {
return 0;
}
#define TIME_EPOCH_USEC ((usec_t) TIME_EPOCH * USEC_PER_SEC)
#define EPOCH_FILE "/usr/lib/clock-epoch"
int clock_apply_epoch(void) {
struct stat st;
struct timespec ts;
usec_t epoch_usec;
if (now(CLOCK_REALTIME) >= TIME_EPOCH_USEC)
if (stat(EPOCH_FILE, &st) < 0) {
if (errno != ENOENT)
log_warning_errno(errno, "Cannot stat %s: %m\n", EPOCH_FILE);
epoch_usec = ((usec_t) TIME_EPOCH * USEC_PER_SEC);
} else
epoch_usec = timespec_load(&st.st_mtim);
if (now(CLOCK_REALTIME) >= epoch_usec)
return 0;
if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, TIME_EPOCH_USEC)) < 0)
if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, epoch_usec)) < 0)
return -errno;
return 1;

View File

@ -148,6 +148,7 @@ units = [
['tmp.mount', '',
'local-fs.target.wants/'],
['umount.target', ''],
['usb-gadget.target', ''],
['user.slice', ''],
['var-lib-machines.mount', 'ENABLE_MACHINED',
'remote-fs.target.wants/ machines.target.wants/'],