2020-03-02 20:31:59 -08:00
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Facebook */
# include <test_progs.h>
# include <sys/stat.h>
# include "test_link_pinning.skel.h"
static int duration = 0 ;
void test_link_pinning_subtest ( struct bpf_program * prog ,
struct test_link_pinning__bss * bss )
{
const char * link_pin_path = " /sys/fs/bpf/pinned_link_test " ;
struct stat statbuf = { } ;
struct bpf_link * link ;
int err , i ;
link = bpf_program__attach ( prog ) ;
2021-05-24 20:59:32 -07:00
if ( ! ASSERT_OK_PTR ( link , " link_attach " ) )
2020-03-02 20:31:59 -08:00
goto cleanup ;
bss - > in = 1 ;
usleep ( 1 ) ;
CHECK ( bss - > out ! = 1 , " res_check1 " , " exp %d, got %d \n " , 1 , bss - > out ) ;
/* pin link */
err = bpf_link__pin ( link , link_pin_path ) ;
if ( CHECK ( err , " link_pin " , " err: %d \n " , err ) )
goto cleanup ;
CHECK ( strcmp ( link_pin_path , bpf_link__pin_path ( link ) ) , " pin_path1 " ,
" exp %s, got %s \n " , link_pin_path , bpf_link__pin_path ( link ) ) ;
/* check that link was pinned */
err = stat ( link_pin_path , & statbuf ) ;
if ( CHECK ( err , " stat_link " , " err %d errno %d \n " , err , errno ) )
goto cleanup ;
bss - > in = 2 ;
usleep ( 1 ) ;
CHECK ( bss - > out ! = 2 , " res_check2 " , " exp %d, got %d \n " , 2 , bss - > out ) ;
/* destroy link, pinned link should keep program attached */
bpf_link__destroy ( link ) ;
link = NULL ;
bss - > in = 3 ;
usleep ( 1 ) ;
CHECK ( bss - > out ! = 3 , " res_check3 " , " exp %d, got %d \n " , 3 , bss - > out ) ;
/* re-open link from BPFFS */
link = bpf_link__open ( link_pin_path ) ;
2021-05-24 20:59:32 -07:00
if ( ! ASSERT_OK_PTR ( link , " link_open " ) )
2020-03-02 20:31:59 -08:00
goto cleanup ;
CHECK ( strcmp ( link_pin_path , bpf_link__pin_path ( link ) ) , " pin_path2 " ,
" exp %s, got %s \n " , link_pin_path , bpf_link__pin_path ( link ) ) ;
/* unpin link from BPFFS, program still attached */
err = bpf_link__unpin ( link ) ;
if ( CHECK ( err , " link_unpin " , " err: %d \n " , err ) )
goto cleanup ;
/* still active, as we have FD open now */
bss - > in = 4 ;
usleep ( 1 ) ;
CHECK ( bss - > out ! = 4 , " res_check4 " , " exp %d, got %d \n " , 4 , bss - > out ) ;
bpf_link__destroy ( link ) ;
link = NULL ;
/* Validate it's finally detached.
* Actual detachment might get delayed a bit , so there is no reliable
* way to validate it immediately here , let ' s count up for long enough
* and see if eventually output stops being updated
*/
for ( i = 5 ; i < 10000 ; i + + ) {
bss - > in = i ;
usleep ( 1 ) ;
if ( bss - > out = = i - 1 )
break ;
}
CHECK ( i = = 10000 , " link_attached " , " got to iteration #%d \n " , i ) ;
cleanup :
2021-05-24 20:59:32 -07:00
bpf_link__destroy ( link ) ;
2020-03-02 20:31:59 -08:00
}
void test_link_pinning ( void )
{
struct test_link_pinning * skel ;
skel = test_link_pinning__open_and_load ( ) ;
if ( CHECK ( ! skel , " skel_open " , " failed to open skeleton \n " ) )
return ;
if ( test__start_subtest ( " pin_raw_tp " ) )
test_link_pinning_subtest ( skel - > progs . raw_tp_prog , skel - > bss ) ;
if ( test__start_subtest ( " pin_tp_btf " ) )
test_link_pinning_subtest ( skel - > progs . tp_btf_prog , skel - > bss ) ;
test_link_pinning__destroy ( skel ) ;
}