1 #include <sys/types.h>
   2 #include <sys/stat.h>
   3 #include <fcntl.h>
   4 #include <stdio.h>
   5 #include <stdlib.h>
   6 #include <string.h>
   7 #include <errno.h>
   8 #include <locale.h>
   9 #include <stddef.h>
  10 #include <limits.h>
  11 #include <rctl.h>
  12 #include <regex.h>
  13 #include <ctype.h>
  14 #include <zone.h>
  15 #include <pool.h>
  16 #include <sys/pool_impl.h>
  17 #include <unistd.h>
  18 #include <stropts.h>
  19 
  20 #include "util.h"
  21 #include "resctl.h"
  22 
  23 sig_t sigs[SIGS_CNT] = {
  24         /* Signal names */
  25         {"ABRT", RESCTL_SIG_ABRT},
  26         {"XRES", RESCTL_SIG_XRES},
  27         {"HUP",  RESCTL_SIG_HUP},
  28         {"STOP", RESCTL_SIG_STOP},
  29         {"TERM", RESCTL_SIG_TERM},
  30         {"KILL", RESCTL_SIG_KILL},
  31         {"XFSZ", RESCTL_SIG_XFSZ},
  32         {"XCPU", RESCTL_SIG_XCPU},
  33 
  34         /* Singnal numbers */
  35         {"6",  RESCTL_SIG_ABRT},
  36         {"38", RESCTL_SIG_XRES},
  37         {"1",  RESCTL_SIG_HUP},
  38         {"23", RESCTL_SIG_STOP},
  39         {"15", RESCTL_SIG_TERM},
  40         {"9",  RESCTL_SIG_KILL},
  41         {"31", RESCTL_SIG_XFSZ},
  42         {"30", RESCTL_SIG_XCPU},
  43 };
  44 
  45 /*
  46  * Check the existance of a resource pool in the system
  47  */
  48 int
  49 resctl_pool_exist(char *name)
  50 {
  51         pool_conf_t *conf;
  52         pool_status_t status;
  53         int fd;
  54 
  55         /*
  56          * Determine if pools are enabled using /dev/pool, as
  57          * libpool may not be present.
  58          */
  59         if (getzoneid() != GLOBAL_ZONEID ||
  60             (fd = open("/dev/pool", O_RDONLY)) < 0) {
  61                 return (1);
  62         }
  63 
  64         if (ioctl(fd, POOL_STATUS, &status) < 0) {
  65                 (void) close(fd);
  66                 return (1);
  67         }
  68 
  69         (void) close(fd);
  70 
  71         if (status.ps_io_state != 1)
  72                 return (1);
  73 
  74         /* If pools are enabled, assume libpool is present. */
  75         if ((conf = pool_conf_alloc()) == NULL)
  76                 return (1);
  77 
  78         if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)) {
  79                 pool_conf_free(conf);
  80                 return (1);
  81         }
  82 
  83         if (pool_get_pool(conf, name) == NULL) {
  84                 (void) pool_conf_close(conf);
  85                 pool_conf_free(conf);
  86                 return (1);
  87         }
  88 
  89         (void) pool_conf_close(conf);
  90         pool_conf_free(conf);
  91         return (0);
  92 }
  93 
  94 int
  95 resctl_get_info(char *name, resctl_info_t *pinfo)
  96 {
  97         rctlblk_t *blk1, *blk2, *tmp;
  98         rctl_priv_t priv;
  99         int ret = 1;
 100 
 101         blk1 = blk2 = tmp = NULL;
 102         blk1 = util_safe_malloc(rctlblk_size());
 103         blk2 = util_safe_malloc(rctlblk_size());
 104 
 105         if (getrctl(name, NULL, blk1, RCTL_FIRST) == 0) {
 106                 priv = rctlblk_get_privilege(blk1);
 107                 while (priv != RCPRIV_SYSTEM) {
 108                         tmp = blk2;
 109                         blk2 = blk1;
 110                         blk1 = tmp;
 111                         if (getrctl(name, blk2, blk1, RCTL_NEXT) != 0) {
 112                                 goto out;
 113                         }
 114                         priv = rctlblk_get_privilege(blk1);
 115                 }
 116 
 117                 pinfo->value = rctlblk_get_value(blk1);
 118                 pinfo->flags = rctlblk_get_global_flags(blk1);
 119                 ret = 0;
 120         }
 121 
 122 out:
 123         free(blk1);
 124         free(blk2);
 125         return (ret);
 126 }
 127 
 128 void
 129 resctl_get_rule(resctl_info_t *pinfo, resctlrule_t *prule)
 130 {
 131 
 132         prule->resctl_max = pinfo->value;
 133         if (pinfo->flags & RCTL_GLOBAL_BYTES) {
 134                 prule->resctl_type = RESCTL_TYPE_BYTES;
 135         } else if (pinfo->flags & RCTL_GLOBAL_SECONDS) {
 136                 prule->resctl_type = RESCTL_TYPE_SCNDS;
 137         } else if (pinfo->flags & RCTL_GLOBAL_COUNT) {
 138                 prule->resctl_type = RESCTL_TYPE_COUNT;
 139         } else {
 140                 prule->resctl_type = RESCTL_TYPE_UNKWN;
 141         }
 142 
 143         if (pinfo->flags & RCTL_GLOBAL_NOBASIC) {
 144                 prule->resctl_privs = RESCTL_PRIV_PRIVE | RESCTL_PRIV_PRIVD;
 145         } else {
 146                 prule->resctl_privs = RESCTL_PRIV_ALLPR;
 147         }
 148 
 149         if (pinfo->flags & RCTL_GLOBAL_DENY_ALWAYS) {
 150                 prule->resctl_action = RESCTL_ACTN_DENY;
 151         } else if (pinfo->flags & RCTL_GLOBAL_DENY_NEVER) {
 152                 prule->resctl_action = RESCTL_ACTN_NONE;
 153         } else {
 154                 prule->resctl_action = RESCTL_ACTN_NONE | RESCTL_ACTN_DENY;
 155         }
 156 
 157         if (pinfo->flags & RCTL_GLOBAL_SIGNAL_NEVER) {
 158                 prule->resctl_sigs = 0;
 159         } else {
 160                 prule->resctl_action |= RESCTL_ACTN_SIGN;
 161                 prule->resctl_sigs = RESCTL_SIG_CMN;
 162                 if (pinfo->flags & RCTL_GLOBAL_CPU_TIME) {
 163                         prule->resctl_sigs |= RESCTL_SIG_XCPU;
 164                 }
 165                 if (pinfo->flags & RCTL_GLOBAL_FILE_SIZE) {
 166                         prule->resctl_sigs |= RESCTL_SIG_XFSZ;
 167                 }
 168         }
 169 }