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 }