Skip to content

Commit 7248788

Browse files
valdaarhunKernel Patches Daemon
authored and
Kernel Patches Daemon
committed
bpftool: Mount bpffs on provided dir instead of parent dir
When pinning programs/objects under PATH (eg: during "bpftool prog loadall") the bpffs is mounted on the parent dir of PATH in the following situations: - the given dir exists but it is not bpffs. - the given dir doesn't exist and the parent dir is not bpffs. Mounting on the parent dir can also have the unintentional side- effect of hiding other files located under the parent dir. If the given dir exists but is not bpffs, then the bpffs should be mounted on the given dir and not its parent dir. Similarly, if the given dir doesn't exist and its parent dir is not bpffs, then the given dir should be created and the bpffs should be mounted on this new dir. Link: https://lore.kernel.org/bpf/[email protected]/T/#t Closes: libbpf/bpftool#100 Fixes: 2a36c26 ("bpftool: Support bpffs mountpoint as pin path for prog loadall") Signed-off-by: Sahil Siddiq <[email protected]>
1 parent beafcaa commit 7248788

File tree

5 files changed

+75
-15
lines changed

5 files changed

+75
-15
lines changed

tools/bpf/bpftool/common.c

+67-11
Original file line numberDiff line numberDiff line change
@@ -244,24 +244,80 @@ int open_obj_pinned_any(const char *path, enum bpf_obj_type exp_type)
244244
return fd;
245245
}
246246

247-
int mount_bpffs_for_pin(const char *name, bool is_dir)
247+
int mount_bpffs_on_dir(const char *dir_name)
248248
{
249249
char err_str[ERR_MAX_LEN];
250-
char *file;
251-
char *dir;
252250
int err = 0;
253251

254-
if (is_dir && is_bpffs(name))
252+
if (is_bpffs(dir_name))
255253
return err;
256254

257-
file = malloc(strlen(name) + 1);
258-
if (!file) {
255+
if (access(dir_name, F_OK) == -1) {
256+
char *temp_name;
257+
char *parent_name;
258+
259+
temp_name = malloc(strlen(dir_name) + 1);
260+
if (!temp_name) {
261+
p_err("mem alloc failed");
262+
return -1;
263+
}
264+
265+
strcpy(temp_name, dir_name);
266+
parent_name = dirname(temp_name);
267+
268+
if (is_bpffs(parent_name)) {
269+
/* nothing to do if already mounted */
270+
free(temp_name);
271+
return err;
272+
}
273+
274+
free(temp_name);
275+
276+
if (block_mount) {
277+
p_err("no BPF file system found, not mounting it due to --nomount option");
278+
return -1;
279+
}
280+
281+
err = mkdir(dir_name, 0700);
282+
if (err) {
283+
p_err("failed to create dir (%s): %s", dir_name, strerror(errno));
284+
return err;
285+
}
286+
} else if (block_mount) {
287+
p_err("no BPF file system found, not mounting it due to --nomount option");
288+
return -1;
289+
}
290+
291+
err = mnt_fs(dir_name, "bpf", err_str, ERR_MAX_LEN);
292+
if (err) {
293+
err_str[ERR_MAX_LEN - 1] = '\0';
294+
p_err("can't mount BPF file system on given dir (%s): %s",
295+
dir_name, err_str);
296+
}
297+
298+
return err;
299+
}
300+
301+
int mount_bpffs_given_file(const char *file_name)
302+
{
303+
char err_str[ERR_MAX_LEN];
304+
char *temp_name;
305+
char *dir;
306+
int err = 0;
307+
308+
if (access(file_name, F_OK) != -1) {
309+
p_err("bpf object can't be pinned since file (%s) already exists", file_name);
310+
return -1;
311+
}
312+
313+
temp_name = malloc(strlen(file_name) + 1);
314+
if (!temp_name) {
259315
p_err("mem alloc failed");
260316
return -1;
261317
}
262318

263-
strcpy(file, name);
264-
dir = dirname(file);
319+
strcpy(temp_name, file_name);
320+
dir = dirname(temp_name);
265321

266322
if (is_bpffs(dir))
267323
/* nothing to do if already mounted */
@@ -277,19 +333,19 @@ int mount_bpffs_for_pin(const char *name, bool is_dir)
277333
if (err) {
278334
err_str[ERR_MAX_LEN - 1] = '\0';
279335
p_err("can't mount BPF file system to pin the object (%s): %s",
280-
name, err_str);
336+
file_name, err_str);
281337
}
282338

283339
out_free:
284-
free(file);
340+
free(temp_name);
285341
return err;
286342
}
287343

288344
int do_pin_fd(int fd, const char *name)
289345
{
290346
int err;
291347

292-
err = mount_bpffs_for_pin(name, false);
348+
err = mount_bpffs_given_file(name);
293349
if (err)
294350
return err;
295351

tools/bpf/bpftool/iter.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static int do_pin(int argc, char **argv)
7676
goto close_obj;
7777
}
7878

79-
err = mount_bpffs_for_pin(path, false);
79+
err = mount_bpffs_given_file(path);
8080
if (err)
8181
goto close_link;
8282

tools/bpf/bpftool/main.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ const char *get_fd_type_name(enum bpf_obj_type type);
142142
char *get_fdinfo(int fd, const char *key);
143143
int open_obj_pinned(const char *path, bool quiet);
144144
int open_obj_pinned_any(const char *path, enum bpf_obj_type exp_type);
145-
int mount_bpffs_for_pin(const char *name, bool is_dir);
145+
int mount_bpffs_given_file(const char *file_name);
146+
int mount_bpffs_on_dir(const char *dir_name);
146147
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(int *, char ***));
147148
int do_pin_fd(int fd, const char *name);
148149

tools/bpf/bpftool/prog.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -1778,7 +1778,10 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
17781778
goto err_close_obj;
17791779
}
17801780

1781-
err = mount_bpffs_for_pin(pinfile, !first_prog_only);
1781+
if (first_prog_only)
1782+
err = mount_bpffs_given_file(pinfile);
1783+
else
1784+
err = mount_bpffs_on_dir(pinfile);
17821785
if (err)
17831786
goto err_close_obj;
17841787

tools/bpf/bpftool/struct_ops.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ static int do_register(int argc, char **argv)
515515
if (argc == 1)
516516
linkdir = GET_ARG();
517517

518-
if (linkdir && mount_bpffs_for_pin(linkdir, true)) {
518+
if (linkdir && mount_bpffs_on_dir(linkdir)) {
519519
p_err("can't mount bpffs for pinning");
520520
return -1;
521521
}

0 commit comments

Comments
 (0)