"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-seal.c" (15 Mar 2019, 4551 Bytes) of package /linux/privat/stress-ng-0.09.56.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stress-seal.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.49_vs_0.09.50.

    1 /*
    2  * Copyright (C) 2013-2019 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 #if defined(__linux__) && defined(HAVE_MEMFD_CREATE)
   28 
   29 #ifndef F_ADD_SEALS
   30 #define F_ADD_SEALS     (1024 + 9)
   31 #endif
   32 #ifndef F_GET_SEALS
   33 #define F_GET_SEALS     (1024 + 10)
   34 #endif
   35 #ifndef F_SEAL_SEAL
   36 #define F_SEAL_SEAL     0x0001
   37 #endif
   38 #ifndef F_SEAL_SHRINK
   39 #define F_SEAL_SHRINK       0x0002
   40 #endif
   41 #ifndef F_SEAL_GROW
   42 #define F_SEAL_GROW     0x0004
   43 #endif
   44 #ifndef F_SEAL_WRITE
   45 #define F_SEAL_WRITE        0x0008
   46 #endif
   47 
   48 #ifndef MFD_ALLOW_SEALING
   49 #define MFD_ALLOW_SEALING   0x0002
   50 #endif
   51 
   52 /*
   53  *  stress_seal
   54  *  stress file sealing
   55  */
   56 static int stress_seal(const args_t *args)
   57 {
   58     int fd, ret;
   59     int rc = EXIT_FAILURE;
   60     const size_t page_size = args->page_size;
   61     char filename[PATH_MAX];
   62 
   63     do {
   64         const off_t sz = page_size;
   65         uint8_t *ptr;
   66         char buf[page_size];
   67 
   68         (void)snprintf(filename, sizeof(filename), "%s-%d-%" PRIu32 "-%" PRIu32,
   69             args->name, args->pid, args->instance, mwc32());
   70 
   71         fd = shim_memfd_create(filename, MFD_ALLOW_SEALING);
   72         if (fd < 0) {
   73             if (errno == ENOSYS) {
   74                 pr_inf("%s: aborting, unimplemented "
   75                     "system call memfd_created\n", args->name);
   76                 return EXIT_NO_RESOURCE;
   77             }
   78             pr_fail_err("memfd_create");
   79             return EXIT_FAILURE;
   80         }
   81 
   82         if (ftruncate(fd, sz) < 0) {
   83             pr_fail_err("ftruncate");
   84             (void)close(fd);
   85             goto err;
   86         }
   87 
   88         if (fcntl(fd, F_GET_SEALS) < 0) {
   89             pr_fail_err("fcntl F_GET_SEALS");
   90             (void)close(fd);
   91             goto err;
   92         }
   93 
   94         /*
   95          *  Add shrink SEAL, file cannot be make smaller
   96          */
   97         if (fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK) < 0) {
   98             pr_fail_err("fcntl F_ADD_SEALS F_SEAL_SHRINK");
   99             (void)close(fd);
  100             goto err;
  101         }
  102         ret = ftruncate(fd, 0);
  103         if ((ret == 0) || ((ret < 0) && (errno != EPERM))) {
  104             pr_fail_err("ftruncate did not fail with EPERM");
  105             (void)close(fd);
  106             goto err;
  107         }
  108 
  109         /*
  110          *  Add grow SEAL, file cannot be made larger
  111          */
  112         if (fcntl(fd, F_ADD_SEALS, F_SEAL_GROW) < 0) {
  113             pr_fail_err("fcntl F_ADD_SEALS F_SEAL_GROW");
  114             (void)close(fd);
  115             goto err;
  116         }
  117         ret = ftruncate(fd, sz + 1);
  118         if ((ret == 0) || ((ret < 0) && (errno != EPERM))) {
  119             pr_fail_err("ftruncate did not fail with EPERM");
  120             (void)close(fd);
  121             goto err;
  122         }
  123 
  124         /*
  125          *  mmap file, sealing it will return EBUSY until
  126          *  the mapping is removed
  127          */
  128         ptr = mmap(NULL, sz, PROT_WRITE, MAP_SHARED,
  129             fd, 0);
  130         if (ptr == MAP_FAILED) {
  131             if (errno == ENOMEM)
  132                 goto next;
  133             pr_fail_err("mmap");
  134             (void)close(fd);
  135             goto err;
  136         }
  137         (void)memset(ptr, 0xea, page_size);
  138         ret = fcntl(fd, F_ADD_SEALS, F_SEAL_WRITE);
  139         if ((ret == 0) || ((ret < 0) && (errno != EBUSY))) {
  140             pr_fail_err("fcntl F_ADD_SEALS F_SEAL_WRITE did not fail with EBUSY");
  141             (void)munmap(ptr, sz);
  142             (void)close(fd);
  143             goto err;
  144         }
  145         (void)shim_msync(ptr, page_size, MS_SYNC);
  146         (void)munmap(ptr, sz);
  147 
  148         /*
  149          *  Now write seal the file, no more writes allowed
  150          */
  151         if (fcntl(fd, F_ADD_SEALS, F_SEAL_WRITE) < 0) {
  152             pr_fail_err("fcntl F_ADD_SEALS F_SEAL_WRITE");
  153             (void)close(fd);
  154             goto err;
  155         }
  156         (void)memset(buf, 0xff, sizeof(buf));
  157         ret = write(fd, buf, sizeof(buf));
  158         if ((ret == 0) || ((ret < 0) && (errno != EPERM))) {
  159             pr_fail_err("write on sealed file did not fail with EPERM");
  160             (void)close(fd);
  161             goto err;
  162         }
  163 next:
  164         (void)close(fd);
  165 
  166         inc_counter(args);
  167     } while (keep_stressing());
  168 
  169     rc = EXIT_SUCCESS;
  170 err:
  171 
  172     return rc;
  173 }
  174 
  175 stressor_info_t stress_seal_info = {
  176     .stressor = stress_seal,
  177     .class = CLASS_OS
  178 };
  179 #else
  180 stressor_info_t stress_seal_info = {
  181     .stressor = stress_not_implemented,
  182     .class = CLASS_OS
  183 };
  184 #endif