summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Golle2020-07-28 23:36:19 +0000
committerDaniel Golle2020-07-29 09:21:31 +0000
commit2d811a4b8816e65b89afdde92371dfef1857144c (patch)
tree74a4db3da51ae1e8b5afe762c18354f5c6ef3c54
parent12740336b315fdaccff8394d6e8538e951ad6764 (diff)
downloadprocd-2d811a4b8816e65b89afdde92371dfef1857144c.tar.gz
jail: add 'kill' method to container.%s object
Using the the current container signal method to send a signal to the jailed process works fine, as signals are being forwarded by the ujail parent process. However, in case of KILL (==9) signal, both, parent and jailed process are killed immediately which results in the 'poststop' OCI hook being skipped. Add new 'kill' method to ujail's container object to allow sending signals to the jailed process directly instead of having to send signals to the parent. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-rw-r--r--jail/jail.c39
-rw-r--r--service/service.c1
2 files changed, 39 insertions, 1 deletions
diff --git a/jail/jail.c b/jail/jail.c
index ee909f3..885a402 100644
--- a/jail/jail.c
+++ b/jail/jail.c
@@ -2279,9 +2279,48 @@ static int handle_state(struct ubus_context *ctx, struct ubus_object *obj,
return UBUS_STATUS_OK;
}
+enum {
+ CONTAINER_KILL_ATTR_SIGNAL,
+ __CONTAINER_KILL_ATTR_MAX,
+};
+
+static const struct blobmsg_policy container_kill_attrs[__CONTAINER_KILL_ATTR_MAX] = {
+ [CONTAINER_KILL_ATTR_SIGNAL] = { "signal", BLOBMSG_TYPE_INT32 },
+};
+
+static int
+container_handle_kill(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct blob_attr *tb[__CONTAINER_KILL_ATTR_MAX], *cur;
+ int sig = SIGTERM;
+
+ blobmsg_parse(container_kill_attrs, __CONTAINER_KILL_ATTR_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg));
+
+ cur = tb[CONTAINER_KILL_ATTR_SIGNAL];
+ if (cur)
+ sig = blobmsg_get_u32(cur);
+
+ if (jail_oci_state == OCI_STATE_CREATING)
+ return UBUS_STATUS_NOT_FOUND;
+
+ if (kill(jail_process.pid, sig) == 0)
+ return 0;
+
+ switch (errno) {
+ case EINVAL: return UBUS_STATUS_INVALID_ARGUMENT;
+ case EPERM: return UBUS_STATUS_PERMISSION_DENIED;
+ case ESRCH: return UBUS_STATUS_NOT_FOUND;
+ }
+
+ return UBUS_STATUS_UNKNOWN_ERROR;
+}
+
static struct ubus_method container_methods[] = {
UBUS_METHOD_NOARG("start", handle_start),
UBUS_METHOD_NOARG("state", handle_state),
+ UBUS_METHOD("kill", container_handle_kill, container_kill_attrs),
};
static struct ubus_object_type container_object_type =
diff --git a/service/service.c b/service/service.c
index 9a174bc..c2d072b 100644
--- a/service/service.c
+++ b/service/service.c
@@ -935,7 +935,6 @@ static struct ubus_method container_object_methods[] = {
UBUS_METHOD("add", service_handle_set, service_set_attrs),
UBUS_METHOD("list", service_handle_list, service_list_attrs),
UBUS_METHOD("delete", service_handle_delete, service_del_attrs),
- UBUS_METHOD("signal", service_handle_signal, service_signal_attrs),
UBUS_METHOD("state", service_handle_state, service_state_attrs),
UBUS_METHOD("console_set", container_handle_console, container_console_policy),
UBUS_METHOD("console_attach", container_handle_console, container_console_policy),