Skip to content

Commit f72fbe1

Browse files
authored
csm-manager.c: Add functionality to restart the cinnamon-launcher (#184)
on-demand. This allows cinnamon to be restarted under the correct login session to prevent blocking of polkit authentication.
1 parent 4e3a757 commit f72fbe1

File tree

9 files changed

+130
-13
lines changed

9 files changed

+130
-13
lines changed

cinnamon-session/csm-app.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -510,18 +510,23 @@ csm_app_restart (CsmApp *app,
510510
GTimeVal current_time;
511511
g_debug ("Re-starting app: %s", app->priv->id);
512512

513-
g_get_current_time (&current_time);
514-
if (app->priv->last_restart_time.tv_sec > 0
515-
&& (current_time.tv_sec - app->priv->last_restart_time.tv_sec) < _CSM_APP_RESPAWN_RATELIMIT_SECONDS) {
516-
g_warning ("App '%s' respawning too quickly", csm_app_peek_app_id (app));
517-
g_set_error (error,
518-
CSM_APP_ERROR,
519-
CSM_APP_ERROR_RESTART_LIMIT,
520-
"Component '%s' crashing too quickly",
521-
csm_app_peek_app_id (app));
522-
return FALSE;
513+
// Cinnamon is *not* autorestart, we will only force it to via dbus RestartCinnamonLauncher
514+
// and don't want that to be skipped for some reason if it happens multiple times within a minute.
515+
// (This shouldn't ever happen anyhow).
516+
if (g_strcmp0 (app->priv->app_id, "cinnamon.desktop") != 0) {
517+
g_get_current_time (&current_time);
518+
if (app->priv->last_restart_time.tv_sec > 0
519+
&& (current_time.tv_sec - app->priv->last_restart_time.tv_sec) < _CSM_APP_RESPAWN_RATELIMIT_SECONDS) {
520+
g_warning ("App '%s' respawning too quickly", csm_app_peek_app_id (app));
521+
g_set_error (error,
522+
CSM_APP_ERROR,
523+
CSM_APP_ERROR_RESTART_LIMIT,
524+
"Component '%s' crashing too quickly",
525+
csm_app_peek_app_id (app));
526+
return FALSE;
527+
}
528+
app->priv->last_restart_time = current_time;
523529
}
524-
app->priv->last_restart_time = current_time;
525530

526531
return CSM_APP_GET_CLASS (app)->impl_restart (app, error);
527532
}

cinnamon-session/csm-consolekit.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,12 @@ csm_consolekit_is_last_session_for_user (CsmSystem *system)
859859
return FALSE;
860860
}
861861

862+
static gchar *
863+
csm_consolekit_get_login_session_id (CsmSystem *system)
864+
{
865+
return NULL;
866+
}
867+
862868
static void
863869
csm_consolekit_system_init (CsmSystemInterface *iface)
864870
{
@@ -876,6 +882,7 @@ csm_consolekit_system_init (CsmSystemInterface *iface)
876882
iface->add_inhibitor = csm_consolekit_add_inhibitor;
877883
iface->remove_inhibitor = csm_consolekit_remove_inhibitor;
878884
iface->is_last_session_for_user = csm_consolekit_is_last_session_for_user;
885+
iface->get_login_session_id = csm_consolekit_get_login_session_id;
879886
}
880887

881888
CsmConsolekit *

cinnamon-session/csm-manager.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1598,6 +1598,17 @@ _csm_manager_set_active_session (CsmManager *manager,
15981598
session_name);
15991599
}
16001600

