User:Keks24/drafts/Non root Xorg

From Gentoo Wiki
Jump to: navigation, search

To-do

  • Fighting for Schmusis (most likely) intentionally failed operation
  • general
    • user sticky (4711) bit on "/usr/bin/Xorg" has still to be set to make an autologin via openrc work or is it just "/dev/tty7"?
      • Automatic_login_to_virtual_console
      • .zprofile autologin
      • CODE /home/ramon/.log/startx/startx.log
        Current version of pixman: 0.40.0
                Before reporting problems, check http://wiki.x.org
                to make sure that you have the latest version.
        Markers: (--) probed, (**) from config file, (==) default setting,
                (++) from command line, (!!) notice, (II) informational,
                (WW) warning, (EE) error, (NI) not implemented, (??) unknown.
        (==) Log file: "/home/ramon/.local/share/xorg/Xorg.0.log", Time: Tue Jul 28 06:15:41 2020
        (==) Using config directory: "/etc/X11/xorg.conf.d"
        (==) Using system config directory "/usr/share/X11/xorg.conf.d"
        (II) [KMS] Kernel modesetting enabled.
        Unable to retrieve master
        (EE)
        Fatal server error:
        (EE) AddScreen/ScreenInit failed for driver 0
        (EE)
        (EE)
        Please consult the The X.Org Foundation support
                 at http://wiki.x.org
         for help.
        (EE) Please also check the log file at "/home/ramon/.local/share/xorg/Xorg.0.log" for additional information.
        (EE)
        (EE) Server terminated with error (1). Closing log file.
        xinit: giving up
        xinit: unable to connect to X server: Connection refused
        xinit: server error
        
    • test non-root without any patches
      • look for error messages
    • test amdgpu patch with Plasma
    • drm_master_util-9999.ebuild
      • make postinst work
  • wiki article
    • instead of referencing to the forum, upload the files to the wiki to make them persistent
    • upload evidences about publishing the diff files under GPLv2 and reference to them
    • adapt new references
  • message
    • kajzer: When the wiki article is done, so he can remove his repository
    • ch1p: When the wiki article is done. Just because and that's why.
    • Ask for permissions to upload below diff files and evidence files about publishing under GPLv2

For discussion page

CODE for discussion page
== Non_root_Xorg ==

{{Talk|open|date=27 July 2020}}

Hello <some_username>,

