Merge branch 'master' of mooncake.coders.se:/home/git/kore into acme

This commit is contained in:
Joris Vink 2019-10-31 14:03:57 +01:00
commit a9864c9ff7
8 changed files with 300 additions and 119 deletions

View File

@ -448,6 +448,9 @@ struct kore_alog_header {
struct kore_worker {
u_int16_t id;
u_int16_t cpu;
#if defined(__linux__)
int tracing;
#endif
pid_t pid;
int pipe[2];
struct connection *msg[2];

View File

@ -158,12 +158,17 @@
KORE_FILTER_LEN(_scfilt)); \
}
extern int kore_seccomp_tracing;
void kore_seccomp_init(void);
void kore_seccomp_drop(void);
void kore_seccomp_enable(void);
void kore_seccomp_traceme(void);
int kore_seccomp_syscall_resolve(const char *);
int kore_seccomp_trace(struct kore_worker *, int);
int kore_seccomp_filter(const char *, void *, size_t);
const char *kore_seccomp_syscall_name(long);
struct sock_filter *kore_seccomp_syscall_filter(const char *, int);
struct sock_filter *kore_seccomp_syscall_arg(const char *, int, int, int);
struct sock_filter *kore_seccomp_syscall_flag(const char *, int, int, int);

View File

@ -20,6 +20,11 @@ else
CFLAGS+=-O2
endif
ifneq ("$(MINIMAL)", "")
CFLAGS+=-DKODEV_MINIMAL
LDFLAGS=
endif
OSNAME=$(shell uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
ifeq ("$(OSNAME)", "darwin")
CFLAGS+=-I/opt/local/include/ -I/usr/local/opt/openssl/include

View File

@ -22,9 +22,11 @@
#include <sys/mman.h>
#include <sys/time.h>
#if !defined(KODEV_MINIMAL)
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#endif
#include <ctype.h>
#include <errno.h>
@ -141,7 +143,6 @@ static void fatal(const char *, ...) __attribute__((noreturn));
static void cli_file_close(int);
static void cli_run_kore(void);
static void cli_run_kore_python(void);
static void cli_generate_certs(void);
static void cli_compile_kore(void *);
static void cli_link_application(void *);
static void cli_compile_source_file(void *);
@ -164,7 +165,6 @@ static void cli_write_asset(const char *, const char *,
struct buildopt *);
static void cli_register_kore_file(char *, struct dirent *);
static void cli_register_source_file(char *, struct dirent *);
static void cli_file_create(const char *, const char *, size_t);
static int cli_file_requires_build(struct stat *, const char *);
static void cli_find_files(const char *,
void (*cb)(char *, struct dirent *));
@ -197,10 +197,11 @@ static void cli_help(int, char **);
static void cli_info(int, char **);
static void cli_build(int, char **);
static void cli_clean(int, char **);
static void cli_create(int, char **);
static void cli_reload(int, char **);
static void cli_flavor(int, char **);
#if !defined(KODEV_MINIMAL)
static void cli_create(int, char **);
static void cli_create_help(void);
static void file_create_src(void);
@ -209,6 +210,10 @@ static void file_create_gitignore(void);
static void file_create_python_src(void);
static void file_create_python_config(void);
static void cli_generate_certs(void);
static void cli_file_create(const char *, const char *, size_t);
#endif
static struct cmd cmds[] = {
{ "help", "this help text", cli_help },
{ "run", "run an application (-fnr implied)", cli_run },
@ -216,11 +221,14 @@ static struct cmd cmds[] = {
{ "info", "show info on kore on this system", cli_info },
{ "build", "build an application", cli_build },
{ "clean", "cleanup the build files", cli_clean },
#if !defined(KODEV_MINIMAL)
{ "create", "create a new application skeleton", cli_create },
#endif
{ "flavor", "switch between build flavors", cli_flavor },
{ NULL, NULL, NULL }
};
#if !defined(KODEV_MINIMAL)
static struct filegen gen_files[] = {
{ file_create_src },
{ file_create_config },
@ -370,6 +378,8 @@ static const char *dh2048_data =
static const char *gitignore = "*.o\n.flavor\n.objs\n%s.so\nassets.h\ncert\n";
#endif /* !KODEV_MINIMAL */
static int s_fd = -1;
static char *appl = NULL;
static int run_after = 0;
@ -399,6 +409,9 @@ usage(void)
int i;
fprintf(stderr, "Usage: kodev [command]\n");
#if defined(KODEV_MINIMAL)
fprintf(stderr, "minimal (only build commands supported)\n");
#endif
fprintf(stderr, "\nAvailable commands:\n");
for (i = 0; cmds[i].name != NULL; i++)
@ -457,6 +470,7 @@ cli_help(int argc, char **argv)
usage();
}
#if !defined(KODEV_MINIMAL)
static void
cli_create_help(void)
{
@ -529,6 +543,7 @@ cli_create(int argc, char **argv)
printf("WARNING: DO NOT USE THE GENERATED DH PARAMETERS "
"AND CERTIFICATES IN PRODUCTION\n");
}
#endif
static void
cli_flavor(int argc, char **argv)
@ -572,13 +587,17 @@ cli_flavor(int argc, char **argv)
static void
cli_build(int argc, char **argv)
{
#if !defined(KODEV_MINIMAL)
int l;
char *data;
#endif
struct dirent dp;
struct cfile *cf;
struct buildopt *bopt;
struct timeval times[2];
char *build_path;
int requires_relink, l;
char *sofile, *config, *data;
int requires_relink;
char *sofile, *config;
char *assets_path, *p, *src_path;
char pwd[PATH_MAX], *assets_header;
@ -614,11 +633,14 @@ cli_build(int argc, char **argv)
cli_flavor_load();
bopt = cli_buildopt_new("_default");
#if !defined(KODEV_MINIMAL)
if (!cli_file_exists(build_path)) {
l = cli_vasprintf(&data, build_data, appl);
cli_file_create("conf/build.conf", data, l);
free(data);
}
#endif
cli_find_files(src_path, cli_register_source_file);
free(src_path);
@ -695,6 +717,7 @@ cli_build(int argc, char **argv)
free(assets_header);
#if !defined(KODEV_MINIMAL)
if (bopt->kore_flavor == NULL ||
!strstr(bopt->kore_flavor, "NOTLS=1")) {
if (!cli_dir_exists("cert")) {
@ -702,6 +725,7 @@ cli_build(int argc, char **argv)
cli_generate_certs();
}
}
#endif
if (bopt->single_binary) {
requires_relink++;
@ -817,6 +841,7 @@ cli_info(int argc, char **argv)
}
}
#if !defined(KODEV_MINIMAL)
static void
file_create_python_src(void)
{
@ -885,6 +910,7 @@ file_create_gitignore(void)
free(name);
free(data);
}
#endif
static void
cli_mkdir(const char *fpath, int mode)
@ -1024,6 +1050,7 @@ cli_file_write(int fd, const void *buf, size_t len)
}
}
#if !defined(KODEV_MINIMAL)
static void
cli_file_create(const char *name, const char *data, size_t len)
{
@ -1035,6 +1062,7 @@ cli_file_create(const char *name, const char *data, size_t len)
printf("created %s\n", name);
}
#endif
static void
cli_write_asset(const char *n, const char *e, struct buildopt *bopt)
@ -1042,7 +1070,10 @@ cli_write_asset(const char *n, const char *e, struct buildopt *bopt)
cli_file_writef(s_fd, "extern const u_int8_t asset_%s_%s[];\n", n, e);
cli_file_writef(s_fd, "extern const u_int32_t asset_len_%s_%s;\n", n, e);
cli_file_writef(s_fd, "extern const time_t asset_mtime_%s_%s;\n", n, e);
#if !defined(KODEV_MINIMAL)
cli_file_writef(s_fd, "extern const char *asset_sha256_%s_%s;\n", n, e);
#endif
if (bopt->flavor_nohttp == 0) {
cli_file_writef(s_fd,
@ -1053,17 +1084,21 @@ cli_write_asset(const char *n, const char *e, struct buildopt *bopt)
static void
cli_build_asset(char *fpath, struct dirent *dp)
{
u_int8_t *d;
struct stat st;
#if !defined(KODEV_MINIMAL)
SHA256_CTX sctx;
int i, len;
struct mime_type *mime;
const char *mime_type;
u_int8_t digest[SHA256_DIGEST_LENGTH];
char hash[(SHA256_DIGEST_LENGTH * 2) + 1];
#endif
off_t off;
void *base;
struct mime_type *mime;
struct buildopt *bopt;
const char *mime_type;
int in, out, i, len;
u_int8_t *d, digest[SHA256_DIGEST_LENGTH];
int in, out;
char *cpath, *ext, *opath, *p, *name;
char hash[(SHA256_DIGEST_LENGTH * 2) + 1];
bopt = cli_buildopt_default();
@ -1145,6 +1180,7 @@ cli_build_asset(char *fpath, struct dirent *dp)
*/
cli_file_writef(out, "0x00");
#if !defined(KODEV_MINIMAL)
/* Calculate the SHA256 digest of the contents. */
(void)SHA256_Init(&sctx);
(void)SHA256_Update(&sctx, base, st.st_size);
@ -1167,6 +1203,7 @@ cli_build_asset(char *fpath, struct dirent *dp)
mime_type = mime->type;
else
mime_type = "text/plain";
#endif
/* Add the meta data. */
cli_file_writef(out, "};\n\n");
@ -1176,6 +1213,7 @@ cli_build_asset(char *fpath, struct dirent *dp)
"const time_t asset_mtime_%s_%s = %" PRI_TIME_T ";\n",
name, ext, st.st_mtime);
#if !defined(KODEV_MINIMAL)
if (bopt->flavor_nohttp == 0) {
cli_file_writef(out,
"const char *asset_sha256_%s_%s = \"\\\"%s\\\"\";\n",
@ -1183,6 +1221,7 @@ cli_build_asset(char *fpath, struct dirent *dp)
cli_file_writef(out, http_serveable_function,
name, ext, name, ext, name, ext, name, ext, mime_type);
}
#endif
/* Write the file symbols into assets.h so they can be used. */
cli_write_asset(name, ext, bopt);
@ -1321,6 +1360,7 @@ cli_find_files(const char *path, void (*cb)(char *, struct dirent *))
closedir(d);
}
#if !defined(KODEV_MINIMAL)
static void
cli_generate_certs(void)
{
@ -1414,6 +1454,7 @@ cli_generate_certs(void)
EVP_PKEY_free(pkey);
X509_free(x509);
}
#endif
static void
cli_compile_source_file(void *arg)

View File

@ -49,6 +49,10 @@
#include "acme.h"
#endif
#if defined(__linux__)
#include "seccomp.h"
#endif
/* XXX - This is becoming a clusterfuck. Fix it. */
static int configure_load(char *);
@ -154,6 +158,10 @@ static int configure_curl_timeout(char *);
static int configure_curl_recv_max(char *);
#endif
#if defined(__linux__)
static int configure_seccomp_tracing(char *);
#endif
static struct {
const char *name;
int (*configure)(char *);
@ -224,6 +232,9 @@ static struct {
#if defined(KORE_USE_PLATFORM_PLEDGE)
{ "pledge", configure_add_pledge },
#endif
#if defined(__linux__)
{ "seccomp_tracing", configure_seccomp_tracing },
#endif
#if !defined(KORE_NO_HTTP)
{ "filemap_ext", configure_filemap_ext },
{ "filemap_index", configure_filemap_index },
@ -1825,3 +1836,21 @@ configure_curl_timeout(char *option)
return (KORE_RESULT_OK);
}
#endif
#if defined(__linux__)
static int
configure_seccomp_tracing(char *opt)
{
if (!strcmp(opt, "yes")) {
kore_seccomp_tracing = 1;
} else if (!strcmp(opt, "no")) {
kore_seccomp_tracing = 0;
} else {
printf("bad seccomp_tracing value: %s (expected yes|no)\n",
opt);
return (KORE_RESULT_ERROR);
}
return (KORE_RESULT_OK);
}
#endif

View File

@ -498,6 +498,7 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object)
switch (ch) {
case '}':
json->offset++;
ret = KORE_RESULT_OK;
goto cleanup;
case '"':
@ -589,6 +590,7 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array)
goto cleanup;
if (ch == ']') {
json->offset++;
ret = KORE_RESULT_OK;
goto cleanup;
}

View File

@ -17,7 +17,9 @@
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/epoll.h>
#include <sys/ptrace.h>
#include <sys/prctl.h>
#include <sys/reg.h>
#include <sys/syscall.h>
#include <linux/seccomp.h>
@ -36,12 +38,8 @@
#endif
#if !defined(SECCOMP_KILL_POLICY)
#if defined(KORE_DEBUG)
#define SECCOMP_KILL_POLICY SECCOMP_RET_TRAP
#else
#define SECCOMP_KILL_POLICY SECCOMP_RET_KILL
#endif
#endif
/*
* The bare minimum to be able to run kore. These are added last and can
@ -140,9 +138,7 @@ static struct sock_filter *seccomp_filter_update(struct sock_filter *,
#define filter_prologue_len KORE_FILTER_LEN(filter_prologue)
#define filter_epilogue_len KORE_FILTER_LEN(filter_epilogue)
#if defined(KORE_DEBUG)
static void seccomp_trap(int sig, siginfo_t *, void *);
#endif
static void seccomp_register_violation(struct kore_worker *);
struct filter {
char *name;
@ -154,6 +150,12 @@ struct filter {
static TAILQ_HEAD(, filter) filters;
static struct filter *ufilter = NULL;
/*
* If enabled will instruct the parent process to ptrace its children and
* log any seccomp SECCOMP_RET_TRACE rule.
*/
int kore_seccomp_tracing = 0;
void
kore_seccomp_init(void)
{
@ -181,26 +183,20 @@ kore_seccomp_drop(void)
void
kore_seccomp_enable(void)
{
#if defined(KORE_DEBUG)
struct sigaction sa;
#endif
struct sock_filter *sf;
struct sock_fprog prog;
struct kore_runtime_call *rcall;
struct filter *filter;
size_t prog_len, off, i;
#if defined(KORE_DEBUG)
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = seccomp_trap;
if (sigfillset(&sa.sa_mask) == -1)
fatalx("sigfillset: %s", errno_s);
if (sigaction(SIGSYS, &sa, NULL) == -1)
fatalx("sigaction: %s", errno_s);
#endif
/*
* If kore_seccomp_tracing is turned on, set the default policy to
* SECCOMP_RET_TRACE so we can log the system calls.
*/
if (kore_seccomp_tracing) {
filter_epilogue[0].k = SECCOMP_RET_TRACE;
kore_log(LOG_NOTICE, "seccomp tracing enabled");
}
#if defined(KORE_USE_PYTHON)
ufilter = TAILQ_FIRST(&filters);
@ -243,10 +239,6 @@ kore_seccomp_enable(void)
TAILQ_FOREACH(filter, &filters, list) {
for (i = 0; i < filter->instructions; i++)
sf[off++] = filter->prog[i];
#if defined(KORE_DEBUG)
kore_log(LOG_INFO,
"seccomp filter '%s' added", filter->name);
#endif
}
for (i = 0; i < filter_epilogue_len; i++)
@ -292,6 +284,55 @@ kore_seccomp_filter(const char *name, void *prog, size_t len)
return (KORE_RESULT_OK);
}
void
kore_seccomp_traceme(void)
{
if (kore_seccomp_tracing == 0)
return;
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1)
fatalx("ptrace. %s", errno_s);
if (kill(worker->pid, SIGSTOP) == -1)
fatalx("kill: %s", errno_s);
}
int
kore_seccomp_trace(struct kore_worker *kw, int status)
{
if (kore_seccomp_tracing == 0)
return (KORE_RESULT_ERROR);
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP) {
if (kw->tracing == 0) {
kw->tracing = 1;
if (ptrace(PTRACE_SETOPTIONS, kw->pid, NULL,
PTRACE_O_TRACESECCOMP) == -1)
fatal("ptrace: %s", errno_s);
if (ptrace(PTRACE_CONT, kw->pid, NULL, NULL) == -1)
fatal("ptrace: %s", errno_s);
}
return (KORE_RESULT_OK);
}
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
if ((status >> 8) ==
(SIGTRAP | (PTRACE_EVENT_SECCOMP << 8)))
seccomp_register_violation(kw);
if (ptrace(PTRACE_CONT, kw->pid, NULL, NULL) == -1)
fatal("ptrace: %s", errno_s);
return (KORE_RESULT_OK);
}
if (WIFSTOPPED(status) && kw->tracing) {
if (ptrace(PTRACE_CONT, kw->pid, NULL, WSTOPSIG(status)) == -1)
fatal("ptrace: %s", errno_s);
return (KORE_RESULT_OK);
}
return (KORE_RESULT_ERROR);
}
int
kore_seccomp_syscall_resolve(const char *name)
{
@ -305,6 +346,19 @@ kore_seccomp_syscall_resolve(const char *name)
return (-1);
}
const char *
kore_seccomp_syscall_name(long sysnr)
{
int i;
for (i = 0; kore_syscall_map[i].name != NULL; i++) {
if (kore_syscall_map[i].nr == sysnr)
return (kore_syscall_map[i].name);
}
return ("unknown");
}
struct sock_filter *
kore_seccomp_syscall_filter(const char *name, int action)
{
@ -349,13 +403,18 @@ kore_seccomp_syscall_flag(const char *name, int action, int arg, int value)
return (seccomp_filter_update(filter, name, KORE_FILTER_LEN(filter)));
}
#if defined(KORE_DEBUG)
static void
seccomp_trap(int sig, siginfo_t *info, void *ucontext)
seccomp_register_violation(struct kore_worker *kw)
{
kore_log(LOG_INFO, "sandbox violation - syscall=%d", info->si_syscall);
long sysnr;
if ((sysnr = ptrace(PTRACE_PEEKUSER, kw->pid,
sizeof(long) * ORIG_RAX, NULL)) == -1)
fatal("ptrace: %s", errno_s);
kore_log(LOG_INFO, "seccomp violation, worker=%d, syscall=%s",
kw->id, kore_seccomp_syscall_name(sysnr));
}
#endif
static struct sock_filter *
seccomp_filter_update(struct sock_filter *filter, const char *name, size_t elm)

