"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/core-out-of-memory.c" (15 Mar 2019, 3575 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 "core-out-of-memory.c" see the Fossies "Dox" file reference documentation.

    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__)
   28 
   29 #define OOM_SCORE_ADJ_MIN   "-1000"
   30 #define OOM_SCORE_ADJ_MAX   "1000"
   31 
   32 #define OOM_ADJ_NO_OOM      "-17"
   33 #define OOM_ADJ_MIN     "-16"
   34 #define OOM_ADJ_MAX     "15"
   35 
   36 /*
   37  *  process_oomed()
   38  *  check if a process has been logged as OOM killed
   39  */
   40 bool process_oomed(const pid_t pid)
   41 {
   42     int fd;
   43     bool oomed = false;
   44 
   45     fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
   46     if (fd < 0)
   47         return oomed;
   48 
   49     for (;;) {
   50         char buf[4096], *ptr;
   51         ssize_t ret;
   52 
   53         ret = read(fd, buf, sizeof(buf) - 1);
   54         if (ret < 0)
   55             break;
   56         buf[ret] = '\0';
   57 
   58         /*
   59          * Look for 'Out of memory: Kill process 22566'
   60          */
   61         ptr = strstr(buf, "process");
   62         if (ptr && (strstr(buf, "Out of memory") ||
   63                 strstr(buf, "oom_reaper"))) {
   64             pid_t oom_pid;
   65 
   66             if (sscanf(ptr + 7, "%10d", &oom_pid) == 1) {
   67                 if (oom_pid == pid) {
   68                     oomed = true;
   69                     break;
   70                 }
   71             }
   72         }
   73     }
   74     (void)close(fd);
   75 
   76     return oomed;
   77 }
   78 
   79 /*
   80  *  set_oom_adjustment()
   81  *  attempt to stop oom killer
   82  *  if we have root privileges then try and make process
   83  *  unkillable by oom killer
   84  */
   85 void set_oom_adjustment(const char *name, const bool killable)
   86 {
   87     int fd;
   88     bool high_priv;
   89     bool make_killable = killable;
   90 
   91     high_priv = (getuid() == 0) && (geteuid() == 0);
   92 
   93     /*
   94      *  main cannot be killable; if OPT_FLAGS_OOMABLE set make
   95      *  all child procs easily OOMable
   96      */
   97     if (!strcmp(name, "main") && (g_opt_flags & OPT_FLAGS_OOMABLE))
   98         make_killable = true;
   99 
  100     /*
  101      *  Try modern oom interface
  102      */
  103     if ((fd = open("/proc/self/oom_score_adj", O_WRONLY)) >= 0) {
  104         char *str;
  105         ssize_t n;
  106 
  107         if (make_killable)
  108             str = OOM_SCORE_ADJ_MAX;
  109         else
  110             str = high_priv ? OOM_SCORE_ADJ_MIN : "0";
  111 
  112 redo_wr1:
  113         n = write(fd, str, strlen(str));
  114         if (n <= 0) {
  115             if ((errno == EAGAIN) || (errno == EINTR))
  116                 goto redo_wr1;
  117             if (errno)
  118                 pr_dbg("%s: can't set oom_score_adj\n", name);
  119         }
  120         (void)close(fd);
  121         return;
  122     }
  123     /*
  124      *  Fall back to old oom interface
  125      */
  126     if ((fd = open("/proc/self/oom_adj", O_WRONLY)) >= 0) {
  127         char *str;
  128         ssize_t n;
  129 
  130         if (make_killable)
  131             str = high_priv ? OOM_ADJ_NO_OOM : OOM_ADJ_MIN;
  132         else
  133             str = OOM_ADJ_MAX;
  134 
  135 redo_wr2:
  136         n = write(fd, str, strlen(str));
  137         if (n <= 0) {
  138             if ((errno == EAGAIN) || (errno == EINTR))
  139                 goto redo_wr2;
  140             if (errno)
  141                 pr_dbg("%s: can't set oom_adj\n", name);
  142         }
  143         (void)close(fd);
  144     }
  145     return;
  146 }
  147 #else
  148 void set_oom_adjustment(const char *name, const bool killable)
  149 {
  150     (void)name;
  151     (void)killable;
  152 }
  153 bool process_oomed(const pid_t pid)
  154 {
  155     (void)pid;
  156 
  157     return false;
  158 }
  159 #endif