Merge pull request #10353 from keszybz/more-manager-reloading
More manager reloading cleanups
This commit is contained in:
commit
02619c033f
|
@ -1613,6 +1613,17 @@ static void manager_ready(Manager *m) {
|
||||||
manager_catchup(m);
|
manager_catchup(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Manager* manager_reloading_start(Manager *m) {
|
||||||
|
m->n_reloading++;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
static void manager_reloading_stopp(Manager **m) {
|
||||||
|
if (*m) {
|
||||||
|
assert((*m)->n_reloading > 0);
|
||||||
|
(*m)->n_reloading--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -1642,10 +1653,14 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
||||||
|
|
||||||
manager_build_unit_path_cache(m);
|
manager_build_unit_path_cache(m);
|
||||||
|
|
||||||
/* If we will deserialize make sure that during enumeration this is already known, so we increase the counter
|
{
|
||||||
* here already */
|
/* This block is (optionally) done with the reloading counter bumped */
|
||||||
|
_cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
|
||||||
|
|
||||||
|
/* If we will deserialize make sure that during enumeration this is already known, so we increase the
|
||||||
|
* counter here already */
|
||||||
if (serialization)
|
if (serialization)
|
||||||
m->n_reloading++;
|
reloading = manager_reloading_start(m);
|
||||||
|
|
||||||
/* First, enumerate what we can from all config files */
|
/* First, enumerate what we can from all config files */
|
||||||
dual_timestamp_get(m->timestamps + manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_UNITS_LOAD_START));
|
dual_timestamp_get(m->timestamps + manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_UNITS_LOAD_START));
|
||||||
|
@ -1660,8 +1675,9 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
||||||
return log_error_errno(r, "Deserialization failed: %m");
|
return log_error_errno(r, "Deserialization failed: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Any fds left? Find some unit which wants them. This is useful to allow container managers to pass some file
|
/* Any fds left? Find some unit which wants them. This is useful to allow container managers to pass
|
||||||
* descriptors to us pre-initialized. This enables socket-based activation of entire containers. */
|
* some file descriptors to us pre-initialized. This enables socket-based activation of entire
|
||||||
|
* containers. */
|
||||||
manager_distribute_fds(m, fds);
|
manager_distribute_fds(m, fds);
|
||||||
|
|
||||||
/* We might have deserialized the notify fd, but if we didn't then let's create the bus now */
|
/* We might have deserialized the notify fd, but if we didn't then let's create the bus now */
|
||||||
|
@ -1695,12 +1711,9 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
||||||
/* Clean up runtime objects */
|
/* Clean up runtime objects */
|
||||||
manager_vacuum(m);
|
manager_vacuum(m);
|
||||||
|
|
||||||
if (serialization) {
|
if (serialization)
|
||||||
assert(m->n_reloading > 0);
|
/* Let's wait for the UnitNew/JobNew messages being sent, before we notify that the
|
||||||
m->n_reloading--;
|
* reload is finished */
|
||||||
|
|
||||||
/* Let's wait for the UnitNew/JobNew messages being sent, before we notify that the reload is
|
|
||||||
* finished */
|
|
||||||
m->send_reloading_done = true;
|
m->send_reloading_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3083,7 +3096,7 @@ int manager_serialize(
|
||||||
assert(f);
|
assert(f);
|
||||||
assert(fds);
|
assert(fds);
|
||||||
|
|
||||||
m->n_reloading++;
|
_cleanup_(manager_reloading_stopp) Manager *reloading = manager_reloading_start(m);
|
||||||
|
|
||||||
fprintf(f, "current-job-id=%"PRIu32"\n", m->current_job_id);
|
fprintf(f, "current-job-id=%"PRIu32"\n", m->current_job_id);
|
||||||
fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
|
fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
|
||||||
|
@ -3112,12 +3125,9 @@ int manager_serialize(
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
t = manager_timestamp_to_string(q);
|
t = manager_timestamp_to_string(q);
|
||||||
{
|
const char *field = strjoina(t, "-timestamp");
|
||||||
char field[strlen(t) + STRLEN("-timestamp") + 1];
|
|
||||||
strcpy(stpcpy(field, t), "-timestamp");
|
|
||||||
dual_timestamp_serialize(f, field, m->timestamps + q);
|
dual_timestamp_serialize(f, field, m->timestamps + q);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!switching_root)
|
if (!switching_root)
|
||||||
(void) serialize_environment(f, m->environment);
|
(void) serialize_environment(f, m->environment);
|
||||||
|
@ -3126,10 +3136,8 @@ int manager_serialize(
|
||||||
int copy;
|
int copy;
|
||||||
|
|
||||||
copy = fdset_put_dup(fds, m->notify_fd);
|
copy = fdset_put_dup(fds, m->notify_fd);
|
||||||
if (copy < 0) {
|
if (copy < 0)
|
||||||
r = copy;
|
return copy;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "notify-fd=%i\n", copy);
|
fprintf(f, "notify-fd=%i\n", copy);
|
||||||
fprintf(f, "notify-socket=%s\n", m->notify_socket);
|
fprintf(f, "notify-socket=%s\n", m->notify_socket);
|
||||||
|
@ -3139,10 +3147,8 @@ int manager_serialize(
|
||||||
int copy;
|
int copy;
|
||||||
|
|
||||||
copy = fdset_put_dup(fds, m->cgroups_agent_fd);
|
copy = fdset_put_dup(fds, m->cgroups_agent_fd);
|
||||||
if (copy < 0) {
|
if (copy < 0)
|
||||||
r = copy;
|
return copy;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "cgroups-agent-fd=%i\n", copy);
|
fprintf(f, "cgroups-agent-fd=%i\n", copy);
|
||||||
}
|
}
|
||||||
|
@ -3151,16 +3157,12 @@ int manager_serialize(
|
||||||
int copy0, copy1;
|
int copy0, copy1;
|
||||||
|
|
||||||
copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
|
copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
|
||||||
if (copy0 < 0) {
|
if (copy0 < 0)
|
||||||
r = copy0;
|
return copy0;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
|
copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
|
||||||
if (copy1 < 0) {
|
if (copy1 < 0)
|
||||||
r = copy1;
|
return copy1;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "user-lookup=%i %i\n", copy0, copy1);
|
fprintf(f, "user-lookup=%i %i\n", copy0, copy1);
|
||||||
}
|
}
|
||||||
|
@ -3169,14 +3171,14 @@ int manager_serialize(
|
||||||
|
|
||||||
r = dynamic_user_serialize(m, f, fds);
|
r = dynamic_user_serialize(m, f, fds);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
return r;
|
||||||
|
|
||||||
manager_serialize_uid_refs(m, f);
|
manager_serialize_uid_refs(m, f);
|
||||||
manager_serialize_gid_refs(m, f);
|
manager_serialize_gid_refs(m, f);
|
||||||
|
|
||||||
r = exec_runtime_serialize(m, f, fds);
|
r = exec_runtime_serialize(m, f, fds);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
return r;
|
||||||
|
|
||||||
(void) fputc('\n', f);
|
(void) fputc('\n', f);
|
||||||
|
|
||||||
|
@ -3190,24 +3192,18 @@ int manager_serialize(
|
||||||
|
|
||||||
r = unit_serialize(u, f, fds, !switching_root);
|
r = unit_serialize(u, f, fds, !switching_root);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = fflush_and_check(f);
|
r = fflush_and_check(f);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
return r;
|
||||||
|
|
||||||
r = bus_fdset_add_all(m, fds);
|
r = bus_fdset_add_all(m, fds);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
|
|
||||||
finish:
|
|
||||||
assert(m->n_reloading > 0);
|
|
||||||
m->n_reloading--;
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
|
@ -3221,19 +3217,17 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
/* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
|
/* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
|
||||||
* increased it to non-zero, which is why we just increase it by one here and down again at the end of this
|
* increased it to non-zero, which is why we just increase it by one here and down again at the end of this
|
||||||
* call. */
|
* call. */
|
||||||
m->n_reloading++;
|
_cleanup_(manager_reloading_stopp) Manager *reloading = manager_reloading_start(m);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char line[LINE_MAX];
|
char line[LINE_MAX];
|
||||||
const char *val, *l;
|
const char *val, *l;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
if (!fgets(line, sizeof(line), f)) {
|
if (!fgets(line, sizeof(line), f)) {
|
||||||
if (feof(f))
|
if (!feof(f))
|
||||||
r = 0;
|
return -errno ?: -EIO;
|
||||||
else
|
return 0;
|
||||||
r = -errno;
|
|
||||||
|
|
||||||
goto finish;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char_array_0(line);
|
char_array_0(line);
|
||||||
|
@ -3332,7 +3326,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
} else if (startswith(l, "env=")) {
|
} else if (startswith(l, "env=")) {
|
||||||
r = deserialize_environment(&m->environment, l);
|
r = deserialize_environment(&m->environment, l);
|
||||||
if (r == -ENOMEM)
|
if (r == -ENOMEM)
|
||||||
goto finish;
|
return r;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
|
log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
|
||||||
|
|
||||||
|
@ -3348,16 +3342,9 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((val = startswith(l, "notify-socket="))) {
|
} else if ((val = startswith(l, "notify-socket="))) {
|
||||||
char *n;
|
r = free_and_strdup(&m->notify_socket, val);
|
||||||
|
if (r < 0)
|
||||||
n = strdup(val);
|
return r;
|
||||||
if (!n) {
|
|
||||||
r = -ENOMEM;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(m->notify_socket);
|
|
||||||
m->notify_socket = n;
|
|
||||||
|
|
||||||
} else if ((val = startswith(l, "cgroups-agent-fd="))) {
|
} else if ((val = startswith(l, "cgroups-agent-fd="))) {
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -3392,10 +3379,8 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
exec_runtime_deserialize_one(m, val, fds);
|
exec_runtime_deserialize_one(m, val, fds);
|
||||||
else if ((val = startswith(l, "subscribed="))) {
|
else if ((val = startswith(l, "subscribed="))) {
|
||||||
|
|
||||||
if (strv_extend(&m->deserialized_subscribed, val) < 0) {
|
if (strv_extend(&m->deserialized_subscribed, val) < 0)
|
||||||
r = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ManagerTimestamp q;
|
ManagerTimestamp q;
|
||||||
|
@ -3423,13 +3408,11 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
const char* unit_name;
|
const char* unit_name;
|
||||||
|
|
||||||
/* Start marker */
|
/* Start marker */
|
||||||
|
errno = 0;
|
||||||
if (!fgets(name, sizeof(name), f)) {
|
if (!fgets(name, sizeof(name), f)) {
|
||||||
if (feof(f))
|
if (!feof(f))
|
||||||
r = 0;
|
return -errno ?: -EIO;
|
||||||
else
|
return 0;
|
||||||
r = -errno;
|
|
||||||
|
|
||||||
goto finish;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char_array_0(name);
|
char_array_0(name);
|
||||||
|
@ -3438,7 +3421,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
r = manager_load_unit(m, unit_name, NULL, NULL, &u);
|
r = manager_load_unit(m, unit_name, NULL, NULL, &u);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (r == -ENOMEM)
|
if (r == -ENOMEM)
|
||||||
goto finish;
|
return r;
|
||||||
|
|
||||||
log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", unit_name);
|
log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", unit_name);
|
||||||
unit_deserialize_skip(f);
|
unit_deserialize_skip(f);
|
||||||
|
@ -3448,21 +3431,13 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
r = unit_deserialize(u, f, fds);
|
r = unit_deserialize(u, f, fds);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (r == -ENOMEM)
|
if (r == -ENOMEM)
|
||||||
goto finish;
|
return r;
|
||||||
|
|
||||||
log_notice_errno(r, "Failed to deserialize unit \"%s\": %m", unit_name);
|
log_notice_errno(r, "Failed to deserialize unit \"%s\": %m", unit_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
return 0;
|
||||||
if (ferror(f))
|
|
||||||
r = -EIO;
|
|
||||||
|
|
||||||
/* We are done with reloading, decrease counter again */
|
|
||||||
assert(m->n_reloading > 0);
|
|
||||||
m->n_reloading--;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void manager_flush_finished_jobs(Manager *m) {
|
static void manager_flush_finished_jobs(Manager *m) {
|
||||||
|
@ -3477,6 +3452,7 @@ static void manager_flush_finished_jobs(Manager *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int manager_reload(Manager *m) {
|
int manager_reload(Manager *m) {
|
||||||
|
_cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
|
||||||
_cleanup_fdset_free_ FDSet *fds = NULL;
|
_cleanup_fdset_free_ FDSet *fds = NULL;
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
@ -3491,21 +3467,18 @@ int manager_reload(Manager *m) {
|
||||||
if (!fds)
|
if (!fds)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
/* We are officially in reload mode from here on */
|
/* We are officially in reload mode from here on. */
|
||||||
m->n_reloading++;
|
reloading = manager_reloading_start(m);
|
||||||
|
|
||||||
r = manager_serialize(m, f, fds, false);
|
r = manager_serialize(m, f, fds, false);
|
||||||
if (r < 0) {
|
if (r < 0)
|
||||||
log_error_errno(r, "Failed to serialize manager: %m");
|
return log_error_errno(r, "Failed to serialize manager: %m");
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fseeko(f, 0, SEEK_SET) < 0) {
|
if (fseeko(f, 0, SEEK_SET) < 0)
|
||||||
r = log_error_errno(errno, "Failed to seek to beginning of serialization: %m");
|
return log_error_errno(errno, "Failed to seek to beginning of serialization: %m");
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 💀 This is the point of no return, from here on there is no way back. 💀 */
|
/* 💀 This is the point of no return, from here on there is no way back. 💀 */
|
||||||
|
reloading = NULL;
|
||||||
|
|
||||||
bus_manager_send_reloading(m, true);
|
bus_manager_send_reloading(m, true);
|
||||||
|
|
||||||
|
@ -3568,14 +3541,6 @@ int manager_reload(Manager *m) {
|
||||||
|
|
||||||
m->send_reloading_done = true;
|
m->send_reloading_done = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
|
||||||
/* Fail the call. Note that we hit this only if we fail before the point of no return, i.e. when the error is
|
|
||||||
* still something that can be handled. */
|
|
||||||
assert(m->n_reloading > 0);
|
|
||||||
m->n_reloading--;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void manager_reset_failed(Manager *m) {
|
void manager_reset_failed(Manager *m) {
|
||||||
|
|
Loading…
Reference in a new issue