Skip to content

Commit b90c11f

Browse files
valdaarhunSasha Levin
authored and
Sasha Levin
committed
bpftool: Mount bpffs on provided dir instead of parent dir
[ Upstream commit 478a535 ] 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. Fixes: 2a36c26 ("bpftool: Support bpffs mountpoint as pin path for prog loadall") Signed-off-by: Sahil Siddiq <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]/T/#t Link: https://lore.kernel.org/bpf/[email protected] Closes: libbpf/bpftool#100 Changes since v1: - Split "mount_bpffs_for_pin" into two functions. This is done to improve maintainability and readability. Changes since v2: - mount_bpffs_for_pin: rename to "create_and_mount_bpffs_dir". - mount_bpffs_given_file: rename to "mount_bpffs_given_file". - create_and_mount_bpffs_dir: - introduce "dir_exists" boolean. - remove new dir if "mnt_fs" fails. - improve error handling and error messages. Changes since v3: - Rectify function name. - Improve error messages and formatting. - mount_bpffs_for_file: - Check if dir exists before block_mount check. Changes since v4: - Use strdup instead of strcpy. - create_and_mount_bpffs_dir: - Use S_IRWXU instead of 0700. - Improve error handling and formatting. Signed-off-by: Sasha Levin <[email protected]>
1 parent a0bec6e commit b90c11f

File tree

5 files changed

+92
-16
lines changed

5 files changed

+92
-16
lines changed

tools/bpf/bpftool/common.c

+84-12
Original file line numberDiff line numberDiff line change
@@ -244,29 +244,101 @@ 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 create_and_mount_bpffs_dir(const char *dir_name)
248248
{
249249
char err_str[ERR_MAX_LEN];
250-
char *file;
251-
char *dir;
250+
bool dir_exists;
252251
int err = 0;
253252

254-
if (is_dir && is_bpffs(name))
253+
if (is_bpffs(dir_name))
255254
return err;
256255

257-
file = malloc(strlen(name) + 1);
258-
if (!file) {
256+
dir_exists = access(dir_name, F_OK) == 0;
257+
258+
if (!dir_exists) {
259+
char *temp_name;
260+
char *parent_name;
261+
262+
temp_name = strdup(dir_name);
263+
if (!temp_name) {
264+
p_err("mem alloc failed");
265+
return -1;
266+
}
267+
268+
parent_name = dirname(temp_name);
269+
270+
if (is_bpffs(parent_name)) {
271+
/* nothing to do if already mounted */
272+
free(temp_name);
273+
return err;
274+
}
275+
276+
if (access(parent_name, F_OK) == -1) {
277+
p_err("can't create dir '%s' to pin BPF object: parent dir '%s' doesn't exist",
278+
dir_name, parent_name);
279+
free(temp_name);
280+
return -1;
281+
}
282+
283+
free(temp_name);
284+
}
285+
286+
if (block_mount) {
287+
p_err("no BPF file system found, not mounting it due to --nomount option");
288+
return -1;
289+
}
290+
291+
if (!dir_exists) {
292+
err = mkdir(dir_name, S_IRWXU);
293+
if (err) {
294+
p_err("failed to create dir '%s': %s", dir_name, strerror(errno));
295+
return err;
296+
}
297+
}
298+
299+
err = mnt_fs(dir_name, "bpf", err_str, ERR_MAX_LEN);
300+
if (err) {
301+
err_str[ERR_MAX_LEN - 1] = '\0';
302+
p_err("can't mount BPF file system on given dir '%s': %s",
303+
dir_name, err_str);
304+
305+
if (!dir_exists)
306+
rmdir(dir_name);
307+
}
308+
309+
return err;
310+
}
311+
312+
int mount_bpffs_for_file(const char *file_name)
313+
{
314+
char err_str[ERR_MAX_LEN];
315+
char *temp_name;
316+
char *dir;
317+
int err = 0;
318+
319+
if (access(file_name, F_OK) != -1) {
320+
p_err("can't pin BPF object: path '%s' already exists", file_name);
321+
return -1;
322+
}
323+
324+
temp_name = strdup(file_name);
325+
if (!temp_name) {
259326
p_err("mem alloc failed");
260327
return -1;
261328
}
262329

263-
strcpy(file, name);
264-
dir = dirname(file);
330+
dir = dirname(temp_name);
265331

266332
if (is_bpffs(dir))
267333
/* nothing to do if already mounted */
268334
goto out_free;
269335

336+
if (access(dir, F_OK) == -1) {
337+
p_err("can't pin BPF object: dir '%s' doesn't exist", dir);
338+
err = -1;
339+
goto out_free;
340+
}
341+
270342
if (block_mount) {
271343
p_err("no BPF file system found, not mounting it due to --nomount option");
272344
err = -1;
@@ -276,20 +348,20 @@ int mount_bpffs_for_pin(const char *name, bool is_dir)
276348
err = mnt_fs(dir, "bpf", err_str, ERR_MAX_LEN);
277349
if (err) {
278350
err_str[ERR_MAX_LEN - 1] = '\0';
279-
p_err("can't mount BPF file system to pin the object (%s): %s",
280-
name, err_str);
351+
p_err("can't mount BPF file system to pin the object '%s': %s",
352+
file_name, err_str);
281353
}
282354

283355
out_free:
284-
free(file);
356+
free(temp_name);
285357
return err;
286358
}
287359

288360
int do_pin_fd(int fd, const char *name)
289361
{
290362
int err;
291363

292-
err = mount_bpffs_for_pin(name, false);
364+
err = mount_bpffs_for_file(name);
293365
if (err)
294366
return err;
295367

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_for_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_for_file(const char *file_name);
146+
int create_and_mount_bpffs_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_for_file(pinfile);
1783+
else
1784+
err = create_and_mount_bpffs_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 && create_and_mount_bpffs_dir(linkdir)) {
519519
p_err("can't mount bpffs for pinning");
520520
return -1;
521521
}

0 commit comments

Comments
 (0)