1  /* Basic tests for the new Linux API added on Linux 5.2.
       2     Copyright (C) 2022-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; see the file COPYING.LIB.  If
      17     not, see <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <errno.h>
      20  #include <support/check.h>
      21  #include <support/xunistd.h>
      22  #include <support/namespace.h>
      23  #include <sys/mount.h>
      24  
      25  _Static_assert (sizeof (struct mount_attr) == MOUNT_ATTR_SIZE_VER0,
      26  		"sizeof (struct mount_attr) != MOUNT_ATTR_SIZE_VER0");
      27  
      28  static int
      29  do_test (void)
      30  {
      31    support_become_root ();
      32    if (!support_enter_mount_namespace ())
      33      FAIL_UNSUPPORTED ("cannot enter mount namespace, skipping test");
      34  
      35    int r = fsopen ("it_should_be_not_a_valid_mount", 0);
      36    TEST_VERIFY_EXIT (r == -1);
      37    if (errno == ENOSYS)
      38      FAIL_UNSUPPORTED ("kernel does not support new mount API, skipping test");
      39    TEST_COMPARE (errno, ENODEV);
      40  
      41    int fd = fsopen ("tmpfs", FSOPEN_CLOEXEC);
      42    TEST_VERIFY (fd != -1);
      43  
      44    TEST_COMPARE (fsconfig (-1, FSCONFIG_SET_STRING, "size", "2048", 0), -1);
      45    TEST_COMPARE (errno, EINVAL);
      46  
      47    {
      48      int r = fsconfig (fd, FSCONFIG_SET_STRING, "size", "2048", 0);
      49      TEST_VERIFY (r != -1);
      50      r = fsconfig (fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
      51      TEST_VERIFY (r != -1);
      52    }
      53  
      54    TEST_COMPARE (fsmount (-1, FSMOUNT_CLOEXEC, MOUNT_ATTR_NODEV), -1);
      55    TEST_COMPARE (errno, EBADF);
      56  
      57    int mfd = fsmount (fd, FSMOUNT_CLOEXEC, MOUNT_ATTR_NODEV);
      58    TEST_VERIFY (mfd != -1);
      59  
      60    TEST_COMPARE (move_mount (-1, "", AT_FDCWD, "/tmp", 0), -1);
      61    TEST_COMPARE (errno, ENOENT);
      62    {
      63      int r = move_mount (mfd, "", AT_FDCWD, "/tmp", MOVE_MOUNT_F_EMPTY_PATH);
      64      TEST_VERIFY (r != -1);
      65    }
      66  
      67    TEST_COMPARE (fspick (AT_FDCWD, "", 0), -1);
      68    TEST_COMPARE (errno, ENOENT);
      69    {
      70      int pfd = fspick (AT_FDCWD, "/tmp", FSPICK_CLOEXEC);
      71      TEST_VERIFY (pfd != -1);
      72    }
      73  
      74    TEST_COMPARE (open_tree (AT_FDCWD, "", 0), -1);
      75    TEST_COMPARE (errno, ENOENT);
      76    int fd_tree = open_tree (AT_FDCWD, "/tmp",
      77  			   OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
      78    TEST_VERIFY (fd_tree != -1);
      79  
      80    {
      81      struct mount_attr attr =
      82      {
      83        .attr_set = MOUNT_ATTR_RDONLY,
      84      };
      85       mount_setattr (fd_tree, "", AT_EMPTY_PATH, &attr,
      86  			   sizeof (attr));
      87      int r = mount_setattr (fd_tree, "", AT_EMPTY_PATH, &attr,
      88  			   sizeof (attr));
      89      /* New mount API was added on 5.1, but mount_setattr on 5.12.  */
      90      if (r == -1)
      91        TEST_COMPARE (errno, ENOSYS);
      92      else
      93        {
      94  	TEST_COMPARE (mount_setattr (-1, "", AT_EMPTY_PATH, &attr,
      95  				     sizeof (attr)), -1);
      96  	TEST_COMPARE (errno, EBADF);
      97  	TEST_COMPARE (mount_setattr (fd_tree, "", AT_EMPTY_PATH, &attr,
      98  				     sizeof (attr) - 8), -1);
      99  	TEST_COMPARE (errno, EINVAL);
     100        }
     101    }
     102  
     103    _exit (0);
     104  }
     105  
     106  #include <support/test-driver.c>