#include "bus-error.h"
#include "bus-locator.h"
+#include "json.h"
#include "macro.h"
#include "process-util.h"
+#include "socket-util.h"
#include "string-util.h"
+#include "varlink.h"
#include "vmspawn-register.h"
-int register_machine(sd_bus *bus, const char *machine_name, sd_id128_t uuid, const char *service, const char *directory) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+int register_machine(
+ sd_bus *bus,
+ const char *machine_name,
+ sd_id128_t uuid,
+ const char *service,
+ const char *directory,
+ unsigned cid,
+ const char *address,
+ const char *key_path) {
+
+ _cleanup_(varlink_unrefp) Varlink *vl = NULL;
int r;
- assert(bus);
assert(machine_name);
assert(service);
- r = bus_call_method(
- bus,
- bus_machine_mgr,
- "RegisterMachine",
- &error,
- NULL,
- "sayssus",
- machine_name,
- SD_BUS_MESSAGE_APPEND_ID128(uuid),
- service,
- "vm",
- (uint32_t) getpid_cached(),
- strempty(directory));
+ /* First try to use varlink, as it provides more features (such as SSH support). */
+ r = varlink_connect_address(&vl, "/run/systemd/machine/io.systemd.Machine");
+ if (r == -ENOENT || ERRNO_IS_DISCONNECT(r)) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+
+ assert(bus);
+
+ /* In case we are running with an older machined, fallback to the existing D-Bus method. */
+ r = bus_call_method(
+ bus,
+ bus_machine_mgr,
+ "RegisterMachine",
+ &error,
+ NULL,
+ "sayssus",
+ machine_name,
+ SD_BUS_MESSAGE_APPEND_ID128(uuid),
+ service,
+ "vm",
+ (uint32_t) getpid_cached(),
+ strempty(directory));
+ if (r < 0)
+ return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
+
+ return 0;
+ }
if (r < 0)
- return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to connect to machined on /run/systemd/machine/io.systemd.Machine: %m");
- return 0;
+
+ return varlink_callb_and_log(vl,
+ "io.systemd.Machine.Register",
+ NULL,
+ JSON_BUILD_OBJECT(
+ JSON_BUILD_PAIR_STRING("name", machine_name),
+ JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(uuid), "id", JSON_BUILD_ID128(uuid)),
+ JSON_BUILD_PAIR_STRING("service", service),
+ JSON_BUILD_PAIR_STRING("class", "vm"),
+ JSON_BUILD_PAIR_CONDITION(VSOCK_CID_IS_REGULAR(cid), "vsockCid", JSON_BUILD_UNSIGNED(cid)),
+ JSON_BUILD_PAIR_CONDITION(directory, "rootDirectory", JSON_BUILD_STRING(directory)),
+ JSON_BUILD_PAIR_CONDITION(address, "sshAddress", JSON_BUILD_STRING(address)),
+ JSON_BUILD_PAIR_CONDITION(key_path, "sshPrivateKeyPath", JSON_BUILD_STRING(key_path))));
}
int unregister_machine(sd_bus *bus, const char *machine_name) {
if (r < 0)
return r;
- if (arg_register) {
- r = register_machine(bus, arg_machine, arg_uuid, trans_scope, arg_directory);
- if (r < 0)
- return r;
- }
-
bool use_kvm = arg_kvm > 0;
if (arg_kvm < 0) {
r = qemu_check_kvm_support();
log_debug("Executing: %s", joined);
}
+ if (arg_register) {
+ char vm_address[STRLEN("vsock/") + DECIMAL_STR_MAX(unsigned)];
+
+ xsprintf(vm_address, "vsock/%u", child_cid);
+ r = register_machine(
+ bus,
+ arg_machine,
+ arg_uuid,
+ trans_scope,
+ arg_directory,
+ child_cid,
+ child_cid != VMADDR_CID_ANY ? vm_address : NULL,
+ ssh_private_key_path);
+ if (r < 0)
+ return r;
+ }
+
assert_se(sigprocmask_many(SIG_BLOCK, /* old_sigset=*/ NULL, SIGCHLD, SIGWINCH) >= 0);
_cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL;