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 }