Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 19 additions & 43 deletions cinnamon-session/csm-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
#include "csm-autostart-app.h"

#include "csm-util.h"
#include "mdm.h"
#include "csm-system.h"
#include "csm-session-save.h"
#include "inhibit-dialog-info.h"
Expand All @@ -67,15 +66,12 @@
* want to wait, at least for something happening more than once.
* We can get deployed on very slow media though like CDROM devices,
* often with complex stacking/compressing filesystems on top, which
* is not a recipie for speed. Particularly now that we throw up

Check failure on line 69 in cinnamon-session/csm-manager.c

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22.3-amd64, Mint 22, true) / Mint 22

recipie ==> recipe
* a fail whale if required components don't show up quickly enough,
* let's make this fairly long.
*/
#define CSM_MANAGER_PHASE_TIMEOUT 30 /* seconds */

#define MDM_FLEXISERVER_COMMAND "mdmflexiserver"
#define MDM_FLEXISERVER_ARGS "--startnew Standard"

#define GDM_FLEXISERVER_COMMAND "gdmflexiserver"
#define GDM_FLEXISERVER_ARGS "--startnew Standard"

Expand Down Expand Up @@ -111,10 +107,8 @@
CSM_MANAGER_LOGOUT_LOGOUT,
CSM_MANAGER_LOGOUT_REBOOT,
CSM_MANAGER_LOGOUT_REBOOT_INTERACT,
CSM_MANAGER_LOGOUT_REBOOT_MDM,
CSM_MANAGER_LOGOUT_SHUTDOWN,
CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT,
CSM_MANAGER_LOGOUT_SHUTDOWN_MDM
CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT
} CsmManagerLogoutType;

struct CsmManagerPrivate
Expand Down Expand Up @@ -473,13 +467,16 @@
static void start_phase (CsmManager *manager);

static void
quit_request_failed (CsmSystem *system,
GError *error,
gpointer user_data)
on_shutdown_prepared (CsmSystem *system,
gboolean success,
gpointer user_data)
{
g_warning ("Using an MDM logout action to shutdown/reboot the system.");
MdmLogoutAction fallback_action = GPOINTER_TO_INT (user_data);
mdm_set_logout_action (fallback_action);
g_signal_handlers_disconnect_by_func (system, on_shutdown_prepared, user_data);
Comment on lines +470 to +474

if (!success) {
g_warning ("Shutdown/restart was not confirmed by logind");
}

csm_quit ();
}

Expand All @@ -498,31 +495,21 @@
case CSM_MANAGER_LOGOUT_REBOOT:
case CSM_MANAGER_LOGOUT_REBOOT_INTERACT:
g_warning ("Requesting system restart...");
mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);
g_signal_connect (manager->priv->system,
"request-failed",
G_CALLBACK (quit_request_failed),
GINT_TO_POINTER (MDM_LOGOUT_ACTION_REBOOT));
"shutdown-prepared",
G_CALLBACK (on_shutdown_prepared),
manager);
csm_system_attempt_restart (manager->priv->system);
break;
case CSM_MANAGER_LOGOUT_REBOOT_MDM:
mdm_set_logout_action (MDM_LOGOUT_ACTION_REBOOT);
csm_quit ();
break;
case CSM_MANAGER_LOGOUT_SHUTDOWN:
case CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
case CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
g_warning ("Requesting system shutdown...");
mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);
g_signal_connect (manager->priv->system,
"request-failed",
G_CALLBACK (quit_request_failed),
GINT_TO_POINTER (MDM_LOGOUT_ACTION_SHUTDOWN));
"shutdown-prepared",
G_CALLBACK (on_shutdown_prepared),
manager);
csm_system_attempt_stop (manager->priv->system);
break;
case CSM_MANAGER_LOGOUT_SHUTDOWN_MDM:
mdm_set_logout_action (MDM_LOGOUT_ACTION_SHUTDOWN);
csm_quit ();
break;
default:
g_assert_not_reached ();
break;
Expand Down Expand Up @@ -1121,7 +1108,6 @@
manager->priv->logout_mode = CSM_MANAGER_LOGOUT_MODE_NORMAL;

manager->priv->logout_type = CSM_MANAGER_LOGOUT_NONE;
mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);

