in storm-core/src/native/worker-launcher/impl/oci/oci.c [700:798]
static void exec_runc(const char* container_id, const char* runc_config_path,
const char* pid_file_path, const char* worker_artifacts_dir) {
char* runc_path = get_value(OCI_RUNC_CONFIG_KEY);
if (runc_path == NULL) {
runc_path = strdup(DEFAULT_OCI_RUNC);
if (runc_path == NULL) {
fputs("ERROR: Unable to allocate memory in exec_runc\n", ERRORFILE);
exit(1);
}
}
char* dir_end = strrchr(runc_config_path, '/');
if (dir_end == NULL) {
fprintf(ERRORFILE, "ERROR: Error getting bundle path from config path %s\n",
runc_config_path);
exit(1);
}
char* bundle_path = strndup(runc_config_path, dir_end - runc_config_path);
//We must use runc detached mode so that
//the worker process can stay alive when the supervisor dies
const char* const runc_args[] = {
runc_path, "run",
"-d",
"--pid-file", pid_file_path,
"-b", bundle_path,
container_id,
NULL
};
const char* const runc_env[] = { NULL };
int i;
fprintf(LOGFILE, "command: ");
for (i = 0; runc_args[i] != NULL; i++) {
fprintf(LOGFILE, "%s ", runc_args[i]);
}
fputs("\n", LOGFILE);
fflush(LOGFILE);
//runc detached mode gives up the control of stdio to the calling process
//The calling process will hang until the runc container terminates if it reads runc container's stdout
//We redirect the stdout and stderr to files as a workaround.
//There maybe a better way to solve this problem.
char* runc_out_file = concatenate("%s/runc-%s.out", "runc out file", 2, worker_artifacts_dir, container_id);
char* runc_err_file = concatenate("%s/runc-%s.err", "runc err file", 2, worker_artifacts_dir, container_id);
int fd_out = open(runc_out_file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (fd_out == -1) {
fprintf(ERRORFILE, "ERROR: Failed to open %s\n", runc_out_file);
exit(ERROR_OPENING_FILE);
}
int fd_err = open(runc_err_file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (fd_err == -1) {
fprintf(ERRORFILE, "ERROR: Failed to open %s\n", runc_err_file);
exit(ERROR_OPENING_FILE);
}
fprintf(LOGFILE, "Redirecting STDOUT and STDERR to %s and %s\n", runc_out_file, runc_err_file);
//Flush everything before redirection
fflush(LOGFILE);
fflush(ERRORFILE);
int save_out = dup(fileno(stdout));
int save_err = dup(fileno(stderr));
if (dup2(fd_out, fileno(stdout)) == -1) {
fprintf(ERRORFILE, "ERROR: Failed to redirect STDOUT to %s\n", runc_out_file);
exit(1);
}
if (dup2(fd_err, fileno(stderr)) == -1) {
fprintf(ERRORFILE, "ERROR: Failed to redirect STDERR to %s\n", runc_err_file);
exit(1);
}
if (execve(runc_path, (char* const*)runc_args, (char* const*)runc_env) == -1) {
char* errstr = strerror(errno);
//restore STDOUT and STDERR redirection
fflush(stdout);
fflush(stderr);
close(fd_out);
close(fd_err);
dup2(save_out, fileno(stdout));
dup2(save_err, fileno(stderr));
close(save_out);
close(save_err);
fputs("ERROR: Failed to exec:", ERRORFILE);
const char* const* argp;
for (argp = runc_args; *argp != NULL; ++argp) {
fprintf(ERRORFILE, " %s", *argp);
}
fprintf(ERRORFILE, " : %s\n", errstr);
free(runc_path);
}
exit(ERROR_OCI_RUN_FAILED);
}