"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-swap.c" (15 Mar 2019, 5501 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-swap.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.52_vs_0.09.54.

    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(HAVE_SYS_SWAP_H) && \
   28     defined(HAVE_SWAP)
   29 
   30 #define SWAP_VERSION        (1)
   31 #define SWAP_UUID_LENGTH    (16)
   32 #define SWAP_LABEL_LENGTH   (16)
   33 #define SWAP_SIGNATURE      "SWAPSPACE2"
   34 #define SWAP_SIGNATURE_SZ   (sizeof(SWAP_SIGNATURE) - 1)
   35 
   36 #define MIN_SWAP_PAGES      (32)
   37 #define MAX_SWAP_PAGES      (256)
   38 
   39 #if !defined(SWAP_FLAG_PRIO_SHIFT)
   40 #define SWAP_FLAG_PRIO_SHIFT    (0)
   41 #endif
   42 #if !defined(SWAP_FLAG_PRIO_MASK)
   43 #define SWAP_FLAG_PRIO_MASK (0x7fff)
   44 #endif
   45 
   46 typedef struct {
   47     uint8_t     bootbits[1024];
   48     uint32_t    version;
   49     uint32_t    last_page;
   50     uint32_t    nr_badpages;
   51     uint8_t     sws_uuid[SWAP_UUID_LENGTH];
   52     uint8_t     sws_volume[SWAP_LABEL_LENGTH];
   53     uint32_t    padding[117];
   54     uint32_t    badpages[1];
   55 } swap_info_t;
   56 
   57 /*
   58  *  stress_swap_supported()
   59  *      check if we can run this as root
   60  */
   61 static int stress_swap_supported(void)
   62 {
   63         if (geteuid() != 0) {
   64         pr_inf("stress-swap stressor needs to be run as root to add/remove swap\n");
   65                 return -1;
   66         }
   67         return 0;
   68 }
   69 
   70 static int stress_swap_zero(
   71     const args_t *args,
   72     const int fd,
   73     const uint32_t npages,
   74     const uint8_t *page)
   75 {
   76     uint32_t i;
   77 
   78     if (lseek(fd, 0, SEEK_SET) < 0) {
   79         pr_fail_err("lseek");
   80         return -1;
   81     }
   82 
   83     for (i = 0; i < npages; i++) {
   84         if (write(fd, page, args->page_size) < 0) {
   85             pr_fail_err("write");
   86             return -1;
   87         }
   88     }
   89     return 0;
   90 }
   91 
   92 static int stress_swap_set_size(
   93     const args_t *args,
   94     const int fd,
   95     const uint32_t npages)
   96 {
   97     static const char signature[] = SWAP_SIGNATURE;
   98     swap_info_t swap_info;
   99     size_t i;
  100 
  101     if (npages < MIN_SWAP_PAGES) {
  102         pr_fail("%s: incorrect swap size, must be > 16\n", args->name);
  103         return -1;
  104     }
  105     if (lseek(fd, 0, SEEK_SET) < 0) {
  106         pr_fail_err("lseek");
  107         return -1;
  108     }
  109     (void)memset(&swap_info, 0, sizeof(swap_info));
  110     for (i = 0; i < sizeof(swap_info.sws_uuid); i++)
  111         swap_info.sws_uuid[i] = mwc8();
  112     (void)snprintf((char *)swap_info.sws_volume,
  113         sizeof(swap_info.sws_volume),
  114         "SNG-SWP-%" PRIx32, args->instance);
  115     swap_info.version = SWAP_VERSION;
  116     swap_info.last_page = npages - 1;
  117     swap_info.nr_badpages = 0;
  118     if (write(fd, &swap_info, sizeof(swap_info)) < 0) {
  119         pr_fail_err("write swap info");
  120         return -1;
  121     }
  122     if (lseek(fd, args->page_size - SWAP_SIGNATURE_SZ, SEEK_SET) < 0) {
  123         pr_fail_err("lseek");
  124         return -1;
  125     }
  126     if (write(fd, signature, SWAP_SIGNATURE_SZ) < 0) {
  127         pr_fail_err("write swap info");
  128         return -1;
  129     }
  130     return 0;
  131 }
  132 
  133 /*
  134  *  stress_swap()
  135  *  stress swap operations
  136  */
  137 static int stress_swap(const args_t *args)
  138 {
  139     char filename[PATH_MAX];
  140     int fd = -1, ret;
  141     uint8_t *page;
  142 
  143     page = calloc(1, args->page_size);
  144     if (!page) {
  145         pr_err("%s: failed to allocate 1 page: errno=%d (%s)\n",
  146             args->name, errno, strerror(errno));
  147         ret = EXIT_NO_RESOURCE;
  148         goto tidy_ret;
  149     }
  150 
  151     ret = stress_temp_dir_mk_args(args);
  152     if (ret < 0) {
  153         ret = exit_status(-ret);
  154         goto tidy_free;
  155     }
  156 
  157     (void)stress_temp_filename_args(args,
  158         filename, sizeof(filename), mwc32());
  159     fd = open(filename, O_CREAT | O_RDWR, S_IRUSR);
  160     if (fd < 0) {
  161         ret = exit_status(errno);
  162         pr_fail_err("open");
  163         goto tidy_rm;
  164     }
  165 
  166     if (stress_swap_zero(args, fd, MAX_SWAP_PAGES, page) < 0) {
  167         ret = EXIT_FAILURE;
  168         goto tidy_close;
  169     }
  170 
  171     do {
  172         int swapflags = 0;
  173         uint32_t npages = (mwc32() % (MAX_SWAP_PAGES - MIN_SWAP_PAGES)) +
  174                   MIN_SWAP_PAGES;
  175 
  176 #if defined(SWAP_FLAG_PREFER)
  177         if (mwc1()) {
  178             swapflags = (mwc8() << SWAP_FLAG_PRIO_SHIFT) & SWAP_FLAG_PRIO_MASK;
  179             swapflags |= SWAP_FLAG_PREFER;
  180         }
  181 #endif
  182         if (stress_swap_set_size(args, fd, npages) < 0) {
  183             ret = EXIT_FAILURE;
  184             goto tidy_close;
  185         }
  186         ret = swapon(filename, swapflags);
  187         if (ret < 0) {
  188             if (errno == EPERM) {
  189                 /*
  190                  * We may hit EPERM if we request
  191                  * too many swap files
  192                  */
  193                 ret = EXIT_NO_RESOURCE;
  194             } else {
  195                 pr_fail_err("swapon");
  196                 ret = EXIT_FAILURE;
  197             }
  198             goto tidy_close;
  199         }
  200 
  201         ret = swapoff(filename);
  202         if (ret < 0) {
  203             pr_fail_err("swapoff");
  204             ret = EXIT_FAILURE;
  205             (void)thrash_stop();
  206             goto tidy_close;
  207         }
  208 
  209         inc_counter(args);
  210     } while (keep_stressing());
  211 
  212     ret = EXIT_SUCCESS;
  213 tidy_close:
  214     (void)close(fd);
  215 tidy_rm:
  216     (void)unlink(filename);
  217     (void)stress_temp_dir_rm_args(args);
  218 tidy_free:
  219     free(page);
  220 tidy_ret:
  221     return ret;
  222 }
  223 
  224 stressor_info_t stress_swap_info = {
  225     .stressor = stress_swap,
  226     .supported = stress_swap_supported,
  227     .class = CLASS_VM | CLASS_OS
  228 };
  229 #else
  230 stressor_info_t stress_swap_info = {
  231     .stressor = stress_not_implemented,
  232     .class = CLASS_VM | CLASS_OS
  233 };
  234 #endif