#include "notify-recv.h"
#include "os-util.h"
#include "parse-util.h"
+#include "path-lookup.h"
#include "percent-util.h"
#include "pidref.h"
#include "process-util.h"
typedef struct Manager {
sd_event *event;
- sd_bus *bus;
+ sd_bus *api_bus;
+ sd_bus *system_bus;
sd_varlink_server *varlink_server;
uint32_t current_transfer_id;
bool use_btrfs_subvol;
bool use_btrfs_quota;
- RuntimeScope runtime_scope; /* for now: always RUNTIME_SCOPE_SYSTEM */
+ RuntimeScope runtime_scope;
} Manager;
#define TRANSFERS_MAX 64
log_full(priority, "(transfer%" PRIu32 ") %s", t->id, line);
r = sd_bus_emit_signal(
- t->manager->bus,
+ t->manager->api_bus,
t->object_path,
"org.freedesktop.import1.Transfer",
"LogMessage",
double progress = transfer_percent_as_double(t);
r = sd_bus_emit_signal(
- t->manager->bus,
+ t->manager->api_bus,
t->object_path,
"org.freedesktop.import1.Transfer",
"ProgressUpdate",
transfer_send_logs(t, true);
r = sd_bus_emit_signal(
- t->manager->bus,
+ t->manager->api_bus,
"/org/freedesktop/import1",
"org.freedesktop.import1.Manager",
"TransferRemoved",
const char *cmd[] = {
NULL, /* systemd-import, systemd-import-fs, systemd-export or systemd-pull */
NULL, /* tar, raw */
+ NULL, /* --system or --user */
NULL, /* --verify= */
NULL, /* verify argument */
NULL, /* --class= */
;
}
+ cmd[k++] = runtime_scope_cmdline_option_to_string(t->manager->runtime_scope);
+
if (t->verify != _IMPORT_VERIFY_INVALID) {
cmd[k++] = "--verify";
cmd[k++] = import_verify_to_string(t->verify);
return r;
r = sd_bus_emit_signal(
- t->manager->bus,
+ t->manager->api_bus,
"/org/freedesktop/import1",
"org.freedesktop.import1.Manager",
"TransferNew",
hashmap_free(m->polkit_registry);
- m->bus = sd_bus_flush_close_unref(m->bus);
+ m->api_bus = sd_bus_flush_close_unref(m->api_bus);
+ m->system_bus = sd_bus_flush_close_unref(m->system_bus);
m->varlink_server = sd_varlink_server_unref(m->varlink_server);
sd_event_unref(m->event);
return 0;
}
-static int manager_new(Manager **ret) {
+static int manager_new(RuntimeScope scope, Manager **ret) {
_cleanup_(manager_unrefp) Manager *m = NULL;
int r;
*m = (Manager) {
.use_btrfs_subvol = true,
.use_btrfs_quota = true,
- .runtime_scope = RUNTIME_SCOPE_SYSTEM,
+ .runtime_scope = scope,
};
r = sd_event_default(&m->event);
assert(msg);
- r = bus_verify_polkit_async(
- msg,
- "org.freedesktop.import1.import",
- /* details= */ NULL,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = bus_verify_polkit_async(
+ msg,
+ "org.freedesktop.import1.import",
+ /* details= */ NULL,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
if (endswith(sd_bus_message_get_member(msg), "Ex")) {
const char *sclass;
assert(msg);
- r = bus_verify_polkit_async(
- msg,
- "org.freedesktop.import1.import",
- /* details= */ NULL,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = bus_verify_polkit_async(
+ msg,
+ "org.freedesktop.import1.import",
+ /* details= */ NULL,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
if (endswith(sd_bus_message_get_member(msg), "Ex")) {
const char *sclass;
assert(msg);
- r = bus_verify_polkit_async(
- msg,
- "org.freedesktop.import1.export",
- /* details= */ NULL,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = bus_verify_polkit_async(
+ msg,
+ "org.freedesktop.import1.export",
+ /* details= */ NULL,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
if (endswith(sd_bus_message_get_member(msg), "Ex")) {
const char *sclass;
assert(msg);
- r = bus_verify_polkit_async(
- msg,
- "org.freedesktop.import1.pull",
- /* details= */ NULL,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = bus_verify_polkit_async(
+ msg,
+ "org.freedesktop.import1.pull",
+ /* details= */ NULL,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
if (endswith(sd_bus_message_get_member(msg), "Ex")) {
const char *sclass;
assert(m);
assert(m->event);
- assert(!m->bus);
+ assert(!m->system_bus);
+ assert(!m->api_bus);
- r = bus_open_system_watch_bind(&m->bus);
+ r = bus_open_system_watch_bind(&m->system_bus);
if (r < 0)
return log_error_errno(r, "Failed to get system bus connection: %m");
- r = bus_add_implementation(m->bus, &manager_object, m);
+ r = sd_bus_attach_event(m->system_bus, m->event, 0);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to attach system bus to event loop: %m");
- r = bus_log_control_api_register(m->bus);
+ if (m->runtime_scope == RUNTIME_SCOPE_SYSTEM)
+ m->api_bus = sd_bus_ref(m->system_bus);
+ else {
+ assert(m->runtime_scope == RUNTIME_SCOPE_USER);
+
+ r = sd_bus_default_user(&m->api_bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get user bus connection: %m");
+
+ r = sd_bus_attach_event(m->api_bus, m->event, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach user bus to event loop: %m");
+ }
+
+ r = bus_add_implementation(m->api_bus, &manager_object, m);
if (r < 0)
return r;
- r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.import1", 0, NULL, NULL);
+ r = bus_log_control_api_register(m->api_bus);
if (r < 0)
- return log_error_errno(r, "Failed to request name: %m");
+ return r;
- r = sd_bus_attach_event(m->bus, m->event, 0);
+ r = sd_bus_request_name_async(m->api_bus, NULL, "org.freedesktop.import1", 0, NULL, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to attach bus to event loop: %m");
+ return log_error_errno(r, "Failed to request name: %m");
return 0;
}
if (manager_find(m, tt, p.remote))
return sd_varlink_errorbo(link, "io.systemd.Import.AlreadyInProgress", SD_JSON_BUILD_PAIR_STRING("remote", p.remote));
- r = varlink_verify_polkit_async(
- link,
- m->bus,
- "org.freedesktop.import1.pull",
- (const char**) STRV_MAKE(
- "remote", p.remote,
- "local", p.local,
- "class", image_class_to_string(p.class),
- "type", import_type_to_string(p.type),
- "verify", import_verify_to_string(p.verify)),
- &m->polkit_registry);
- if (r <= 0)
- return r;
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async(
+ link,
+ m->system_bus,
+ "org.freedesktop.import1.pull",
+ (const char**) STRV_MAKE(
+ "remote", p.remote,
+ "local", p.local,
+ "class", image_class_to_string(p.class),
+ "type", import_type_to_string(p.type),
+ "verify", import_verify_to_string(p.verify)),
+ &m->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
_cleanup_(transfer_unrefp) Transfer *t = NULL;
assert(m->event);
assert(!m->varlink_server);
- r = varlink_server_new(&m->varlink_server,
- SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA,
- m);
+ r = varlink_server_new(
+ &m->varlink_server,
+ (m->runtime_scope != RUNTIME_SCOPE_USER ? SD_VARLINK_SERVER_ACCOUNT_UID : 0)|
+ SD_VARLINK_SERVER_INHERIT_USERDATA,
+ m);
if (r < 0)
return log_error_errno(r, "Failed to allocate varlink server object: %m");
if (r < 0)
return log_error_errno(r, "Failed to bind to passed Varlink sockets: %m");
if (r == 0) {
- r = sd_varlink_server_listen_address(m->varlink_server, "/run/systemd/io.systemd.Import", 0666);
+ _cleanup_free_ char *socket_path = NULL;
+ r = runtime_directory_generic(m->runtime_scope, "systemd/io.systemd.Import", &socket_path);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine socket path: %m");
+
+ r = sd_varlink_server_listen_address(m->varlink_server, socket_path, runtime_scope_to_socket_mode(m->runtime_scope) | SD_VARLINK_SERVER_MODE_MKDIR_0755);
if (r < 0)
return log_error_errno(r, "Failed to bind to Varlink socket: %m");
}
static int run(int argc, char *argv[]) {
_cleanup_(manager_unrefp) Manager *m = NULL;
+ RuntimeScope scope = RUNTIME_SCOPE_SYSTEM;
int r;
log_setup();
"VM and container image import and export service.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
- /* runtime_scope= */ NULL,
+ &scope,
argc, argv);
if (r <= 0)
return r;
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD) >= 0);
- r = manager_new(&m);
+ r = manager_new(scope, &m);
if (r < 0)
return log_error_errno(r, "Failed to allocate manager object: %m");
r = bus_event_loop_with_idle(
m->event,
- m->bus,
+ m->api_bus,
"org.freedesktop.import1",
DEFAULT_EXIT_USEC,
manager_check_idle,