Skip to content

Commit 49f3fff

Browse files
committed
machined: rework state tracking logic for machines
This splits up the stopping logic for machines into two steps: first on machine_stop() we begin with the shutdown of a machine by queuing the stop method call for it. Then, in machine_finalize() we actually remove the rest of its runtime context. This mimics closely how sessions are handled in logind. This also reworks the GC logic to strictly check the current state of the machine unit, rather than shortcutting a few cases, like for example assuming that UnitRemoved really means a machine is gone (which it isn't since Reloading might trigger it, see adamlaska#376). Fixes adamlaska#376.
1 parent e5a840c commit 49f3fff

File tree

4 files changed

+36
-47
lines changed

4 files changed

+36
-47
lines changed

src/machine/machine.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,19 @@ static int machine_stop_scope(Machine *m) {
419419
}
420420

421421
int machine_stop(Machine *m) {
422-
int r = 0, k;
422+
int r;
423+
assert(m);
424+
425+
r = machine_stop_scope(m);
426+
427+
m->stopping = true;
428+
429+
machine_save(m);
430+
431+
return r;
432+
}
433+
434+
int machine_finalize(Machine *m) {
423435
assert(m);
424436

425437
if (m->started)
@@ -430,20 +442,15 @@ int machine_stop(Machine *m) {
430442
LOG_MESSAGE("Machine %s terminated.", m->name),
431443
NULL);
432444

433-
/* Kill cgroup */
434-
k = machine_stop_scope(m);
435-
if (k < 0)
436-
r = k;
437-
438445
machine_unlink(m);
439446
machine_add_to_gc_queue(m);
440447

441-
if (m->started)
448+
if (m->started) {
442449
machine_send_signal(m, false);
450+
m->started = false;
451+
}
443452

444-
m->started = false;
445-
446-
return r;
453+
return 0;
447454
}
448455

449456
bool machine_check_gc(Machine *m, bool drop_not_started) {
@@ -474,8 +481,11 @@ void machine_add_to_gc_queue(Machine *m) {
474481
MachineState machine_get_state(Machine *s) {
475482
assert(s);
476483

484+
if (s->stopping)
485+
return MACHINE_CLOSING;
486+
477487
if (s->scope_job)
478-
return s->started ? MACHINE_OPENING : MACHINE_CLOSING;
488+
return MACHINE_OPENING;
479489

480490
return MACHINE_RUNNING;
481491
}

src/machine/machine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct Machine {
8282

8383
bool in_gc_queue:1;
8484
bool started:1;
85+
bool stopping:1;
8586

8687
sd_bus_message *create_message;
8788

@@ -100,6 +101,7 @@ bool machine_check_gc(Machine *m, bool drop_not_started);
100101
void machine_add_to_gc_queue(Machine *m);
101102
int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error);
102103
int machine_stop(Machine *m);
104+
int machine_finalize(Machine *m);
103105
int machine_save(Machine *m);
104106
int machine_load(Machine *m);
105107
int machine_kill(Machine *m, KillWho who, int signo);

src/machine/machined-dbus.c

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,8 +1136,9 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
11361136

11371137
machine_send_create_reply(machine, &e);
11381138
}
1139-
} else
1140-
machine_save(machine);
1139+
}
1140+
1141+
machine_save(machine);
11411142
}
11421143

11431144
machine_add_to_gc_queue(machine);
@@ -1146,7 +1147,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
11461147

11471148
int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
11481149
_cleanup_free_ char *unit = NULL;
1149-
const char *path, *interface;
1150+
const char *path;
11501151
Manager *m = userdata;
11511152
Machine *machine;
11521153
int r;
@@ -1170,36 +1171,6 @@ int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_err
11701171
if (!machine)
11711172
return 0;
11721173

1173-
r = sd_bus_message_read(message, "s", &interface);
1174-
if (r < 0) {
1175-
bus_log_parse_error(r);
1176-
return 0;
1177-
}
1178-
1179-
if (streq(interface, "org.freedesktop.systemd1.Unit")) {
1180-
struct properties {
1181-
char *active_state;
1182-
char *sub_state;
1183-
} properties = {};
1184-
1185-
const struct bus_properties_map map[] = {
1186-
{ "ActiveState", "s", NULL, offsetof(struct properties, active_state) },
1187-
{ "SubState", "s", NULL, offsetof(struct properties, sub_state) },
1188-
{}
1189-
};
1190-
1191-
r = bus_message_map_properties_changed(message, map, &properties);
1192-
if (r < 0)
1193-
bus_log_parse_error(r);
1194-
else if (streq_ptr(properties.active_state, "inactive") ||
1195-
streq_ptr(properties.active_state, "failed") ||
1196-
streq_ptr(properties.sub_state, "auto-restart"))
1197-
machine_release_unit(machine);
1198-
1199-
free(properties.active_state);
1200-
free(properties.sub_state);
1201-
}
1202-
12031174
machine_add_to_gc_queue(machine);
12041175
return 0;
12051176
}
@@ -1223,9 +1194,7 @@ int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *er
12231194
if (!machine)
12241195
return 0;
12251196

1226-
machine_release_unit(machine);
12271197
machine_add_to_gc_queue(machine);
1228-
12291198
return 0;
12301199
}
12311200

src/machine/machined.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,16 @@ void manager_gc(Manager *m, bool drop_not_started) {
247247
LIST_REMOVE(gc_queue, m->machine_gc_queue, machine);
248248
machine->in_gc_queue = false;
249249

250-
if (!machine_check_gc(machine, drop_not_started)) {
250+
/* First, if we are not closing yet, initiate stopping */
251+
if (!machine_check_gc(machine, drop_not_started) &&
252+
machine_get_state(machine) != MACHINE_CLOSING)
251253
machine_stop(machine);
254+
255+
/* Now, the stop stop probably made this referenced
256+
* again, but if it didn't, then it's time to let it
257+
* go entirely. */
258+
if (!machine_check_gc(machine, drop_not_started)) {
259+
machine_finalize(machine);
252260
machine_free(machine);
253261
}
254262
}

0 commit comments

Comments
 (0)