manager->priv->dialog_action = CSM_LOGOUT_ACTION_UNDEFINED;

Expand Down Expand Up @@ -1186,7 +1172,7 @@
NULL,
&error)) {
if (error) {
g_debug ("CsmManager: Unable to start MDM greeter: %s", error->message);
g_debug ("CsmManager: Unable to start greeter: %s", error->message);
g_error_free (error);
}
}
Expand All @@ -1205,15 +1191,7 @@
return;
}

if (process_is_running ("mdm")) {
const gchar *command[] = {
MDM_FLEXISERVER_COMMAND,
MDM_FLEXISERVER_ARGS,
NULL
};

flexiserver_launch (command);
} else if (process_is_running("gdm") || process_is_running("gdm3")) {
if (process_is_running("gdm") || process_is_running("gdm3")) {
const gchar *command[] = {
GDM_FLEXISERVER_COMMAND,
GDM_FLEXISERVER_ARGS,
Expand Down Expand Up @@ -1349,12 +1327,10 @@
break;
case CSM_MANAGER_LOGOUT_REBOOT:
case CSM_MANAGER_LOGOUT_REBOOT_INTERACT:
case CSM_MANAGER_LOGOUT_REBOOT_MDM:
action = CSM_LOGOUT_ACTION_REBOOT;
break;
case CSM_MANAGER_LOGOUT_SHUTDOWN:
case CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
case CSM_MANAGER_LOGOUT_SHUTDOWN_MDM:
action = CSM_LOGOUT_ACTION_SHUTDOWN;
break;
default:
Expand Down
12 changes: 12 additions & 0 deletions cinnamon-session/csm-system.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

enum {
REQUEST_FAILED = 0,
SHUTDOWN_PREPARED,
LAST_SIGNAL
};

Expand All @@ -50,6 +51,17 @@ csm_system_default_init (CsmSystemInterface *iface)
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1, G_TYPE_POINTER);

signals [SHUTDOWN_PREPARED] =
g_signal_new ("shutdown-prepared",
CSM_TYPE_SYSTEM,
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE,
1, G_TYPE_BOOLEAN);
}

GQuark
Expand Down
129 changes: 98 additions & 31 deletions cinnamon-session/csm-systemd.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,18 @@ struct _CsmSystemdPrivate

GSList *inhibitors;
gint inhibit_fd;
gint shutdown_inhibit_fd;
gboolean prepare_for_shutdown_expected;
};

static void csm_systemd_system_init (CsmSystemInterface *iface);

static void sd_proxy_signal_cb (GDBusProxy *proxy,
const gchar *sender_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data);

G_DEFINE_TYPE_WITH_CODE (CsmSystemd, csm_systemd, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (CSM_TYPE_SYSTEM,
csm_systemd_system_init))
Expand Down Expand Up @@ -92,6 +100,9 @@ csm_systemd_finalize (GObject *object)
g_slist_free_full (systemd->priv->inhibitors, g_free);
}
drop_system_inhibitor (systemd);
if (systemd->priv->shutdown_inhibit_fd != -1) {
close (systemd->priv->shutdown_inhibit_fd);
}

G_OBJECT_CLASS (csm_systemd_parent_class)->finalize (object);
}
Expand Down Expand Up @@ -120,6 +131,7 @@ csm_systemd_init (CsmSystemd *manager)
CsmSystemdPrivate);

manager->priv->inhibit_fd = -1;
manager->priv->shutdown_inhibit_fd = -1;

error = NULL;

Expand All @@ -143,6 +155,9 @@ csm_systemd_init (CsmSystemd *manager)
g_warning ("Failed to connect to systemd: %s",
error->message);
g_error_free (error);
} else {
g_signal_connect (manager->priv->sd_proxy, "g-signal",
G_CALLBACK (sd_proxy_signal_cb), manager);
}

Comment on lines +158 to 162
g_object_unref (bus);
Expand Down Expand Up @@ -174,21 +189,62 @@ csm_systemd_init (CsmSystemd *manager)
}

