X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fmachine%2Fmachine.c;h=edd244f30daee3f9c8484c2c8f3040053343c8e9;hb=19e887e709c31ee4366ec44a770d3963cd48cb86;hp=c0fa1b24b6c068e06923d05d0f2f39834ed4731e;hpb=206e7a5f7b55ac61188efd895e65ab26e478cbb2;p=elogind.git diff --git a/src/machine/machine.c b/src/machine/machine.c index c0fa1b24b..edd244f30 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -32,9 +32,10 @@ #include "fileio.h" #include "special.h" #include "unit-name.h" -#include "machine.h" #include "bus-util.h" #include "bus-error.h" +#include "machine.h" +#include "machine-dbus.h" Machine* machine_new(Manager *manager, const char *name) { Machine *m; @@ -73,6 +74,9 @@ fail: void machine_free(Machine *m) { assert(m); + while (m->operations) + machine_operation_unref(m->operations); + if (m->in_gc_queue) LIST_REMOVE(gc_queue, m->manager->machine_gc_queue, m); @@ -94,6 +98,7 @@ void machine_free(Machine *m) { free(m->state_file); free(m->service); free(m->root_directory); + free(m->netif); free(m); } @@ -176,6 +181,21 @@ int machine_save(Machine *m) { m->timestamp.realtime, m->timestamp.monotonic); + if (m->n_netif > 0) { + unsigned i; + + fputs("NETIF=", f); + + for (i = 0; i < m->n_netif; i++) { + if (i != 0) + fputc(' ', f); + + fprintf(f, "%i", m->netif[i]); + } + + fputc('\n', f); + } + r = fflush_and_check(f); if (r < 0) goto finish; @@ -185,23 +205,25 @@ int machine_save(Machine *m) { goto finish; } + free(temp_path); + temp_path = NULL; + if (m->unit) { char *sl; /* Create a symlink from the unit name to the machine * name, so that we can quickly find the machine for * each given unit */ - sl = strappenda("/run/systemd/machines/unit:", m->unit); + sl = strjoina("/run/systemd/machines/unit:", m->unit); symlink(m->name, sl); } finish: - if (r < 0) { - if (temp_path) - unlink(temp_path); + if (temp_path) + unlink(temp_path); - log_error("Failed to save machine data %s: %s", m->state_file, strerror(-r)); - } + if (r < 0) + log_error_errno(r, "Failed to save machine data %s: %m", m->state_file); return r; } @@ -213,7 +235,7 @@ static void machine_unlink(Machine *m) { char *sl; - sl = strappenda("/run/systemd/machines/unit:", m->unit); + sl = strjoina("/run/systemd/machines/unit:", m->unit); unlink(sl); } @@ -222,7 +244,7 @@ static void machine_unlink(Machine *m) { } int machine_load(Machine *m) { - _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL; + _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL, *netif = NULL; int r; assert(m); @@ -237,13 +259,13 @@ int machine_load(Machine *m) { "CLASS", &class, "REALTIME", &realtime, "MONOTONIC", &monotonic, + "NETIF", &netif, NULL); if (r < 0) { if (r == -ENOENT) return 0; - log_error("Failed to read %s: %s", m->state_file, strerror(-r)); - return r; + return log_error_errno(r, "Failed to read %s: %m", m->state_file); } if (id) @@ -272,6 +294,35 @@ int machine_load(Machine *m) { m->timestamp.monotonic = l; } + if (netif) { + size_t l, allocated = 0, nr = 0; + const char *word, *state; + int *ni = NULL; + + FOREACH_WORD(word, l, netif, state) { + char buf[l+1]; + int ifi; + + *(char*) (mempcpy(buf, word, l)) = 0; + + if (safe_atoi(buf, &ifi) < 0) + continue; + if (ifi <= 0) + continue; + + if (!GREEDY_REALLOC(ni, allocated, nr+1)) { + free(ni); + return log_oom(); + } + + ni[nr++] = ifi; + } + + free(m->netif); + m->netif = ni; + m->n_netif = nr; + } + return r; } @@ -292,7 +343,7 @@ static int machine_start_scope(Machine *m, sd_bus_message *properties, sd_bus_er if (!scope) return log_oom(); - description = strappenda(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); + description = strjoina(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, properties, error, &job); if (r < 0) { @@ -331,10 +382,10 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) { return r; log_struct(LOG_INFO, - MESSAGE_ID(SD_MESSAGE_MACHINE_START), + LOG_MESSAGE_ID(SD_MESSAGE_MACHINE_START), "NAME=%s", m->name, "LEADER="PID_FMT, m->leader, - "MESSAGE=New machine %s.", m->name, + LOG_MESSAGE("New machine %s.", m->name), NULL); if (!dual_timestamp_is_set(&m->timestamp)) @@ -360,18 +411,16 @@ static int machine_stop_scope(Machine *m) { if (!m->unit) return 0; - if (!m->registered) { - r = manager_stop_unit(m->manager, m->unit, &error, &job); - if (r < 0) { - log_error("Failed to stop machine scope: %s", bus_error_message(&error, r)); - return r; - } + r = manager_stop_unit(m->manager, m->unit, &error, &job); + if (r < 0) { + log_error("Failed to stop machine scope: %s", bus_error_message(&error, r)); + return r; } free(m->scope_job); m->scope_job = job; - return r; + return 0; } int machine_stop(Machine *m) { @@ -380,10 +429,10 @@ int machine_stop(Machine *m) { if (m->started) log_struct(LOG_INFO, - MESSAGE_ID(SD_MESSAGE_MACHINE_STOP), + LOG_MESSAGE_ID(SD_MESSAGE_MACHINE_STOP), "NAME=%s", m->name, "LEADER="PID_FMT, m->leader, - "MESSAGE=Machine %s terminated.", m->name, + LOG_MESSAGE("Machine %s terminated.", m->name), NULL); /* Kill cgroup */ @@ -447,12 +496,36 @@ int machine_kill(Machine *m, KillWho who, int signo) { if (kill(m->leader, signo) < 0) return -errno; + + return 0; } /* Otherwise make PID 1 do it for us, for the entire cgroup */ return manager_kill_unit(m->manager, m->unit, signo, NULL); } +MachineOperation *machine_operation_unref(MachineOperation *o) { + if (!o) + return NULL; + + sd_event_source_unref(o->event_source); + + safe_close(o->errno_fd); + + if (o->pid > 1) + (void) kill(o->pid, SIGKILL); + + sd_bus_message_unref(o->message); + + if (o->machine) { + LIST_REMOVE(operations, o->machine->operations, o); + o->machine->n_operations--; + } + + free(o); + return NULL; +} + static const char* const machine_class_table[_MACHINE_CLASS_MAX] = { [MACHINE_CONTAINER] = "container", [MACHINE_VM] = "vm"