I am currently working on [[Non_root_Xorg#Handling_of_DRM_ioctls]] and I would like to persist the diff files on the article, instead of only referncing to them.
I do not want to blow up the article, therefore I was about to upload them here, but I am only allowed to upload picture files.

Could you please give the permissions to upload the files?

Thank you!

[[User:Keks24/drafts/Non_root_Xorg#Files|My current draft]]

PS. I also would like to upload and reference to the evidences from Evgeny "ch1p" Zinoviev and "kajzersoze", that they agreed to publish their work under "GPLv2".

~~~~

author tree

  • rootless_modesetting_1.20.3.patch: Evgeny "ch1p" Zinoviev, license: GPL2 (see e-mail history)
  • new patch names
    • rootless_modesetting_1.20.3.patch -> xorg-server-non-root-modesetting-1.20.4.diff
    • amdgpu-non-root.diff -> amdgpu-non-root-drm_19.1.0.diff
    • radeon-non-root.diff -> radeon-non-root-drm_19.1.0.diff

Actual wiki article

https://wiki.gentoo.org/wiki/Non_root_Xorg

Handling of DRM ioctls

No management of group membership can grant the CAP_SYS_ADMIN capability needed to perform the DRM ioctls. However, a simple program named drm_master_util has been made available in GitHub[1], which must be installed with the set-user-ID on execution file mode bit set (i.e. ls -l would show -rwsr-xr-x or -rws--x--x), and can perform ioctl() calls on behalf of other processes, with the help of libdrm (from package x11-libs/libdrm). The program gets open file descriptors for character special files from a UNIX domain socket via file descriptor passing (SCM_RIGHTS control messages sent as ancillary data with a POSIX sendmsg() call), and command-line options specify the requested ioctl. Several ebuilds suitable for a custom repository are available for the package in the Gentoo Forums[2]

Patches are available[3][4] for making the modesetting, amdgpu and ati X.Org video drivers work with drm_master_util. The ebuilds for their corresponding packages (x11-base/xorg-server, x11-drivers/xf86-video-amdgpu and x11-drivers/xf86-video-ati, respectively) can apply them as user patches in the usual way.

Use custom ebuild repository


  • Instructions to add the overlay manually?
    • Mask all packages /etc/portage/package.mask
    • Unmask wanted packages. Research: Has an alternative been implemented yet?
    • Add entry in /etc/portage/package.accept_keywords
    • FILE /etc/portage/package.accept_keywords
      # custom - 20200726 - rfischer: unmask "x11-misc/drm_master_util", in order to use "x11-base/xorg-server" without root privileges
      >=x11-misc/drm_master_util-9999 ~amd64
      
    • FILE /etc/portage/repos.conf/keks24-overlay.conf
      [keks24]
      location = /var/db/repos/keks24-overlay
      sync-type = git
      sync-uri = https://codeberg.org/keks24/gentoo-overlay.git
      auto-sync = yes
      
    • emerge --sync / eix-sync
    • emerge --ask x11-misc/drm_master_util

Apply patch files

  • Only apply the patch file for the video driver, which is currently in use
  • Upload and reference evidence about the agreement to apply GPL2 to patch files
Modesetting: x11-base/xorg-server
  • Instructions to apply the patch files
  • Put download link here
AMDGPU: x11-drivers/xf86-video-amdgpu
  • Instructions to apply the patch files
  • Put download link here
Radeon: x11-drivers/xf86-video-ati
  • Instructions to apply the patch files
  • Put download link here

Verification

  • startx output
  • /home/username/.local/share/xorg/Xorg.0.log

Files

ebuild: drm_master_util-9999.ebuild

https://codeberg.org/keks24/gentoo-overlay/src/branch/master/x11-misc/drm_master_util/drm_master_util-9999.ebuild

/var/db/repos/localrepo/x11-misc/drm_master_util/drm_master_util-9999.ebuild

Modesetting: x11-base/xorg-server

https://ch1p.io/non-root-xorg-modesetting/

FILE /etc/portage/patches/x11-base/xorg-server/xorg-server-non-root-modesetting-1.20.4.diff
###################################################################################
# Copyright (C) 2020  Evgeny "ch1p" Zinoviev                                      #
#                                                                                 #
# This program is free software; you can redistribute it and/or                   #
# modify it under the terms of the GNU General Public License                     #
# as published by the Free Software Foundation; either version 2                  #
# of the License, or (at your option) any later version.                          #
#                                                                                 #
# This program is distributed in the hope that it will be useful,                 #
# but WITHOUT ANY WARRANTY; without even the implied warranty of                  #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                   #
# GNU General Public License for more details.                                    #
#                                                                                 #
# You should have received a copy of the GNU General Public License               #
# along with this program; if not, write to the Free Software                     #
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. #
###################################################################################

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 8d29b13..1034ef9 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -34,6 +34,11 @@
 #endif
 
 #include &lt;unistd.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;sys/wait.h&gt;
+#include &lt;pthread.h&gt;
+#include &lt;sys/socket.h&gt;
+#include &lt;sys/un.h&gt;
 #include &lt;fcntl.h&gt;
 #include "xf86.h"
 #include "xf86Priv.h"
@@ -62,6 +67,8 @@
 
 #include "driver.h"
 
+#define DRM_HACK_SOCKET_NAME "xorg_drm_master_util"
+
 static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y);
 static Bool CloseScreen(ScreenPtr pScreen);
 static Bool EnterVT(ScrnInfoPtr pScrn);
@@ -1513,11 +1520,66 @@ msSharedPixmapNotifyDamage(PixmapPtr ppix)
     return ret;
 }
 
+static int
+send_fd(int sock, int fd)
+{
+    // This function does the arcane magic for sending
+    // file descriptors over unix domain sockets
+    struct msghdr msg;
+    struct iovec iov[1];
+    struct cmsghdr *cmsg = NULL;
+    char ctrl_buf[CMSG_SPACE(sizeof(int))];
+    char data[1];
+
+    memset(&msg, 0, sizeof(struct msghdr));
+    memset(ctrl_buf, 0, CMSG_SPACE(sizeof(int)));
+
+    data[0] = ' ';
+    iov[0].iov_base = data;
+    iov[0].iov_len = sizeof(data);
+
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+    msg.msg_controllen =  CMSG_SPACE(sizeof(int));
+    msg.msg_control = ctrl_buf;
+
+    cmsg = CMSG_FIRSTHDR(&msg);
+    cmsg-&gt;cmsg_level = SOL_SOCKET;
+    cmsg-&gt;cmsg_type = SCM_RIGHTS;
+    cmsg-&gt;cmsg_len = CMSG_LEN(sizeof(int));
+
+    *((int *) CMSG_DATA(cmsg)) = fd;
+
+    return sendmsg(sock, &msg, 0);
+}
+
+static void*
+thread_func(void* argument)
+{
+    int ret;
+    int option = *(int *)argument;
+    char cmd[32];
+    sprintf(cmd, "/usr/bin/drm_master_util %s -r", (!option ? "-s" : "-d"));
+
+    ret = system(cmd);
+    if (ret == -1 || WEXITSTATUS(ret) != 0) {
+        fprintf(stderr, "%s\n", strerror(errno));
+        //exit(1);
+    }
+
+    pthread_exit(NULL); // you could also return NULL here to exit no difference
+}
+
 static Bool
 SetMaster(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
-    int ret;
+    int ret = 0;
+    pthread_t my_thread;
+    struct sockaddr_un addr;
+    int sock, conn, option = 0;
 
 #ifdef XF86_PDEV_SERVER_FD
     if (ms-&gt;pEnt-&gt;location.type == BUS_PLATFORM &&
@@ -1528,10 +1590,21 @@ SetMaster(ScrnInfoPtr pScrn)
     if (ms-&gt;fd_passed)
         return TRUE;
 
-    ret = drmSetMaster(ms-&gt;fd);
-    if (ret)
-        xf86DrvMsg(pScrn-&gt;scrnIndex, X_ERROR, "drmSetMaster failed: %s\n",
-                   strerror(errno));
+    sock = socket(AF_UNIX, SOCK_STREAM, 0);
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+    bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+    listen(sock, 1);
+    pthread_create(&my_thread, NULL, thread_func, &option);
+
+    conn = accept(sock, NULL, 0);
+    send_fd(conn, ms-&gt;fd);
+    close(conn);
+    close(sock);
+
+    pthread_join(my_thread, NULL);
 
     return ret == 0;
 }
@@ -1769,6 +1842,9 @@ static void
 LeaveVT(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
+    pthread_t my_thread;
+    struct sockaddr_un addr;
+    int sock, conn, option = 1;
 
     xf86_hide_cursors(pScrn);
 
@@ -1780,8 +1856,21 @@ LeaveVT(ScrnInfoPtr pScrn)
         return;
 #endif
 
-    if (!ms-&gt;fd_passed)
-        drmDropMaster(ms-&gt;fd);
+    sock = socket(AF_UNIX, SOCK_STREAM, 0);
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+    bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+    listen(sock, 1);
+    pthread_create(&my_thread, NULL, thread_func, &option);
+
+    conn = accept(sock, NULL, 0);
+    send_fd(conn, ms-&gt;fd);
+    close(conn);
+    close(sock);
+
+    pthread_join(my_thread, NULL);
 }
 
 /*

AMDGPU: x11-drivers/xf86-video-amdgpu

https://github.com/kajzersoze/patches/blob/master/amdgpu-nonroot.diff

FILE /etc/portage/patches/x11-drivers/xf86-video-amdgpu/amdgpu-non-root-drm_19.1.0.diff
###################################################################################
# Copyright (C) 2020  Evgeny "ch1p" Zinoviev, "kajzersoze"                        #
#                                                                                 #
# This program is free software; you can redistribute it and/or                   #
# modify it under the terms of the GNU General Public License                     #
# as published by the Free Software Foundation; either version 2                  #
# of the License, or (at your option) any later version.                          #
#                                                                                 #
# This program is distributed in the hope that it will be useful,                 #
# but WITHOUT ANY WARRANTY; without even the implied warranty of                  #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                   #
# GNU General Public License for more details.                                    #
#                                                                                 #
# You should have received a copy of the GNU General Public License               #
# along with this program; if not, write to the Free Software                     #
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. #
###################################################################################

--- a/src/amdgpu_kms.c	2019-03-19 18:49:55.000000000 +0100
+++ b/src/amdgpu_kms.c	2019-10-06 18:44:29.338375483 +0200
@@ -24,6 +24,13 @@
  *    Dave Airlie &lt;airlied@redhat.com&gt;
  *
  */
+#include &lt;stdio.h&gt;
+#include &lt;sys/wait.h&gt;
+#include &lt;pthread.h&gt;
+#include &lt;sys/socket.h&gt;
+#include &lt;sys/un.h&gt;
+#define DRM_HACK_SOCKET_NAME "xorg_drm_master_util"
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -62,6 +69,59 @@
 
 #include &lt;gbm.h&gt;
 
+static int
+send_fd(int sock, int fd)
+{
+    // This function does the arcane magic for sending
+    // file descriptors over unix domain sockets
+    struct msghdr msg;
+    struct iovec iov[1];
+    struct cmsghdr *cmsg = NULL;
+    char ctrl_buf[CMSG_SPACE(sizeof(int))];
+    char data[1];
+
+    memset(&msg, 0, sizeof(struct msghdr));
+    memset(ctrl_buf, 0, CMSG_SPACE(sizeof(int)));
+
+    data[0] = ' ';
+    iov[0].iov_base = data;
+    iov[0].iov_len = sizeof(data);
+
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+    msg.msg_controllen =  CMSG_SPACE(sizeof(int));
+    msg.msg_control = ctrl_buf;
+
+    cmsg = CMSG_FIRSTHDR(&msg);
+    cmsg-&gt;cmsg_level = SOL_SOCKET;
+    cmsg-&gt;cmsg_type = SCM_RIGHTS;
+    cmsg-&gt;cmsg_len = CMSG_LEN(sizeof(int));
+
+    *((int *) CMSG_DATA(cmsg)) = fd;
+
+    return sendmsg(sock, &msg, 0);
+}
+
+static void*
+thread_func(void* argument)
+{
+    int ret;
+    int option = *(int *)argument;
+    char cmd[32];
+    sprintf(cmd, "/usr/bin/drm_master_util %s -r", (!option ? "-s" : "-d"));
+
+    ret = system(cmd);
+    if (ret == -1 || WEXITSTATUS(ret) != 0) {
+        fprintf(stderr, "%s\n", strerror(errno));
+        //exit(1);
+    }
+
+    pthread_exit(NULL); // you could also return NULL here to exit no difference
+}
+
+
 static DevPrivateKeyRec amdgpu_window_private_key;
 static DevScreenPrivateKeyRec amdgpu_client_private_key;
 DevScreenPrivateKeyRec amdgpu_device_private_key;
@@ -1820,7 +1880,12 @@
 static Bool amdgpu_set_drm_master(ScrnInfoPtr pScrn)
 {
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
-	int err;
+    int err = 0;
+    pthread_t my_thread;
+    struct sockaddr_un addr;
+    int sock, conn, option = 0;
+
+
 
 #ifdef XF86_PDEV_SERVER_FD
 	if (pAMDGPUEnt-&gt;platform_dev &&
@@ -1828,9 +1893,21 @@
 		return TRUE;
 #endif
 
-	err = drmSetMaster(pAMDGPUEnt-&gt;fd);
-	if (err)
-		ErrorF("Unable to retrieve master\n");
+    sock = socket(AF_UNIX, SOCK_STREAM, 0);
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+    bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+    listen(sock, 1);
+    pthread_create(&my_thread, NULL, thread_func, &option);
+
+    conn = accept(sock, NULL, 0);
+    send_fd(conn, pAMDGPUEnt-&gt;fd);
+    close(conn);
+    close(sock);
+
+    pthread_join(my_thread, NULL);
 
 	return err == 0;
 }
@@ -1838,6 +1915,10 @@
 static void amdgpu_drop_drm_master(ScrnInfoPtr pScrn)
 {
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
+    pthread_t my_thread;
+    struct sockaddr_un addr;
+    int sock, conn, option = 1;
+
 
 #ifdef XF86_PDEV_SERVER_FD
 	if (pAMDGPUEnt-&gt;platform_dev &&
@@ -1845,7 +1926,23 @@
 		return;
 #endif
 
-	drmDropMaster(pAMDGPUEnt-&gt;fd);
+    sock = socket(AF_UNIX, SOCK_STREAM, 0);
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+    bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+    listen(sock, 1);
+    pthread_create(&my_thread, NULL, thread_func, &option);
+
+    conn = accept(sock, NULL, 0);
+    send_fd(conn, pAMDGPUEnt-&gt;fd);
+    close(conn);
+    close(sock);
+
+    pthread_join(my_thread, NULL);
+
+
 }

Radeon: x11-drivers/xf86-video-ati

https://github.com/kajzersoze/patches/blob/master/radeon-nonroot.diff

FILE /etc/portage/patches/x11-drivers/xf86-video-ati/radeon-non-root-drm_19.1.0.diff
###################################################################################
# Copyright (C) 2020  Evgeny "ch1p" Zinoviev, "kajzersoze"                        #
#                                                                                 #
# This program is free software; you can redistribute it and/or                   #
# modify it under the terms of the GNU General Public License                     #
# as published by the Free Software Foundation; either version 2                  #
# of the License, or (at your option) any later version.                          #
#                                                                                 #
# This program is distributed in the hope that it will be useful,                 #
# but WITHOUT ANY WARRANTY; without even the implied warranty of                  #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                   #
# GNU General Public License for more details.                                    #
#                                                                                 #
# You should have received a copy of the GNU General Public License               #
# along with this program; if not, write to the Free Software                     #
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. #
###################################################################################

--- a/src/radeon_kms.c   2020-04-24 12:56:35.767706045 +0200
+++ b/src/radeon_kms.c   2020-04-24 14:47:37.049171521 +0200
@@ -24,6 +24,13 @@
  *    Dave Airlie &lt;airlied@redhat.com&gt;
  *
  */
+#include &lt;stdio.h&gt;
+#include &lt;sys/wait.h&gt;
+#include &lt;pthread.h&gt;
+#include &lt;sys/socket.h&gt;
+#include &lt;sys/un.h&gt;
+#define DRM_HACK_SOCKET_NAME "xorg_drm_master_util"
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -66,6 +73,60 @@
 #include "radeon_cs_gem.h"
 #include "radeon_vbo.h"
 
+static int
+send_fd(int sock, int fd)
+{
+    // This function does the arcane magic for sending
+    // file descriptors over unix domain sockets
+    struct msghdr msg;
+    struct iovec iov[1];
+    struct cmsghdr *cmsg = NULL;
+    char ctrl_buf[CMSG_SPACE(sizeof(int))];
+    char data[1];
+
+    memset(&msg, 0, sizeof(struct msghdr));
+    memset(ctrl_buf, 0, CMSG_SPACE(sizeof(int)));
+
+    data[0] = ' ';
+    iov[0].iov_base = data;
+    iov[0].iov_len = sizeof(data);
+
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+    msg.msg_controllen =  CMSG_SPACE(sizeof(int));
+    msg.msg_control = ctrl_buf;
+
+    cmsg = CMSG_FIRSTHDR(&msg);
+    cmsg-&gt;cmsg_level = SOL_SOCKET;
+    cmsg-&gt;cmsg_type = SCM_RIGHTS;
+    cmsg-&gt;cmsg_len = CMSG_LEN(sizeof(int));
+
+    *((int *) CMSG_DATA(cmsg)) = fd;
+
+    return sendmsg(sock, &msg, 0);
+}
+
+static void*
+thread_func(void* argument)
+{
+    int ret;
+    int option = *(int *)argument;
+    char cmd[32];
+    sprintf(cmd, "/usr/bin/drm_master_util %s -r", (!option ? "-s" : "-d"));
+
+    ret = system(cmd);
+    if (ret == -1 || WEXITSTATUS(ret) != 0) {
+        fprintf(stderr, "%s\n", strerror(errno));
+        //exit(1);
+    }
+
+    pthread_exit(NULL); // you could also return NULL here to exit no difference
+}
+
+
+
 static DevScreenPrivateKeyRec radeon_client_private_key;
 DevScreenPrivateKeyRec radeon_device_private_key;
 
@@ -2160,7 +2221,10 @@
 static Bool radeon_set_drm_master(ScrnInfoPtr pScrn)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    int err;
+    int err = 0;
+    pthread_t my_thread;
+    struct sockaddr_un addr;
+    int sock, conn, option = 0;
 
 #ifdef XF86_PDEV_SERVER_FD
     if (pRADEONEnt-&gt;platform_dev &&
@@ -2168,9 +2232,21 @@
         return TRUE;
 #endif
 
-    err = drmSetMaster(pRADEONEnt-&gt;fd);
-    if (err)
-        ErrorF("Unable to retrieve master\n");
+    sock = socket(AF_UNIX, SOCK_STREAM, 0);
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+    bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+    listen(sock, 1);
+    pthread_create(&my_thread, NULL, thread_func, &option);
+   
+    conn = accept(sock, NULL, 0);
+    send_fd(conn, pRADEONEnt-&gt;fd);
+    close(conn);
+    close(sock);
+
+    pthread_join(my_thread, NULL);
 
     return err == 0;
 }
@@ -2178,6 +2254,9 @@
 static void radeon_drop_drm_master(ScrnInfoPtr pScrn)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    pthread_t my_thread;
+    struct sockaddr_un addr;
+    int sock, conn, option = 1;
 
 #ifdef XF86_PDEV_SERVER_FD
     if (pRADEONEnt-&gt;platform_dev &&
@@ -2185,7 +2264,21 @@
         return;
 #endif
 
-    drmDropMaster(pRADEONEnt-&gt;fd);
+    sock = socket(AF_UNIX, SOCK_STREAM, 0);
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+    bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+    listen(sock, 1);
+    pthread_create(&my_thread, NULL, thread_func, &option);
+
+    conn = accept(sock, NULL, 0);
+    send_fd(conn, pRADEONEnt-&gt;fd);
+    close(conn);
+    close(sock);
+
+    pthread_join(my_thread, NULL);
 }
 
 /* Called at the end of each server generation.  Restore the original

References and stuff

  1. Git repository of drm_master_util at GitHub. Retrieved on July 17th, 2020.
  2. Gentoo Forums thread "Non root Xorg on AMD video cards", starting from page 4. Retrieved on July 17th, 2020.
  3. Gentoo Forums thread "Non root Xorg on AMD video cards", post #8329654 (for the modesetting driver) and post #8376782 (for the amdgpu driver). Retrieved on July 17th, 2020.
  4. Gentoo Forums thread "Unable to start X as user without dbus, elogind..", post #8448466 (ati driver). Retrieved on July 17th, 2020.