@@ -107,6 +107,7 @@ static char root_mntpoint[] = "/tmp/statmount_test_root.XXXXXX";
107107static int orig_root ;
108108static uint64_t root_id , parent_id ;
109109static uint32_t old_root_id , old_parent_id ;
110+ static FILE * f_mountinfo ;
110111
111112static void cleanup_namespace (void )
112113{
@@ -134,6 +135,11 @@ static void setup_namespace(void)
134135 sprintf (buf , "0 %d 1" , gid );
135136 write_file ("/proc/self/gid_map" , buf );
136137
138+ f_mountinfo = fopen ("/proc/self/mountinfo" , "re" );
139+ if (!f_mountinfo )
140+ ksft_exit_fail_msg ("failed to open mountinfo: %s\n" ,
141+ strerror (errno ));
142+
137143 ret = mount ("" , "/" , NULL , MS_REC |MS_PRIVATE , NULL );
138144 if (ret == -1 )
139145 ksft_exit_fail_msg ("making mount tree private: %s\n" ,
@@ -435,6 +441,88 @@ static void test_statmount_fs_type(void)
435441 free (sm );
436442}
437443
444+ static void test_statmount_mnt_opts (void )
445+ {
446+ struct statmount * sm ;
447+ const char * statmount_opts ;
448+ char * line = NULL ;
449+ size_t len = 0 ;
450+
451+ sm = statmount_alloc (root_id , STATMOUNT_MNT_BASIC | STATMOUNT_MNT_OPTS ,
452+ 0 );
453+ if (!sm ) {
454+ ksft_test_result_fail ("statmount mnt opts: %s\n" ,
455+ strerror (errno ));
456+ return ;
457+ }
458+
459+ while (getline (& line , & len , f_mountinfo ) != -1 ) {
460+ int i ;
461+ char * p , * p2 ;
462+ unsigned int old_mnt_id ;
463+
464+ old_mnt_id = atoi (line );
465+ if (old_mnt_id != sm -> mnt_id_old )
466+ continue ;
467+
468+ for (p = line , i = 0 ; p && i < 5 ; i ++ )
469+ p = strchr (p + 1 , ' ' );
470+ if (!p )
471+ continue ;
472+
473+ p2 = strchr (p + 1 , ' ' );
474+ if (!p2 )
475+ continue ;
476+ * p2 = '\0' ;
477+ p = strchr (p2 + 1 , '-' );
478+ if (!p )
479+ continue ;
480+ for (p ++ , i = 0 ; p && i < 2 ; i ++ )
481+ p = strchr (p + 1 , ' ' );
482+ if (!p )
483+ continue ;
484+ p ++ ;
485+
486+ /* skip generic superblock options */
487+ if (strncmp (p , "ro" , 2 ) == 0 )
488+ p += 2 ;
489+ else if (strncmp (p , "rw" , 2 ) == 0 )
490+ p += 2 ;
491+ if (* p == ',' )
492+ p ++ ;
493+ if (strncmp (p , "sync" , 4 ) == 0 )
494+ p += 4 ;
495+ if (* p == ',' )
496+ p ++ ;
497+ if (strncmp (p , "dirsync" , 7 ) == 0 )
498+ p += 7 ;
499+ if (* p == ',' )
500+ p ++ ;
501+ if (strncmp (p , "lazytime" , 8 ) == 0 )
502+ p += 8 ;
503+ if (* p == ',' )
504+ p ++ ;
505+ p2 = strrchr (p , '\n' );
506+ if (p2 )
507+ * p2 = '\0' ;
508+
509+ statmount_opts = sm -> str + sm -> mnt_opts ;
510+ if (strcmp (statmount_opts , p ) != 0 )
511+ ksft_test_result_fail (
512+ "unexpected mount options: '%s' != '%s'\n" ,
513+ statmount_opts , p );
514+ else
515+ ksft_test_result_pass ("statmount mount options\n" );
516+ free (sm );
517+ free (line );
518+ return ;
519+ }
520+
521+ ksft_test_result_fail ("didnt't find mount entry\n" );
522+ free (sm );
523+ free (line );
524+ }
525+
438526static void test_statmount_string (uint64_t mask , size_t off , const char * name )
439527{
440528 struct statmount * sm ;
@@ -561,14 +649,15 @@ int main(void)
561649
562650 setup_namespace ();
563651
564- ksft_set_plan (14 );
652+ ksft_set_plan (15 );
565653 test_listmount_empty_root ();
566654 test_statmount_zero_mask ();
567655 test_statmount_mnt_basic ();
568656 test_statmount_sb_basic ();
569657 test_statmount_mnt_root ();
570658 test_statmount_mnt_point ();
571659 test_statmount_fs_type ();
660+ test_statmount_mnt_opts ();
572661 test_statmount_string (STATMOUNT_MNT_ROOT , str_off (mnt_root ), "mount root" );
573662 test_statmount_string (STATMOUNT_MNT_POINT , str_off (mnt_point ), "mount point" );
574663 test_statmount_string (STATMOUNT_FS_TYPE , str_off (fs_type ), "fs type" );
0 commit comments