Print this page
    
OS-11 rcapd behaves poorly when under extreme load
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/rcap/common/utils.c
          +++ new/usr/src/cmd/rcap/common/utils.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright (c) 2011, Joyent, Inc. All rights reserved.
  24   25   */
  25   26  
  26   27  #include <sys/param.h>
  27   28  #include <libintl.h>
  28   29  #include <stdarg.h>
  29   30  #include <stdio.h>
  30   31  #include <stdlib.h>
  31   32  #include <strings.h>
  32   33  #include <syslog.h>
  33   34  #include <unistd.h>
  34   35  #include <errno.h>
  35   36  
  36   37  #include "utils.h"
  37   38  
  38   39  static char ERRNO_FMT[] = ": %s";
  39   40  
  40   41  static char *pname = NULL;
  41   42  static rcm_level_t message_priority = RCM_WARN;
  42   43  static rcm_dst_t message_dst = RCD_STD;
  43   44  
  44   45  static void dmesg(int level, char *msg);
  45   46  
  46   47  /*PRINTFLIKE2*/
  47   48  void
  48   49  dprintfe(int level, char *format, ...)
  49   50  {
  50   51          va_list alist;
  51   52  
  52   53          va_start(alist, format);
  53   54          vdprintfe(level, format, alist);
  54   55          va_end(alist);
  55   56  }
  56   57  
  57   58  /*PRINTFLIKE2*/
  58   59  void
  59   60  vdprintfe(int level, const char *format, va_list alist)
  60   61  {
  61   62          char buf[LINELEN];
  62   63          char *c;
  63   64          int err = errno;
  64   65  
  65   66          *buf = 0;
  66   67  
  67   68          if ((strlen(buf) + 1) < LINELEN)
  68   69                  (void) vsnprintf(buf + strlen(buf), LINELEN - 1 - strlen(buf),
  69   70                      format, alist);
  70   71          if ((c = strchr(buf, '\n')) == NULL) {
  71   72                  if ((strlen(buf) + 1) < LINELEN)
  72   73                          (void) snprintf(buf + strlen(buf), LINELEN - 1 -
  73   74                              strlen(buf), gettext(ERRNO_FMT), strerror(err));
  74   75          } else
  75   76                  *c = 0;
  76   77  
  77   78          dmesg(level, buf);
  78   79  }
  79   80  
  80   81  #ifdef DEBUG_MSG
  81   82  /*PRINTFLIKE1*/
  82   83  void
  83   84  debug(char *format, ...)
  84   85  {
  85   86          va_list alist;
  86   87  
  87   88          if (get_message_priority() < RCM_DEBUG)
  88   89                  return;
  89   90  
  90   91          va_start(alist, format);
  91   92          vdprintfe(RCM_DEBUG, format, alist);
  92   93          va_end(alist);
  93   94  }
  94   95  
  95   96  /*PRINTFLIKE1*/
  96   97  void
  97   98  debug_high(char *format, ...)
  98   99  {
  99  100          va_list alist;
 100  101  
 101  102          if (get_message_priority() < RCM_DEBUG_HIGH)
 102  103                  return;
 103  104  
 104  105          va_start(alist, format);
 105  106          vdprintfe(RCM_DEBUG_HIGH, format, alist);
 106  107          va_end(alist);
 107  108  }
 108  109  #endif /* DEBUG_MSG */
 109  110  
 110  111  /*PRINTFLIKE1*/
 111  112  void
 112  113  warn(const char *format, ...)
 113  114  {
 114  115          va_list alist;
 115  116  
 116  117          if (get_message_priority() < RCM_WARN)
 117  118                  return;
 118  119  
 119  120          va_start(alist, format);
 120  121          vdprintfe(RCM_WARN, format, alist);
 121  122          va_end(alist);
 122  123  }
 123  124  
 124  125  /*PRINTFLIKE1*/
 125  126  void
 126  127  die(char *format, ...)
 127  128  {
 128  129          va_list alist;
 129  130  
 130  131          if (get_message_priority() < RCM_ERR)
 131  132                  return;
 132  133  
 133  134          va_start(alist, format);
 134  135          vdprintfe(RCM_ERR, format, alist);
 135  136          va_end(alist);
 136  137  
 137  138          exit(E_ERROR);
 138  139  }
 139  140  
 140  141  /*PRINTFLIKE1*/
 141  142  void
 142  143  info(char *format, ...)
 143  144  {
 144  145          va_list alist;
 145  146  
 146  147          if (get_message_priority() < RCM_INFO)
 147  148                  return;
 148  149  
 149  150          va_start(alist, format);
 150  151          vdprintfe(RCM_INFO, format, alist);
 151  152          va_end(alist);
 152  153  }
 153  154  
 154  155  char *
 155  156  setpname(char *arg0)
 156  157  {
 157  158          char *p = strrchr(arg0, '/');
 158  159  
 159  160          if (p == NULL)
 160  161                  p = arg0;
 161  162          else
 162  163                  p++;
 163  164          pname = p;
 164  165          return (pname);
 165  166  }
 166  167  
 167  168  /*
 168  169   * Output a message to the controlling tty or log, depending on which is
 169  170   * configured.  The message should contain no newlines.
 170  171   */
 171  172  static void
 172  173  dmesg(int level, char *msg)
 173  174  {
 174  175          if (message_priority >= level) {
 175  176                  FILE *fp;
 176  177                  int syslog_severity = -1;
 177  178  
 178  179                  switch (message_dst) {
 179  180                  case RCD_STD:
 180  181                          fp = level >= RCM_DEBUG ? stderr : stdout;
 181  182  
 182  183                          if (pname != NULL) {
 183  184                                  (void) fputs(pname, fp);
 184  185                                  (void) fputs(": ", fp);
 185  186                          }
 186  187                          (void) fputs(msg, fp);
 187  188                          (void) fputc('\n', fp);
 188  189                          (void) fflush(fp);
 189  190                          break;
 190  191                  case RCD_SYSLOG:
 191  192                          switch (level) {
 192  193                          case RCM_ERR:
 193  194                                  syslog_severity = LOG_ERR;
 194  195                                  break;
 195  196                          case RCM_WARN:
 196  197                                  syslog_severity = LOG_WARNING;
 197  198                                  break;
 198  199                          case RCM_INFO:
 199  200                                  syslog_severity = LOG_INFO;
 200  201                                  break;
 201  202                          case RCM_DEBUG:
 202  203                                  syslog_severity = LOG_DEBUG;
 203  204                                  break;
 204  205                          }
 205  206                          if (syslog_severity >= 0)
 206  207                                  (void) syslog(syslog_severity, "%s", msg);
 207  208                          break;
 208  209                  }
 209  210          }
 210  211  }
 211  212  
 212  213  rcm_level_t
 213  214  get_message_priority(void)
 214  215  {
 215  216          return (message_priority);
 216  217  }
 217  218  
 218  219  rcm_level_t
 219  220  set_message_priority(rcm_level_t new_priority)
 220  221  {
 221  222          rcm_level_t old_priority = message_priority;
 222  223  
 223  224          message_priority = new_priority;
 224  225          return (old_priority);
 225  226  }
 226  227  
 227  228  rcm_dst_t
 228  229  set_message_destination(rcm_dst_t new_dst)
 229  230  {
 230  231          rcm_dst_t old_dst = message_dst;
 231  232  
 232  233          if ((message_dst = new_dst) == RCD_SYSLOG)
 233  234                  openlog(pname, LOG_ODELAY | LOG_PID, LOG_DAEMON);
 234  235  
 235  236          return (old_dst);
 236  237  }
 237  238  
 238  239  void
 239  240  hrt2ts(hrtime_t hrt, timestruc_t *tsp)
 240  241  {
 241  242          tsp->tv_sec = hrt / NANOSEC;
 242  243          tsp->tv_nsec = hrt % NANOSEC;
 243  244  }
 244  245  
 245  246  int
 246  247  xatoi(char *p)
 247  248  {
 248  249          int i;
  
    | 
      ↓ open down ↓ | 
    215 lines elided | 
    
      ↑ open up ↑ | 
  
 249  250          char *q;
 250  251  
 251  252          errno = 0;
 252  253          i = (int)strtol(p, &q, 10);
 253  254          if (errno != 0 || q == p || i < 0 || *q != '\0') {
 254  255                  warn(gettext("illegal argument -- %s\n"), p);
 255  256                  return (-1);
 256  257          } else {
 257  258                  return (i);
 258  259          }
 259      -}
 260      -
 261      -/*
 262      - * get_running_zones() calls zone_list(2) to find out how many zones are
 263      - * running.  It then calls zone_list(2) again to fetch the list of running
 264      - * zones (stored in *zents).
 265      - */
 266      -int
 267      -get_running_zones(uint_t *nzents, zone_entry_t **zents)
 268      -{
 269      -        zoneid_t *zids;
 270      -        uint_t nzents_saved;
 271      -        int i;
 272      -        zone_entry_t *zentp;
 273      -        zone_state_t zstate;
 274      -
 275      -        *zents = NULL;
 276      -        if (zone_list(NULL, nzents) != 0) {
 277      -                warn(gettext("could not get zoneid list\n"));
 278      -                return (E_ERROR);
 279      -        }
 280      -
 281      -again:
 282      -        if (*nzents == 0)
 283      -                return (E_SUCCESS);
 284      -
 285      -        if ((zids = (zoneid_t *)calloc(*nzents, sizeof (zoneid_t))) == NULL) {
 286      -                warn(gettext("out of memory: zones will not be capped\n"));
 287      -                return (E_ERROR);
 288      -        }
 289      -
 290      -        nzents_saved = *nzents;
 291      -
 292      -        if (zone_list(zids, nzents) != 0) {
 293      -                warn(gettext("could not get zone list\n"));
 294      -                free(zids);
 295      -                return (E_ERROR);
 296      -        }
 297      -        if (*nzents != nzents_saved) {
 298      -                /* list changed, try again */
 299      -                free(zids);
 300      -                goto again;
 301      -        }
 302      -
 303      -        *zents = calloc(*nzents, sizeof (zone_entry_t));
 304      -        if (*zents == NULL) {
 305      -                warn(gettext("out of memory: zones will not be capped\n"));
 306      -                free(zids);
 307      -                return (E_ERROR);
 308      -        }
 309      -
 310      -        zentp = *zents;
 311      -        for (i = 0; i < *nzents; i++) {
 312      -                char name[ZONENAME_MAX];
 313      -
 314      -                if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) {
 315      -                        warn(gettext("could not get name for "
 316      -                            "zoneid %d\n"), zids[i]);
 317      -                        continue;
 318      -                }
 319      -
 320      -                (void) strlcpy(zentp->zname, name, sizeof (zentp->zname));
 321      -                zentp->zid = zids[i];
 322      -                if (zone_get_state(name, &zstate) != Z_OK ||
 323      -                    zstate != ZONE_STATE_RUNNING)
 324      -                        continue;
 325      -
 326      -
 327      -                zentp++;
 328      -        }
 329      -        *nzents = zentp - *zents;
 330      -
 331      -        free(zids);
 332      -        return (E_SUCCESS);
 333  260  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX