depending on hardware capabilities).</para>
<para>If <varname>RuntimeWatchdogSec=</varname> is set to a non-zero value, the watchdog hardware
- (<filename>/dev/watchdog</filename> or the path specified with <varname>WatchdogDevice=</varname> or
+ (<filename>/dev/watchdog0</filename> or the path specified with <varname>WatchdogDevice=</varname> or
the kernel option <varname>systemd.watchdog-device=</varname>) will be programmed to automatically
reboot the system if it is not contacted within the specified timeout interval. The system manager
will ensure to contact it at least once in half the specified timeout interval. This feature requires
<listitem><para>Configure the hardware watchdog device that the
runtime and shutdown watchdog timers will open and use. Defaults
- to <filename>/dev/watchdog</filename>. This setting has no
+ to <filename>/dev/watchdog0</filename>. This setting has no
effect if a hardware watchdog is not available.</para></listitem>
</varlistentry>
if conf.get('ENABLE_LOCALED') == 1
if conf.get('HAVE_XKBCOMMON') == 1
- # logind will load libxkbcommon.so dynamically on its own
- deps = [libdl]
- extra_includes = [libxkbcommon.get_pkgconfig_variable('includedir')]
+ # logind will load libxkbcommon.so dynamically on its own, but we still
+ # need to specify where the headers are
+ deps = [libdl, libxkbcommon.partial_dependency(compile_args: true)]
else
deps = []
- extra_includes = []
endif
executable(
'systemd-localed',
systemd_localed_sources,
- include_directories : includes + extra_includes,
+ include_directories : includes,
link_with : [libshared],
dependencies : deps,
install_rpath : rootlibexecdir,
int home_activate_cifs(
UserRecord *h,
+ HomeSetup *setup,
PasswordCache *cache,
UserRecord **ret_home) {
- _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
const char *hdo, *hd;
int r;
assert(h);
assert(user_record_storage(h) == USER_CIFS);
+ assert(setup);
assert(ret_home);
if (!h->cifs_service)
assert_se(hdo = user_record_home_directory(h));
hd = strdupa_safe(hdo); /* copy the string out, since it might change later in the home record object */
- r = home_setup_cifs(h, 0, &setup);
+ r = home_setup_cifs(h, 0, setup);
if (r < 0)
return r;
- r = home_refresh(h, &setup, NULL, cache, NULL, &new_home);
+ r = home_refresh(h, setup, NULL, cache, NULL, &new_home);
if (r < 0)
return r;
- setup.root_fd = safe_close(setup.root_fd);
+ setup->root_fd = safe_close(setup->root_fd);
r = home_move_mount(NULL, hd);
if (r < 0)
return r;
- setup.undo_mount = false;
+ setup->undo_mount = false;
log_info("Everything completed.");
return 1;
}
-int home_create_cifs(UserRecord *h, UserRecord **ret_home) {
- _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
+int home_create_cifs(UserRecord *h, HomeSetup *setup, UserRecord **ret_home) {
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
_cleanup_(closedirp) DIR *d = NULL;
_cleanup_close_ int copy = -1;
assert(h);
assert(user_record_storage(h) == USER_CIFS);
+ assert(setup);
assert(ret_home);
if (!h->cifs_service)
return log_error_errno(errno, "Unable to detect whether /sbin/mount.cifs exists: %m");
}
- r = home_setup_cifs(h, 0, &setup);
+ r = home_setup_cifs(h, 0, setup);
if (r < 0)
return r;
- copy = fcntl(setup.root_fd, F_DUPFD_CLOEXEC, 3);
+ copy = fcntl(setup->root_fd, F_DUPFD_CLOEXEC, 3);
if (copy < 0)
return -errno;
if (errno != 0)
return log_error_errno(errno, "Failed to detect if CIFS directory is empty: %m");
- r = home_populate(h, setup.root_fd);
+ r = home_populate(h, setup->root_fd);
if (r < 0)
return r;
- r = home_sync_and_statfs(setup.root_fd, NULL);
+ r = home_sync_and_statfs(setup->root_fd, NULL);
if (r < 0)
return r;
int home_setup_cifs(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup);
-int home_activate_cifs(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
+int home_activate_cifs(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home);
-int home_create_cifs(UserRecord *h, UserRecord **ret_home);
+int home_create_cifs(UserRecord *h, HomeSetup *setup, UserRecord **ret_home);
int home_activate_directory(
UserRecord *h,
+ HomeSetup *setup,
PasswordCache *cache,
UserRecord **ret_home) {
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *header_home = NULL;
- _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
const char *hdo, *hd, *ipo, *ip;
int r;
assert(h);
assert(IN_SET(user_record_storage(h), USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT));
+ assert(setup);
assert(ret_home);
assert_se(ipo = user_record_image_path(h));
assert_se(hdo = user_record_home_directory(h));
hd = strdupa_safe(hdo);
- r = home_setup(h, 0, cache, &setup, &header_home);
+ r = home_setup(h, 0, cache, setup, &header_home);
if (r < 0)
return r;
- r = home_refresh(h, &setup, header_home, cache, NULL, &new_home);
+ r = home_refresh(h, setup, header_home, cache, NULL, &new_home);
if (r < 0)
return r;
- setup.root_fd = safe_close(setup.root_fd);
+ setup->root_fd = safe_close(setup->root_fd);
/* Create mount point to mount over if necessary */
if (!path_equal(ip, hd))
#include "user-record.h"
int home_setup_directory(UserRecord *h, HomeSetup *setup);
-int home_activate_directory(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
+int home_activate_directory(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home);
int home_create_directory_or_subvolume(UserRecord *h, UserRecord **ret_home);
int home_resize_directory(UserRecord *h, HomeSetupFlags flags, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_home);
int home_setup_fscrypt(
UserRecord *h,
- PasswordCache *cache,
+ const PasswordCache *cache,
HomeSetup *setup) {
_cleanup_(erase_and_freep) void *volume_key = NULL;
int home_passwd_fscrypt(
UserRecord *h,
HomeSetup *setup,
- PasswordCache *cache, /* the passwords acquired via PKCS#11/FIDO2 security tokens */
+ const PasswordCache *cache, /* the passwords acquired via PKCS#11/FIDO2 security tokens */
char **effective_passwords /* new passwords */) {
_cleanup_(erase_and_freep) void *volume_key = NULL;
#include "homework.h"
#include "user-record.h"
-int home_setup_fscrypt(UserRecord *h, PasswordCache *cache, HomeSetup *setup);
+int home_setup_fscrypt(UserRecord *h, const PasswordCache *cache, HomeSetup *setup);
int home_create_fscrypt(UserRecord *h, char **effective_passwords, UserRecord **ret_home);
-int home_passwd_fscrypt(UserRecord *h, HomeSetup *setup, PasswordCache *cache, char **effective_passwords);
+int home_passwd_fscrypt(UserRecord *h, HomeSetup *setup, const PasswordCache *cache, char **effective_passwords);
return log_oom();
r = -ENOKEY;
- FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, passwords) {
+ FOREACH_POINTER(list,
+ cache ? cache->pkcs11_passwords : NULL,
+ cache ? cache->fido2_passwords : NULL,
+ passwords) {
r = luks_try_passwords(cd, list, vk, &vks);
if (r != -ENOKEY)
break;
static int luks_open(
const char *dm_name,
char **passwords,
- PasswordCache *cache,
+ const PasswordCache *cache,
struct crypt_device **ret,
sd_id128_t *ret_found_uuid,
void **ret_volume_key,
return log_oom();
r = -ENOKEY;
- FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, passwords) {
+ FOREACH_POINTER(list,
+ cache ? cache->pkcs11_passwords : NULL,
+ cache ? cache->fido2_passwords : NULL,
+ passwords) {
r = luks_try_passwords(cd, list, vk, &vks);
if (r != -ENOKEY)
break;
return 0;
}
+static int open_image_file(
+ UserRecord *h,
+ const char *force_image_path,
+ struct stat *ret_stat) {
+
+ _cleanup_close_ int image_fd = -1;
+ struct stat st;
+ const char *ip;
+ int r;
+
+ ip = force_image_path ?: user_record_image_path(h);
+
+ image_fd = open(ip, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+ if (image_fd < 0)
+ return log_error_errno(errno, "Failed to open image file %s: %m", ip);
+
+ if (fstat(image_fd, &st) < 0)
+ return log_error_errno(errno, "Failed to fstat() image file: %m");
+ if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
+ return log_error_errno(
+ S_ISDIR(st.st_mode) ? SYNTHETIC_ERRNO(EISDIR) : SYNTHETIC_ERRNO(EBADFD),
+ "Image file %s is not a regular file or block device: %m", ip);
+
+ r = lock_image_fd(image_fd, ip);
+ if (r < 0)
+ return r;
+
+ if (ret_stat)
+ *ret_stat = st;
+
+ return TAKE_FD(image_fd);
+}
+
int home_setup_luks(
UserRecord *h,
HomeSetupFlags flags,
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(erase_and_freep) void *volume_key = NULL;
- _cleanup_close_ int root_fd = -1, image_fd = -1;
+ _cleanup_close_ int opened_image_fd = -1, root_fd = -1;
bool dm_activated = false, mounted = false;
size_t volume_key_size = 0;
bool marked_dirty = false;
uint64_t offset, size;
- int r;
+ int r, image_fd = -1;
assert(h);
assert(setup);
if (!subdir)
return log_oom();
- image_fd = open(ip, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
- if (image_fd < 0)
- return log_error_errno(errno, "Failed to open image file %s: %m", ip);
-
- if (fstat(image_fd, &st) < 0)
- return log_error_errno(errno, "Failed to fstat() image file: %m");
- if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
- return log_error_errno(
- S_ISDIR(st.st_mode) ? SYNTHETIC_ERRNO(EISDIR) : SYNTHETIC_ERRNO(EBADFD),
- "Image file %s is not a regular file or block device: %m", ip);
+ /* Reuse the image fd if it has already been opened by an earlier step */
+ if (setup->image_fd < 0) {
+ opened_image_fd = open_image_file(h, force_image_path, &st);
+ if (opened_image_fd < 0)
+ return opened_image_fd;
- r = lock_image_fd(image_fd, ip);
- if (r < 0)
- return r;
+ image_fd = opened_image_fd;
+ } else
+ image_fd = setup->image_fd;
r = luks_validate(image_fd, user_record_user_name_and_realm(h), h->partition_uuid, &found_partition_uuid, &offset, &size);
if (r < 0)
if (user_record_luks_discard(h))
(void) run_fitrim(root_fd);
- setup->image_fd = TAKE_FD(image_fd);
+ /* And now, fill in everything */
+ if (opened_image_fd >= 0) {
+ safe_close(setup->image_fd);
+ setup->image_fd = TAKE_FD(opened_image_fd);
+ }
+
setup->do_offline_fallocate = !(setup->do_offline_fitrim = user_record_luks_offline_discard(h));
setup->do_mark_clean = marked_dirty;
}
int home_activate_luks(
UserRecord *h,
+ HomeSetup *setup,
PasswordCache *cache,
UserRecord **ret_home) {
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *luks_home_record = NULL;
- _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
uint64_t host_size, encrypted_size;
const char *hdo, *hd;
struct statfs sfs;
assert(h);
assert(user_record_storage(h) == USER_LUKS);
+ assert(setup);
assert(ret_home);
r = dlopen_cryptsetup();
assert_se(hdo = user_record_home_directory(h));
hd = strdupa_safe(hdo); /* copy the string out, since it might change later in the home record object */
- r = home_get_state_luks(h, &setup);
+ r = home_get_state_luks(h, setup);
if (r < 0)
return r;
if (r > 0)
- return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Device mapper device %s already exists, refusing.", setup.dm_node);
+ return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Device mapper device %s already exists, refusing.", setup->dm_node);
r = home_setup_luks(
h,
0,
NULL,
cache,
- &setup,
+ setup,
&luks_home_record);
if (r < 0)
return r;
- r = block_get_size_by_fd(setup.loop->fd, &host_size);
+ r = block_get_size_by_fd(setup->loop->fd, &host_size);
if (r < 0)
return log_error_errno(r, "Failed to get loopback block device size: %m");
- r = block_get_size_by_path(setup.dm_node, &encrypted_size);
+ r = block_get_size_by_path(setup->dm_node, &encrypted_size);
if (r < 0)
return log_error_errno(r, "Failed to get LUKS block device size: %m");
r = home_refresh(
h,
- &setup,
+ setup,
luks_home_record,
cache,
&sfs,
if (r < 0)
return r;
- r = home_extend_embedded_identity(new_home, h, &setup);
+ r = home_extend_embedded_identity(new_home, h, setup);
if (r < 0)
return r;
- setup.root_fd = safe_close(setup.root_fd);
+ setup->root_fd = safe_close(setup->root_fd);
r = home_move_mount(user_record_user_name_and_realm(h), hd);
if (r < 0)
return r;
- setup.undo_mount = false;
- setup.do_offline_fitrim = false;
+ setup->undo_mount = false;
+ setup->do_offline_fitrim = false;
- loop_device_relinquish(setup.loop);
+ loop_device_relinquish(setup->loop);
- r = sym_crypt_deactivate_by_name(NULL, setup.dm_name, CRYPT_DEACTIVATE_DEFERRED);
+ r = sym_crypt_deactivate_by_name(NULL, setup->dm_name, CRYPT_DEACTIVATE_DEFERRED);
if (r < 0)
log_warning_errno(r, "Failed to relinquish DM device, ignoring: %m");
- setup.undo_dm = false;
- setup.do_offline_fallocate = false;
- setup.do_mark_clean = false;
+ setup->undo_dm = false;
+ setup->do_offline_fallocate = false;
+ setup->do_mark_clean = false;
log_info("Everything completed.");
STRV_FOREACH(pp, effective_passwords) {
- if (strv_contains(cache->pkcs11_passwords, *pp) ||
- strv_contains(cache->fido2_passwords, *pp)) {
+ if (password_cache_contains(cache, *pp)) { /* is this a fido2 or pkcs11 password? */
log_debug("Using minimal PBKDF for slot %i", slot);
r = sym_crypt_set_pbkdf_type(cd, &minimal_pbkdf);
} else {
int home_create_luks(
UserRecord *h,
- PasswordCache *cache,
+ const PasswordCache *cache,
char **effective_passwords,
UserRecord **ret_home) {
uint64_t old_image_size, new_image_size, old_fs_size, new_fs_size, crypto_offset, new_partition_size;
_cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *embedded_home = NULL, *new_home = NULL;
_cleanup_(fdisk_unref_tablep) struct fdisk_table *table = NULL;
+ _cleanup_close_ int opened_image_fd = -1;
_cleanup_free_ char *whole_disk = NULL;
- _cleanup_close_ int image_fd = -1;
+ int r, resize_type, image_fd = -1;
sd_id128_t disk_uuid;
const char *ip, *ipo;
struct statfs sfs;
struct stat st;
- int r, resize_type;
assert(h);
assert(user_record_storage(h) == USER_LUKS);
assert_se(ipo = user_record_image_path(h));
ip = strdupa_safe(ipo); /* copy out since original might change later in home record object */
- image_fd = open(ip, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
- if (image_fd < 0)
- return log_error_errno(errno, "Failed to open image file %s: %m", ip);
+ if (setup->image_fd < 0) {
+ setup->image_fd = open_image_file(h, NULL, &st);
+ if (setup->image_fd < 0)
+ return setup->image_fd;
+ } else {
+ if (fstat(setup->image_fd, &st) < 0)
+ return log_error_errno(errno, "Failed to stat image file %s: %m", ip);
+ }
+
+ image_fd = setup->image_fd;
- if (fstat(image_fd, &st) < 0)
- return log_error_errno(errno, "Failed to stat image file %s: %m", ip);
if (S_ISBLK(st.st_mode)) {
dev_t parent;
if (r < 0)
return log_error_errno(r, "Failed to derive whole disk path for %s: %m", ip);
- safe_close(image_fd);
-
- image_fd = open(whole_disk, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
- if (image_fd < 0)
+ opened_image_fd = open(whole_disk, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+ if (opened_image_fd < 0)
return log_error_errno(errno, "Failed to open whole block device %s: %m", whole_disk);
+ image_fd = opened_image_fd;
+
if (fstat(image_fd, &st) < 0)
return log_error_errno(errno, "Failed to stat whole block device %s: %m", whole_disk);
if (!S_ISBLK(st.st_mode))
int home_passwd_luks(
UserRecord *h,
HomeSetup *setup,
- PasswordCache *cache, /* the passwords acquired via PKCS#11/FIDO2 security tokens */
+ const PasswordCache *cache, /* the passwords acquired via PKCS#11/FIDO2 security tokens */
char **effective_passwords /* new passwords */) {
size_t volume_key_size, max_key_slots, n_effective;
return log_oom();
r = -ENOKEY;
- FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, h->password) {
+ FOREACH_POINTER(list,
+ cache ? cache->pkcs11_passwords : NULL,
+ cache ? cache->fido2_passwords : NULL,
+ h->password) {
+
r = luks_try_passwords(setup->crypt_device, list, volume_key, &volume_key_size);
if (r != -ENOKEY)
break;
continue;
}
- if (strv_contains(cache->pkcs11_passwords, effective_passwords[i]) ||
- strv_contains(cache->fido2_passwords, effective_passwords[i])) {
+ if (password_cache_contains(cache, effective_passwords[i])) { /* Is this a FIDO2 or PKCS#11 password? */
log_debug("Using minimal PBKDF for slot %zu", i);
r = sym_crypt_set_pbkdf_type(setup->crypt_device, &minimal_pbkdf);
} else {
return -ENOKEY;
}
-int home_unlock_luks(UserRecord *h, PasswordCache *cache) {
+int home_unlock_luks(UserRecord *h, const PasswordCache *cache) {
_cleanup_free_ char *dm_name = NULL, *dm_node = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
char **list;
cryptsetup_enable_logging(cd);
r = -ENOKEY;
- FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, h->password) {
+ FOREACH_POINTER(list,
+ cache ? cache->pkcs11_passwords : NULL,
+ cache ? cache->fido2_passwords : NULL,
+ h->password) {
r = luks_try_resume(cd, dm_name, list);
if (r != -ENOKEY)
break;
int home_setup_luks(UserRecord *h, HomeSetupFlags flags, const char *force_image_path, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_luks_home);
-int home_activate_luks(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
+int home_activate_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home);
int home_deactivate_luks(UserRecord *h);
int home_trim_luks(UserRecord *h);
int home_store_header_identity_luks(UserRecord *h, HomeSetup *setup, UserRecord *old_home);
-int home_create_luks(UserRecord *h, PasswordCache *cache, char **effective_passwords, UserRecord **ret_home);
+int home_create_luks(UserRecord *h, const PasswordCache *cache, char **effective_passwords, UserRecord **ret_home);
int home_get_state_luks(UserRecord *h, HomeSetup *setup);
int home_resize_luks(UserRecord *h, HomeSetupFlags flags, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_home);
-int home_passwd_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache, char **effective_passwords);
+int home_passwd_luks(UserRecord *h, HomeSetup *setup, const PasswordCache *cache, char **effective_passwords);
int home_lock_luks(UserRecord *h);
-int home_unlock_luks(UserRecord *h, PasswordCache *cache);
+int home_unlock_luks(UserRecord *h, const PasswordCache *cache);
static inline uint64_t luks_volume_key_size_convert(struct crypt_device *cd) {
int k;
}
static int home_activate(UserRecord *h, UserRecord **ret_home) {
- _cleanup_(password_cache_free) PasswordCache cache = {};
+ _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
+ _cleanup_(password_cache_free) PasswordCache cache = {};
int r;
assert(h);
switch (user_record_storage(h)) {
case USER_LUKS:
- r = home_activate_luks(h, &cache, &new_home);
+ r = home_activate_luks(h, &setup, &cache, &new_home);
if (r < 0)
return r;
case USER_SUBVOLUME:
case USER_DIRECTORY:
case USER_FSCRYPT:
- r = home_activate_directory(h, &cache, &new_home);
+ r = home_activate_directory(h, &setup, &cache, &new_home);
if (r < 0)
return r;
break;
case USER_CIFS:
- r = home_activate_cifs(h, &cache, &new_home);
+ r = home_activate_cifs(h, &setup, &cache, &new_home);
if (r < 0)
return r;
static int home_create(UserRecord *h, UserRecord **ret_home) {
_cleanup_(strv_free_erasep) char **effective_passwords = NULL;
+ _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
_cleanup_(password_cache_free) PasswordCache cache = {};
UserStorage new_storage = _USER_STORAGE_INVALID;
break;
case USER_CIFS:
- r = home_create_cifs(h, &new_home);
+ r = home_create_cifs(h, &setup, &new_home);
break;
default:
#include "sd-id128.h"
#include "loop-util.h"
+#include "strv.h"
#include "user-record.h"
#include "user-record-util.h"
} HomeSetup;
typedef struct PasswordCache {
- /* Decoding passwords from security tokens is expensive and typically requires user interaction, hence cache any we already figured out. */
+ /* Decoding passwords from security tokens is expensive and typically requires user interaction,
+ * hence cache any we already figured out. */
char **pkcs11_passwords;
char **fido2_passwords;
} PasswordCache;
void password_cache_free(PasswordCache *cache);
+static inline bool password_cache_contains(const PasswordCache *cache, const char *p) {
+ if (!cache)
+ return false;
+
+ return strv_contains(cache->pkcs11_passwords, p) || strv_contains(cache->fido2_passwords, p);
+}
+
#define HOME_SETUP_INIT \
{ \
.root_fd = -1, \
}
if (fd < 0) {
- sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
+ sock = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
if (sock < 0)
return log_debug_errno(errno, "sd-device-monitor: Failed to create socket: %m");
}
int socket_open(int family) {
int fd;
- fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, family);
+ fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, family);
if (fd < 0)
return -errno;
case RTM_NEWNEIGH:
if (neighbor) {
neighbor_enter_configured(neighbor);
- log_neighbor_debug(tmp, "Received remembered", link);
+ log_neighbor_debug(neighbor, "Received remembered", link);
} else {
neighbor_enter_configured(tmp);
log_neighbor_debug(tmp, "Remembering", link);
assert(send_fd >= 0);
- fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_ROUTE);
+ fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_ROUTE);
if (fd < 0)
return log_error_errno(errno, "Failed to allocate container netlink: %m");
#include "errno-util.h"
#include "fd-util.h"
#include "log.h"
+#include "path-util.h"
#include "string-util.h"
#include "time-util.h"
#include "watchdog.h"
static int watchdog_set_enable(bool enable) {
int flags = enable ? WDIOS_ENABLECARD : WDIOS_DISABLECARD;
- int r;
assert(watchdog_fd >= 0);
- r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
- if (r < 0) {
+ if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) {
if (!enable)
return log_warning_errno(errno, "Failed to disable hardware watchdog, ignoring: %m");
static int watchdog_get_timeout(void) {
int sec = 0;
- assert(watchdog_fd > 0);
+ assert(watchdog_fd >= 0);
if (ioctl(watchdog_fd, WDIOC_GETTIMEOUT, &sec) < 0)
return -errno;
if (watchdog_timeout == USEC_INFINITY) {
r = watchdog_get_timeout();
if (r < 0)
- return log_error_errno(errno, "Failed to query watchdog HW timeout: %m");
+ return log_error_errno(r, "Failed to query watchdog HW timeout: %m");
}
r = watchdog_set_enable(true);
if (watchdog_fd >= 0)
return 0;
- fn = watchdog_device ?: "/dev/watchdog";
+ /* Let's prefer new-style /dev/watchdog0 (i.e. kernel 3.5+) over classic /dev/watchdog. The former
+ * has the benefit that we can easily find the matching directory in sysfs from it, as the relevant
+ * sysfs attributes can only be found via /sys/dev/char/<major>:<minor> if the new-style device
+ * major/minor is used, not the old-style. */
+ fn = !watchdog_device || path_equal(watchdog_device, "/dev/watchdog") ?
+ "/dev/watchdog0" : watchdog_device;
+
watchdog_fd = open(fn, O_WRONLY|O_CLOEXEC);
if (watchdog_fd < 0)
return log_debug_errno(errno, "Failed to open watchdog device %s, ignoring: %m", fn);