static void
restart_done (GObject *source,
GAsyncResult *result,
gpointer user_data)
take_shutdown_inhibitor (CsmSystemd *manager)
{
GVariant *res;
GUnixFDList *fd_list = NULL;
GError *error = NULL;
gint idx;

if (manager->priv->shutdown_inhibit_fd != -1)
return;

res = g_dbus_proxy_call_with_unix_fd_list_sync (manager->priv->sd_proxy,
"Inhibit",
g_variant_new ("(ssss)",
"shutdown",
g_get_user_name (),
"Ensuring session exits cleanly before shutdown",
"delay"),
0,
G_MAXINT,
NULL,
&fd_list,
NULL,
&error);
if (res == NULL) {
g_warning ("Unable to inhibit shutdown: %s", error->message);
g_error_free (error);
return;
}

g_variant_get (res, "(h)", &idx);
manager->priv->shutdown_inhibit_fd = g_unix_fd_list_get (fd_list, idx, &error);
if (manager->priv->shutdown_inhibit_fd == -1) {
g_warning ("Failed to receive shutdown inhibitor fd: %s", error->message);
g_error_free (error);
}

g_object_unref (fd_list);
g_variant_unref (res);
}

static void
reboot_or_poweroff_done (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GDBusProxy *proxy = G_DBUS_PROXY (source);
CsmSystemd *manager = user_data;
GError *error = NULL;
GVariant *res;

res = g_dbus_proxy_call_finish (proxy, result, &error);
res = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);

if (!res) {
g_warning ("Unable to restart system via systemd: %s", error->message);
g_signal_emit_by_name (G_OBJECT (manager), "request-failed", NULL);
if (res == NULL) {
g_warning ("Unable to shutdown/restart system via systemd: %s", error->message);
g_error_free (error);
manager->priv->prepare_for_shutdown_expected = FALSE;
g_signal_emit_by_name (manager, "shutdown-prepared", FALSE);
} else {
g_variant_unref (res);
}
Expand All @@ -201,54 +257,65 @@ csm_systemd_attempt_restart (CsmSystem *system)

CsmSystemd *manager = CSM_SYSTEMD (system);

drop_system_inhibitor (manager);
take_shutdown_inhibitor (manager);
manager->priv->prepare_for_shutdown_expected = TRUE;

g_dbus_proxy_call (manager->priv->sd_proxy,
"Reboot",
g_variant_new ("(b)", TRUE),
0,
G_MAXINT,
NULL,
restart_done,
reboot_or_poweroff_done,
manager);
}

static void
stop_done (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GDBusProxy *proxy = G_DBUS_PROXY (source);
CsmSystemd *manager = user_data;
GError *error = NULL;
GVariant *res;

res = g_dbus_proxy_call_finish (proxy, result, &error);

if (!res) {
g_warning ("Unable to stop system via systemd: %s", error->message);
g_signal_emit_by_name (G_OBJECT (manager), "request-failed", NULL);
g_error_free (error);
} else {
g_variant_unref (res);
}
}

static void
csm_systemd_attempt_stop (CsmSystem *system)
{
g_warning ("Attempting to shutdown using systemd...");

CsmSystemd *manager = CSM_SYSTEMD (system);

drop_system_inhibitor (manager);
take_shutdown_inhibitor (manager);
manager->priv->prepare_for_shutdown_expected = TRUE;

g_dbus_proxy_call (manager->priv->sd_proxy,
"PowerOff",
g_variant_new ("(b)", TRUE),
0,
G_MAXINT,
NULL,
stop_done,
reboot_or_poweroff_done,
manager);
}

static void
sd_proxy_signal_cb (GDBusProxy *proxy,
const gchar *sender_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
CsmSystemd *manager = user_data;
gboolean is_about_to_shutdown;

if (g_strcmp0 (signal_name, "PrepareForShutdown") != 0)
return;

g_variant_get (parameters, "(b)", &is_about_to_shutdown);
if (!is_about_to_shutdown)
return;

if (manager->priv->prepare_for_shutdown_expected) {
g_debug ("Shutdown successfully prepared");
manager->priv->prepare_for_shutdown_expected = FALSE;
g_signal_emit_by_name (manager, "shutdown-prepared", TRUE);
}
}

static void
csm_systemd_set_session_idle (CsmSystem *system,
gboolean is_idle)
Expand Down
Loading
Loading