summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac18
-rw-r--r--hwdb/60-sensor.hwdb13
-rw-r--r--man/systemd-firstboot.xml10
-rw-r--r--src/basic/MurmurHash2.c6
-rw-r--r--src/basic/fs-util.c23
-rw-r--r--src/basic/khash.c2
-rw-r--r--src/basic/nss-util.h6
-rw-r--r--src/basic/siphash24.c7
-rw-r--r--src/basic/socket-util.c2
-rw-r--r--src/basic/time-util.c2
-rw-r--r--src/core/dbus-execute.c2
-rw-r--r--src/core/job.c2
-rw-r--r--src/core/socket.c1
-rw-r--r--src/core/timer.c3
-rw-r--r--src/coredump/coredump.c6
-rw-r--r--src/hostname/hostnamed.c4
-rw-r--r--src/journal-remote/journal-gatewayd.c9
-rw-r--r--src/journal-remote/journal-remote.c4
-rw-r--r--src/journal-remote/microhttpd-util.h16
-rw-r--r--src/journal/journal-file.c2
-rw-r--r--src/journal/lookup3.c4
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c2
-rw-r--r--src/libsystemd/sd-device/sd-device.c2
-rw-r--r--src/libudev/libudev-util.c14
-rw-r--r--src/network/networkd-address.c4
-rw-r--r--src/nspawn/nspawn.c22
-rw-r--r--src/systemctl/systemctl.c21
-rw-r--r--src/test/test-fs-util.c7
-rw-r--r--src/test/test-socket-util.c3
-rw-r--r--src/udev/udev-event.c449
-rw-r--r--units/initrd-switch-root.service.in1
-rw-r--r--units/systemd-vconsole-setup.service.in1
32 files changed, 374 insertions, 294 deletions
diff --git a/configure.ac b/configure.ac
index 48c71ce340..b9143d28ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -601,6 +601,15 @@ AC_ARG_WITH([nobody-group],
AC_SUBST(NOBODY_GROUP_NAME)
AC_DEFINE_UNQUOTED(NOBODY_GROUP_NAME, ["$NOBODY_GROUP_NAME"], [The name of the nobody group (the one with GID 65534)])
+AC_ARG_WITH([fallback-hostname],
+ AS_HELP_STRING([--with-fallback-hostname=NAME],
+ [specify the hostname used if none configured]),
+ [FALLBACK_HOSTNAME="$withval"],
+ [FALLBACK_HOSTNAME=localhost])
+
+AC_SUBST(FALLBACK_HOSTNAME)
+AC_DEFINE_UNQUOTED(FALLBACK_HOSTNAME, ["$FALLBACK_HOSTNAME"], [The hostname used if none configured])
+
# ------------------------------------------------------------------------------
have_xz=no
AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [disable optional XZ support]))
@@ -1715,12 +1724,13 @@ AC_MSG_RESULT([
Wheel group: ${have_wheel_group}
Debug shell: ${SUSHELL} @ ${DEBUGTTY}
TTY GID: ${TTY_GID}
- Maximum System UID: ${SYSTEM_UID_MAX}
- Maximum System GID: ${SYSTEM_GID_MAX}
+ Maximum system UID: ${SYSTEM_UID_MAX}
+ Maximum system GID: ${SYSTEM_GID_MAX}
Certificate root: ${CERTIFICATEROOT}
Support URL: ${SUPPORT_URL}
- Nobody User Name: ${NOBODY_USER_NAME}
- Nobody Group Name: ${NOBODY_GROUP_NAME}
+ nobody user name: ${NOBODY_USER_NAME}
+ nobody group name: ${NOBODY_GROUP_NAME}
+ Fallback hostname: ${FALLBACK_HOSTNAME}
CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
diff --git a/hwdb/60-sensor.hwdb b/hwdb/60-sensor.hwdb
index 3160cf77e8..fcbdcabf30 100644
--- a/hwdb/60-sensor.hwdb
+++ b/hwdb/60-sensor.hwdb
@@ -15,7 +15,7 @@
# /etc/udev/hwdb.d/61-sensor-local.hwdb
# and add your rules there. To load the new rules execute (as root):
# systemd-hwdb update
-# udevadm trigger `dirname $(udevadm info -n "/dev/iio:deviceXXX" -q path)`
+# udevadm trigger -y `dirname $(udevadm info -n "/dev/iio:deviceXXX" -q path)`
# where /dev/iio:deviceXXX is the device in question.
#
# If your changes are generally applicable, preferably send them as a pull
@@ -25,6 +25,9 @@
# include your new rules, a description of the device, and the output of
# udevadm info --export-db
#
+# For hwdb format and systemd behavior:
+# https://www.freedesktop.org/software/systemd/man/hwdb.html
+#
# Allowed properties are:
# ACCEL_MOUNT_MATRIX=<matrix>
#
@@ -34,11 +37,17 @@
# eg. the identity matrix.
#
# [1]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dfc57732ad38f93ae6232a3b4e64fd077383a0f1
-
+#
#
# Sort by brand, model
#########################################
+# AsusTek
+#########################################
+sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB*
+ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 0
+
+#########################################
# Winbook
#########################################
sensor:modalias:acpi:BMA250*:dmi:*svn*WinBook*:*pn*TW100*
diff --git a/man/systemd-firstboot.xml b/man/systemd-firstboot.xml
index 8cdc297a0e..539422ab98 100644
--- a/man/systemd-firstboot.xml
+++ b/man/systemd-firstboot.xml
@@ -63,8 +63,14 @@
<para><command>systemd-firstboot</command> initializes the most
basic system settings interactively on the first boot, or
- optionally non-interactively when a system image is created. The
- following settings may be set up:</para>
+ optionally non-interactively when a system image is created.
+ The service is started if <varname>ConditionFirstBoot=yes</varname>
+ is satisfied. This essentially means that <filename>/etc</filename>
+ is empty, see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details.</para>
+
+ <para>The following settings may be set up:</para>
<itemizedlist>
<listitem><para>The system locale, more specifically the two
diff --git a/src/basic/MurmurHash2.c b/src/basic/MurmurHash2.c
index 9020793930..a282a21201 100644
--- a/src/basic/MurmurHash2.c
+++ b/src/basic/MurmurHash2.c
@@ -69,9 +69,9 @@ uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed )
switch(len)
{
- case 3: h ^= data[2] << 16;
- case 2: h ^= data[1] << 8;
- case 1: h ^= data[0];
+ case 3: h ^= data[2] << 16; /* fall through */
+ case 2: h ^= data[1] << 8; /* fall through */
+ case 1: h ^= data[0]; /* fall through */
h *= m;
};
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index e31fa2711a..8fe19ee4e4 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -723,6 +723,8 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
return -errno;
if (S_ISLNK(st.st_mode)) {
+ char *joined;
+
_cleanup_free_ char *destination = NULL;
/* This is a symlink, in this case read the destination. But let's make sure we don't follow
@@ -746,9 +748,6 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
if (fd < 0)
return -errno;
- free_and_replace(buffer, destination);
-
- todo = buffer;
free(done);
/* Note that we do not revalidate the root, we take it as is. */
@@ -760,19 +759,17 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
return -ENOMEM;
}
- } else {
- char *joined;
+ }
- /* A relative destination. If so, this is what we'll prefix what's left to do with what
- * we just read, and start the loop again, but remain in the current directory. */
+ /* Prefix what's left to do with what we just read, and start the loop again,
+ * but remain in the current directory. */
- joined = strjoin("/", destination, todo);
- if (!joined)
- return -ENOMEM;
+ joined = strjoin("/", destination, todo);
+ if (!joined)
+ return -ENOMEM;
- free(buffer);
- todo = buffer = joined;
- }
+ free(buffer);
+ todo = buffer = joined;
continue;
}
diff --git a/src/basic/khash.c b/src/basic/khash.c
index 9a2a3edb75..84648dc1c9 100644
--- a/src/basic/khash.c
+++ b/src/basic/khash.c
@@ -143,7 +143,7 @@ int khash_dup(khash *h, khash **ret) {
copy->fd = -1;
copy->algorithm = strdup(h->algorithm);
- if (!copy)
+ if (!copy->algorithm)
return -ENOMEM;
copy->fd = accept4(h->fd, NULL, 0, SOCK_CLOEXEC);
diff --git a/src/basic/nss-util.h b/src/basic/nss-util.h
index e7844fff96..9d927a8227 100644
--- a/src/basic/nss-util.h
+++ b/src/basic/nss-util.h
@@ -27,6 +27,10 @@
#define NSS_SIGNALS_BLOCK SIGALRM,SIGVTALRM,SIGPIPE,SIGCHLD,SIGTSTP,SIGIO,SIGHUP,SIGUSR1,SIGUSR2,SIGPROF,SIGURG,SIGWINCH
+#ifndef DEPRECATED_RES_USE_INET6
+# define DEPRECATED_RES_USE_INET6 0x00002000
+#endif
+
#define NSS_GETHOSTBYNAME_PROTOTYPES(module) \
enum nss_status _nss_##module##_gethostbyname4_r( \
const char *name, \
@@ -92,7 +96,7 @@ enum nss_status _nss_##module##_gethostbyname_r( \
int *errnop, int *h_errnop) { \
enum nss_status ret = NSS_STATUS_NOTFOUND; \
\
- if (_res.options & RES_USE_INET6) \
+ if (_res.options & DEPRECATED_RES_USE_INET6) \
ret = _nss_##module##_gethostbyname3_r( \
name, \
AF_INET6, \
diff --git a/src/basic/siphash24.c b/src/basic/siphash24.c
index 8c1cdc3db6..4bb41786c8 100644
--- a/src/basic/siphash24.c
+++ b/src/basic/siphash24.c
@@ -127,18 +127,25 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
switch (left) {
case 7:
state->padding |= ((uint64_t) in[6]) << 48;
+ /* fall through */
case 6:
state->padding |= ((uint64_t) in[5]) << 40;
+ /* fall through */
case 5:
state->padding |= ((uint64_t) in[4]) << 32;
+ /* fall through */
case 4:
state->padding |= ((uint64_t) in[3]) << 24;
+ /* fall through */
case 3:
state->padding |= ((uint64_t) in[2]) << 16;
+ /* fall through */
case 2:
state->padding |= ((uint64_t) in[1]) << 8;
+ /* fall through */
case 1:
state->padding |= ((uint64_t) in[0]);
+ /* fall through */
case 0:
break;
}
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index c882b8a12a..77f81a60ba 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -887,7 +887,7 @@ bool ifname_valid(const char *p) {
if ((unsigned char) *p <= 32U)
return false;
- if (*p == '/')
+ if (*p == ':' || *p == '/')
return false;
numeric = numeric && (*p >= '0' && *p <= '9');
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index 7a5b29d77e..1310c76336 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -1271,7 +1271,7 @@ bool clock_supported(clockid_t clock) {
if (!clock_boottime_supported())
return false;
- /* fall through, after checking the cached value for CLOCK_BOOTTIME. */
+ /* fall through */
default:
/* For everything else, check properly */
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 3ae894d59c..cc10e2d8e7 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -1698,7 +1698,7 @@ int bus_exec_context_set_transient_property(
if (!path_is_absolute(source))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
if (!path_is_absolute(destination))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", source);
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
if (!IN_SET(mount_flags, 0, MS_REC))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
diff --git a/src/core/job.c b/src/core/job.c
index f7c4c59c32..00f7d7998f 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -697,7 +697,7 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR
static void job_print_status_message(Unit *u, JobType t, JobResult result) {
static const struct {
const char *color, *word;
- } const statuses[_JOB_RESULT_MAX] = {
+ } statuses[_JOB_RESULT_MAX] = {
[JOB_DONE] = { ANSI_GREEN, " OK " },
[JOB_TIMEOUT] = { ANSI_HIGHLIGHT_RED, " TIME " },
[JOB_FAILED] = { ANSI_HIGHLIGHT_RED, "FAILED" },
diff --git a/src/core/socket.c b/src/core/socket.c
index 3cae6b31bb..a7b9ada65c 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2668,6 +2668,7 @@ const char* socket_port_type_to_string(SocketPort *p) {
if (socket_address_family(&p->address) == AF_NETLINK)
return "Netlink";
+ /* fall through */
default:
return NULL;
}
diff --git a/src/core/timer.c b/src/core/timer.c
index a2c08b53d0..d7441d638f 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -422,7 +422,8 @@ static void timer_enter_waiting(Timer *t, bool initial) {
}
/* In a container we don't want to include the time the host
* was already up when the container started, so count from
- * our own startup. Fall through. */
+ * our own startup. */
+ /* fall through */
case TIMER_STARTUP:
base = UNIT(t)->manager->userspace_timestamp.monotonic;
break;
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index d55d896df4..1f6fb5de1e 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -642,7 +642,11 @@ static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) {
if (r < 0)
return r;
- return get_process_cmdline(container_pid, 0, false, cmdline);
+ r = get_process_cmdline(container_pid, 0, false, cmdline);
+ if (r < 0)
+ return r;
+
+ return 1;
}
static int change_uid_gid(const char *context[]) {
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index 74256e4444..4657cf8c77 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -283,7 +283,7 @@ static int context_update_kernel_hostname(Context *c) {
/* ... and the ultimate fallback */
else
- hn = "localhost";
+ hn = FALLBACK_HOSTNAME;
if (sethostname_idempotent(hn) < 0)
return -errno;
@@ -419,7 +419,7 @@ static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *
name = c->data[PROP_STATIC_HOSTNAME];
if (isempty(name))
- name = "localhost";
+ name = FALLBACK_HOSTNAME;
if (!hostname_is_valid(name, false))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", name);
diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
index f86b67faa2..9a1c5b76ca 100644
--- a/src/journal-remote/journal-gatewayd.c
+++ b/src/journal-remote/journal-gatewayd.c
@@ -1029,10 +1029,9 @@ int main(int argc, char *argv[]) {
{ MHD_OPTION_END, 0, NULL }};
int opts_pos = 2;
- /* We force MHD_USE_PIPE_FOR_SHUTDOWN here, in order
- * to make sure libmicrohttpd doesn't use shutdown()
- * on our listening socket, which would break socket
- * re-activation. See
+ /* We force MHD_USE_ITC here, in order to make sure
+ * libmicrohttpd doesn't use shutdown() on our listening
+ * socket, which would break socket re-activation. See
*
* https://lists.gnu.org/archive/html/libmicrohttpd/2015-09/msg00014.html
* https://github.com/systemd/systemd/pull/1286
@@ -1041,7 +1040,7 @@ int main(int argc, char *argv[]) {
int flags =
MHD_USE_DEBUG |
MHD_USE_DUAL_STACK |
- MHD_USE_PIPE_FOR_SHUTDOWN |
+ MHD_USE_ITC |
MHD_USE_POLL |
MHD_USE_THREAD_PER_CONNECTION;
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index d86c3681b1..d0d8d936e3 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -648,9 +648,9 @@ static int setup_microhttpd_server(RemoteServer *s,
int flags =
MHD_USE_DEBUG |
MHD_USE_DUAL_STACK |
- MHD_USE_EPOLL_LINUX_ONLY |
+ MHD_USE_EPOLL |
MHD_USE_PEDANTIC_CHECKS |
- MHD_USE_PIPE_FOR_SHUTDOWN;
+ MHD_USE_ITC;
const union MHD_DaemonInfo *info;
int r, epoll_fd;
diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h
index af26ab69fe..49def4f630 100644
--- a/src/journal-remote/microhttpd-util.h
+++ b/src/journal-remote/microhttpd-util.h
@@ -24,13 +24,25 @@
#include "macro.h"
+/* Those defines are added when options are renamed, hence the check for the *old* name. */
+
/* Compatiblity with libmicrohttpd < 0.9.38 */
#ifndef MHD_HTTP_NOT_ACCEPTABLE
-#define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE
+# define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE
+#endif
+
+/* Renamed in µhttpd 0.9.52 */
+#ifndef MHD_USE_EPOLL_LINUX_ONLY
+# define MHD_USE_EPOLL MHD_USE_EPOLL_LINUX_ONLY
+#endif
+
+/* Renamed in µhttpd 0.9.51 */
+#ifndef MHD_USE_PIPE_FOR_SHUTDOWN
+# define MHD_USE_ITC MHD_USE_PIPE_FOR_SHUTDOWN
#endif
#if MHD_VERSION < 0x00094203
-#define MHD_create_response_from_fd_at_offset64 MHD_create_response_from_fd_at_offset
+# define MHD_create_response_from_fd_at_offset64 MHD_create_response_from_fd_at_offset
#endif
void microhttpd_logger(void *arg, const char *fmt, va_list ap) _printf_(2, 0);
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index bb1443725f..0a264aef92 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -285,7 +285,7 @@ static int journal_file_set_online(JournalFile *f) {
continue;
/* Canceled restart from offlining, must wait for offlining to complete however. */
- /* fall through to wait */
+ /* fall through */
default: {
int r;
diff --git a/src/journal/lookup3.c b/src/journal/lookup3.c
index d8f1a4977d..ec725ce46c 100644
--- a/src/journal/lookup3.c
+++ b/src/journal/lookup3.c
@@ -48,6 +48,10 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
# include <endian.h> /* attempt to define endianness */
#endif
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
+
/*
* My best guess at if you are big-endian or little-endian. This may
* need adjustment.
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index e81215f7d7..6444b0ce94 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -999,7 +999,7 @@ static int client_receive_message(
break;
}
- /* fall through for Soliciation Rapid Commit option check */
+ /* fall through */ /* for Soliciation Rapid Commit option check */
case DHCP6_STATE_REQUEST:
case DHCP6_STATE_RENEW:
case DHCP6_STATE_REBIND:
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index bc5e92f8fe..efeadf0cd4 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -560,7 +560,7 @@ int device_read_uevent_file(sd_device *device) {
value = &uevent[i];
state = VALUE;
- /* fall through to handle empty property */
+ /* fall through */ /* to handle empty property */
case VALUE:
if (strchr(NEWLINE, uevent[i])) {
uevent[i] = '\0';
diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c
index a9819b9db3..1d73d8f090 100644
--- a/src/libudev/libudev-util.c
+++ b/src/libudev/libudev-util.c
@@ -161,6 +161,20 @@ void util_remove_trailing_chars(char *path, char c)
path[--len] = '\0';
}
+/*
+ * Copy from 'str' to 'to', while removing all leading and trailing whitespace,
+ * and replacing each run of consecutive whitespace with a single underscore.
+ * The chars from 'str' are copied up to the \0 at the end of the string, or
+ * at most 'len' chars. This appends \0 to 'to', at the end of the copied
+ * characters.
+ *
+ * If 'len' chars are copied into 'to', the final \0 is placed at len+1
+ * (i.e. 'to[len] = \0'), so the 'to' buffer must have at least len+1
+ * chars available.
+ *
+ * Note this may be called with 'str' == 'to', i.e. to replace whitespace
+ * in-place in a buffer. This function can handle that situation.
+ */
int util_replace_whitespace(const char *str, char *to, size_t len)
{
size_t i, j;
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 2b698d9531..ffd2e18a45 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -809,8 +809,8 @@ int config_parse_label(
if (r < 0)
return r;
- if (!ifname_valid(rvalue)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is not valid or too long, ignoring assignment: %s", rvalue);
+ if (strlen(rvalue) >= IFNAMSIZ) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is too long, ignoring assignment: %s", rvalue);
return 0;
}
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 532be148a6..0474f61d43 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -676,9 +676,8 @@ static int parse_argv(int argc, char *argv[]) {
r = free_and_strdup(&arg_machine, optarg);
if (r < 0)
return log_oom();
-
- break;
}
+ break;
case 'Z':
arg_selinux_context = optarg;
@@ -1918,7 +1917,7 @@ static int wait_for_container(pid_t pid, ContainerStatus *container) {
return 0;
}
- /* CLD_KILLED fallthrough */
+ /* fall through */
case CLD_DUMPED:
log_error("Container %s terminated by signal %s.", arg_machine, signal_to_string(status.si_status));
@@ -2131,6 +2130,7 @@ static int inner_child(
NULL, /* NOTIFY_SOCKET */
NULL
};
+ const char *exec_target;
_cleanup_strv_free_ char **env_use = NULL;
int r;
@@ -2317,28 +2317,32 @@ static int inner_child(
memcpy_safe(a + 1, arg_parameters, m * sizeof(char*));
a[1 + m] = NULL;
- a[0] = (char*) "/usr/lib/systemd/systemd";
+ exec_target = a[0] = (char*) "/usr/lib/systemd/systemd";
execve(a[0], a, env_use);
- a[0] = (char*) "/lib/systemd/systemd";
+ exec_target = a[0] = (char*) "/lib/systemd/systemd";
execve(a[0], a, env_use);
- a[0] = (char*) "/sbin/init";
+ exec_target = a[0] = (char*) "/sbin/init";
execve(a[0], a, env_use);
- } else if (!strv_isempty(arg_parameters))
+ } else if (!strv_isempty(arg_parameters)) {
+ exec_target = arg_parameters[0];
execvpe(arg_parameters[0], arg_parameters, env_use);
- else {
+ } else {
if (!arg_chdir)
/* If we cannot change the directory, we'll end up in /, that is expected. */
(void) chdir(home ?: "/root");
+ exec_target = "/bin/bash";
execle("/bin/bash", "-bash", NULL, env_use);
+
+ exec_target = "/bin/sh";
execle("/bin/sh", "-sh", NULL, env_use);
}
r = -errno;
(void) log_open();
- return log_error_errno(r, "execv() failed: %m");
+ return log_error_errno(r, "execv(%s) failed: %m", exec_target);
}
static int setup_sd_notify_child(void) {
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 41e8d6075a..a20ca1bcb5 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -5655,16 +5655,22 @@ static int switch_root(int argc, char *argv[], void *userdata) {
}
/* Instruct PID1 to exclude us from its killing spree applied during
- * the transition from the initrd to the main system otherwise we would
- * exit with a failure status even though the switch to the new root
- * has succeed. */
- if (in_initrd())
- argv_cmdline[0] = '@';
+ * the transition. Otherwise we would exit with a failure status even
+ * though the switch to the new root has succeed. */
+ argv_cmdline[0] = '@';
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ /* If we are slow to exit after the root switch, the new systemd instance
+ * will send us a signal to terminate. Just ignore it and exit normally.
+ * This way the unit does not end up as failed.
+ */
+ r = ignore_signals(SIGTERM, -1);
+ if (r < 0)
+ log_warning_errno(r, "Failed to change disposition of SIGTERM to ignore: %m");
+
log_debug("Switching root - root: %s; init: %s", root, strna(init));
r = sd_bus_call_method(
@@ -5676,8 +5682,11 @@ static int switch_root(int argc, char *argv[], void *userdata) {
&error,
NULL,
"ss", root, init);
- if (r < 0)
+ if (r < 0) {
+ (void) default_signals(SIGTERM, -1);
+
return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r));
+ }
return 0;
}
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index ae68587be9..4cb465d0d2 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -186,6 +186,13 @@ static void test_chase_symlinks(void) {
r = chase_symlinks(p, NULL, CHASE_NONEXISTENT, &result);
assert_se(r == -ENOENT);
+ p = strjoina(temp, "/target");
+ q = strjoina(temp, "/top");
+ assert_se(symlink(q, p) >= 0);
+ p = strjoina(temp, "/target/idontexist");
+ r = chase_symlinks(p, NULL, 0, &result);
+ assert_se(r == -ENOENT);
+
assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
}
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index e1f5fd5084..d80613dc84 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -30,7 +30,6 @@
static void test_ifname_valid(void) {
assert(ifname_valid("foo"));
assert(ifname_valid("eth0"));
- assert(ifname_valid("eth0:0"));
assert(!ifname_valid("0"));
assert(!ifname_valid("99"));
@@ -45,7 +44,7 @@ static void test_ifname_valid(void) {
assert(!ifname_valid("."));
assert(!ifname_valid(".."));
assert(ifname_valid("foo.bar"));
- assert(ifname_valid("x:y"));
+ assert(!ifname_valid("x:y"));
assert(ifname_valid("xxxxxxxxxxxxxxx"));
assert(!ifname_valid("xxxxxxxxxxxxxxxx"));
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index deffefd60b..3f9c3ed0cf 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -73,29 +73,219 @@ void udev_event_unref(struct udev_event *event) {
free(event);
}
+enum subst_type {
+ SUBST_UNKNOWN,
+ SUBST_DEVNODE,
+ SUBST_ATTR,
+ SUBST_ENV,
+ SUBST_KERNEL,
+ SUBST_KERNEL_NUMBER,
+ SUBST_DRIVER,
+ SUBST_DEVPATH,
+ SUBST_ID,
+ SUBST_MAJOR,
+ SUBST_MINOR,
+ SUBST_RESULT,
+ SUBST_PARENT,
+ SUBST_NAME,
+ SUBST_LINKS,
+ SUBST_ROOT,
+ SUBST_SYS,
+};
+
+static size_t subst_format_var(struct udev_event *event, struct udev_device *dev,
+ enum subst_type type, char *attr,
+ char *dest, size_t l) {
+ char *s = dest;
+
+ switch (type) {
+ case SUBST_DEVPATH:
+ l = strpcpy(&s, l, udev_device_get_devpath(dev));
+ break;
+ case SUBST_KERNEL:
+ l = strpcpy(&s, l, udev_device_get_sysname(dev));
+ break;
+ case SUBST_KERNEL_NUMBER:
+ if (udev_device_get_sysnum(dev) == NULL)
+ break;
+ l = strpcpy(&s, l, udev_device_get_sysnum(dev));
+ break;
+ case SUBST_ID:
+ if (event->dev_parent == NULL)
+ break;
+ l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
+ break;
+ case SUBST_DRIVER: {
+ const char *driver;
+
+ if (event->dev_parent == NULL)
+ break;
+
+ driver = udev_device_get_driver(event->dev_parent);
+ if (driver == NULL)
+ break;
+ l = strpcpy(&s, l, driver);
+ break;
+ }
+ case SUBST_MAJOR: {
+ char num[UTIL_PATH_SIZE];
+
+ sprintf(num, "%u", major(udev_device_get_devnum(dev)));
+ l = strpcpy(&s, l, num);
+ break;
+ }
+ case SUBST_MINOR: {
+ char num[UTIL_PATH_SIZE];
+
+ sprintf(num, "%u", minor(udev_device_get_devnum(dev)));
+ l = strpcpy(&s, l, num);
+ break;
+ }
+ case SUBST_RESULT: {
+ char *rest;
+ int i;
+
+ if (event->program_result == NULL)
+ break;
+ /* get part of the result string */
+ i = 0;
+ if (attr != NULL)
+ i = strtoul(attr, &rest, 10);
+ if (i > 0) {
+ char result[UTIL_PATH_SIZE];
+ char tmp[UTIL_PATH_SIZE];
+ char *cpos;
+
+ strscpy(result, sizeof(result), event->program_result);
+ cpos = result;
+ while (--i) {
+ while (cpos[0] != '\0' && !isspace(cpos[0]))
+ cpos++;
+ while (isspace(cpos[0]))
+ cpos++;
+ if (cpos[0] == '\0')
+ break;
+ }
+ if (i > 0) {
+ log_error("requested part of result string not found");
+ break;
+ }
+ strscpy(tmp, sizeof(tmp), cpos);
+ /* %{2+}c copies the whole string from the second part on */
+ if (rest[0] != '+') {
+ cpos = strchr(tmp, ' ');
+ if (cpos)
+ cpos[0] = '\0';
+ }
+ l = strpcpy(&s, l, tmp);
+ } else {
+ l = strpcpy(&s, l, event->program_result);
+ }
+ break;
+ }
+ case SUBST_ATTR: {
+ const char *value = NULL;
+ char vbuf[UTIL_NAME_SIZE];
+ size_t len;
+ int count;
+
+ if (attr == NULL) {
+ log_error("missing file parameter for attr");
+ break;
+ }
+
+ /* try to read the value specified by "[dmi/id]product_name" */
+ if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
+ value = vbuf;
+
+ /* try to read the attribute the device */
+ if (value == NULL)
+ value = udev_device_get_sysattr_value(event->dev, attr);
+
+ /* try to read the attribute of the parent device, other matches have selected */
+ if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
+ value = udev_device_get_sysattr_value(event->dev_parent, attr);
+
+ if (value == NULL)
+ break;
+
+ /* strip trailing whitespace, and replace unwanted characters */
+ if (value != vbuf)
+ strscpy(vbuf, sizeof(vbuf), value);
+ len = strlen(vbuf);
+ while (len > 0 && isspace(vbuf[--len]))
+ vbuf[len] = '\0';
+ count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
+ if (count > 0)
+ log_debug("%i character(s) replaced" , count);
+ l = strpcpy(&s, l, vbuf);
+ break;
+ }
+ case SUBST_PARENT: {
+ struct udev_device *dev_parent;
+ const char *devnode;
+
+ dev_parent = udev_device_get_parent(event->dev);
+ if (dev_parent == NULL)
+ break;
+ devnode = udev_device_get_devnode(dev_parent);
+ if (devnode != NULL)
+ l = strpcpy(&s, l, devnode + strlen("/dev/"));
+ break;
+ }
+ case SUBST_DEVNODE:
+ if (udev_device_get_devnode(dev) != NULL)
+ l = strpcpy(&s, l, udev_device_get_devnode(dev));
+ break;
+ case SUBST_NAME:
+ if (event->name != NULL)
+ l = strpcpy(&s, l, event->name);
+ else if (udev_device_get_devnode(dev) != NULL)
+ l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
+ else
+ l = strpcpy(&s, l, udev_device_get_sysname(dev));
+ break;
+ case SUBST_LINKS: {
+ struct udev_list_entry *list_entry;
+
+ list_entry = udev_device_get_devlinks_list_entry(dev);
+ if (list_entry == NULL)
+ break;
+ l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+ udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
+ l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
+ break;
+ }
+ case SUBST_ROOT:
+ l = strpcpy(&s, l, "/dev");
+ break;
+ case SUBST_SYS:
+ l = strpcpy(&s, l, "/sys");
+ break;
+ case SUBST_ENV:
+ if (attr == NULL) {
+ break;
+ } else {
+ const char *value;
+
+ value = udev_device_get_property_value(event->dev, attr);
+ if (value == NULL)
+ break;
+ l = strpcpy(&s, l, value);
+ break;
+ }
+ default:
+ log_error("unknown substitution type=%i", type);
+ break;
+ }
+
+ return s - dest;
+}
+
size_t udev_event_apply_format(struct udev_event *event,
const char *src, char *dest, size_t size,
bool replace_whitespace) {
struct udev_device *dev = event->dev;
- enum subst_type {
- SUBST_UNKNOWN,
- SUBST_DEVNODE,
- SUBST_ATTR,
- SUBST_ENV,
- SUBST_KERNEL,
- SUBST_KERNEL_NUMBER,
- SUBST_DRIVER,
- SUBST_DEVPATH,
- SUBST_ID,
- SUBST_MAJOR,
- SUBST_MINOR,
- SUBST_RESULT,
- SUBST_PARENT,
- SUBST_NAME,
- SUBST_LINKS,
- SUBST_ROOT,
- SUBST_SYS,
- };
static const struct subst_map {
const char *name;
const char fmt;
@@ -132,10 +322,9 @@ size_t udev_event_apply_format(struct udev_event *event,
for (;;) {
enum subst_type type = SUBST_UNKNOWN;
- char attrbuf[UTIL_PATH_SIZE], sbuf[UTIL_PATH_SIZE];
- char *attr = NULL, *_s;
- size_t _l;
- bool replws = replace_whitespace;
+ char attrbuf[UTIL_PATH_SIZE];
+ char *attr = NULL;
+ size_t subst_len;
while (from[0] != '\0') {
if (from[0] == '$') {
@@ -204,213 +393,17 @@ subst:
attr = NULL;
}
- /* result subst handles space as field separator */
- if (type == SUBST_RESULT)
- replws = false;
-
- if (replws) {
- /* store dest string ptr and remaining len */
- _s = s;
- _l = l;
- /* temporarily use sbuf */
- s = sbuf;
- l = UTIL_PATH_SIZE;
- }
-
- switch (type) {
- case SUBST_DEVPATH:
- l = strpcpy(&s, l, udev_device_get_devpath(dev));
- break;
- case SUBST_KERNEL:
- l = strpcpy(&s, l, udev_device_get_sysname(dev));
- break;
- case SUBST_KERNEL_NUMBER:
- if (udev_device_get_sysnum(dev) == NULL)
- break;
- l = strpcpy(&s, l, udev_device_get_sysnum(dev));
- break;
- case SUBST_ID:
- if (event->dev_parent == NULL)
- break;
- l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
- break;
- case SUBST_DRIVER: {
- const char *driver;
-
- if (event->dev_parent == NULL)
- break;
-
- driver = udev_device_get_driver(event->dev_parent);
- if (driver == NULL)
- break;
- l = strpcpy(&s, l, driver);
- break;
- }
- case SUBST_MAJOR: {
- char num[UTIL_PATH_SIZE];
-
- sprintf(num, "%u", major(udev_device_get_devnum(dev)));
- l = strpcpy(&s, l, num);
- break;
- }
- case SUBST_MINOR: {
- char num[UTIL_PATH_SIZE];
-
- sprintf(num, "%u", minor(udev_device_get_devnum(dev)));
- l = strpcpy(&s, l, num);
- break;
- }
- case SUBST_RESULT: {
- char *rest;
- int i;
-
- if (event->program_result == NULL)
- break;
- /* get part of the result string */
- i = 0;
- if (attr != NULL)
- i = strtoul(attr, &rest, 10);
- if (i > 0) {
- char result[UTIL_PATH_SIZE];
- char tmp[UTIL_PATH_SIZE];
- char *cpos;
-
- strscpy(result, sizeof(result), event->program_result);
- cpos = result;
- while (--i) {
- while (cpos[0] != '\0' && !isspace(cpos[0]))
- cpos++;
- while (isspace(cpos[0]))
- cpos++;
- if (cpos[0] == '\0')
- break;
- }
- if (i > 0) {
- log_error("requested part of result string not found");
- break;
- }
- strscpy(tmp, sizeof(tmp), cpos);
- /* %{2+}c copies the whole string from the second part on */
- if (rest[0] != '+') {
- cpos = strchr(tmp, ' ');
- if (cpos)
- cpos[0] = '\0';
- }
- l = strpcpy(&s, l, tmp);
- } else {
- l = strpcpy(&s, l, event->program_result);
- }
- break;
- }
- case SUBST_ATTR: {
- const char *value = NULL;
- char vbuf[UTIL_NAME_SIZE];
- size_t len;
- int count;
-
- if (attr == NULL) {
- log_error("missing file parameter for attr");
- break;
- }
-
- /* try to read the value specified by "[dmi/id]product_name" */
- if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
- value = vbuf;
-
- /* try to read the attribute the device */
- if (value == NULL)
- value = udev_device_get_sysattr_value(event->dev, attr);
-
- /* try to read the attribute of the parent device, other matches have selected */
- if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
- value = udev_device_get_sysattr_value(event->dev_parent, attr);
-
- if (value == NULL)
- break;
+ subst_len = subst_format_var(event, dev, type, attr, s, l);
- /* strip trailing whitespace, and replace unwanted characters */
- if (value != vbuf)
- strscpy(vbuf, sizeof(vbuf), value);
- len = strlen(vbuf);
- while (len > 0 && isspace(vbuf[--len]))
- vbuf[len] = '\0';
- count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
- if (count > 0)
- log_debug("%i character(s) replaced" , count);
- l = strpcpy(&s, l, vbuf);
- break;
- }
- case SUBST_PARENT: {
- struct udev_device *dev_parent;
- const char *devnode;
-
- dev_parent = udev_device_get_parent(event->dev);
- if (dev_parent == NULL)
- break;
- devnode = udev_device_get_devnode(dev_parent);
- if (devnode != NULL)
- l = strpcpy(&s, l, devnode + strlen("/dev/"));
- break;
- }
- case SUBST_DEVNODE:
- if (udev_device_get_devnode(dev) != NULL)
- l = strpcpy(&s, l, udev_device_get_devnode(dev));
- break;
- case SUBST_NAME:
- if (event->name != NULL)
- l = strpcpy(&s, l, event->name);
- else if (udev_device_get_devnode(dev) != NULL)
- l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
- else
- l = strpcpy(&s, l, udev_device_get_sysname(dev));
- break;
- case SUBST_LINKS: {
- struct udev_list_entry *list_entry;
+ /* SUBST_RESULT handles spaces itself */
+ if (replace_whitespace && type != SUBST_RESULT)
+ /* util_replace_whitespace can replace in-place,
+ * and does nothing if subst_len == 0
+ */
+ subst_len = util_replace_whitespace(s, s, subst_len);
- list_entry = udev_device_get_devlinks_list_entry(dev);
- if (list_entry == NULL)
- break;
- l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
- udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
- l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
- break;
- }
- case SUBST_ROOT:
- l = strpcpy(&s, l, "/dev");
- break;
- case SUBST_SYS:
- l = strpcpy(&s, l, "/sys");
- break;
- case SUBST_ENV:
- if (attr == NULL) {
- break;
- } else {
- const char *value;
-
- value = udev_device_get_property_value(event->dev, attr);
- if (value == NULL)
- break;
- l = strpcpy(&s, l, value);
- break;
- }
- default:
- log_error("unknown substitution type=%i", type);
- break;
- }
-
- /* replace whitespace in sbuf and copy to dest */
- if (replws) {
- size_t tmplen = UTIL_PATH_SIZE - l;
-
- /* restore s and l to dest string values */
- s = _s;
- l = _l;
-
- /* copy ws-replaced value to s */
- tmplen = util_replace_whitespace(sbuf, s, MIN(tmplen, l));
- l -= tmplen;
- s += tmplen;
- }
+ s += subst_len;
+ l -= subst_len;
}
out:
diff --git a/units/initrd-switch-root.service.in b/units/initrd-switch-root.service.in
index 219748d19b..d31497f5e3 100644
--- a/units/initrd-switch-root.service.in
+++ b/units/initrd-switch-root.service.in
@@ -16,4 +16,3 @@ AllowIsolate=yes
[Service]
Type=oneshot
ExecStart=@rootbindir@/systemctl --no-block switch-root /sysroot
-KillMode=none
diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
index 2bd1fd1a5d..8bb75c6a4f 100644
--- a/units/systemd-vconsole-setup.service.in
+++ b/units/systemd-vconsole-setup.service.in
@@ -9,6 +9,7 @@
Description=Setup Virtual Console
Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5)
DefaultDependencies=no
+Before=initrd-switch-root.target shutdown.target
ConditionPathExists=/dev/tty0
[Service]