mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-05 09:17:44 +03:00
Merge pull request #14030 from keszybz/path-no-trigger
Fix spurious triggering of PathExists=
This commit is contained in:
commit
3049e6a233
@ -52,11 +52,7 @@ void path_hash_func(const char *q, struct siphash *state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int path_compare_func(const char *a, const char *b) {
|
DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare);
|
||||||
return path_compare(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare_func);
|
|
||||||
|
|
||||||
void trivial_hash_func(const void *p, struct siphash *state) {
|
void trivial_hash_func(const void *p, struct siphash *state) {
|
||||||
siphash24_compress(&p, sizeof(p), state);
|
siphash24_compress(&p, sizeof(p), state);
|
||||||
|
@ -79,7 +79,6 @@ extern const struct hash_ops string_hash_ops;
|
|||||||
extern const struct hash_ops string_hash_ops_free_free;
|
extern const struct hash_ops string_hash_ops_free_free;
|
||||||
|
|
||||||
void path_hash_func(const char *p, struct siphash *state);
|
void path_hash_func(const char *p, struct siphash *state);
|
||||||
int path_compare_func(const char *a, const char *b) _pure_;
|
|
||||||
extern const struct hash_ops path_hash_ops;
|
extern const struct hash_ops path_hash_ops;
|
||||||
|
|
||||||
/* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings
|
/* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings
|
||||||
|
@ -897,7 +897,7 @@ static const char* counting_what(void) {
|
|||||||
return "userspace processes (excl. kernel)";
|
return "userspace processes (excl. kernel)";
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(group_hash_ops, char, path_hash_func, path_compare_func, Group, group_free);
|
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(group_hash_ops, char, path_hash_func, path_compare, Group, group_free);
|
||||||
|
|
||||||
static int run(int argc, char *argv[]) {
|
static int run(int argc, char *argv[]) {
|
||||||
_cleanup_hashmap_free_ Hashmap *a = NULL, *b = NULL;
|
_cleanup_hashmap_free_ Hashmap *a = NULL, *b = NULL;
|
||||||
|
@ -9,12 +9,14 @@
|
|||||||
#include "bus-util.h"
|
#include "bus-util.h"
|
||||||
#include "dbus-path.h"
|
#include "dbus-path.h"
|
||||||
#include "dbus-unit.h"
|
#include "dbus-unit.h"
|
||||||
|
#include "escape.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "glob-util.h"
|
#include "glob-util.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "mkdir.h"
|
#include "mkdir.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
#include "path-util.h"
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "special.h"
|
#include "special.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
@ -27,19 +29,18 @@ static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
|
|||||||
[PATH_DEAD] = UNIT_INACTIVE,
|
[PATH_DEAD] = UNIT_INACTIVE,
|
||||||
[PATH_WAITING] = UNIT_ACTIVE,
|
[PATH_WAITING] = UNIT_ACTIVE,
|
||||||
[PATH_RUNNING] = UNIT_ACTIVE,
|
[PATH_RUNNING] = UNIT_ACTIVE,
|
||||||
[PATH_FAILED] = UNIT_FAILED
|
[PATH_FAILED] = UNIT_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int path_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
static int path_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
||||||
|
|
||||||
int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
|
int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
|
||||||
|
|
||||||
static const int flags_table[_PATH_TYPE_MAX] = {
|
static const int flags_table[_PATH_TYPE_MAX] = {
|
||||||
[PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
|
[PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
|
||||||
[PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
|
[PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
|
||||||
[PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
|
[PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
|
||||||
[PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY,
|
[PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY,
|
||||||
[PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
|
[PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
@ -174,12 +175,14 @@ int path_spec_fd_event(PathSpec *s, uint32_t revents) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool path_spec_check_good(PathSpec *s, bool initial) {
|
static bool path_spec_check_good(PathSpec *s, bool initial) {
|
||||||
bool good = false;
|
bool b, good = false;
|
||||||
|
|
||||||
switch (s->type) {
|
switch (s->type) {
|
||||||
|
|
||||||
case PATH_EXISTS:
|
case PATH_EXISTS:
|
||||||
good = access(s->path, F_OK) >= 0;
|
b = access(s->path, F_OK) >= 0;
|
||||||
|
good = b && !s->previous_exists;
|
||||||
|
s->previous_exists = b;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATH_EXISTS_GLOB:
|
case PATH_EXISTS_GLOB:
|
||||||
@ -195,14 +198,11 @@ static bool path_spec_check_good(PathSpec *s, bool initial) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case PATH_CHANGED:
|
case PATH_CHANGED:
|
||||||
case PATH_MODIFIED: {
|
case PATH_MODIFIED:
|
||||||
bool b;
|
|
||||||
|
|
||||||
b = access(s->path, F_OK) >= 0;
|
b = access(s->path, F_OK) >= 0;
|
||||||
good = !initial && b != s->previous_exists;
|
good = !initial && b != s->previous_exists;
|
||||||
s->previous_exists = b;
|
s->previous_exists = b;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
@ -601,6 +601,7 @@ static int path_stop(Unit *u) {
|
|||||||
|
|
||||||
static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
|
static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||||
Path *p = PATH(u);
|
Path *p = PATH(u);
|
||||||
|
PathSpec *s;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
assert(f);
|
assert(f);
|
||||||
@ -609,6 +610,19 @@ static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
|
|||||||
(void) serialize_item(f, "state", path_state_to_string(p->state));
|
(void) serialize_item(f, "state", path_state_to_string(p->state));
|
||||||
(void) serialize_item(f, "result", path_result_to_string(p->result));
|
(void) serialize_item(f, "result", path_result_to_string(p->result));
|
||||||
|
|
||||||
|
LIST_FOREACH(spec, s, p->specs) {
|
||||||
|
_cleanup_free_ char *escaped = NULL;
|
||||||
|
|
||||||
|
escaped = cescape(s->path);
|
||||||
|
if (!escaped)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
(void) serialize_item_format(f, "path-spec", "%s %i %s",
|
||||||
|
path_type_to_string(s->type),
|
||||||
|
s->previous_exists,
|
||||||
|
s->path);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,6 +652,38 @@ static int path_deserialize_item(Unit *u, const char *key, const char *value, FD
|
|||||||
else if (f != PATH_SUCCESS)
|
else if (f != PATH_SUCCESS)
|
||||||
p->result = f;
|
p->result = f;
|
||||||
|
|
||||||
|
} else if (streq(key, "path-spec")) {
|
||||||
|
int previous_exists, skip = 0, r;
|
||||||
|
_cleanup_free_ char *type_str = NULL;
|
||||||
|
|
||||||
|
if (sscanf(value, "%ms %i %n", &type_str, &previous_exists, &skip) < 2)
|
||||||
|
log_unit_debug(u, "Failed to parse path-spec value: %s", value);
|
||||||
|
else {
|
||||||
|
_cleanup_free_ char *unescaped = NULL;
|
||||||
|
PathType type;
|
||||||
|
PathSpec *s;
|
||||||
|
|
||||||
|
type = path_type_from_string(type_str);
|
||||||
|
if (type < 0) {
|
||||||
|
log_unit_warning(u, "Unknown path type \"%s\", ignoring.", type_str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = cunescape(value+skip, 0, &unescaped);
|
||||||
|
if (r < 0) {
|
||||||
|
log_unit_warning_errno(u, r, "Failed to unescape serialize path: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_FOREACH(spec, s, p->specs)
|
||||||
|
if (s->type == type &&
|
||||||
|
path_equal(s->path, unescaped)) {
|
||||||
|
|
||||||
|
s->previous_exists = previous_exists;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
log_unit_debug(u, "Unknown serialization key: %s", key);
|
log_unit_debug(u, "Unknown serialization key: %s", key);
|
||||||
|
|
||||||
@ -670,7 +716,7 @@ static int path_dispatch_io(sd_event_source *source, int fd, uint32_t revents, v
|
|||||||
if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
|
if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* log_debug("inotify wakeup on %s.", u->id); */
|
/* log_debug("inotify wakeup on %s.", UNIT(p)->id); */
|
||||||
|
|
||||||
LIST_FOREACH(spec, s, p->specs)
|
LIST_FOREACH(spec, s, p->specs)
|
||||||
if (path_spec_owns_inotify_fd(s, fd))
|
if (path_spec_owns_inotify_fd(s, fd))
|
||||||
|
Loading…
Reference in New Issue
Block a user