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
};
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 */
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,
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)
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;
#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>
#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"
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);