mirror of
https://github.com/systemd/systemd.git
synced 2025-01-26 14:04:03 +03:00
fs-util: introduce inotify_add_watch_and_warn() helper
The default message for ENOSPC is very misleading: it says that the disk is filled, but in fact the inotify watch limit is the problem. So let's introduce and use a wrapper that simply calls inotify_add_watch(2) and which fixes the error message up in case ENOSPC is returned.
This commit is contained in:
parent
5461cdebfa
commit
27c3112dcb
@ -660,6 +660,21 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) {
|
||||
if (inotify_add_watch(fd, pathname, mask) < 0) {
|
||||
const char *reason;
|
||||
|
||||
if (errno == ENOSPC)
|
||||
reason = "inotify watch limit reached";
|
||||
else
|
||||
reason = strerror_safe(errno);
|
||||
|
||||
return log_error_errno(errno, "Failed to add a watch for %s: %s", pathname, reason);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool unsafe_transition(const struct stat *a, const struct stat *b) {
|
||||
/* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to
|
||||
* privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files
|
||||
|
@ -72,6 +72,7 @@ union inotify_event_buffer {
|
||||
};
|
||||
|
||||
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
||||
int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask);
|
||||
|
||||
enum {
|
||||
CHASE_PREFIX_ROOT = 1 << 0, /* The specified path will be prefixed by the specified root before beginning the iteration */
|
||||
|
@ -295,10 +295,12 @@ static int manager_check_ask_password(Manager *m) {
|
||||
if (m->ask_password_inotify_fd < 0)
|
||||
return log_error_errno(errno, "Failed to create inotify object: %m");
|
||||
|
||||
if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
|
||||
log_error_errno(errno, "Failed to watch \"/run/systemd/ask-password\": %m");
|
||||
r = inotify_add_watch_and_warn(m->ask_password_inotify_fd,
|
||||
"/run/systemd/ask-password",
|
||||
IN_CREATE|IN_DELETE|IN_MOVE);
|
||||
if (r < 0) {
|
||||
manager_close_ask_password(m);
|
||||
return -errno;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_event_add_io(m->event, &m->ask_password_event_source,
|
||||
|
@ -89,24 +89,29 @@ int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
|
||||
break;
|
||||
}
|
||||
|
||||
r = log_warning_errno(errno, "Failed to add watch on %s: %s", s->path, errno == ENOSPC ? "too many watches" : strerror_safe(r));
|
||||
if (cut)
|
||||
*cut = tmp;
|
||||
goto fail;
|
||||
} else {
|
||||
exists = true;
|
||||
|
||||
/* Path exists, we don't need to watch parent too closely. */
|
||||
if (oldslash) {
|
||||
char *cut2 = oldslash + (oldslash == s->path);
|
||||
char tmp2 = *cut2;
|
||||
*cut2 = '\0';
|
||||
|
||||
(void) inotify_add_watch(s->inotify_fd, s->path, IN_MOVE_SELF);
|
||||
/* Error is ignored, the worst can happen is we get spurious events. */
|
||||
|
||||
*cut2 = tmp2;
|
||||
/* This second call to inotify_add_watch() should fail like the previous
|
||||
* one and is done for logging the error in a comprehensive way. */
|
||||
r = inotify_add_watch_and_warn(s->inotify_fd, s->path, flags);
|
||||
if (r < 0) {
|
||||
if (cut)
|
||||
*cut = tmp;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Hmm, we succeeded in adding the watch this time... let's continue. */
|
||||
}
|
||||
exists = true;
|
||||
|
||||
/* Path exists, we don't need to watch parent too closely. */
|
||||
if (oldslash) {
|
||||
char *cut2 = oldslash + (oldslash == s->path);
|
||||
char tmp2 = *cut2;
|
||||
*cut2 = '\0';
|
||||
|
||||
(void) inotify_add_watch(s->inotify_fd, s->path, IN_MOVE_SELF);
|
||||
/* Error is ignored, the worst can happen is we get spurious events. */
|
||||
|
||||
*cut2 = tmp2;
|
||||
}
|
||||
|
||||
if (cut)
|
||||
|
@ -225,9 +225,9 @@ static int run(int argc, char * argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create notify event source: %m");
|
||||
|
||||
r = inotify_add_watch(state.inotify_fd, "/run/systemd/", IN_CREATE);
|
||||
r = inotify_add_watch_and_warn(state.inotify_fd, "/run/systemd/", IN_CREATE);
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "Failed to watch /run/systemd/: %m");
|
||||
return r;
|
||||
|
||||
state.run_systemd_wd = r;
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/socket.h>
|
||||
@ -29,6 +28,7 @@
|
||||
#include "exit-status.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "io-util.h"
|
||||
#include "macro.h"
|
||||
@ -510,12 +510,9 @@ static int process_and_watch_password_files(void) {
|
||||
if (notify < 0)
|
||||
return log_error_errno(errno, "Failed to allocate directory watch: %m");
|
||||
|
||||
if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) {
|
||||
if (errno == ENOSPC)
|
||||
return log_error_errno(errno, "Failed to add /run/systemd/ask-password to directory watch: inotify watch limit reached");
|
||||
else
|
||||
return log_error_errno(errno, "Failed to add /run/systemd/ask-password to directory watch: %m");
|
||||
}
|
||||
r = inotify_add_watch_and_warn(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert_se(sigemptyset(&mask) >= 0);
|
||||
assert_se(sigset_add_many(&mask, SIGINT, SIGTERM, -1) >= 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user