1 #define _GNU_SOURCE /* struct ucred */
7 #include <sys/resource.h>
8 #include <sys/socket.h>
17 daemon_chat(char *cmd
)
19 int s
= socket(AF_UNIX
, SOCK_STREAM
, 0);
20 struct sockaddr_un sun
= { .sun_family
= AF_UNIX
, .sun_path
= SOCKFILE
};
21 if (connect(s
, (struct sockaddr
*) &sun
, sizeof(sun
.sun_family
) + strlen(sun
.sun_path
) + 1) < 0) {
28 struct iovec iov_cmd
= {
30 .iov_len
= strlen(cmd
),
37 /* Include credentials in the message. */
43 char cbuf
[CMSG_SPACE(sizeof(cred
))];
44 msg
.msg_control
= cbuf
;
45 msg
.msg_controllen
= sizeof(cbuf
);
46 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(&msg
);
47 cmsg
->cmsg_level
= SOL_SOCKET
;
48 cmsg
->cmsg_type
= SCM_CREDENTIALS
;
49 cmsg
->cmsg_len
= CMSG_LEN(sizeof(cred
));
50 memcpy(CMSG_DATA(cmsg
), &cred
, sizeof(cred
));
52 ssize_t sent
= sendmsg(s
, &msg
, 0);
57 if ((size_t) sent
< msg
.msg_iov
->iov_len
) {
58 fprintf(stderr
, "incomplete send %zd < %zu, FIXME\n", sent
, msg
.msg_iov
->iov_len
);
65 struct iovec iov_reply
= {
67 .iov_len
= sizeof(reply
),
69 msg
.msg_iov
= &iov_reply
;
73 int replylen
= recvmsg(s
, &msg
, 0);
80 if (replylen
>= 1024) {
81 fprintf(stderr
, "too long reply from the server\n");
93 fputs("compctl - Computations under control\n\n"
94 #include "help-in-quotes"
95 "Contact <wizards@kam.mff.cuni.cz> with bug reports and comments.\n", f
);
99 run(int argc
, char *argv
[])
101 char *line
= daemon_chat("blessme");
102 if (line
[0] != '1') {
103 fprintf(stderr
, "%s\n", *line
? line
: "unexpected hangup");
109 if (setpriority(PRIO_PROCESS
, 0, COMPNICE
) < 0)
110 perror("Warning: setpriority()");
112 char *argvx
[argc
+ 1];
113 for (int i
= 0; i
< argc
; i
++)
116 execvp(argvx
[0], argvx
);
122 screen(int argc
, char *argv
[])
124 char *argvx
[argc
+ 2];
127 for (int i
= 0; i
< argc
; i
++)
128 argvx
[i
+ 2] = argv
[i
];
129 return run(argc
+ 2, argvx
);
135 char cmd
[256]; snprintf(cmd
, sizeof(cmd
), "stop %d", pid
);
136 char *line
= daemon_chat(cmd
);
137 if (line
[0] != '1') {
138 fprintf(stderr
, "%s\n", *line
? line
: "unexpected hangup");
147 char *line
= daemon_chat("stopall");
148 if (line
[0] != '1') {
149 fprintf(stderr
, "%s\n", *line
? line
: "unexpected hangup");
157 limit_mem(size_t limit
)
160 snprintf(cmd
, sizeof(cmd
), "limitmem %zu", limit
* 1048576);
161 char *line
= daemon_chat(cmd
);
162 if (line
[0] != '1') {
163 /* TODO: More error message postprocessing. */
164 fprintf(stderr
, "%s\n", *line
? line
: "unexpected hangup");
165 if (line
[0] == '0') {
166 fprintf(stderr
, "Most likely, the computations are already using too much memory.\n"
167 "Consider stopping some of them first.\n");
177 size_t usage
= cgroup_get_mem_usage(chier
, cgroup
);
178 size_t limit
= cgroup_get_mem_limit(chier
, cgroup
);
179 printf("Memory usage:\t%zuM / %zuM\n", usage
/ 1048576, limit
/ 1048576);
186 int tasks_n
= cgroup_task_list(chier
, cgroup
, &tasks
);
189 for (int i
= 0; i
< tasks_n
; i
++) {
190 /* TODO: Print process details. */
191 printf("%d\n", tasks
[i
]);
196 main(int argc
, char *argv
[])
200 if (argc
== optind
) {
205 while (argc
> optind
) {
206 char *cmd
= argv
[optind
++];
207 if (!strcmp(cmd
, "--run")) {
208 if (argc
<= optind
) {
209 fputs("missing arguments for --run\n", stderr
);
212 return run(argc
- optind
, &argv
[optind
]);
214 } else if (!strcmp(cmd
, "--screen")) {
215 if (argc
<= optind
) {
216 fputs("missing arguments for --screen\n", stderr
);
219 return screen(argc
- optind
, &argv
[optind
]);
221 } else if (!strcmp(cmd
, "--usage")) {
224 } else if (!strcmp(cmd
, "--list")) {
227 } else if (!strcmp(cmd
, "--stop")) {
228 if (argc
<= optind
) {
229 fputs("missing argument for --stop\n", stderr
);
232 stop(atoi(argv
[optind
++]));
234 } else if (!strcmp(cmd
, "--stopall")) {
237 } else if (!strcmp(cmd
, "--limitmem")) {
238 if (argc
<= optind
) {
239 fputs("missing argument for --limitmem\n", stderr
);
242 limit_mem(atol(argv
[optind
++]));
244 } else if (!strcmp(cmd
, "--help")) {