Skip to content

Commit 353a2ea

Browse files
authored
[SYCL] glob instead of iterating over possible range of renderD* modules (#19538)
1 parent 3fa14e0 commit 353a2ea

File tree

3 files changed

+73
-41
lines changed

3 files changed

+73
-41
lines changed
Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,57 @@
11
#define _GNU_SOURCE
22

33
#include <errno.h>
4+
#include <glob.h>
45
#include <stdarg.h>
56
#include <stdlib.h>
67
#include <string.h>
7-
#include <sys/stat.h>
88

9-
int stat(const char *pathname, struct stat *statbuf) {
10-
const char *mock_mode = getenv("MOCK_STAT_MODE");
11-
if (strstr(pathname, "renderD128")) {
12-
if (mock_mode && strcmp(mock_mode, "notfound") == 0) {
13-
errno = ENOENT;
14-
return -1;
15-
}
16-
if (mock_mode && strcmp(mock_mode, "exists") == 0) {
17-
memset(statbuf, 0, sizeof(*statbuf));
18-
statbuf->st_mode = S_IFCHR | 0666;
19-
return 0;
9+
int glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
10+
glob_t *pglob) {
11+
const char *mock_mode = getenv("MOCK_GLOB_MODE");
12+
if (mock_mode && strcmp(mock_mode, "exists") == 0) {
13+
// Simulate that /dev/dri/renderD* exists
14+
pglob->gl_pathc = 2;
15+
pglob->gl_pathv = malloc(2 * sizeof(char *));
16+
pglob->gl_pathv[0] = strdup("/dev/dri/renderD128");
17+
pglob->gl_pathv[1] = strdup("/dev/dri/renderD129");
18+
return 0;
19+
}
20+
// Default behavior: no matches
21+
pglob->gl_pathc = 0;
22+
pglob->gl_pathv = NULL;
23+
return 0;
24+
}
25+
26+
void globfree(glob_t *pglob) {
27+
if (pglob->gl_pathv) {
28+
for (size_t i = 0; i < pglob->gl_pathc; ++i) {
29+
free(pglob->gl_pathv[i]);
2030
}
31+
free(pglob->gl_pathv);
32+
pglob->gl_pathv = NULL;
33+
pglob->gl_pathc = 0;
2134
}
22-
// Default: file does not exist
23-
errno = ENOENT;
24-
return -1;
2535
}
2636

2737
int open(const char *pathname, int flags, ...) {
2838
const char *mock_mode = getenv("MOCK_OPEN_MODE");
29-
if (strstr(pathname, "renderD128")) {
39+
if (strstr(pathname, "renderD12")) {
3040
if (mock_mode && strcmp(mock_mode, "deny") == 0) {
3141
errno = EACCES;
3242
return -1;
3343
}
44+
45+
if (mock_mode && strcmp(mock_mode, "deny_second") == 0) {
46+
// Simulate that the second file is not accessible
47+
if (strstr(pathname, "renderD129")) {
48+
errno = EACCES;
49+
return -1;
50+
} else {
51+
return 3;
52+
}
53+
}
54+
3455
if (mock_mode && strcmp(mock_mode, "allow") == 0) {
3556
return 3; // Dummy fd
3657
}
@@ -39,3 +60,5 @@ int open(const char *pathname, int flags, ...) {
3960
errno = EACCES;
4061
return -1;
4162
}
63+
64+
int close(int fd) { return 0; }

sycl/test/tools/render-group.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,27 @@
44
// LD_PRELOAD to mock the stat and open functions.
55
// RUN: %clang -shared -fPIC -o %t-mock_stat.so %S/Inputs/mock_renderd_access.c
66

7-
// Check the case when /dev/dri/renderD128 does not exist.
8-
// 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
7+
// Check the case when /dev/dri/renderD12* don't exist.
8+
// 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
99
// We don't expect any warning about permissions in this case.
10-
// CHECK-NOTFOUND-NOT: WARNING: Unable to access /dev/dri/renderD128 due to permissions (EACCES).
10+
// CHECK-NOTFOUND-NOT: WARNING: Unable to access /dev/dri/renderD12
1111

12-
// Check the case when /dev/dri/renderD128 exists but is not accessible.
13-
// 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
12+
// Check the case when /dev/dri/renderD12* exist but not accessible.
13+
// 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
1414
// CHECK-DENY: WARNING: Unable to access /dev/dri/renderD128 due to permissions (EACCES).
1515
// CHECK-DENY-NEXT: You might be missing the 'render' group locally.
1616
// CHECK-DENY-NEXT: Try: sudo usermod -a -G render $USER
1717
// CHECK-DENY-NEXT: Then log out and log back in.
1818

19-
// Check the case when /dev/dri/renderD128 exists and is accessible.
20-
// 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
21-
// CHECK-GRANT-NOT: WARNING: Unable to access /dev/dri/renderD128 due to permissions (EACCES).
19+
// Check the case when /dev/dri/renderD12* exist but only the first one is
20+
// accessible.
21+
// 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
22+
// CHECK-DENY-SECOND-NOT: WARNING: Unable to access /dev/dri/renderD128 due to permissions (EACCES).
23+
// CHECK-DENY-SECOND: WARNING: Unable to access /dev/dri/renderD129 due to permissions (EACCES).
24+
// CHECK-DENY-SECOND-NEXT: You might be missing the 'render' group locally.
25+
// CHECK-DENY-SECOND-NEXT: Try: sudo usermod -a -G render $USER
26+
// CHECK-DENY-SECOND-NEXT: Then log out and log back in.
27+
28+
// Check the case when /dev/dri/renderD12* exist and is accessible.
29+
// 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
30+
// CHECK-GRANT-NOT: WARNING: Unable to access /dev/dri/renderD12

sycl/tools/sycl-ls/sycl-ls.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#ifdef __linux__
3030
#include <errno.h>
3131
#include <fcntl.h>
32-
#include <sys/stat.h>
32+
#include <glob.h>
3333
#include <sys/types.h>
3434
#include <unistd.h>
3535
#endif
@@ -353,24 +353,24 @@ static int unsetFilterEnvVarsAndFork() {
353353

354354
static void checkRenderGroupPermission() {
355355
#ifdef __linux__
356-
// Check for /dev/dri/render* devices
357-
for (int i = 128; i < 256; ++i) {
358-
std::string path = std::string("/dev/dri/renderD") + std::to_string(i);
359-
struct stat st;
360-
if (stat(path.c_str(), &st) == 0) {
361-
int fd = open(path.c_str(), O_RDWR);
362-
if (fd < 0 && errno == EACCES) {
363-
std::cerr << "WARNING: Unable to access " << path
364-
<< " due to permissions (EACCES).\n"
365-
<< "You might be missing the 'render' group locally.\n"
366-
<< "Try: sudo usermod -a -G render $USER\n"
367-
<< "Then log out and log back in.\n";
368-
break;
369-
}
370-
if (fd >= 0)
371-
close(fd);
356+
glob_t glob_result;
357+
glob("/dev/dri/renderD*", 0, nullptr, &glob_result);
358+
for (size_t i = 0; i < glob_result.gl_pathc; ++i) {
359+
const char *path = glob_result.gl_pathv[i];
360+
int fd = open(path, O_RDWR);
361+
if (fd < 0 && errno == EACCES) {
362+
std::cerr << "WARNING: Unable to access " << path
363+
<< " due to permissions (EACCES).\n"
364+
<< "You might be missing the 'render' group locally.\n"
365+
<< "Try: sudo usermod -a -G render $USER\n"
366+
<< "Then log out and log back in.\n";
367+
globfree(&glob_result);
368+
break;
372369
}
370+
if (fd >= 0)
371+
close(fd);
373372
}
373+
globfree(&glob_result);
374374
#endif
375375
}
376376

0 commit comments

Comments
 (0)