Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c
          +++ new/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.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
  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   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   * Copyright 2011 Joyent, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  #include <procfs.h>
  28   28  #include <project.h>
  29   29  #include <stdlib.h>
  30   30  #include <strings.h>
  31   31  #include <zone.h>
  32   32  #include <libzonecfg.h>
  33   33  #include <dirent.h>
  34   34  #include <libproc.h>
  35   35  #include "rcapd.h"
  36   36  #include "utils.h"
  37   37  
  38   38  extern boolean_t gz_capped;
  39   39  
  40   40                                  /* round up to next y = 2^n */
  41   41  #define ROUNDUP(x, y)           (((x) + ((y) - 1)) & ~((y) - 1))
  42   42  
  43   43  static struct ps_prochandle *
  44   44  grab_zone_proc(zoneid_t zid)
  45   45  {
  46   46          DIR *dirp;
  47   47          struct dirent *dentp;
  48   48          int pid, pid_self, tmp;
  49   49          psinfo_t psinfo;
  50   50          struct ps_prochandle *pr = NULL;
  51   51  
  52   52          pid_self = getpid();
  53   53  
  54   54          if ((dirp = opendir("/proc")) == NULL)
  55   55                  return (NULL);
  56   56  
  57   57          while (dentp = readdir(dirp)) {
  58   58                  pid = atoi(dentp->d_name);
  59   59  
  60   60                  /* Skip self */
  61   61                  if (pid == pid_self)
  62   62                          continue;
  63   63  
  64   64                  if (proc_get_psinfo(pid, &psinfo) != 0)
  65   65                          continue;
  66   66  
  67   67                  if (psinfo.pr_zoneid != zid)
  68   68                          continue;
  69   69  
  70   70                  /* attempt to grab process */
  71   71                  if ((pr = Pgrab(pid, 0, &tmp)) != NULL) {
  72   72                          if (Psetflags(pr, PR_RLC) != 0) {
  73   73                                  Prelease(pr, 0);
  74   74                          }
  75   75                          if (Pcreate_agent(pr) == 0) {
  76   76                                  if (pr_getzoneid(pr) != zid) {
  77   77                                          Prelease(pr, 0);
  78   78                                          continue;
  79   79                                  }
  80   80  
  81   81                                  (void) closedir(dirp);
  82   82                                  return (pr);
  83   83                          } else {
  84   84                                  Prelease(pr, 0);
  85   85                          }
  86   86                  }
  87   87          }
  88   88  
  89   89          (void) closedir(dirp);
  90   90          return (NULL);
  91   91  }
  92   92  
  93   93  static uint64_t
  94   94  get_zone_cap(zoneid_t zid)
  95   95  {
  96   96          rctlblk_t *rblk;
  97   97          uint64_t mcap;
  98   98          struct ps_prochandle *pr;
  99   99  
 100  100          if ((rblk = (rctlblk_t *)malloc(rctlblk_size())) == NULL)
 101  101                  return (UINT64_MAX);
 102  102  
 103  103          if ((pr = grab_zone_proc(zid)) == NULL) {
 104  104                  free(rblk);
 105  105                  return (UINT64_MAX);
 106  106          }
 107  107  
 108  108          if (pr_getrctl(pr, "zone.max-physical-memory", NULL, rblk,
 109  109              RCTL_FIRST)) {
 110  110                  Pdestroy_agent(pr);
 111  111                  Prelease(pr, 0);
 112  112                  free(rblk);
 113  113                  return (UINT64_MAX);
 114  114          }
 115  115  
 116  116          Pdestroy_agent(pr);
 117  117          Prelease(pr, 0);
 118  118  
 119  119          mcap = rctlblk_get_value(rblk);
 120  120          free(rblk);
 121  121          return (mcap);
 122  122  }
 123  123  
 124  124  /*
 125  125   * For zones, rcapd only caps the global zone, since each non-global zone
 126  126   * caps itself.
 127  127   */
 128  128  /* ARGSUSED */
 129  129  void
 130  130  lcollection_update_zone(lcollection_update_type_t ut,
 131  131      void(*update_notification_cb)(char *, char *, int, uint64_t, int))
 132  132  {
 133  133          int changes;
 134  134          int64_t max_rss;
 135  135          uint64_t mcap;
 136  136          lcollection_t *lcol;
 137  137          rcid_t colid;
 138  138  
 139  139          mcap = get_zone_cap(GLOBAL_ZONEID);
 140  140          if (mcap != 0 && mcap != UINT64_MAX) {
 141  141                  max_rss = ROUNDUP(mcap, 1024) / 1024;
 142  142                  gz_capped = B_TRUE;
 143  143          } else {
 144  144                  max_rss = UINT64_MAX / 1024;
 145  145                  gz_capped = B_FALSE;
 146  146          }
 147  147  
 148  148          colid.rcid_type = RCIDT_ZONE;
 149  149          colid.rcid_val = GLOBAL_ZONEID;
 150  150  
 151  151          lcol = lcollection_insert_update(&colid, max_rss, GLOBAL_ZONENAME,
 152  152              &changes);
 153  153          if (update_notification_cb != NULL)
 154  154                  update_notification_cb("zone", GLOBAL_ZONENAME, changes,
 155  155                      max_rss, (lcol != NULL) ? lcol->lcol_mark : 0);
 156  156  }
  
    | 
      ↓ open down ↓ | 
    156 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX