1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-06 16:59:03 +03:00

path: after installing inotify watches, recheck file again to fix race

This commit is contained in:
Lennart Poettering 2011-03-04 01:49:37 +01:00
parent 3fc546f93d
commit 0595f9a1c1

View File

@ -282,7 +282,7 @@ static void path_set_state(Path *p, PathState state) {
unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state], true); unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state], true);
} }
static void path_enter_waiting(Path *p, bool initial, bool recheck); static void path_enter_waiting(Path *p, bool initial, bool recheck, bool skip_watch);
static int path_coldplug(Unit *u) { static int path_coldplug(Unit *u) {
Path *p = PATH(u); Path *p = PATH(u);
@ -294,7 +294,7 @@ static int path_coldplug(Unit *u) {
if (p->deserialized_state == PATH_WAITING || if (p->deserialized_state == PATH_WAITING ||
p->deserialized_state == PATH_RUNNING) p->deserialized_state == PATH_RUNNING)
path_enter_waiting(p, true, true); path_enter_waiting(p, true, true, false);
else else
path_set_state(p, p->deserialized_state); path_set_state(p, p->deserialized_state);
} }
@ -341,7 +341,7 @@ fail:
} }
static void path_enter_waiting(Path *p, bool initial, bool recheck) { static void path_enter_waiting(Path *p, bool initial, bool recheck, bool skip_watch) {
PathSpec *s; PathSpec *s;
int r; int r;
bool good = false; bool good = false;
@ -389,8 +389,16 @@ static void path_enter_waiting(Path *p, bool initial, bool recheck) {
} }
waiting: waiting:
if ((r = path_watch(p)) < 0) if (!skip_watch) {
goto fail; if ((r = path_watch(p)) < 0)
goto fail;
/* Hmm, so now we have created inotify watches, but the file
* might have appeared/been removed by now, so we must
* recheck */
path_enter_waiting(p, false, true, true);
return;
}
path_set_state(p, PATH_WAITING); path_set_state(p, PATH_WAITING);
return; return;
@ -410,7 +418,7 @@ static int path_start(Unit *u) {
return -ENOENT; return -ENOENT;
p->failure = false; p->failure = false;
path_enter_waiting(p, true, true); path_enter_waiting(p, true, true, false);
return 0; return 0;
} }
@ -541,7 +549,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
if (changed) if (changed)
path_enter_running(p); path_enter_running(p);
else else
path_enter_waiting(p, false, true); path_enter_waiting(p, false, true, false);
free(buf); free(buf);
@ -590,7 +598,7 @@ void path_unit_notify(Unit *u, UnitActiveState new_state) {
/* Hmm, so inotify was triggered since the /* Hmm, so inotify was triggered since the
* last activation, so I guess we need to * last activation, so I guess we need to
* recheck what is going on. */ * recheck what is going on. */
path_enter_waiting(p, false, p->inotify_triggered); path_enter_waiting(p, false, p->inotify_triggered, false);
} }
} }