44#ifndef _GNU_SOURCE
55#define _GNU_SOURCE
66#endif
7+ #include <assert.h>
78#include <ctype.h>
89#include <errno.h>
910#include <fcntl.h>
@@ -193,7 +194,8 @@ int mount_tracefs(const char *target)
193194 return err ;
194195}
195196
196- int open_obj_pinned (const char * path , bool quiet )
197+ int open_obj_pinned (const char * path , bool quiet ,
198+ const struct bpf_obj_get_opts * opts )
197199{
198200 char * pname ;
199201 int fd = -1 ;
@@ -205,7 +207,7 @@ int open_obj_pinned(const char *path, bool quiet)
205207 goto out_ret ;
206208 }
207209
208- fd = bpf_obj_get (pname );
210+ fd = bpf_obj_get_opts (pname , opts );
209211 if (fd < 0 ) {
210212 if (!quiet )
211213 p_err ("bpf obj get (%s): %s" , pname ,
@@ -221,12 +223,13 @@ int open_obj_pinned(const char *path, bool quiet)
221223 return fd ;
222224}
223225
224- int open_obj_pinned_any (const char * path , enum bpf_obj_type exp_type )
226+ int open_obj_pinned_any (const char * path , enum bpf_obj_type exp_type ,
227+ const struct bpf_obj_get_opts * opts )
225228{
226229 enum bpf_obj_type type ;
227230 int fd ;
228231
229- fd = open_obj_pinned (path , false);
232+ fd = open_obj_pinned (path , false, opts );
230233 if (fd < 0 )
231234 return -1 ;
232235
@@ -555,7 +558,7 @@ static int do_build_table_cb(const char *fpath, const struct stat *sb,
555558 if (typeflag != FTW_F )
556559 goto out_ret ;
557560
558- fd = open_obj_pinned (fpath , true);
561+ fd = open_obj_pinned (fpath , true, NULL );
559562 if (fd < 0 )
560563 goto out_ret ;
561564
@@ -928,7 +931,7 @@ int prog_parse_fds(int *argc, char ***argv, int **fds)
928931 path = * * argv ;
929932 NEXT_ARGP ();
930933
931- (* fds )[0 ] = open_obj_pinned_any (path , BPF_OBJ_PROG );
934+ (* fds )[0 ] = open_obj_pinned_any (path , BPF_OBJ_PROG , NULL );
932935 if ((* fds )[0 ] < 0 )
933936 return -1 ;
934937 return 1 ;
@@ -965,14 +968,16 @@ int prog_parse_fd(int *argc, char ***argv)
965968 return fd ;
966969}
967970
968- static int map_fd_by_name (char * name , int * * fds )
971+ static int map_fd_by_name (char * name , int * * fds ,
972+ const struct bpf_get_fd_by_id_opts * opts )
969973{
970974 unsigned int id = 0 ;
971975 int fd , nb_fds = 0 ;
972976 void * tmp ;
973977 int err ;
974978
975979 while (true) {
980+ LIBBPF_OPTS (bpf_get_fd_by_id_opts , opts_ro );
976981 struct bpf_map_info info = {};
977982 __u32 len = sizeof (info );
978983
@@ -985,7 +990,9 @@ static int map_fd_by_name(char *name, int **fds)
985990 return nb_fds ;
986991 }
987992
988- fd = bpf_map_get_fd_by_id (id );
993+ /* Request a read-only fd to query the map info */
994+ opts_ro .open_flags = BPF_F_RDONLY ;
995+ fd = bpf_map_get_fd_by_id_opts (id , & opts_ro );
989996 if (fd < 0 ) {
990997 p_err ("can't get map by id (%u): %s" ,
991998 id , strerror (errno ));
@@ -1004,6 +1011,19 @@ static int map_fd_by_name(char *name, int **fds)
10041011 continue ;
10051012 }
10061013
1014+ /* Get an fd with the requested options, if they differ
1015+ * from the read-only options used to get the fd above.
1016+ */
1017+ if (memcmp (opts , & opts_ro , sizeof (opts_ro ))) {
1018+ close (fd );
1019+ fd = bpf_map_get_fd_by_id_opts (id , opts );
1020+ if (fd < 0 ) {
1021+ p_err ("can't get map by id (%u): %s" , id ,
1022+ strerror (errno ));
1023+ goto err_close_fds ;
1024+ }
1025+ }
1026+
10071027 if (nb_fds > 0 ) {
10081028 tmp = realloc (* fds , (nb_fds + 1 ) * sizeof (int ));
10091029 if (!tmp ) {
@@ -1023,8 +1043,13 @@ static int map_fd_by_name(char *name, int **fds)
10231043 return -1 ;
10241044}
10251045
1026- int map_parse_fds (int * argc , char * * * argv , int * * fds )
1046+ int map_parse_fds (int * argc , char * * * argv , int * * fds , __u32 open_flags )
10271047{
1048+ LIBBPF_OPTS (bpf_get_fd_by_id_opts , opts );
1049+
1050+ assert ((open_flags & ~BPF_F_RDONLY ) == 0 );
1051+ opts .open_flags = open_flags ;
1052+
10281053 if (is_prefix (* * argv , "id" )) {
10291054 unsigned int id ;
10301055 char * endptr ;
@@ -1038,7 +1063,7 @@ int map_parse_fds(int *argc, char ***argv, int **fds)
10381063 }
10391064 NEXT_ARGP ();
10401065
1041- (* fds )[0 ] = bpf_map_get_fd_by_id (id );
1066+ (* fds )[0 ] = bpf_map_get_fd_by_id_opts (id , & opts );
10421067 if ((* fds )[0 ] < 0 ) {
10431068 p_err ("get map by id (%u): %s" , id , strerror (errno ));
10441069 return -1 ;
@@ -1056,16 +1081,18 @@ int map_parse_fds(int *argc, char ***argv, int **fds)
10561081 }
10571082 NEXT_ARGP ();
10581083
1059- return map_fd_by_name (name , fds );
1084+ return map_fd_by_name (name , fds , & opts );
10601085 } else if (is_prefix (* * argv , "pinned" )) {
10611086 char * path ;
1087+ LIBBPF_OPTS (bpf_obj_get_opts , get_opts );
1088+ get_opts .file_flags = open_flags ;
10621089
10631090 NEXT_ARGP ();
10641091
10651092 path = * * argv ;
10661093 NEXT_ARGP ();
10671094
1068- (* fds )[0 ] = open_obj_pinned_any (path , BPF_OBJ_MAP );
1095+ (* fds )[0 ] = open_obj_pinned_any (path , BPF_OBJ_MAP , & get_opts );
10691096 if ((* fds )[0 ] < 0 )
10701097 return -1 ;
10711098 return 1 ;
@@ -1075,7 +1102,7 @@ int map_parse_fds(int *argc, char ***argv, int **fds)
10751102 return -1 ;
10761103}
10771104
1078- int map_parse_fd (int * argc , char * * * argv )
1105+ int map_parse_fd (int * argc , char * * * argv , __u32 open_flags )
10791106{
10801107 int * fds = NULL ;
10811108 int nb_fds , fd ;
@@ -1085,7 +1112,7 @@ int map_parse_fd(int *argc, char ***argv)
10851112 p_err ("mem alloc failed" );
10861113 return -1 ;
10871114 }
1088- nb_fds = map_parse_fds (argc , argv , & fds );
1115+ nb_fds = map_parse_fds (argc , argv , & fds , open_flags );
10891116 if (nb_fds != 1 ) {
10901117 if (nb_fds > 1 ) {
10911118 p_err ("several maps match this handle" );
@@ -1103,12 +1130,12 @@ int map_parse_fd(int *argc, char ***argv)
11031130}
11041131
11051132int map_parse_fd_and_info (int * argc , char * * * argv , struct bpf_map_info * info ,
1106- __u32 * info_len )
1133+ __u32 * info_len , __u32 open_flags )
11071134{
11081135 int err ;
11091136 int fd ;
11101137
1111- fd = map_parse_fd (argc , argv );
1138+ fd = map_parse_fd (argc , argv , open_flags );
11121139 if (fd < 0 )
11131140 return -1 ;
11141141
0 commit comments