jail: add 'kill' method to container.%s object
authorDaniel Golle <daniel@makrotopia.org>
Tue, 28 Jul 2020 23:36:19 +0000 (00:36 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Wed, 29 Jul 2020 09:21:31 +0000 (10:21 +0100)
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>
jail/jail.c
service/service.c

index ee909f3483ef74c3875eb5d1d3484e40d317d0f5..885a4027433adcabec694668de5cb8c2d93f3bd1 100644 (file)
@@ -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 =
index 9a174bc7fee896d58b81473b02b8e0f9c6a671e6..c2d072be1802b16679586d647a2f3ee39df3ebc4 100644 (file)
@@ -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),