Compare commits

..

5 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 21d0dd5a89 meson: allow WatchdogSec= in services to be configured
As discussed on systemd-devel [1], in Fedora we get lots of abrt reports
about the watchdog firing [2], but 100% of them seem to be caused by resource
starvation in the machine, and never actual deadlocks in the services being
monitored. Killing the services not only does not improve anything, but it
makes the resource starvation worse, because the service needs cycles to restart,
and coredump processing is also fairly expensive. This adds a configuration option
to allow the value to be changed. If the setting is not set, there is no change.

My plan is to set it to some ridiculusly high value, maybe 1h, to catch cases
where a service is actually hanging.

[1] https://lists.freedesktop.org/archives/systemd-devel/2019-October/043618.html
[2] https://bugzilla.redhat.com/show_bug.cgi?id=1300212
2019-10-25 17:20:24 +02:00
Franck Bui 21b40f1662 fileio: introduce read_full_virtual_file() for reading virtual files in sysfs, procfs
Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work
with two sorts of virtual files.

One sort uses "seq_file", and the results of the first read are buffered for
the second read. The other sort uses "raw" reads which always go direct to the
device.

In the later case, the content of the virtual file must be retrieved with a
single read otherwise subsequent read might get the new value instead of
finding EOF immediately. That's the reason why the usage of fread(3) is
prohibited in this case as it always performs a second call to read(2) looking
for EOF which is subject to the race described previously.

Fixes: #13585.
2019-10-25 15:24:49 +02:00
Zbigniew Jędrzejewski-Szmek f5d28be33f
Merge pull request #13682 from zachsmith/systemd-sleep-prefer-resume-over-priority
systemd-sleep: prefer resume device or file
2019-10-25 14:48:12 +02:00
Zach Smith ea470720e4 systemd-sleep: improve /proc/swaps open fail message 2019-10-24 07:38:31 -07:00
Zach Smith 7bdf56a28a systemd-sleep: always prefer resume device or file
This change checks each swap partition or file reported in /proc/swaps
to see if it matches the values configured with resume= and
resume_offset= kernel parameters. If a match is found, the matching swap
entry is used as the hibernation location regardless of swap priority.
2019-10-24 07:38:24 -07:00
23 changed files with 373 additions and 141 deletions

View File

@ -795,6 +795,10 @@ conf.set_quoted('SYSTEMD_DEFAULT_LOCALE', default_locale)
conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
service_watchdog = get_option('service-watchdog')
substs.set('SERVICE_WATCHDOG',
service_watchdog == '' ? '' : 'WatchdogSec=' + service_watchdog)
substs.set('SUSHELL', get_option('debug-shell'))
substs.set('DEBUGTTY', get_option('debug-tty'))
conf.set_quoted('DEBUGTTY', get_option('debug-tty'))
@ -3113,7 +3117,8 @@ status = [
'default cgroup hierarchy: @0@'.format(default_hierarchy),
'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme),
'default KillUserProcesses setting: @0@'.format(kill_user_processes),
'default locale: @0@'.format(default_locale)]
'default locale: @0@'.format(default_locale),
'systemd service watchdog: @0@'.format(service_watchdog == '' ? 'disabled' : service_watchdog)]
alt_dns_servers = '\n '.join(dns_servers.split(' '))
alt_ntp_servers = '\n '.join(ntp_servers.split(' '))

View File

