Browse Source

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>
Daniel Golle 3 years ago
parent
commit
2d811a4b88
2 changed files with 39 additions and 1 deletions
  1. 39 0
      jail/jail.c
  2. 0 1
      service/service.c

+ 39 - 0
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 =

+ 0 - 1
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),