From adfaa222fdfa6115ea2b320b0bbc2126db9270a5 Mon Sep 17 00:00:00 2001 From: Fabian Vogt Date: Thu, 12 Nov 2020 20:30:55 +0100 Subject: [PATCH 1/3] Retry starting the display server Even if the CanGraphical property of a Seat is true, it's possible that it's still too early for X to start, as it might need some driver or device which isn't present yet. Fixes #1316 --- src/daemon/Seat.cpp | 23 ++++++++++++++++++----- src/daemon/Seat.h | 4 +++- src/daemon/XorgDisplayServer.cpp | 10 ++++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/daemon/Seat.cpp b/src/daemon/Seat.cpp index eef26da4..838c2221 100644 --- a/src/daemon/Seat.cpp +++ b/src/daemon/Seat.cpp @@ -28,6 +28,7 @@ #include #include +#include #include @@ -52,7 +53,7 @@ namespace SDDM { return m_name; } - bool Seat::createDisplay(int terminalId) { + void Seat::createDisplay(int terminalId) { //reload config if needed mainConfig.load(); @@ -84,12 +85,24 @@ namespace SDDM { m_displays << display; // start the display - if (!display->start()) { - qCritical() << "Could not start Display server on vt" << terminalId; - return false; + startDisplay(display); + } + + void Seat::startDisplay(Display *display, int tryNr) { + if (display->start()) + return; + + // It's possible that the system isn't ready yet (driver not loaded, + // device not enumerated, ...). It's not possible to tell when that changes, + // so try a few times with a delay in between. + qWarning() << "Attempt" << tryNr << "starting the Display server on vt" << display->terminalId() << "failed"; + + if(tryNr >= 3) { + qCritical() << "Could not start Display server on vt" << display->terminalId(); + return; } - return true; + QTimer::singleShot(2000, display, [=] { startDisplay(display, tryNr + 1); }); } void Seat::removeDisplay(Display* display) { diff --git a/src/daemon/Seat.h b/src/daemon/Seat.h index bf22566b..f9fe7331 100644 --- a/src/daemon/Seat.h +++ b/src/daemon/Seat.h @@ -35,13 +35,15 @@ namespace SDDM { const QString &name() const; public slots: - bool createDisplay(int terminalId = -1); + void createDisplay(int terminalId = -1); void removeDisplay(SDDM::Display* display); private slots: void displayStopped(); private: + void startDisplay(SDDM::Display *display, int tryNr = 1); + QString m_name; QVector m_displays; diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp index e60c0221..5f40fe8c 100644 --- a/src/daemon/XorgDisplayServer.cpp +++ b/src/daemon/XorgDisplayServer.cpp @@ -248,6 +248,12 @@ namespace SDDM { } void XorgDisplayServer::finished() { + // clean up + if (process) { + process->deleteLater(); + process = nullptr; + } + // check flag if (!m_started) return; @@ -283,10 +289,6 @@ namespace SDDM { displayStopScript->deleteLater(); displayStopScript = nullptr; - // clean up - process->deleteLater(); - process = nullptr; - // remove authority file QFile::remove(m_authPath); From d11e1e987b440fa1aaa741719b92472eeee79b17 Mon Sep 17 00:00:00 2001 From: Fabian Vogt Date: Wed, 9 Dec 2020 19:28:41 +0100 Subject: [PATCH 2/3] Explicitly stop Xorg when starting fails When Xorg starts but there is an error, stop it explicitly instead of assuming that X exits itself. This avoids a possibly lingering Xorg process in the XorgDisplayServer instance. Add a check and warning message if Xorg is restarted too early (shouldn't happen). --- src/daemon/XorgDisplayServer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp index 5f40fe8c..3a7bee0d 100644 --- a/src/daemon/XorgDisplayServer.cpp +++ b/src/daemon/XorgDisplayServer.cpp @@ -118,6 +118,11 @@ namespace SDDM { if (m_started) return false; + if (process) { + qCritical() << "Tried to start Xorg before previous instance exited"; + return false; + } + // create process process = new QProcess(this); @@ -195,6 +200,7 @@ namespace SDDM { qCritical("Failed to open pipe to start X Server"); close(pipeFds[0]); + stop(); return false; } QByteArray displayNumber = readPipe.readLine(); @@ -203,6 +209,7 @@ namespace SDDM { qCritical("Failed to read display number from pipe"); close(pipeFds[0]); + stop(); return false; } displayNumber.prepend(QByteArray(":")); @@ -219,6 +226,7 @@ namespace SDDM { if(m_display != QStringLiteral(":0")) { if(!addCookie(m_authPath)) { qCritical() << "Failed to write xauth file"; + stop(); return false; } } @@ -232,8 +240,7 @@ namespace SDDM { } void XorgDisplayServer::stop() { - // check flag - if (!m_started) + if (!process) return; // log message From 78048b22e3988d3daec9c271883fa114abc114dc Mon Sep 17 00:00:00 2001 From: Fabian Vogt Date: Wed, 9 Dec 2020 19:33:08 +0100 Subject: [PATCH 3/3] Emit XorgDisplayServer::started only when the auth file is ready --- src/daemon/XorgDisplayServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp index 3a7bee0d..331adcda 100644 --- a/src/daemon/XorgDisplayServer.cpp +++ b/src/daemon/XorgDisplayServer.cpp @@ -219,8 +219,6 @@ namespace SDDM { // close our pipe close(pipeFds[0]); - emit started(); - // The file is also used by the greeter, which does care about the // display number. Write the proper entry, if it's different. if(m_display != QStringLiteral(":0")) { @@ -232,6 +230,8 @@ namespace SDDM { } changeOwner(m_authPath); + emit started(); + // set flag m_started = true;