1601+
void
1602+
_csm_manager_export_login_session_id (CsmManager *manager)
1603+
{
1604+
g_autofree gchar *session_id = NULL;
1605+
1606+
session_id = csm_system_get_login_session_id (manager->priv->system);
1607+
1608+
csm_exported_manager_set_session_id (manager->priv->skeleton,
1609+
session_id);
1610+
}
1611+
16011612
static gboolean
16021613
_app_has_app_id (const char *id,
16031614
CsmApp *app,
@@ -1695,6 +1706,29 @@ find_app_for_startup_id (CsmManager *manager,
16951706
return found_app;
16961707
}
16971708

1709+
static gboolean
1710+
restart_cinnamon_launcher (CsmManager *manager)
1711+
{
1712+
CsmApp *app;
1713+
1714+
app = find_app_for_app_id (manager, "cinnamon.desktop");
1715+
1716+
if (app) {
1717+
GError *error = NULL;
1718+
1719+
g_debug ("CsmManager: Restarting cinnamon-launcher");
1720+
1721+
if (!csm_app_restart (app, &error)) {
1722+
g_warning ("CsmManager: Unable to restart cinnamon-launcher: %s", error->message);
1723+
g_error_free (error);
1724+
}
1725+
} else {
1726+
g_warning ("CsmManager: Unable to find the cinnamon-launcher");
1727+
}
1728+
1729+
return G_SOURCE_REMOVE;
1730+
}
1731+
16981732
static gboolean
16991733
csm_manager_setenv (CsmExportedManager *skeleton,
17001734
GDBusMethodInvocation *invocation,
@@ -2348,6 +2382,30 @@ csm_manager_request_reboot (CsmExportedManager *skeleton,
23482382
return TRUE;
23492383
}
23502384

2385+
static gboolean
2386+
csm_manager_restart_cinnamon_launcher (CsmExportedManager *skeleton,
2387+
GDBusMethodInvocation *invocation,
2388+
CsmManager *manager)
2389+
{
2390+
g_debug ("CsmManager: RestartCinnamonLauncher called");
2391+
2392+
if (manager->priv->phase != CSM_MANAGER_PHASE_RUNNING) {
2393+
g_dbus_method_invocation_return_error (invocation,
2394+
CSM_MANAGER_ERROR,
2395+
CSM_MANAGER_ERROR_NOT_IN_RUNNING,
2396+
"RestartCinnamonLauncher interface is only available during the Running phase");
2397+
2398+
return TRUE;
2399+
}
2400+
2401+
g_idle_add ((GSourceFunc)restart_cinnamon_launcher, manager);
2402+
2403+
csm_exported_manager_complete_restart_cinnamon_launcher (skeleton,
2404+
invocation);
2405+
2406+
return TRUE;
2407+
}
2408+
23512409
static void
23522410
_disconnect_client (CsmManager *manager,
23532411
CsmClient *client)
@@ -2759,7 +2817,8 @@ static SkeletonSignal skeleton_signals[] = {
27592817
{ "handle-logout", csm_manager_logout_dbus },
27602818
{ "handle-is-session-running", csm_manager_is_session_running },
27612819
{ "handle-request-shutdown", csm_manager_request_shutdown },
2762-
{ "handle-request-reboot", csm_manager_request_reboot }
2820+
{ "handle-request-reboot", csm_manager_request_reboot },
2821+
{ "handle-restart-cinnamon-launcher", csm_manager_restart_cinnamon_launcher }
27632822
};
27642823

27652824
static SkeletonSignal dialog_skeleton_signals[] = {

cinnamon-session/csm-manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ void _csm_manager_set_active_session (CsmManager *
143143
const char *session_name,
144144
gboolean is_fallback);
145145

146+
void _csm_manager_export_login_session_id (CsmManager *manager);
147+
146148
gboolean csm_manager_set_phase (CsmManager *manager,
147149
CsmManagerPhase phase);
148150

cinnamon-session/csm-session-fill.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ csm_session_fill (CsmManager *manager,
496496
}
497497

498498
_csm_manager_set_active_session (manager, actual_session, is_fallback);
499+
_csm_manager_export_login_session_id (manager);
499500

500501
g_free (actual_session);
501502

cinnamon-session/csm-system.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ csm_system_is_last_session_for_user (CsmSystem *system)
164164
return CSM_SYSTEM_GET_IFACE (system)->is_last_session_for_user (system);
165165
}
166166

167+
gchar *
168+
csm_system_get_login_session_id (CsmSystem *system)
169+
{
170+
return CSM_SYSTEM_GET_IFACE (system)->get_login_session_id (system);
171+
}
172+
167173
CsmSystem *
168174
csm_get_system (void)
169175
{

cinnamon-session/csm-system.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct _CsmSystemInterface
7070
void (* remove_inhibitor) (CsmSystem *system,
7171
const gchar *id);
7272
gboolean (* is_last_session_for_user) (CsmSystem *system);
73+
gchar * (* get_login_session_id) (CsmSystem *system);
7374
};
7475

7576
enum _CsmSystemError {
@@ -119,7 +120,7 @@ void csm_system_add_inhibitor (CsmSystem *system,
119120

120121
void csm_system_remove_inhibitor (CsmSystem *system,
121122
const gchar *id);
122-
123+
gchar *csm_system_get_login_session_id (CsmSystem *system);
123124
G_END_DECLS
124125

125126
#endif /* __CSM_SYSTEM_H__ */

cinnamon-session/csm-systemd.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,26 @@ csm_systemd_is_last_session_for_user (CsmSystem *system)
718718
return is_last_session;
719719
}
720720

721+
static gchar *
722+
csm_systemd_get_login_session_id (CsmSystem *system)
723+
{
724+
CsmSystemd *manager = CSM_SYSTEMD (system);
725+
726+
gchar *pid_session;
727+
gint ret;
728+
729+
ret = sd_pid_get_session (getpid (), &pid_session);
730+
731+
if (ret < 0) {
732+
g_printerr ("can't get login session id for cinnamon-session. errno: %d\n", -ret);
733+
return NULL;
734+
}
735+
736+
g_debug ("Login session ID is: %s\n", pid_session);
737+
738+
return pid_session;
739+
}
740+
721741
static void
722742
csm_systemd_system_init (CsmSystemInterface *iface)
723743
{
@@ -737,6 +757,7 @@ csm_systemd_system_init (CsmSystemInterface *iface)
737757
iface->add_inhibitor = csm_systemd_add_inhibitor;
738758
iface->remove_inhibitor = csm_systemd_remove_inhibitor;
739759
iface->is_last_session_for_user = csm_systemd_is_last_session_for_user;
760+
iface->get_login_session_id = csm_systemd_get_login_session_id;
740761
}
741762

742763
CsmSystemd *

cinnamon-session/org.gnome.SessionManager.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,5 +431,20 @@
431431
</doc:doc>
432432
</property>
433433

434+
<property name="SessionId" type="s" access="read">
435+
<doc:doc>
436+
<doc:description>
437+
<doc:para>The login session ID of cinnamon-session.</doc:para>
438+
</doc:description>
439+
</doc:doc>
440+
</property>
441+
442+
<method name="RestartCinnamonLauncher">
443+
<doc:doc>
444+
<doc:description>
445+
<doc:para>Launches cinnamon-launcher for current session.</doc:para>
446+
</doc:description>
447+
</doc:doc>
448+
</method>
434449
</interface>
435450
</node>

0 commit comments

Comments
 (0)