Skip to content

[SYCL] glob instead of iterating over possible range of renderD* modules #19538

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 39 additions & 16 deletions sycl/test/tools/Inputs/mock_renderd_access.c
Original file line number Diff line number Diff line change
@@ -1,36 +1,57 @@
#define _GNU_SOURCE

#include <errno.h>
#include <glob.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

int stat(const char *pathname, struct stat *statbuf) {
const char *mock_mode = getenv("MOCK_STAT_MODE");
if (strstr(pathname, "renderD128")) {
if (mock_mode && strcmp(mock_mode, "notfound") == 0) {
errno = ENOENT;
return -1;
}
if (mock_mode && strcmp(mock_mode, "exists") == 0) {
memset(statbuf, 0, sizeof(*statbuf));
statbuf->st_mode = S_IFCHR | 0666;
return 0;
int glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
glob_t *pglob) {
const char *mock_mode = getenv("MOCK_GLOB_MODE");
if (mock_mode && strcmp(mock_mode, "exists") == 0) {
// Simulate that /dev/dri/renderD* exists
pglob->gl_pathc = 2;
pglob->gl_pathv = malloc(2 * sizeof(char *));
pglob->gl_pathv[0] = strdup("/dev/dri/renderD128");
pglob->gl_pathv[1] = strdup("/dev/dri/renderD129");
return 0;
}
// Default behavior: no matches
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
return 0;
}

void globfree(glob_t *pglob) {
if (pglob->gl_pathv) {
for (size_t i = 0; i < pglob->gl_pathc; ++i) {
free(pglob->gl_pathv[i]);
}
free(pglob->gl_pathv);
pglob->gl_pathv = NULL;
pglob->gl_pathc = 0;
}
// Default: file does not exist
errno = ENOENT;
return -1;
}

int open(const char *pathname, int flags, ...) {
const char *mock_mode = getenv("MOCK_OPEN_MODE");
if (strstr(pathname, "renderD128")) {
if (strstr(pathname, "renderD12")) {
if (mock_mode && strcmp(mock_mode, "deny") == 0) {
errno = EACCES;
return -1;
}

if (mock_mode && strcmp(mock_mode, "deny_second") == 0) {
// Simulate that the second file is not accessible
if (strstr(pathname, "renderD129")) {
errno = EACCES;
return -1;
} else {
return 3;
}
}

if (mock_mode && strcmp(mock_mode, "allow") == 0) {
return 3; // Dummy fd
}
Expand All @@ -39,3 +60,5 @@ int open(const char *pathname, int flags, ...) {
errno = EACCES;
return -1;
}

int close(int fd) { return 0; }
25 changes: 17 additions & 8 deletions sycl/test/tools/render-group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@
// LD_PRELOAD to mock the stat and open functions.
// RUN: %clang -shared -fPIC -o %t-mock_stat.so %S/Inputs/mock_renderd_access.c

// Check the case when /dev/dri/renderD128 does not exist.
// RUN: env MOCK_STAT_MODE=notfound LD_PRELOAD=%t-mock_stat.so sycl-ls --verbose --ignore-device-selectors 2>&1 | FileCheck %s -check-prefix=CHECK-NOTFOUND
// Check the case when /dev/dri/renderD12* don't exist.
// RUN: env MOCK_GLOB_MODE=notfound LD_PRELOAD=%t-mock_stat.so sycl-ls --verbose --ignore-device-selectors 2>&1 | FileCheck %s -check-prefix=CHECK-NOTFOUND
// We don't expect any warning about permissions in this case.
// CHECK-NOTFOUND-NOT: WARNING: Unable to access /dev/dri/renderD128 due to permissions (EACCES).
// CHECK-NOTFOUND-NOT: WARNING: Unable to access /dev/dri/renderD12

// Check the case when /dev/dri/renderD128 exists but is not accessible.
// RUN: env MOCK_STAT_MODE=exists MOCK_OPEN_MODE=deny LD_PRELOAD=%t-mock_stat.so sycl-ls --verbose --ignore-device-selectors 2>&1 | FileCheck %s --check-prefix=CHECK-DENY
// Check the case when /dev/dri/renderD12* exist but not accessible.
// RUN: env MOCK_GLOB_MODE=exists MOCK_OPEN_MODE=deny LD_PRELOAD=%t-mock_stat.so sycl-ls --verbose --ignore-device-selectors 2>&1 | FileCheck %s --check-prefix=CHECK-DENY
// CHECK-DENY: WARNING: Unable to access /dev/dri/renderD128 due to permissions (EACCES).
// CHECK-DENY-NEXT: You might be missing the 'render' group locally.
// CHECK-DENY-NEXT: Try: sudo usermod -a -G render $USER
// CHECK-DENY-NEXT: Then log out and log back in.

// Check the case when /dev/dri/renderD128 exists and is accessible.
// RUN: env MOCK_STAT_MODE=exists MOCK_OPEN_MODE=allow LD_PRELOAD=%t-mock_stat.so sycl-ls --verbose --ignore-device-selectors 2>&1 | FileCheck %s --check-prefix=CHECK-GRANT
// CHECK-GRANT-NOT: WARNING: Unable to access /dev/dri/renderD128 due to permissions (EACCES).
// Check the case when /dev/dri/renderD12* exist but only the first one is
// accessible.
// RUN: env MOCK_GLOB_MODE=exists MOCK_OPEN_MODE=deny_second LD_PRELOAD=%t-mock_stat.so sycl-ls --verbose --ignore-device-selectors 2>&1 | FileCheck %s --check-prefix=CHECK-DENY-SECOND
// CHECK-DENY-SECOND-NOT: WARNING: Unable to access /dev/dri/renderD128 due to permissions (EACCES).
// CHECK-DENY-SECOND: WARNING: Unable to access /dev/dri/renderD129 due to permissions (EACCES).
// CHECK-DENY-SECOND-NEXT: You might be missing the 'render' group locally.
// CHECK-DENY-SECOND-NEXT: Try: sudo usermod -a -G render $USER
// CHECK-DENY-SECOND-NEXT: Then log out and log back in.

// Check the case when /dev/dri/renderD12* exist and is accessible.
// RUN: env MOCK_GLOB_MODE=exists MOCK_OPEN_MODE=allow LD_PRELOAD=%t-mock_stat.so sycl-ls --verbose --ignore-device-selectors 2>&1 | FileCheck %s --check-prefix=CHECK-GRANT
// CHECK-GRANT-NOT: WARNING: Unable to access /dev/dri/renderD12
34 changes: 17 additions & 17 deletions sycl/tools/sycl-ls/sycl-ls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#ifdef __linux__
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <glob.h>
#include <sys/types.h>
#include <unistd.h>
#endif
Expand Down Expand Up @@ -353,24 +353,24 @@ static int unsetFilterEnvVarsAndFork() {

static void checkRenderGroupPermission() {
#ifdef __linux__
// Check for /dev/dri/render* devices
for (int i = 128; i < 256; ++i) {
std::string path = std::string("/dev/dri/renderD") + std::to_string(i);
struct stat st;
if (stat(path.c_str(), &st) == 0) {
int fd = open(path.c_str(), O_RDWR);
if (fd < 0 && errno == EACCES) {
std::cerr << "WARNING: Unable to access " << path
<< " due to permissions (EACCES).\n"
<< "You might be missing the 'render' group locally.\n"
<< "Try: sudo usermod -a -G render $USER\n"
<< "Then log out and log back in.\n";
break;
}
if (fd >= 0)
close(fd);
glob_t glob_result;
glob("/dev/dri/renderD*", 0, nullptr, &glob_result);
for (size_t i = 0; i < glob_result.gl_pathc; ++i) {
const char *path = glob_result.gl_pathv[i];
int fd = open(path, O_RDWR);
if (fd < 0 && errno == EACCES) {
std::cerr << "WARNING: Unable to access " << path
<< " due to permissions (EACCES).\n"
<< "You might be missing the 'render' group locally.\n"
<< "Try: sudo usermod -a -G render $USER\n"
<< "Then log out and log back in.\n";
globfree(&glob_result);
break;
}
if (fd >= 0)
close(fd);
}
globfree(&glob_result);
#endif
}

Expand Down