+ r = manager_setup_varlink_server(m, &s);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set up varlink server: %m");
+
+ if (!MANAGER_IS_TEST_RUN(m)) {
+ (void) mkdir_p_label("/run/systemd/userdb", 0755);
+
+ FOREACH_STRING(address, "/run/systemd/userdb/io.systemd.DynamicUser", VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM) {
+ if (MANAGER_IS_RELOADING(m)) {
+ /* If manager is reloading, we skip listening on existing addresses, since
+ * the fd should be acquired later through deserialization. */
+ if (access(address, F_OK) >= 0)
+ continue;
+ if (errno != ENOENT)
+ return log_error_errno(errno,
+ "Failed to check if varlink socket '%s' exists: %m", address);
+ }
+
+ r = varlink_server_listen_address(s, address, 0666);
+ if (r < 0)
+ return log_error_errno(r, "Failed to bind to varlink socket '%s': %m", address);
+ }
+ }
+
+ r = varlink_server_attach_event(s, m->event, EVENT_PRIORITY_IPC);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
+
+ m->varlink_server = TAKE_PTR(s);
+ return 1;
+}
+
+static int vl_reply(Varlink *link, JsonVariant *parameters, const char *error_id, VarlinkReplyFlags flags, void *userdata) {
+ Manager *m = ASSERT_PTR(userdata);
+ int r;
+
+ if (error_id)
+ log_debug("varlink systemd-oomd client error: %s", error_id);
+
+ if (FLAGS_SET(flags, VARLINK_REPLY_ERROR) && FLAGS_SET(flags, VARLINK_REPLY_LOCAL)) {
+ /* Varlink connection was closed, likely because of systemd-oomd restart. Let's try to
+ * reconnect and send the initial ManagedOOM update again. */
+
+ m->managed_oom_varlink = varlink_unref(link);
+
+ log_debug("Reconnecting to %s", VARLINK_ADDR_PATH_MANAGED_OOM_USER);
+
+ r = manager_varlink_init(m);
+ if (r <= 0)
+ return r;
+ }
+
+ return 0;
+}
+
+static int manager_varlink_init_user(Manager *m) {
+ _cleanup_(varlink_close_unrefp) Varlink *link = NULL;
+ int r;
+
+ assert(m);
+
+ if (m->managed_oom_varlink)
+ return 1;
+
+ if (MANAGER_IS_TEST_RUN(m))
+ return 0;
+
+ r = varlink_connect_address(&link, VARLINK_ADDR_PATH_MANAGED_OOM_USER);
+ if (r < 0) {
+ if (r == -ENOENT || ERRNO_IS_DISCONNECT(r)) {
+ log_debug("systemd-oomd varlink unix socket not found, skipping user manager varlink setup");
+ return 0;
+ }
+ return log_error_errno(r, "Failed to connect to %s: %m", VARLINK_ADDR_PATH_MANAGED_OOM_USER);
+ }
+
+ varlink_set_userdata(link, m);
+
+ r = varlink_bind_reply(link, vl_reply);
+ if (r < 0)
+ return r;
+
+ r = varlink_attach_event(link, m->event, EVENT_PRIORITY_IPC);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
+
+ m->managed_oom_varlink = TAKE_PTR(link);
+
+ /* Queue the initial ManagedOOM update. */
+ (void) manager_varlink_send_managed_oom_initial(m);
+
+ return 1;
+}
+
+int manager_setup_varlink_server(Manager *m, VarlinkServer **ret) {
+ _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
+ int r;
+
+ assert(m);
+ assert(ret);
+