#include "special.h"
#include "stdio-util.h"
#include "string-table.h"
+#include "string-util.h"
#include "terminal-util.h"
#include "tmpfile-util.h"
#include "uid-range.h"
#include "unit-name.h"
#include "user-util.h"
-int machine_new(Manager *manager, MachineClass class, const char *name, Machine **ret) {
+int machine_new(MachineClass class, const char *name, Machine **ret) {
_cleanup_(machine_freep) Machine *m = NULL;
- int r;
- assert(manager);
assert(class < _MACHINE_CLASS_MAX);
- assert(name);
assert(ret);
/* Passing class == _MACHINE_CLASS_INVALID here is fine. It
.leader = PIDREF_NULL,
};
- m->name = strdup(name);
- if (!m->name)
- return -ENOMEM;
-
- if (class != MACHINE_HOST) {
- m->state_file = path_join("/run/systemd/machines", m->name);
- if (!m->state_file)
+ if (name) {
+ m->name = strdup(name);
+ if (!m->name)
return -ENOMEM;
}
m->class = class;
- r = hashmap_put(manager->machines, m->name, m);
+ *ret = TAKE_PTR(m);
+ return 0;
+}
+
+int machine_link(Manager *manager, Machine *machine) {
+ int r;
+
+ assert(manager);
+ assert(machine);
+
+ if (machine->manager)
+ return -EEXIST;
+ if (!machine->name)
+ return -EINVAL;
+
+ if (machine->class != MACHINE_HOST) {
+ char *temp = path_join("/run/systemd/machines", machine->name);
+ if (!temp)
+ return -ENOMEM;
+
+ free_and_replace(machine->state_file, temp);
+ }
+
+ r = hashmap_put(manager->machines, machine->name, machine);
if (r < 0)
return r;
- m->manager = manager;
+ machine->manager = manager;
- *ret = TAKE_PTR(m);
return 0;
}
LIST_REMOVE(gc_queue, m->manager->machine_gc_queue, m);
}
- machine_release_unit(m);
-
- free(m->scope_job);
-
if (m->manager) {
+ machine_release_unit(m);
+
(void) hashmap_remove(m->manager->machines, m->name);
if (m->manager->host_machine == m)
sd_bus_message_unref(m->create_message);
free(m->name);
+ free(m->scope_job);
free(m->state_file);
free(m->service);
free(m->root_directory);
LIST_FIELDS(Machine, gc_queue);
};
-int machine_new(Manager *manager, MachineClass class, const char *name, Machine **ret);
+int machine_new(MachineClass class, const char *name, Machine **ret);
+int machine_link(Manager *manager, Machine *machine);
Machine* machine_free(Machine *m);
bool machine_may_gc(Machine *m, bool drop_not_started);
void machine_add_to_gc_queue(Machine *m);
machine = hashmap_get(m->machines, name);
if (!machine) {
- r = machine_new(m, _MACHINE_CLASS_INVALID, name, &machine);
+ r = machine_new(_MACHINE_CLASS_INVALID, name, &machine);
if (r < 0)
return r;
+
+ r = machine_link(m, machine);
+ if (r < 0)
+ return 0;
}
if (_machine)
if (r < 0)
return log_error_errno(r, "Failed to open reference to PID 1: %m");
- r = machine_new(m, MACHINE_HOST, ".host", &t);
+ r = machine_new(MACHINE_HOST, ".host", &t);
if (r < 0)
return log_error_errno(r, "Failed to create machine: %m");
+ r = machine_link(m, t);
+ if (r < 0)
+ return log_error_errno(r, "Failed to link machine to manager: %m");
+
t->leader = TAKE_PIDREF(pidref);
t->id = mid;