View File

@ -55,6 +55,10 @@
#include "curl.h"
#endif
#if defined(__linux__)
#include "seccomp.h"
#endif
#if !defined(WAIT_ANY)
#define WAIT_ANY (-1)
#endif
@ -72,6 +76,7 @@ struct wlock {
static int worker_trylock(void);
static void worker_unlock(void);
static void worker_reaper(pid_t, int);
static inline int worker_acceptlock_obtain(void);
static inline void worker_acceptlock_release(void);
@ -220,7 +225,19 @@ kore_worker_shutdown(void)
pid = waitpid(kw->pid, &status, 0);
if (pid == -1)
continue;
kw->pid = 0;
#if defined(__linux__)
kore_seccomp_trace(kw, status);
#endif
if (WIFEXITED(status)) {
kw->pid = 0;
if (!kore_quiet) {
kore_log(LOG_NOTICE,
"worker %d exited", kw->id);
}
}
}
}
@ -332,6 +349,10 @@ kore_worker_entry(struct kore_worker *kw)
worker = kw;
#if defined(__linux__)
kore_seccomp_traceme();
#endif
switch (kw->id) {
case KORE_WORKER_KEYMGR:
(void)snprintf(buf, sizeof(buf), "[keymgr]");
@ -523,6 +544,7 @@ kore_worker_entry(struct kore_worker *kw)
kore_free(rcall);
}
kore_msg_send(KORE_MSG_PARENT, KORE_MSG_SHUTDOWN, NULL, 0);
kore_server_cleanup();
kore_platform_event_cleanup();
@ -551,10 +573,7 @@ kore_worker_entry(struct kore_worker *kw)
void
kore_worker_reap(void)
{
u_int16_t idx;
pid_t pid;
struct kore_worker *kw;
const char *func;
int status;
for (;;) {
@ -570,83 +589,10 @@ kore_worker_reap(void)
return;
}
break;
}
if (pid == 0)
return;
if (pid == 0)
return;
for (idx = 0; idx < worker_count; idx++) {
kw = WORKER(idx);
if (kw->pid != pid)
continue;
if (!kore_quiet) {
kore_log(LOG_NOTICE,
"worker %d (%d) exited with status %d",
kw->id, pid, status);
}
func = "none";
#if !defined(KORE_NO_HTTP)
if (kw->active_hdlr != NULL)
func = kw->active_hdlr->func;
#endif
kore_log(LOG_NOTICE,
"worker %d (pid: %d) (hdlr: %s) gone",
kw->id, kw->pid, func);
#if defined(__linux__)
if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSYS) {
kore_log(LOG_NOTICE,
"worker %d died from sandbox violation", kw->id);
}
#endif
if (kw->id == KORE_WORKER_KEYMGR ||
kw->id == KORE_WORKER_ACME) {
kore_log(LOG_CRIT,
"keymgr or acme process gone, stopping");
kw->pid = 0;
if (raise(SIGTERM) != 0) {
kore_log(LOG_WARNING,
"failed to raise SIGTERM signal");
}
break;
}
if (kw->pid == accept_lock->current &&
worker_no_lock == 0)
worker_unlock();
#if !defined(KORE_NO_HTTP)
if (kw->active_hdlr != NULL) {
kw->active_hdlr->errors++;
kore_log(LOG_NOTICE,
"hdlr %s has caused %d error(s)",
kw->active_hdlr->func,
kw->active_hdlr->errors);
}
#endif
if (worker_policy == KORE_WORKER_POLICY_TERMINATE) {
kw->pid = 0;
kore_log(LOG_NOTICE,
"worker policy is 'terminate', stopping");
if (raise(SIGTERM) != 0) {
kore_log(LOG_WARNING,
"failed to raise SIGTERM signal");
}
break;
}
kore_log(LOG_NOTICE, "restarting worker %d", kw->id);
kw->restarted = 1;
kore_msg_parent_remove(kw);
kore_worker_spawn(idx, kw->id, kw->cpu);
kore_msg_parent_add(kw);
break;
worker_reaper(pid, status);
}
}
@ -720,6 +666,97 @@ kore_worker_keymgr_response_verify(struct kore_msg *msg, const void *data,
return (KORE_RESULT_OK);
}
static void
worker_reaper(pid_t pid, int status)
{
u_int16_t id;
struct kore_worker *kw;
const char *func;
for (id = 0; id < worker_count; id++) {
kw = WORKER(id);
if (kw->pid != pid)
continue;
#if defined(__linux__)
if (kore_seccomp_trace(kw, status))
break;
#endif
if (!kore_quiet) {
kore_log(LOG_NOTICE,
"worker %d (%d) exited with status %d",
kw->id, pid, status);
}
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
kw->pid = 0;
break;
}
func = "none";
#if !defined(KORE_NO_HTTP)
if (kw->active_hdlr != NULL)
func = kw->active_hdlr->func;
#endif
kore_log(LOG_NOTICE,
"worker %d (pid: %d) (hdlr: %s) gone",
kw->id, kw->pid, func);
#if defined(__linux__)
if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSYS) {
kore_log(LOG_NOTICE,
"worker %d died from sandbox violation", kw->id);
}
#endif
if (kw->id == KORE_WORKER_KEYMGR ||
kw->id == KORE_WORKER_ACME) {
kore_log(LOG_CRIT,
"keymgr or acme process gone, stopping");
kw->pid = 0;
if (raise(SIGTERM) != 0) {
kore_log(LOG_WARNING,
"failed to raise SIGTERM signal");
}
break;
}
if (kw->pid == accept_lock->current &&
worker_no_lock == 0)
worker_unlock();
#if !defined(KORE_NO_HTTP)
if (kw->active_hdlr != NULL) {
kw->active_hdlr->errors++;
kore_log(LOG_NOTICE,
"hdlr %s has caused %d error(s)",
kw->active_hdlr->func,
kw->active_hdlr->errors);
}
#endif
if (worker_policy == KORE_WORKER_POLICY_TERMINATE) {
kw->pid = 0;
kore_log(LOG_NOTICE,
"worker policy is 'terminate', stopping");
if (raise(SIGTERM) != 0) {
kore_log(LOG_WARNING,
"failed to raise SIGTERM signal");
}
break;
}
kore_log(LOG_NOTICE, "restarting worker %d", kw->id);
kw->restarted = 1;
kore_msg_parent_remove(kw);
kore_worker_spawn(idx, kw->id, kw->cpu);
kore_msg_parent_add(kw);
break;
}
}
static inline void
worker_acceptlock_release(void)
{