gdm

Merge lp:~albertomilone/gdm/lp1697882 into lp:~ubuntu-desktop/gdm/ubuntu

Proposed by Alberto Milone
Status: Merged
Approved by: Iain Lane
Approved revision: 432
Merged at revision: 432
Proposed branch: lp:~albertomilone/gdm/lp1697882
Merge into: lp:~ubuntu-desktop/gdm/ubuntu
Diff against target: 271 lines (+256/-0)
2 files modified
debian/patches/95_hide_x11_sessions_with_nvidia_kms.patch (+255/-0)
debian/patches/series (+1/-0)
To merge this branch: bzr merge lp:~albertomilone/gdm/lp1697882
Reviewer Review Type Date Requested Status
Iain Lane Approve
Daniel van Vugt (community) Needs Fixing
Jeremy BĂ­cha Pending
Review via email: mp+326426@code.launchpad.net

Description of the change

This change, which is (Ubuntu specific), will hide away the X11 sessions when KMS is enabled in the nvidia driver, leaving the Wayland session as the only option.

Disabling KMS will make the sessions available again after a reboot.

Fixes LP: #1697882

To post a comment you must log in.
Revision history for this message
Iain Lane (laney) wrote :

Thanks. Please could you file upstream and then add that URL into the patch as "Forwarded: <url>"?

Is there a better way than looking at a configuration file such as looking at the loaded modules somehow? Isn't that distro specific or at least fragile?

review: Needs Information
Revision history for this message
Alberto Milone (albertomilone) wrote :

> Thanks. Please could you file upstream and then add that URL into the patch as
> "Forwarded: <url>"?
>

This is something that will have to be fixed in the kernel, when the Unix Device Memory Allocator API lands in the kernel. It will take a while. I don't think it's a GNOME specific problem, but we might want to work around it for now.

> Is there a better way than looking at a configuration file such as looking at
> the loaded modules somehow? Isn't that distro specific or at least fragile?

