- q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set);
- if (q < 0)
- if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
- r = q;
+error:
+ log_error("cannot mute VT %u for session %s (%d/%d)", s->vtnr, s->id, r, errno);
+ session_restore_vt(s);
+}
+
+void session_restore_vt(Session *s) {
+ _cleanup_free_ char *utf8 = NULL;
+ int vt, kb = K_XLATE;
+ struct vt_mode mode = { 0 };
+
+ vt = session_open_vt(s);
+ if (vt < 0)
+ return;
+
+ s->vt_source = sd_event_source_unref(s->vt_source);
+
+ ioctl(vt, KDSETMODE, KD_TEXT);
+
+ if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && *utf8 == '1')
+ kb = K_UNICODE;
+
+ ioctl(vt, KDSKBMODE, kb);
+
+ mode.mode = VT_AUTO;
+ ioctl(vt, VT_SETMODE, &mode);
+
+ fchown(vt, 0, -1);
+
+ s->vtfd = safe_close(s->vtfd);
+}
+
+bool session_is_controller(Session *s, const char *sender) {
+ assert(s);
+
+ return streq_ptr(s->controller, sender);
+}
+
+static void session_swap_controller(Session *s, char *name) {
+ SessionDevice *sd;
+
+ if (s->controller) {
+ manager_drop_busname(s->manager, s->controller);
+ free(s->controller);
+ s->controller = NULL;
+
+ /* Drop all devices as they're now unused. Do that after the
+ * controller is released to avoid sending out useles
+ * dbus signals. */
+ while ((sd = hashmap_first(s->devices)))
+ session_device_free(sd);
+
+ if (!name)
+ session_restore_vt(s);
+ }
+
+ s->controller = name;
+ session_save(s);
+}
+
+int session_set_controller(Session *s, const char *sender, bool force) {
+ char *t;
+ int r;
+
+ assert(s);
+ assert(sender);
+
+ if (session_is_controller(s, sender))
+ return 0;
+ if (s->controller && !force)
+ return -EBUSY;
+
+ t = strdup(sender);
+ if (!t)
+ return -ENOMEM;
+
+ r = manager_watch_busname(s->manager, sender);
+ if (r) {
+ free(t);
+ return r;