guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/05: gnu: igt-gpu-tools: Fix build with procps@4.


From: guix-commits
Subject: 01/05: gnu: igt-gpu-tools: Fix build with procps@4.
Date: Fri, 23 Jun 2023 19:13:46 -0400 (EDT)

nckx pushed a commit to branch master
in repository guix.

commit 22642d460488896ec1ddb25d7eb262938db810eb
Author: Tobias Geerinckx-Rice <me@tobias.gr>
AuthorDate: Sat Jun 24 00:17:52 2023 +0200

    gnu: igt-gpu-tools: Fix build with procps@4.
    
    * gnu/packages/patches/igt-gpu-tools-Use-libproc2.patch: New file.
    * gnu/packages/admin.scm (igt-gpu-tools)[source]: Use it.
    * gnu/local.mk (dist_patch_DATA): Add it.
---
 gnu/local.mk                                       |   1 +
 gnu/packages/admin.scm                             |   4 +-
 .../patches/igt-gpu-tools-Use-libproc2.patch       | 505 +++++++++++++++++++++
 3 files changed, 509 insertions(+), 1 deletion(-)

diff --git a/gnu/local.mk b/gnu/local.mk
index 1b59cc522b..09a0741cc3 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1374,6 +1374,7 @@ dist_patch_DATA =                                         
\
   %D%/packages/patches/id3lib-CVE-2007-4460.patch                      \
   %D%/packages/patches/id3lib-UTF16-writing-bug.patch                  \
   %D%/packages/patches/idris-test-ffi008.patch                 \
+  %D%/packages/patches/igt-gpu-tools-Use-libproc2.patch                \
   %D%/packages/patches/ilmbase-fix-tests.patch                 \
   %D%/packages/patches/imagemagick-CVE-2020-27829.patch                \
   %D%/packages/patches/imagemagick-ReadDCMImage-fix.patch      \
diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index 529a477ed0..a81a3f3414 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -3903,7 +3903,9 @@ buffers.")
              (commit (string-append "v" version))))
        (file-name (git-file-name name version))
        (sha256
-        (base32 "0d6jsj77qddccv0vfmqmbw3k2prvxzvmgc8zdi83gdi3wpp5i7zd"))))
+        (base32 "0d6jsj77qddccv0vfmqmbw3k2prvxzvmgc8zdi83gdi3wpp5i7zd"))
+       (patches
+        (search-patches "igt-gpu-tools-Use-libproc2.patch"))))
     (build-system meson-build-system)
     (arguments
      `(#:tests? #f              ; many of the tests try to load kernel modules
diff --git a/gnu/packages/patches/igt-gpu-tools-Use-libproc2.patch 
b/gnu/packages/patches/igt-gpu-tools-Use-libproc2.patch
new file mode 100644
index 0000000000..131fea28fc
--- /dev/null
+++ b/gnu/packages/patches/igt-gpu-tools-Use-libproc2.patch
@@ -0,0 +1,505 @@
+diff --git a/lib/igt_aux.c b/lib/igt_aux.c
+index 672d7d4b0..4c24b0928 100644
+--- a/lib/igt_aux.c
++++ b/lib/igt_aux.c
+@@ -52,8 +52,16 @@
+ #include <assert.h>
+ #include <grp.h>
+ 
+-#include <proc/readproc.h>
+-#include <libudev.h>
++#ifdef HAVE_LIBPROCPS
++#  include <proc/readproc.h>
++#else
++#  include <libproc2/pids.h>
++#endif
++
++#include <dirent.h>
++#ifdef __linux__
++#  include <libudev.h>
++#endif
+ 
+ #include "drmtest.h"
+ #include "i915_drm.h"
+@@ -1217,6 +1225,7 @@ void igt_unlock_mem(void)
+  */
+ int igt_is_process_running(const char *comm)
+ {
++#if HAVE_LIBPROCPS
+       PROCTAB *proc;
+       proc_t *proc_info;
+       bool found = false;
+@@ -1235,6 +1244,26 @@ int igt_is_process_running(const char *comm)
+ 
+       closeproc(proc);
+       return found;
++#else
++      enum pids_item Item[] = { PIDS_CMD };
++      struct pids_info *info = NULL;
++      struct pids_stack *stack;
++      char *pid_comm;
++      bool found = false;
++
++      if (procps_pids_new(&info, Item, 1) < 0)
++              return false;
++      while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) {
++              pid_comm = PIDS_VAL(0, str, stack, info);
++              if (!strncasecmp(pid_comm, comm, strlen(pid_comm))) {
++                      found = true;
++                      break;
++              }
++      }
++
++      procps_pids_unref(&info);
++      return found;
++#endif
+ }
+ 
+ /**
+@@ -1251,6 +1280,7 @@ int igt_is_process_running(const char *comm)
+  */
+ int igt_terminate_process(int sig, const char *comm)
+ {
++#if HAVE_LIBPROCPS
+       PROCTAB *proc;
+       proc_t *proc_info;
+       int err = 0;
+@@ -1272,6 +1302,28 @@ int igt_terminate_process(int sig, const char *comm)
+ 
+       closeproc(proc);
+       return err;
++#else
++      enum pids_item Items[] = { PIDS_ID_PID, PIDS_CMD };
++      struct pids_info *info = NULL;
++      struct pids_stack *stack;
++      char *pid_comm;
++      int pid;
++      int err = 0;
++
++      if (procps_pids_new(&info, Items, 2) < 0)
++              return -errno;
++      while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) {
++              pid = PIDS_VAL(0, s_int, stack, info);
++              pid_comm = PIDS_VAL(1, str, stack, info);
++              if (!strncasecmp(pid_comm, comm, strlen(pid_comm))) {
++                      if (kill(pid, sig) < 0)
++                              err = -errno;
++                      break;
++              }
++      }
++      procps_pids_unref(&info);
++      return err;
++#endif
+ }
+ 
+ struct pinfo {
+@@ -1341,9 +1393,9 @@ igt_show_stat_header(void)
+ }
+ 
+ static void
+-igt_show_stat(proc_t *info, int *state, const char *fn)
++igt_show_stat(const pid_t tid, const char *cmd, int *state, const char *fn)
+ {
+-      struct pinfo p = { .pid = info->tid, .comm = info->cmd, .fn = fn };
++      struct pinfo p = { .pid = tid, .comm = cmd, .fn = fn };
+ 
+       if (!*state)
+               igt_show_stat_header();
+@@ -1353,7 +1405,7 @@ igt_show_stat(proc_t *info, int *state, const char *fn)
+ }
+ 
+ static void
+-__igt_lsof_fds(proc_t *proc_info, int *state, char *proc_path, const char 
*dir)
++__igt_lsof_fds(const pid_t tid, const char *cmd, int *state, char *proc_path, 
const char *dir)
+ {
+       struct dirent *d;
+       struct stat st;
+@@ -1400,7 +1452,7 @@ again:
+               dirn = dirname(copy_fd_lnk);
+ 
+               if (!strncmp(dir, dirn, strlen(dir)))
+-                      igt_show_stat(proc_info, state, fd_lnk);
++                      igt_show_stat(tid, cmd, state, fd_lnk);
+ 
+               free(copy_fd_lnk);
+               free(fd_lnk);
+@@ -1416,13 +1468,13 @@ again:
+ static void
+ __igt_lsof(const char *dir)
+ {
+-      PROCTAB *proc;
+-      proc_t *proc_info;
+-
+       char path[30];
+       char *name_lnk;
+       struct stat st;
+       int state = 0;
++#ifdef HAVE_LIBPROCPS
++      PROCTAB *proc;
++      proc_t *proc_info;
+ 
+       proc = openproc(PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLARG);
+       igt_assert(proc != NULL);
+@@ -1443,19 +1495,56 @@ __igt_lsof(const char *dir)
+               name_lnk[read] = '\0';
+ 
+               if (!strncmp(dir, name_lnk, strlen(dir)))
+-                      igt_show_stat(proc_info, &state, name_lnk);
++                      igt_show_stat(proc_info->tid, proc_info->cmd, &state, 
name_lnk);
+ 
+               /* check also fd, seems that lsof(8) doesn't look here */
+               memset(path, 0, sizeof(path));
+               snprintf(path, sizeof(path), "/proc/%d/fd", proc_info->tid);
+ 
+-              __igt_lsof_fds(proc_info, &state, path, dir);
++              __igt_lsof_fds(proc_info->tid, proc_info->cmd, &state, path, 
dir);
+ 
+               free(name_lnk);
+               freeproc(proc_info);
+       }
+ 
+       closeproc(proc);
++#else
++      enum pids_item Items[] = { PIDS_ID_PID, PIDS_CMD };
++      struct pids_info *info = NULL;
++      struct pids_stack *stack;
++
++      if (procps_pids_new(&info, Items, 2) < 0)
++              return;
++      while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) {
++              ssize_t read;
++              int tid = PIDS_VAL(0, s_int, stack, info);
++              char *pid_comm = PIDS_VAL(1, str, stack, info);
++
++              /* check current working directory */
++              memset(path, 0, sizeof(path));
++              snprintf(path, sizeof(path), "/proc/%d/cwd", tid);
++
++              if (stat(path, &st) == -1)
++                      continue;
++
++              name_lnk = malloc(st.st_size + 1);
++
++              igt_assert((read = readlink(path, name_lnk, st.st_size + 1)));
++              name_lnk[read] = '\0';
++
++              if (!strncmp(dir, name_lnk, strlen(dir)))
++                      igt_show_stat(tid, pid_comm, &state, name_lnk);
++
++              /* check also fd, seems that lsof(8) doesn't look here */
++              memset(path, 0, sizeof(path));
++              snprintf(path, sizeof(path), "/proc/%d/fd", tid);
++
++              __igt_lsof_fds(tid, pid_comm, &state, path, dir);
++
++              free(name_lnk);
++      }
++      procps_pids_unref(&info);
++#endif
+ }
+ 
+ /**
+@@ -1490,7 +1579,7 @@ igt_lsof(const char *dpath)
+       free(sanitized);
+ }
+ 
+-static void pulseaudio_unload_module(proc_t *proc_info)
++static void pulseaudio_unload_module(const uid_t euid, const gid_t egid)
+ {
+       struct igt_helper_process pa_proc = {};
+       char xdg_dir[PATH_MAX];
+@@ -1498,14 +1587,14 @@ static void pulseaudio_unload_module(proc_t *proc_info)
+       struct passwd *pw;
+ 
+       igt_fork_helper(&pa_proc) {
+-              pw = getpwuid(proc_info->euid);
++              pw = getpwuid(euid);
+               homedir = pw->pw_dir;
+-              snprintf(xdg_dir, sizeof(xdg_dir), "/run/user/%d", 
proc_info->euid);
++              snprintf(xdg_dir, sizeof(xdg_dir), "/run/user/%d", euid);
+ 
+               igt_info("Request pulseaudio to stop using audio device\n");
+ 
+-              setgid(proc_info->egid);
+-              setuid(proc_info->euid);
++              setgid(egid);
++              setuid(euid);
+               clearenv();
+               setenv("HOME", homedir, 1);
+               setenv("XDG_RUNTIME_DIR",xdg_dir, 1);
+@@ -1524,10 +1613,13 @@ static void pipewire_reserve_wait(void)
+       char xdg_dir[PATH_MAX];
+       const char *homedir;
+       struct passwd *pw;
+-      proc_t *proc_info;
+-      PROCTAB *proc;
++      int tid = 0, euid, egid;
+ 
++#ifdef HAVE_LIBPROCPS
+       igt_fork_helper(&pw_reserve_proc) {
++              proc_t *proc_info;
++              PROCTAB *proc;
++
+               igt_info("Preventing pipewire-pulse to use the audio 
drivers\n");
+ 
+               proc = openproc(PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLARG);
+@@ -1540,19 +1632,45 @@ static void pipewire_reserve_wait(void)
+               }
+               closeproc(proc);
+ 
++              tid = proc_info->tid;
++              euid = proc_info->euid;
++              egid = proc_info->egid;
++              freeproc(proc_info);
++#else
++      igt_fork_helper(&pw_reserve_proc) {
++              enum pids_item Items[] = { PIDS_ID_PID, PIDS_ID_EUID, 
PIDS_ID_EGID };
++              enum rel_items { EU_PID, EU_EUID, EU_EGID };
++              struct pids_info *info = NULL;
++              struct pids_stack *stack;
++
++              igt_info("Preventing pipewire-pulse to use the audio 
drivers\n");
++
++              if (procps_pids_new(&info, Items, 3) < 0) {
++                      igt_info("error getting pids: %d\n", errno);
++                      exit(errno);
++              }
++              while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) {
++                      tid = PIDS_VAL(EU_PID, s_int, stack, info);
++                      if (pipewire_pulse_pid == tid)
++                              break;
++              }
++              euid = PIDS_VAL(EU_EUID, s_int, stack, info);
++              egid = PIDS_VAL(EU_EGID, s_int, stack, info);
++              procps_pids_unref(&info);
++#endif
++
+               /* Sanity check: if it can't find the process, it means it has 
gone */
+-              if (pipewire_pulse_pid != proc_info->tid)
++              if (pipewire_pulse_pid != tid)
+                       exit(0);
+ 
+-              pw = getpwuid(proc_info->euid);
++              pw = getpwuid(euid);
+               homedir = pw->pw_dir;
+-              snprintf(xdg_dir, sizeof(xdg_dir), "/run/user/%d", 
proc_info->euid);
+-              setgid(proc_info->egid);
+-              setuid(proc_info->euid);
++              snprintf(xdg_dir, sizeof(xdg_dir), "/run/user/%d", euid);
++              setgid(egid);
++              setuid(euid);
+               clearenv();
+               setenv("HOME", homedir, 1);
+               setenv("XDG_RUNTIME_DIR",xdg_dir, 1);
+-              freeproc(proc_info);
+ 
+               /*
+                * pw-reserve will run in background. It will only exit when
+@@ -1570,9 +1688,7 @@ static void pipewire_reserve_wait(void)
+ int pipewire_pulse_start_reserve(void)
+ {
+       bool is_pw_reserve_running = false;
+-      proc_t *proc_info;
+       int attempts = 0;
+-      PROCTAB *proc;
+ 
+       if (!pipewire_pulse_pid)
+               return 0;
+@@ -1584,6 +1700,10 @@ int pipewire_pulse_start_reserve(void)
+        * pipewire version 0.3.50 or upper.
+        */
+       for (attempts = 0; attempts < PIPEWIRE_RESERVE_MAX_TIME; attempts++) {
++#ifdef HAVE_LIBPROCPS
++              PROCTAB *proc;
++              proc_t *proc_info;
++
+               usleep(1000);
+               proc = openproc(PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLARG);
+               igt_assert(proc != NULL);
+@@ -1598,6 +1718,24 @@ int pipewire_pulse_start_reserve(void)
+                       freeproc(proc_info);
+               }
+               closeproc(proc);
++#else
++              enum pids_item Items[] = { PIDS_ID_PID, PIDS_CMD };
++              struct pids_info *info = NULL;
++              struct pids_stack *stack;
++
++              usleep(1000);
++
++              if (procps_pids_new(&info, Items, 2) < 0)
++                      return 1;
++              while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) {
++                      if (!strcmp(PIDS_VAL(1, str, stack, info), 
"pw-reserve")) {
++                              is_pw_reserve_running = true;
++                              pipewire_pw_reserve_pid = PIDS_VAL(0, s_int, 
stack, info);
++                              break;
++                      }
++              }
++              procps_pids_unref(&info);
++#endif
+               if (is_pw_reserve_running)
+                       break;
+       }
+@@ -1645,7 +1783,7 @@ void pipewire_pulse_stop_reserve(void)
+  * If the check fails, it means that the process can simply be killed.
+  */
+ static int
+-__igt_lsof_audio_and_kill_proc(proc_t *proc_info, char *proc_path)
++__igt_lsof_audio_and_kill_proc(const pid_t tid, const char *cmd, const uid_t 
euid, const gid_t egid, char *proc_path)
+ {
+       const char *audio_dev = "/dev/snd/";
+       char path[PATH_MAX * 2];
+@@ -1670,10 +1808,10 @@ __igt_lsof_audio_and_kill_proc(proc_t *proc_info, char 
*proc_path)
+        * 2) unload/unbind the the audio driver(s);
+        * 3) stop the pw-reserve thread.
+        */
+-      if (!strcmp(proc_info->cmd, "pipewire-pulse")) {
++      if (!strcmp(cmd, "pipewire-pulse")) {
+               igt_info("process %d (%s) is using audio device. Should be 
requested to stop using them.\n",
+-                       proc_info->tid, proc_info->cmd);
+-              pipewire_pulse_pid = proc_info->tid;
++                       tid, cmd);
++              pipewire_pulse_pid = tid;
+               return 0;
+       }
+       /*
+@@ -1685,9 +1823,9 @@ __igt_lsof_audio_and_kill_proc(proc_t *proc_info, char 
*proc_path)
+        * will respawn them. So, just ignore here, they'll honor pw-reserve,
+        * when the time comes.
+        */
+-      if (!strcmp(proc_info->cmd, "pipewire-media-session"))
++      if (!strcmp(cmd, "pipewire-media-session"))
+               return 0;
+-      if (!strcmp(proc_info->cmd, "wireplumber"))
++      if (!strcmp(cmd, "wireplumber"))
+               return 0;
+ 
+       dp = opendir(proc_path);
+@@ -1723,22 +1861,22 @@ __igt_lsof_audio_and_kill_proc(proc_t *proc_info, char 
*proc_path)
+                * enough to unbind audio modules and won't cause race issues
+                * with systemd trying to reload it.
+                */
+-              if (!strcmp(proc_info->cmd, "pulseaudio")) {
+-                      pulseaudio_unload_module(proc_info);
++              if (!strcmp(cmd, "pulseaudio")) {
++                      pulseaudio_unload_module(euid, egid);
+                       break;
+               }
+ 
+               /* For all other processes, just kill them */
+               igt_info("process %d (%s) is using audio device. Should be 
terminated.\n",
+-                              proc_info->tid, proc_info->cmd);
++                              tid, cmd);
+ 
+-              if (kill(proc_info->tid, SIGTERM) < 0) {
++              if (kill(tid, SIGTERM) < 0) {
+                       igt_info("Fail to terminate %s (pid: %d) with 
SIGTERM\n",
+-                              proc_info->cmd, proc_info->tid);
+-                      if (kill(proc_info->tid, SIGABRT) < 0) {
++                              cmd, tid);
++                      if (kill(tid, SIGABRT) < 0) {
+                               fail++;
+                               igt_info("Fail to terminate %s (pid: %d) with 
SIGABRT\n",
+-                                      proc_info->cmd, proc_info->tid);
++                                      cmd, tid);
+                       }
+               }
+ 
+@@ -1760,23 +1898,47 @@ int
+ igt_lsof_kill_audio_processes(void)
+ {
+       char path[PATH_MAX];
++      int fail = 0;
++
++#ifdef HAVE_LIBPROCPS
+       proc_t *proc_info;
+       PROCTAB *proc;
+-      int fail = 0;
+ 
+       proc = openproc(PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLARG);
+       igt_assert(proc != NULL);
+       pipewire_pulse_pid = 0;
+-
+       while ((proc_info = readproc(proc, NULL))) {
+               if (snprintf(path, sizeof(path), "/proc/%d/fd", proc_info->tid) 
< 1)
+                       fail++;
+               else
+-                      fail += __igt_lsof_audio_and_kill_proc(proc_info, path);
++                      fail += __igt_lsof_audio_and_kill_proc(proc_info->tid, 
proc_info->cmd, proc_info->euid, proc_info->egid, path);
+ 
+               freeproc(proc_info);
+       }
+       closeproc(proc);
++#else
++      enum pids_item Items[] = { PIDS_ID_PID, PIDS_CMD, PIDS_ID_EUID, 
PIDS_ID_EGID };
++      enum rel_items { EU_PID, EU_CMD, EU_EUID, EU_EGID };
++      struct pids_info *info = NULL;
++      struct pids_stack *stack;
++      pid_t tid;
++
++      if (procps_pids_new(&info, Items, 4) < 0)
++              return 1;
++      while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) {
++              tid = PIDS_VAL(EU_PID, s_int, stack, info);
++
++              if (snprintf(path, sizeof(path), "/proc/%d/fd", tid) < 1)
++                      fail++;
++              else
++                      fail += __igt_lsof_audio_and_kill_proc(tid,
++                              PIDS_VAL(EU_CMD, str, stack, info),
++                              PIDS_VAL(EU_EUID, s_int, stack, info),
++                              PIDS_VAL(EU_EGID, s_int, stack, info),
++                              path);
++      }
++      procps_pids_unref(&info);
++#endif
+ 
+       return fail;
+ }
+diff --git a/lib/meson.build b/lib/meson.build
+index 85f100f75..55efdc83b 100644
+--- a/lib/meson.build
++++ b/lib/meson.build
+@@ -114,7 +114,6 @@ lib_deps = [
+       libdrm,
+       libdw,
+       libkmod,
+-      libprocps,
+       libudev,
+       math,
+       pciaccess,
+@@ -178,6 +177,12 @@ if chamelium.found()
+       lib_sources += 'monitor_edids/monitor_edids_helper.c'
+ endif
+ 
++if libprocps.found()
++      lib_deps += libprocps
++else
++      lib_deps += libproc2
++endif
++
+ if get_option('srcdir') != ''
+     srcdir = join_paths(get_option('srcdir'), 'tests')
+ else
+diff --git a/meson.build b/meson.build
+index 1c872cc9c..0487158dc 100644
+--- a/meson.build
++++ b/meson.build
+@@ -125,7 +125,15 @@ build_info += 'With libdrm: ' + ','.join(libdrm_info)
+ 
+ pciaccess = dependency('pciaccess', version : '>=0.10')
+ libkmod = dependency('libkmod')
+-libprocps = dependency('libprocps', required : true)
++libprocps = dependency('libprocps', required : false)
++libproc2 = dependency('libproc2', required : false)
++if libprocps.found()
++  config.set('HAVE_LIBPROCPS', 1)
++elif libproc2.found()
++  config.set('HAVE_LIBPROC2', 1)
++else
++  error('Either libprocps or libproc2 is required')
++endif
+ 
+ libunwind = dependency('libunwind', required : get_option('libunwind'))
+ build_info += 'With libunwind: @0@'.format(libunwind.found())



reply via email to

[Prev in Thread] Current Thread [Next in Thread]