@ -207,6 +207,8 @@ option('gshadow', type : 'boolean',
description : 'support for shadow group')
option('default-locale', type : 'string', value : '',
description : 'default locale used when /etc/locale.conf does not exist')
option('service-watchdog', type : 'string', value : '3min',
description : 'default watchdog setting for systemd services')
option('default-dnssec', type : 'combo',
description : 'default DNSSEC mode',

View File

@ -310,6 +310,113 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
return 1;
}
int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size) {
_cleanup_free_ char *buf = NULL;
_cleanup_close_ int fd = -1;
struct stat st;
size_t n, size;
int n_retries;
char *p;
assert(ret_contents);
/* Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work
* with two sorts of virtual files. One sort uses "seq_file", and the results of
* the first read are buffered for the second read. The other sort uses "raw"
* reads which always go direct to the device. In the latter case, the content of
* the virtual file must be retrieved with a single read otherwise a second read
* might get the new value instead of finding EOF immediately. That's the reason
* why the usage of fread(3) is prohibited in this case as it always performs a
* second call to read(2) looking for EOF. See issue 13585. */
fd = open(filename, O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
/* Start size for files in /proc which usually report a file size of 0. */
size = LINE_MAX / 2;
/* Limit the number of attempts to read the number of bytes returned by fstat(). */
n_retries = 3;
for (;;) {
if (n_retries <= 0)
return -EIO;
if (fstat(fd, &st) < 0)
return -errno;
if (!S_ISREG(st.st_mode))
return -EBADF;
/* Be prepared for files from /proc which generally report a file size of 0. */
if (st.st_size > 0) {
size = st.st_size;
n_retries--;
} else
size = size * 2;
if (size > READ_FULL_BYTES_MAX)
return -E2BIG;
p = realloc(buf, size + 1);
if (!p)
return -ENOMEM;
buf = TAKE_PTR(p);
for (;;) {
ssize_t k;
/* Read one more byte so we can detect whether the content of the
* file has already changed or the guessed size for files from /proc
* wasn't large enough . */
k = read(fd, buf, size + 1);
if (k >= 0) {
n = k;
break;
}
if (errno != -EINTR)
return -errno;
}
/* Consider a short read as EOF */
if (n <= size)
break;
/* Hmm... either we read too few bytes from /proc or less likely the content
* of the file might have been changed (and is now bigger) while we were
* processing, let's try again either with a bigger guessed size or the new
* file size. */
if (lseek(fd, 0, SEEK_SET) < 0)
return -errno;
}
if (n < size) {
p = realloc(buf, n + 1);
if (!p)
return -ENOMEM;
buf = TAKE_PTR(p);
}
if (!ret_size) {
/* Safety check: if the caller doesn't want to know the size of what we
* just read it will rely on the trailing NUL byte. But if there's an
* embedded NUL byte, then we should refuse operation as otherwise
* there'd be ambiguity about what we just read. */
if (memchr(buf, 0, n))
return -EBADMSG;
} else
*ret_size = n;
buf[n] = 0;
*ret_contents = TAKE_PTR(buf);
return 0;
}
int read_full_stream_full(
FILE *f,
const char *filename,
@ -342,9 +449,9 @@ int read_full_stream_full(
if (st.st_size > READ_FULL_BYTES_MAX)
return -E2BIG;
/* Start with the right file size, but be prepared for files from /proc which generally report a file
* size of 0. Note that we increase the size to read here by one, so that the first read attempt
* already makes us notice the EOF. */
/* Start with the right file size. Note that we increase the size
* to read here by one, so that the first read attempt already
* makes us notice the EOF. */
if (st.st_size > 0)
n_next = st.st_size + 1;
@ -502,7 +609,7 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin
assert(pattern);
assert(field);
r = read_full_file(filename, &status, NULL);
r = read_full_virtual_file(filename, &status, NULL);
if (r < 0)
return r;

View File

@ -56,6 +56,7 @@ int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **co
static inline int read_full_file(const char *filename, char **contents, size_t *size) {
return read_full_file_full(filename, 0, contents, size);
}
int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size);
int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size);
static inline int read_full_stream(FILE *f, char **contents, size_t *size) {
return read_full_stream_full(f, NULL, 0, contents, size);

View File

@ -1786,7 +1786,7 @@ _public_ int sd_device_get_sysattr_value(sd_device *device, const char *sysattr,
size_t size;
/* read attribute value */
r = read_full_file(path, &value, &size);
r = read_full_virtual_file(path, &value, &size);
if (r < 0)
return r;

View File

@ -17,6 +17,7 @@
#include <unistd.h>
#include "alloc-util.h"
#include "btrfs-util.h"
#include "conf-parser.h"
#include "def.h"
#include "env-util.h"
@ -28,6 +29,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "sleep-config.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
@ -165,16 +167,7 @@ int can_sleep_disk(char **types) {
#define HIBERNATION_SWAP_THRESHOLD 0.98
/* entry in /proc/swaps */
typedef struct SwapEntry {
char *device;
char *type;
uint64_t size;
uint64_t used;
int priority;
} SwapEntry;
static SwapEntry* swap_entry_free(SwapEntry *se) {
SwapEntry* swap_entry_free(SwapEntry *se) {
if (!se)
return NULL;
@ -184,24 +177,153 @@ static SwapEntry* swap_entry_free(SwapEntry *se) {
return mfree(se);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(SwapEntry*, swap_entry_free);
HibernateLocation* hibernate_location_free(HibernateLocation *hl) {
if (!hl)
return NULL;
int find_hibernate_location(char **device, char **type, uint64_t *size, uint64_t *used) {
swap_entry_free(hl->swap);
free(hl->resume);
return mfree(hl);
}
static int swap_device_to_major_minor(const SwapEntry *swap, char **ret) {
_cleanup_free_ char *major_minor = NULL;
_cleanup_close_ int fd = -1;
struct stat sb;
dev_t swap_dev;
int r;
assert(swap);
assert(swap->device);
assert(swap->type);
fd = open(swap->device, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0)
return log_debug_errno(errno, "Unable to open '%s': %m", swap->device);
r = fstat(fd, &sb);
if (r < 0)
return log_debug_errno(errno, "Unable to stat %s: %m", swap->device);
swap_dev = streq(swap->type, "partition") ? sb.st_rdev : sb.st_dev;
if (asprintf(&major_minor, "%u:%u", major(swap_dev), minor(swap_dev)) < 0)
return log_oom();
*ret = TAKE_PTR(major_minor);
return 0;
}
static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offset) {
_cleanup_close_ int fd = -1;
_cleanup_free_ struct fiemap *fiemap = NULL;
struct stat sb;
int r, btrfs;
assert(swap);
assert(swap->device);
assert(streq(swap->type, "file"));
fd = open(swap->device, O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (!fd)
return log_error_errno(errno, "Failed to open %s: %m", swap->device);
r = fstat(fd, &sb);
if (r < 0)
return log_error_errno(errno, "Failed to stat %s: %m", swap->device);
btrfs = btrfs_is_filesystem(fd);
if (btrfs < 0)
return log_error_errno(r, "Error checking %s for Btrfs filesystem: %m", swap->device);
else if (btrfs > 0) {
log_debug("Detection of swap file offset on Btrfs is not supported: %s; skipping", swap->device);
*ret_offset = 0;
return 0;
}
r = read_fiemap(fd, &fiemap);
if (r < 0)
return log_debug_errno(r, "Unable to read extent map for '%s': %m", swap->device);
*ret_offset = fiemap->fm_extents[0].fe_physical / page_size();
return 0;
}
static int read_resume_files(char **ret_resume, uint64_t *ret_resume_offset) {
_cleanup_free_ char *resume, *resume_offset_str = NULL;
uint64_t resume_offset = 0;
int r;
r = read_one_line_file("/sys/power/resume", &resume);
if (r < 0)
return log_debug_errno(r, "Error reading from /sys/power/resume: %m");
r = read_one_line_file("/sys/power/resume_offset", &resume_offset_str);
if (r < 0) {
if (r == -ENOENT)
log_debug("Kernel does not support resume_offset; swap file offset detection will be skipped.");
else
return log_debug_errno(r, "Error reading from /sys/power/resume_offset: %m");
} else {
r = safe_atou64(resume_offset_str, &resume_offset);
if (r < 0)
return log_error_errno(r, "Failed to parse 'resume_offset' from string: %s", resume_offset_str);
}
if (resume_offset > 0 && streq(*ret_resume, "0:0")) {
log_debug("Found offset in /sys/power/resume_offset: %" PRIu64 "; no device id found in /sys/power/resume; ignoring resume_offset", resume_offset);
resume_offset = 0;
}
*ret_resume = TAKE_PTR(resume);
*ret_resume_offset = resume_offset;
return 0;
}
static bool location_is_resume_device(const HibernateLocation *location, const char *sys_resume, const uint64_t sys_offset) {
assert(location);
assert(location->resume);
assert(sys_resume);
return streq(sys_resume, location->resume) && sys_offset == location->resume_offset;
}
/*
* Attempt to find the hibernation location by parsing /proc/swaps, /sys/power/resume, and
* /sys/power/resume_offset.
*
* Returns:
* 1 - HibernateLocation matches values found in /sys/power/resume & /sys/power/resume_offset
* 0 - HibernateLocation is highest priority swap with most remaining space; no valid values exist in /sys/power/resume & /sys/power/resume_offset
* negative value in the case of error
*/
int find_hibernate_location(HibernateLocation **ret_hibernate_location) {
_cleanup_fclose_ FILE *f;
_cleanup_(swap_entry_freep) SwapEntry *selected_swap = NULL;
_cleanup_(hibernate_location_freep) HibernateLocation *hibernate_location = NULL;
_cleanup_free_ char *sys_resume = NULL;
uint64_t sys_offset = 0;
unsigned i;
int r;
/* read the /sys/power/resume & /sys/power/resume_offset values */
r = read_resume_files(&sys_resume, &sys_offset);
if (r < 0)
return r;
f = fopen("/proc/swaps", "re");
if (!f) {
log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
"Failed to retrieve open /proc/swaps: %m");
"Failed to open /proc/swaps: %m");
return negative_errno();
}
(void) fscanf(f, "%*s %*s %*s %*s %*s\n");
for (i = 1;; i++) {
_cleanup_(swap_entry_freep) SwapEntry *swap = NULL;
uint64_t swap_offset = 0;
int k;
swap = new0(SwapEntry, 1);
@ -223,12 +345,14 @@ int find_hibernate_location(char **device, char **type, uint64_t *size, uint64_t
}
if (streq(swap->type, "file")) {
if (endswith(swap->device, "\\040(deleted)")) {
log_warning("Ignoring deleted swap file '%s'.", swap->device);
continue;
}
r = calculate_swap_file_offset(swap, &swap_offset);
if (r < 0)
return r;
} else if (streq(swap->type, "partition")) {
const char *fn;
@ -237,45 +361,64 @@ int find_hibernate_location(char **device, char **type, uint64_t *size, uint64_t
log_debug("Ignoring compressed RAM swap device '%s'.", swap->device);
continue;
}
} else {
log_debug("Swap type %s is unsupported for hibernation: %s; skipping", swap->type, swap->device);
continue;
}
/* prefer highest priority or swap with most remaining space when same priority */
if (!selected_swap || swap->priority > selected_swap->priority
|| ((swap->priority == selected_swap->priority)
&& (swap->size - swap->used) > (selected_swap->size - selected_swap->used))) {
selected_swap = swap_entry_free(selected_swap);
selected_swap = TAKE_PTR(swap);
/* prefer resume device or highest priority swap with most remaining space */
if (!hibernate_location || swap->priority > hibernate_location->swap->priority
|| ((swap->priority == hibernate_location->swap->priority)
&& (swap->size - swap->used) > (hibernate_location->swap->size - hibernate_location->swap->used))) {
_cleanup_free_ char *swap_device_id = NULL;
r = swap_device_to_major_minor(swap, &swap_device_id);
if (r < 0)
return r;
hibernate_location = hibernate_location_free(hibernate_location);
hibernate_location = new0(HibernateLocation, 1);
if (!hibernate_location)
return log_oom();
hibernate_location->resume = TAKE_PTR(swap_device_id);
hibernate_location->resume_offset = swap_offset;
hibernate_location->swap = TAKE_PTR(swap);
/* if the swap is the resume device, stop looping swaps */
if (location_is_resume_device(hibernate_location, sys_resume, sys_offset))
break;
}
}
if (!selected_swap)
return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS), "No swap partitions or files were found.");
if (!hibernate_location)
return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS), "No swap partitions or files were found");
/* use the swap entry with the highest priority */
if (device)
*device = TAKE_PTR(selected_swap->device);
if (type)
*type = TAKE_PTR(selected_swap->type);
if (size)
*size = selected_swap->size;
if (used)
*used = selected_swap->used;
if (!streq(sys_resume, "0:0") && !location_is_resume_device(hibernate_location, sys_resume, sys_offset))
return log_warning_errno(SYNTHETIC_ERRNO(ENOSYS), "/sys/power/resume and /sys/power/resume_offset has no matching entry in /proc/swaps; Hibernation will fail: resume=%s, resume_offset=%" PRIu64,
sys_resume, sys_offset);
log_debug("Highest priority swap entry found %s: %i", selected_swap->device, selected_swap->priority);
log_debug("Hibernation will attempt to use swap entry with path: %s, device: %s, offset: %" PRIu64 ", priority: %i",
hibernate_location->swap->device, hibernate_location->resume, hibernate_location->resume_offset, hibernate_location->swap->priority);
*ret_hibernate_location = TAKE_PTR(hibernate_location);
if (location_is_resume_device(*ret_hibernate_location, sys_resume, sys_offset))
return 1;
return 0;
}
static bool enough_swap_for_hibernation(void) {
_cleanup_free_ char *active = NULL;
_cleanup_(hibernate_location_freep) HibernateLocation *hibernate_location = NULL;
unsigned long long act = 0;
uint64_t size = 0, used = 0;
int r;
if (getenv_bool("SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK") > 0)
return true;
r = find_hibernate_location(NULL, NULL, &size, &used);
r = find_hibernate_location(&hibernate_location);
if (r < 0)
return false;
@ -291,9 +434,9 @@ static bool enough_swap_for_hibernation(void) {
return false;
}
r = act <= (size - used) * HIBERNATION_SWAP_THRESHOLD;
r = act <= (hibernate_location->swap->size - hibernate_location->swap->used) * HIBERNATION_SWAP_THRESHOLD;
log_debug("%s swap for hibernation, Active(anon)=%llu kB, size=%" PRIu64 " kB, used=%" PRIu64 " kB, threshold=%.2g%%",
r ? "Enough" : "Not enough", act, size, used, 100*HIBERNATION_SWAP_THRESHOLD);
r ? "Enough" : "Not enough", act, hibernate_location->swap->size, hibernate_location->swap->used, 100*HIBERNATION_SWAP_THRESHOLD);
return r;
}

View File

@ -23,11 +23,36 @@ typedef struct SleepConfig {
void free_sleep_config(SleepConfig *sc);
DEFINE_TRIVIAL_CLEANUP_FUNC(SleepConfig*, free_sleep_config);
/* entry in /proc/swaps */
typedef struct SwapEntry {
char *device;
char *type;
uint64_t size;
uint64_t used;
int priority;
} SwapEntry;
SwapEntry* swap_entry_free(SwapEntry *se);
DEFINE_TRIVIAL_CLEANUP_FUNC(SwapEntry*, swap_entry_free);
/*
* represents values for /sys/power/resume & /sys/power/resume_offset
* and the matching /proc/swap entry.
*/
typedef struct HibernateLocation {
char *resume;
uint64_t resume_offset;
SwapEntry *swap;
} HibernateLocation;
HibernateLocation* hibernate_location_free(HibernateLocation *hl);
DEFINE_TRIVIAL_CLEANUP_FUNC(HibernateLocation*, hibernate_location_free);
int sleep_settings(const char *verb, const SleepConfig *sleep_config, bool *ret_allow, char ***ret_modes, char ***ret_states);
int read_fiemap(int fd, struct fiemap **ret);
int parse_sleep_config(SleepConfig **sleep_config);
int find_hibernate_location(char **device, char **type, uint64_t *size, uint64_t *used);
int find_hibernate_location(HibernateLocation **ret_hibernate_location);
int can_sleep(const char *verb);
int can_sleep_disk(char **types);

View File

@ -38,78 +38,47 @@ static char* arg_verb = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_verb, freep);
static int write_hibernate_location_info(void) {
_cleanup_free_ char *device = NULL, *type = NULL;
_cleanup_free_ struct fiemap *fiemap = NULL;
static int write_hibernate_location_info(const HibernateLocation *hibernate_location) {
char offset_str[DECIMAL_STR_MAX(uint64_t)];
char device_str[DECIMAL_STR_MAX(uint64_t)];
_cleanup_close_ int fd = -1;
struct stat stb;
uint64_t offset;
int r;
r = find_hibernate_location(&device, &type, NULL, NULL);
assert(hibernate_location);
assert(hibernate_location->swap);
assert(hibernate_location->resume);
r = write_string_file("/sys/power/resume", hibernate_location->resume, WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0)
return log_debug_errno(r, "Unable to find hibernation location: %m");
return log_debug_errno(r, "Failed to write partition device to /sys/power/resume for '%s': '%s': %m",
hibernate_location->swap->device, hibernate_location->resume);
/* if it's a swap partition, we just write the disk to /sys/power/resume */
if (streq(type, "partition")) {
r = write_string_file("/sys/power/resume", device, WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0)
return log_debug_errno(r, "Failed to write partition device to /sys/power/resume: %m");
log_debug("Wrote resume= value for %s to /sys/power/resume: %s", hibernate_location->swap->device, hibernate_location->resume);
/* if it's a swap partition, we're done */
if (streq(hibernate_location->swap->type, "partition"))
return r;
}
if (!streq(type, "file"))
if (!streq(hibernate_location->swap->type, "file"))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"Invalid hibernate type: %s", type);
"Invalid hibernate type: %s", hibernate_location->swap->type);
/* Only available in 4.17+ */
if (access("/sys/power/resume_offset", W_OK) < 0) {
if (hibernate_location->resume_offset > 0 && access("/sys/power/resume_offset", W_OK) < 0) {
if (errno == ENOENT) {
log_debug("Kernel too old, can't configure resume offset, ignoring.");
log_debug("Kernel too old, can't configure resume_offset for %s, ignoring: %" PRIu64,
hibernate_location->swap->device, hibernate_location->resume_offset);
return 0;
}
return log_debug_errno(errno, "/sys/power/resume_offset not writeable: %m");
}
fd = open(device, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0)
return log_debug_errno(errno, "Unable to open '%s': %m", device);
r = fstat(fd, &stb);
if (r < 0)
return log_debug_errno(errno, "Unable to stat %s: %m", device);
r = btrfs_is_filesystem(fd);
if (r < 0)
return log_error_errno(r, "Error checking %s for Btrfs filesystem: %m", device);
if (r)
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"Unable to calculate swapfile offset when using Btrfs: %s", device);
r = read_fiemap(fd, &fiemap);
if (r < 0)
return log_debug_errno(r, "Unable to read extent map for '%s': %m", device);
if (fiemap->fm_mapped_extents == 0)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"No extents found in '%s'", device);
offset = fiemap->fm_extents[0].fe_physical / page_size();
xsprintf(offset_str, "%" PRIu64, offset);
xsprintf(offset_str, "%" PRIu64, hibernate_location->resume_offset);
r = write_string_file("/sys/power/resume_offset", offset_str, WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0)
return log_debug_errno(r, "Failed to write offset '%s': %m", offset_str);
return log_debug_errno(r, "Failed to write swap file offset to /sys/power/resume_offset for '%s': '%s': %m",
hibernate_location->swap->device, offset_str);
log_debug("Wrote calculated resume_offset value to /sys/power/resume_offset: %s", offset_str);
xsprintf(device_str, "%lx", (unsigned long)stb.st_dev);
r = write_string_file("/sys/power/resume", device_str, WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0)
return log_debug_errno(r, "Failed to write device '%s': %m", device_str);
log_debug("Wrote device id to /sys/power/resume: %s", device_str);
log_debug("Wrote resume_offset= value for %s to /sys/power/resume_offset: %s", hibernate_location->swap->device, offset_str);
return 0;
}
@ -156,32 +125,6 @@ static int write_state(FILE **f, char **states) {
return r;
}
static int configure_hibernation(void) {
_cleanup_free_ char *resume = NULL, *resume_offset = NULL;
int r;
/* check for proper hibernation configuration */
r = read_one_line_file("/sys/power/resume", &resume);
if (r < 0)
return log_debug_errno(r, "Error reading from /sys/power/resume: %m");
r = read_one_line_file("/sys/power/resume_offset", &resume_offset);
if (r < 0)
return log_debug_errno(r, "Error reading from /sys/power/resume_offset: %m");
if (!streq(resume_offset, "0") && !streq(resume, "0:0")) {
log_debug("Hibernating using device id and offset read from /sys/power/resume: %s and /sys/power/resume_offset: %s", resume, resume_offset);
return 0;
} else if (!streq(resume, "0:0")) {
log_debug("Hibernating using device id read from /sys/power/resume: %s", resume);
return 0;
} else if (!streq(resume_offset, "0"))
log_debug("Found offset in /sys/power/resume_offset: %s; no device id found in /sys/power/resume; ignoring offset", resume_offset);
/* if hibernation is not properly configured, attempt to calculate and write values */
return write_hibernate_location_info();
}
static int execute(char **modes, char **states) {
char *arguments[] = {
NULL,
@ -194,8 +137,9 @@ static int execute(char **modes, char **states) {
NULL
};
int r;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_(hibernate_location_freep) HibernateLocation *hibernate_location = NULL;
int r;
/* This file is opened first, so that if we hit an error,
* we can abort before modifying any state. */
@ -207,9 +151,14 @@ static int execute(char **modes, char **states) {
/* Configure the hibernation mode */
if (!strv_isempty(modes)) {
r = configure_hibernation();
r = find_hibernate_location(&hibernate_location);
if (r < 0)
return log_error_errno(r, "Failed to prepare for hibernation: %m");
return r;
else if (r == 0) {
r = write_hibernate_location_info(hibernate_location);
if (r < 0)
return log_error_errno(r, "Failed to prepare for hibernation: %m");
}
r = write_mode(modes);
if (r < 0)

View File

@ -36,4 +36,4 @@ RestrictSUIDSGID=yes
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service sethostname
WatchdogSec=3min
@SERVICE_WATCHDOG@

View File

@ -15,7 +15,6 @@ Documentation=https://www.freedesktop.org/wiki/Software/systemd/importd
[Service]
ExecStart=@rootlibexecdir@/systemd-importd
BusName=org.freedesktop.import1
WatchdogSec=3min
KillMode=mixed
CapabilityBoundingSet=CAP_CHOWN CAP_FOWNER CAP_FSETID CAP_MKNOD CAP_SETFCAP CAP_SYS_ADMIN CAP_SETPCAP CAP_DAC_OVERRIDE
NoNewPrivileges=yes
@ -28,3 +27,4 @@ SystemCallFilter=@system-service @mount
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
@SERVICE_WATCHDOG@

View File

@ -33,7 +33,7 @@ RestrictRealtime=yes
RestrictSUIDSGID=yes
SystemCallArchitectures=native
User=systemd-journal-remote
WatchdogSec=3min
@SERVICE_WATCHDOG@
# If there are many split up journal files we need a lot of fds to access them
# all in parallel.

View File

@ -31,7 +31,7 @@ StateDirectory=systemd/journal-upload
SupplementaryGroups=systemd-journal
SystemCallArchitectures=native
User=systemd-journal-upload
WatchdogSec=3min
@SERVICE_WATCHDOG@
# If there are many split up journal files we need a lot of fds to access them
# all in parallel.

View File

@ -37,7 +37,7 @@ SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service
Type=notify
WatchdogSec=3min
@SERVICE_WATCHDOG@
# If there are many split up journal files we need a lot of fds to access them
# all in parallel.

View File

@ -37,4 +37,4 @@ RestrictSUIDSGID=yes
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service
WatchdogSec=3min
@SERVICE_WATCHDOG@

View File

@ -55,7 +55,7 @@ StateDirectory=systemd/linger
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service
WatchdogSec=3min
@SERVICE_WATCHDOG@
# Increase the default a bit in order to allow many simultaneous logins since
# we keep one fd open per session.

View File

@ -29,7 +29,7 @@ RestrictRealtime=yes
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service @mount
WatchdogSec=3min
@SERVICE_WATCHDOG@
# Note that machined cannot be placed in a mount namespace, since it
# needs access to the host's mount namespace in order to implement the

View File

@ -44,7 +44,7 @@ SystemCallFilter=@system-service
Type=notify
RestartKillSignal=SIGUSR2
User=systemd-network
WatchdogSec=3min
@SERVICE_WATCHDOG@
[Install]
WantedBy=multi-user.target

View File

@ -23,10 +23,10 @@ KillMode=mixed
Type=notify
RestartForceExitStatus=133
SuccessExitStatus=133
WatchdogSec=3min
Slice=machine.slice
Delegate=yes
TasksMax=16384
@SERVICE_WATCHDOG@
# Enforce a strict device policy, similar to the one nspawn configures when it
# allocates its own scope unit. Make sure to keep these policies in sync if you

View File

@ -15,7 +15,6 @@ RequiresMountsFor=/var/lib/portables
[Service]
ExecStart=@rootlibexecdir@/systemd-portabled
BusName=org.freedesktop.portable1
WatchdogSec=3min
CapabilityBoundingSet=CAP_KILL CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_SETGID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_CHOWN CAP_FOWNER CAP_FSETID CAP_MKNOD
MemoryDenyWriteExecute=yes
ProtectHostname=yes
@ -26,3 +25,4 @@ SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
IPAddressDeny=any
@SERVICE_WATCHDOG@

View File

@ -46,7 +46,7 @@ SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service
Type=notify
User=systemd-resolve
WatchdogSec=3min
@SERVICE_WATCHDOG@
[Install]
WantedBy=multi-user.target

View File

@ -36,4 +36,4 @@ RestrictSUIDSGID=yes
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service @clock
WatchdogSec=3min
@SERVICE_WATCHDOG@

View File

@ -46,7 +46,7 @@ SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service @clock
Type=notify
User=systemd-timesync
WatchdogSec=3min
@SERVICE_WATCHDOG@
[Install]
WantedBy=sysinit.target

View File

@ -25,7 +25,6 @@ RestartSec=0
ExecStart=@rootlibexecdir@/systemd-udevd
ExecReload=@rootbindir@/udevadm control --reload --timeout 0
KillMode=mixed
WatchdogSec=3min
TasksMax=infinity
PrivateMounts=yes
ProtectHostname=yes
@ -38,3 +37,4 @@ SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
IPAddressDeny=any
@SERVICE_WATCHDOG@