Sure, /sys/module/nvidia_drm/parameters/modeset would be the best place to check the availability of KMS. Unfortunately, that would require root privileges, which (correct me if I'm wrong) we don't have.

Revision history for this message
Iain Lane (laney) wrote :

On Wed, Jun 28, 2017 at 04:35:35PM -0000, Alberto Milone wrote:
> > Thanks. Please could you file upstream and then add that URL into the patch as
> > "Forwarded: <url>"?
> >
>
> This is something that will have to be fixed in the kernel, when the Unix Device Memory Allocator API lands in the kernel. It will take a while. I don't think it's a GNOME specific problem, but we might want to work around it for now.

Right, but it is correct that this workaround (disabling X on nvidia +
modesetting) is not Ubuntu specific, isn't it?

> > Is there a better way than looking at a configuration file such as looking at
> > the loaded modules somehow? Isn't that distro specific or at least fragile?
>
> Sure, /sys/module/nvidia_drm/parameters/modeset would be the best place to check the availability of KMS. Unfortunately, that would require root privileges, which (correct me if I'm wrong) we don't have.

gdm3 runs as root. I'm not sure if it drops permissions before getting
to this point - I think probably not, and this is worth looking into.

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
Alberto Milone (albertomilone) wrote :

> On Wed, Jun 28, 2017 at 04:35:35PM -0000, Alberto Milone wrote:
> > > Thanks. Please could you file upstream and then add that URL into the
> patch as
> > > "Forwarded: <url>"?
> > >
> >
> > This is something that will have to be fixed in the kernel, when the Unix
> Device Memory Allocator API lands in the kernel. It will take a while. I don't
> think it's a GNOME specific problem, but we might want to work around it for
> now.
>
> Right, but it is correct that this workaround (disabling X on nvidia +
> modesetting) is not Ubuntu specific, isn't it?
>

Correct. It is how we check KMS that, with the current approach, is Ubuntu specific (because of the root privileges thing).

> gdm3 runs as root. I'm not sure if it drops permissions before getting
> to this point - I think probably not, and this is worth looking into.
>

I'm pretty sure I ran into this problem when I started working on this. I can double check, as the effort should be minimal.

Revision history for this message
Alberto Milone (albertomilone) wrote :

Unfortunately, I have just checked, and we no longer have root privileges by the time can_create_environment() is called.

Revision history for this message
Iain Lane (laney) wrote :

On Wed, Jun 28, 2017 at 06:41:32PM -0000, Alberto Milone wrote:
> Unfortunately, I have just checked, and we no longer have root privileges by the time can_create_environment() is called.

Ok, that's annoying - I don't suppose it's possible to grab this value
before privileges are dropped and pass it around?

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
Alberto Milone (albertomilone) wrote :

> On Wed, Jun 28, 2017 at 06:41:32PM -0000, Alberto Milone wrote:
> > Unfortunately, I have just checked, and we no longer have root privileges by
> the time can_create_environment() is called.
>
> Ok, that's annoying - I don't suppose it's possible to grab this value
> before privileges are dropped and pass it around?
>

I'm not sure about that. It's probably easier to use the current udev rule, that the nvidia packages ship, to check the value when the module is loaded, and to write it somewhere in /run, so that GDM can read it later.

What do you think?

Revision history for this message
Iain Lane (laney) wrote :

On Thu, Jun 29, 2017 at 10:29:58AM -0000, Alberto Milone wrote:
> > On Wed, Jun 28, 2017 at 06:41:32PM -0000, Alberto Milone wrote:
> > > Unfortunately, I have just checked, and we no longer have root privileges by
> > the time can_create_environment() is called.
> >
> > Ok, that's annoying - I don't suppose it's possible to grab this value
> > before privileges are dropped and pass it around?
> >
>
> I'm not sure about that. It's probably easier to use the current udev rule, that the nvidia packages ship, to check the value when the module is loaded, and to write it somewhere in /run, so that GDM can read it later.
>
> What do you think?

I like that more than reading the configuration file - but it doesn't
sounds like something that could go in gdm upstream? Unless maybe you
can get some buy in for standardising on this. Maybe file a bug on
bugzilla and ask for opinions.

If it's too hard to grab the value from /sys, I guess we can do it this
way.

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
Alberto Milone (albertomilone) wrote :

> I like that more than reading the configuration file - but it doesn't
> sounds like something that could go in gdm upstream? Unless maybe you
> can get some buy in for standardising on this. Maybe file a bug on
> bugzilla and ask for opinions.
>

I don't think it should be upstreamed, and I hope we can drop this in the near future. I think we can live with a small patch for now (which I am going to maintain).

> If it's too hard to grab the value from /sys, I guess we can do it this
> way.

Ok, I'll work on it.

Revision history for this message
Iain Lane (laney) wrote :

On Thu, Jun 29, 2017 at 11:59:23AM -0000, Alberto Milone wrote:
> > I like that more than reading the configuration file - but it doesn't
> > sounds like something that could go in gdm upstream? Unless maybe you
> > can get some buy in for standardising on this. Maybe file a bug on
> > bugzilla and ask for opinions.
> >
>
> I don't think it should be upstreamed, and I hope we can drop this in the near future. I think we can live with a small patch for now (which I am going to maintain).

Why not? Does this somehow work on other distributions? If it doesn't,
why would it be desirable to keep showing broken sessions there?

> > If it's too hard to grab the value from /sys, I guess we can do it this
> > way.
>
> Ok, I'll work on it.

k.

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
Alberto Milone (albertomilone) wrote :

I have just filed an upstream bug report about this:
https://bugzilla.gnome.org/show_bug.cgi?id=784470

lp:~albertomilone/gdm/lp1697882 updated
411. By Ken VanDine

Only prompt the user to choose display managers when we haven't already determined a migration to gdm3 is recommended.

412. By Ken VanDine

Merged

413. By Ken VanDine

* debian/gdm3.config
  - Only prompt the user to choose display managers when we haven't already
    determined a migration to gdm3 is recommended.
* debian/control.in
  - Explicitly depend on ubuntu-session so we can ensure gdm3 configure gets
    run after ubuntu-session's configure to handle the transition from
    lightdm to gdm3

414. By Ken VanDine

released

415. By Ken VanDine

* debian/gdm3.config
  - Handle the transition from lightdm in gdm3 rather than ubuntu-session
* debian/control.in
  - Dropped depends from ubuntu-session

416. By Ken VanDine

Fixed ubuntu-session version check

417. By Ken VanDine

Dropped depends for ubuntu-session

418. By Ken VanDine

releasing package gdm3 version 3.24.2-1ubuntu5

419. By Didier Roche-Tolomelli

debian/patches/ubuntu_prefer_x11_session.patch:
Prefer X11 session over wayland. As we are not ready yet for
switching to wayland yet, let's prefer X11 session when no specific
choice was made. (LP: #1703601)
This will be reverted once we switch to wayland by default.

420. By Didier Roche-Tolomelli

releasing package gdm3 version 3.24.2-1ubuntu6

421. By Iain Lane

debian/gdm3.config: Check the version of gdm3 instead of ubuntu-session.

And some other minor improvements.

422. By Iain Lane

Compare with a ~ version, so that any backports of this exact version aren't re-migrated

423. By Iain Lane

releasing package gdm3 version 3.24.2-1ubuntu7

424. By Daniel van Vugt

First attempt

425. By Daniel van Vugt

Remember the changelog

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Pretty sure this will have conflicts now, sorry.

review: Needs Fixing
lp:~albertomilone/gdm/lp1697882 updated
426. By Will Cooke

* debian/default.pa
  - Added new file to disable Bluetooth audio devices in PulseAudio from
    gdm3. (LP: #1703415) (LP: #1489651)
* debian/gdm3.install
  - Added details of the default.pa file
* debian/gdm3.postinst
  - Added installation of default.pa and creation of dir if it doesn't
    exist.

427. By Jeremy BĂ­cha

releasing package gdm3 version 3.24.2-1ubuntu9

428. By Jeremy BĂ­cha

New upstream release 3.25.90.1

* debian/control.in:
  - Bump minimum gnome-settings-daemon to 3.24
* Drop patches applied in new release:
  - Avoid-double-NULL-terminated-array-LP-1704050.patch
  - revert_drop_gdm_shell_session.patch

429. By Jeremy BĂ­cha

releasing package gdm3 version 3.25.90.1-0ubuntu1

430. By Didier Roche-Tolomelli

* debian/patches/ubuntu_prefer_x11_session.patch:
  - remove x11 session preference now that both Ubuntu and GNOME
    switched to wayland

431. By Didier Roche-Tolomelli

releasing package gdm3 version 3.25.90.1-0ubuntu2

Revision history for this message
Alberto Milone (albertomilone) wrote :

I have come up with a better solution, which I attached to the upstream bug report:
https://bugzilla.gnome.org/show_bug.cgi?id=784470

lp:~albertomilone/gdm/lp1697882 updated
432. By Alberto Milone

Hide X11 sessions when KMS is enabled in the nvidia driver

NOTE: this doesn't affect systems with hybrid graphics

Fixes LP: #1697882

Revision history for this message
Alberto Milone (albertomilone) wrote :

The latest patch is based on what upstream recommended. I have already pushed a change to the udev rule included in the NVIDIA driver in Artful, so that the Gnome shell (which doesn't run with root privileges) can check KMS when getting the sessions using libgdm.

My patch works well here.

Revision history for this message
Iain Lane (laney) wrote :

I left some comments upstream - please consider those for Ubuntu before the 17.10 release - but I think we can probably upload this now.

Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'debian/patches/95_hide_x11_sessions_with_nvidia_kms.patch'
--- debian/patches/95_hide_x11_sessions_with_nvidia_kms.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/95_hide_x11_sessions_with_nvidia_kms.patch 2017-08-24 09:08:19 +0000
@@ -0,0 +1,255 @@
1From 06a4117ae5761c184c2c9fe54e4f297becf1d2a9 Mon Sep 17 00:00:00 2001
2From: Alberto Milone <alberto.milone@canonical.com>
3Date: Tue, 20 Jun 2017 16:49:10 +0200
4Subject: [PATCH 1/1] Hide X11 sessions when KMS is enabled in the nvidia
5 driver
6
7Fixes LP: #1697882
8---
9 common/gdm-common.c | 78 ++++++++++++++++++++++++++++++++++++++
10 common/gdm-common.h | 2 +
11 daemon/gdm-display.c | 10 +++++
12 daemon/gdm-local-display-factory.c | 5 +++
13 daemon/gdm-session.c | 6 ++-
14 libgdm/Makefile.am | 3 ++
15 libgdm/gdm-sessions.c | 8 +++-
16 7 files changed, 109 insertions(+), 3 deletions(-)
17
18diff --git a/common/gdm-common.c b/common/gdm-common.c
19index 31fc810..0dcbbe2 100644
20--- a/common/gdm-common.c
21+++ b/common/gdm-common.c
22@@ -47,6 +47,8 @@
23
24 G_DEFINE_QUARK (gdm-common-error, gdm_common_error);
25
26+int nvidia_has_kms = -1;
27+
28 const char *
29 gdm_make_temp_dir (char *template)
30 {
31@@ -797,3 +799,79 @@ gdm_shell_expand (const char *str,
32 }
33 return g_string_free (s, FALSE);
34 }
35+
36+static gboolean
37+is_module_loaded (const char *module) {
38+ char line[4096];
39+ gboolean status = FALSE;
40+ FILE *file = NULL;
41+ const char *modules_file = "/proc/modules";
42+
43+ file = fopen (modules_file, "r");
44+ if (!file) {
45+ g_debug ("Failed to parse %s\n", modules_file);
46+ return status;
47+ }
48+
49+ while (fgets (line, sizeof (line), file)) {
50+ char *tok;
51+ tok = strtok (line, " \t");
52+ if (strstr (tok, module) != NULL) {
53+ status = TRUE;
54+ break;
55+ }
56+ }
57+ fclose(file);
58+
59+ return status;
60+}
61+
62+gboolean
63+is_nvidia_kms_available (void)
64+{
65+ gsize length;
66+ GError *error = NULL;
67+ gboolean status = FALSE;
68+ gchar *contents = NULL;
69+ const char *kms_file = "/sys/module/nvidia_drm/parameters/modeset";
70+
71+ g_debug ("Checking if the NVIDIA driver is loaded, and has KMS enabled\n");
72+
73+ /* Use the cached value */
74+ if (nvidia_has_kms > -1) {
75+ g_debug ("is_nvidia_kms_available: using cached value %d\n", nvidia_has_kms);
76+ return (nvidia_has_kms == 1);
77+ }
78+
79+ /* Let's leave hybrid graphics alone */
80+ if (is_module_loaded ("i915")) {
81+ g_debug ("is_nvidia_kms_available: Intel detected, doing nothing.\n");
82+ goto end;
83+ }
84+
85+ if (!g_file_test (kms_file, G_FILE_TEST_EXISTS)) {
86+ g_debug ("is_nvidia_kms_available: Cannot access '%s'", kms_file);
87+ goto end;
88+ }
89+
90+ if (!g_file_get_contents (kms_file, &contents, &length, &error)) {
91+ g_debug ("is_nvidia_kms_available: Failed to parse '%s': %s",
92+ kms_file,
93+ (error && error->message) ? error->message : "(null)");
94+ g_error_free (error);
95+ goto end;
96+ }
97+
98+ g_debug ("is_nvidia_kms_available: contents, \n%s\n", contents);
99+
100+ status = (strstr (contents, "Y\n") != NULL);
101+ g_free (contents);
102+
103+end:
104+ /* Cache the value */
105+ nvidia_has_kms = status ? 1 : 0;
106+
107+ g_debug ("is_nvidia_kms_available: setting status to %d\n", status);
108+
109+ return status;
110+}
111diff --git a/common/gdm-common.h b/common/gdm-common.h
112index 8d83a12..6f88f2f 100644
113--- a/common/gdm-common.h
114+++ b/common/gdm-common.h
115@@ -71,6 +71,8 @@ char * gdm_shell_expand (const char *str,
116 GdmExpandVarFunc expand_func,
117 gpointer user_data);
118
119+gboolean is_nvidia_kms_available (void);
120+
121 G_END_DECLS
122
123 #endif /* _GDM_COMMON_H */
124diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
125index 0057e2c..42648f9 100644
126--- a/daemon/gdm-display.c
127+++ b/daemon/gdm-display.c
128@@ -54,6 +54,8 @@
129
130 #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate))
131
132+extern int nvidia_has_kms;
133+
134 struct GdmDisplayPrivate
135 {
136 char *id;
137@@ -118,6 +120,7 @@ enum {
138 PROP_DOING_INITIAL_SETUP,
139 };
140
141+
142 static void gdm_display_class_init (GdmDisplayClass *klass);
143 static void gdm_display_init (GdmDisplay *self);
144 static void gdm_display_finalize (GObject *object);
145@@ -1447,6 +1450,13 @@ can_create_environment (const char *session_id)
146 char *path;
147 gboolean session_exists;
148
149+#ifdef ENABLE_WAYLAND_SUPPORT
150+ /* Disable X11 sessions if KMS is enabled in the nvidia driver
151+ * See LP: #1697882.
152+ */
153+ if (is_nvidia_kms_available ())
154+ return FALSE;
155+#endif
156 path = g_strdup_printf (GNOME_SESSION_SESSIONS_PATH "/%s.session", session_id);
157 session_exists = g_file_test (path, G_FILE_TEST_EXISTS);
158
159diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
160index 7a4643d..50ddaea 100644
161--- a/daemon/gdm-local-display-factory.c
162+++ b/daemon/gdm-local-display-factory.c
163@@ -48,6 +48,8 @@
164
165 #define MAX_DISPLAY_FAILURES 5
166
167+extern int nvidia_has_kms;
168+
169 struct GdmLocalDisplayFactoryPrivate
170 {
171 GdmDBusLocalDisplayFactory *skeleton;
172@@ -459,6 +461,9 @@ gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory)
173 is_initial = FALSE;
174 }
175
176+ if (is_nvidia_kms_available ())
177+ session_type = "wayland";
178+
179 create_display (factory, seat, session_type, is_initial);
180 }
181
182diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
183index 0b83223..5e597c4 100644
184--- a/daemon/gdm-session.c
185+++ b/daemon/gdm-session.c
186@@ -62,6 +62,8 @@
187
188 #define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker"
189
190+extern int nvidia_has_kms;
191+
192 typedef struct
193 {
194 GdmSession *session;
195@@ -354,7 +356,9 @@ get_system_session_dirs (GdmSession *self)
196
197 search_array = g_array_new (TRUE, TRUE, sizeof (char *));
198
199- g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
200+ if (!is_nvidia_kms_available ()) {
201+ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
202+ }
203
204 #ifdef ENABLE_WAYLAND_SUPPORT
205 if (!self->priv->ignore_wayland) {
206diff --git a/libgdm/Makefile.am b/libgdm/Makefile.am
207index 99ada9a..66af6b5 100644
208--- a/libgdm/Makefile.am
209+++ b/libgdm/Makefile.am
210@@ -36,6 +36,8 @@ AM_CPPFLAGS = \
211 -I$(builddir) \
212 -I$(top_srcdir) \
213 -I$(top_builddir) \
214+ -I$(top_srcdir)/common \
215+ -I$(top_builddir)/common \
216 -DG_LOG_DOMAIN=\"Gdm\" \
217 -DDMCONFDIR=\""$(dmconfdir)"\" \
218 -DDATADIR=\""$(datadir)"\" \
219@@ -64,6 +66,7 @@ libgdm_la_LDFLAGS = \
220 $(END_OF_LIST)
221
222 libgdm_la_LIBADD = \
223+ $(top_builddir)/common/libgdmcommon.la \
224 $(LIBGDM_LIBS) \
225 $(SYSTEMD_LIBS) \
226 $(END_OF_LIST)
227diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c
228index a645224..419f055 100644
229--- a/libgdm/gdm-sessions.c
230+++ b/libgdm/gdm-sessions.c
231@@ -37,6 +37,8 @@
232
233 #include "gdm-sessions.h"
234
235+extern int nvidia_has_kms;
236+
237 typedef struct _GdmSessionFile {
238 char *id;
239 char *path;
240@@ -208,8 +210,10 @@ collect_sessions (void)
241 g_free, g_free);
242 }
243
244- for (i = 0; xorg_search_dirs [i] != NULL; i++) {
245- collect_sessions_from_directory (xorg_search_dirs [i]);
246+ if (!is_nvidia_kms_available ()) {
247+ for (i = 0; xorg_search_dirs [i] != NULL; i++) {
248+ collect_sessions_from_directory (xorg_search_dirs [i]);
249+ }
250 }
251
252 #ifdef ENABLE_WAYLAND_SUPPORT
253--
2542.7.4
255
0256
=== modified file 'debian/patches/series'
--- debian/patches/series 2017-08-21 08:48:14 +0000
+++ debian/patches/series 2017-08-24 09:08:19 +0000
@@ -5,6 +5,7 @@
592_systemd_unit.patch592_systemd_unit.patch
693_translate-default-desktop.patch693_translate-default-desktop.patch
794_retain_xorg_log.patch794_retain_xorg_log.patch
895_hide_x11_sessions_with_nvidia_kms.patch
8ubuntu_run_xsession.d.patch9ubuntu_run_xsession.d.patch
9ubuntu_xresources_is_a_dir.patch10ubuntu_xresources_is_a_dir.patch
10ubuntu_nvidia_prime.patch11ubuntu_nvidia_prime.patch

Subscribers

People subscribed via source and target branches

to all changes: