Skip to content

Commit df4a076

Browse files
committed
initrd-put: Extend the mechanism for ignoring elf_dlopen dependencies
Signed-off-by: Alexey Gladkov <[email protected]>
1 parent f953b17 commit df4a076

File tree

2 files changed

+83
-16
lines changed

2 files changed

+83
-16
lines changed

mk/config.mk.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,14 @@ PUT_DIRS ?=
117117
PUT_FILES ?=
118118
PUT_PROGS ?=
119119

120+
#
121+
# Variables allow to ignore some dependencies from ELF_DLOPEN_METADATA by
122+
# feature name or by priority.
123+
#
124+
# Format: [<filename-regex>:]<value>[,[<regex>:]<value>,...]
125+
#
120126
# See https://github.com/systemd/systemd/blob/main/docs/ELF_DLOPEN_METADATA.md
127+
#
121128
IGNORE_PUT_DLOPEN_FEATURE ?=
122129
IGNORE_PUT_DLOPEN_PRIORITY ?=
123130

utils/initrd-put/elf_dlopen.c

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <stdio.h>
99
#include <stdint.h>
1010
#include <string.h>
11+
#include <regex.h>
1112
#include <errno.h>
1213
#include <err.h>
1314

@@ -36,30 +37,89 @@ struct visit_data {
3637
char *outbuf;
3738
};
3839

39-
static int in_list(const char *list, const char delim, const char *value)
40+
static int in_envvar(const char *envname, const char *filename, const char *value)
4041
{
41-
const char *s, *e, *p;
42+
const char *s, *e, *p, *list, *sep, *file_regex, *word;
43+
size_t sz, file_regex_sz, word_sz, buf_sz;
44+
char *buf, *new;
45+
int ret;
4246

43-
if (!list)
47+
int regex_err;
48+
regex_t regex = { 0 };
49+
50+
if (!(list = getenv(envname)))
4451
return 0;
4552

53+
ret = 0;
54+
55+
buf = NULL;
56+
buf_sz = 0;
57+
4658
s = p = list;
4759
e = s + strlen(s);
4860

49-
while (p < e) {
50-
p = strchr(s, delim);
51-
if (!p)
61+
for (; p < e; s = p + 1) {
62+
if (!(p = strchr(s, ',')))
5263
p = e + 1;
53-
if (!strncmp(s, value, (size_t)(p - s)))
54-
return 1;
55-
s = p + 1;
64+
65+
sz = (size_t) (p - s);
66+
67+
if ((sep = memchr(s, ':', sz)) != NULL) {
68+
file_regex = s;
69+
file_regex_sz = (size_t) (sep - file_regex);
70+
71+
word = sep + 1;
72+
word_sz = sz - file_regex_sz - 1;
73+
} else {
74+
file_regex = NULL;
75+
file_regex_sz = 0;
76+
77+
word = s;
78+
word_sz = sz;
79+
}
80+
81+
if (file_regex) {
82+
// Release the previous regex if any.
83+
regfree(&regex);
84+
85+
// Add place for null-byte.
86+
file_regex_sz += 1;
87+
88+
if (buf_sz < file_regex_sz) {
89+
buf_sz = file_regex_sz * 2;
90+
91+
if (!(new = realloc(buf, buf_sz))) {
92+
warn("realloc");
93+
break;
94+
}
95+
buf = new;
96+
}
97+
98+
strlcpy(buf, file_regex, file_regex_sz);
99+
100+
if ((regex_err = regcomp(&regex, buf, REG_NOSUB | REG_EXTENDED)) != 0) {
101+
char errbuf[BUFSIZ];
102+
103+
regerror(regex_err, &regex, errbuf, sizeof(errbuf));
104+
105+
warnx("in_envvar: bad regex: %s", errbuf);
106+
continue;
107+
}
108+
109+
if (regexec(&regex, filename, 0, NULL, 0) == REG_NOMATCH)
110+
continue;
111+
}
112+
113+
if (!strncmp(word, value, word_sz)) {
114+
ret = 1;
115+
break;
116+
}
56117
}
57-
return 0;
58-
}
59118

60-
static int in_envvar(const char *envname, const char *value)
61-
{
62-
return in_list(getenv(envname), ',', value);
119+
regfree(&regex);
120+
free(buf);
121+
122+
return ret;
63123
}
64124

65125
static pid_t waitpid_retry(pid_t pid, int *wstatus, int options)
@@ -230,8 +290,8 @@ static int visit_userfunc(json_object *jso, int flags, json_object *,
230290
if (!elf_metadata.priority)
231291
elf_metadata.priority = "recommended";
232292

233-
if (in_envvar("IGNORE_PUT_DLOPEN_FEATURE", elf_metadata.feature) ||
234-
in_envvar("IGNORE_PUT_DLOPEN_PRIORITY", elf_metadata.priority))
293+
if (in_envvar("IGNORE_PUT_DLOPEN_FEATURE", data->filename, elf_metadata.feature) ||
294+
in_envvar("IGNORE_PUT_DLOPEN_PRIORITY", data->filename, elf_metadata.priority))
235295
return JSON_C_VISIT_RETURN_SKIP;
236296

237297
soname = xcalloc(array_len, sizeof(char *));

0 commit comments

Comments
 (0)