summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Golle2020-07-29 12:49:38 +0000
committerDaniel Golle2020-07-30 15:40:32 +0000
commit47a9f0d652678a0994595095de6e15f980cb37d3 (patch)
treec7500f3f6850315b302172c29218c9bf1548b988
parent2ae5cbcf1d4509837a16eceafca374e9bf0ea850 (diff)
downloadprocd-47a9f0d652678a0994595095de6e15f980cb37d3.tar.gz
service: add method to query available container features
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-rw-r--r--service/service.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/service/service.c b/service/service.c
index c2d072b..cabc69c 100644
--- a/service/service.c
+++ b/service/service.c
@@ -14,7 +14,12 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
#include <unistd.h>
+#include <sched.h>
#include <libubox/blobmsg_json.h>
#include <libubox/avl-cmp.h>
@@ -297,6 +302,97 @@ static inline bool is_container_obj(struct ubus_object *obj)
return (obj && (strcmp(obj->name, "container") == 0));
}
+static inline void put_namespace(struct blob_buf *b, char *name)
+{
+ char nsfname[32];
+ struct stat statbuf;
+
+ snprintf(nsfname, sizeof(nsfname), "/proc/self/ns/%s", name);
+
+ if (!stat(nsfname, &statbuf))
+ blobmsg_add_string(b, NULL, name);
+}
+
+static void put_cgroups(struct blob_buf *b)
+{
+ int fd, ret;
+ static char buf[512] = "";
+ char *t, *z;
+
+ fd = open("/sys/fs/cgroup/cgroup.controllers", O_RDONLY);
+ if (fd == -1)
+ return;
+
+ ret = read(fd, &buf, sizeof(buf));
+ close(fd);
+
+ if (ret < 2)
+ return;
+
+ t = buf;
+ while(t) {
+ z = t;
+ /* replace space with \0 and direct next entry */
+ t = strchr(z, ' ');
+ if (t) {
+ *(t++) = '\0';
+ } else { /* replace trailing new-line with \0 */
+ t = strchr(z, '\n');
+ if (!t) /* shouldn't happen, but don't segfault if it does */
+ break;
+
+ *t = '\0';
+ t = NULL;
+ }
+ blobmsg_add_string(b, NULL, z);
+ }
+}
+
+static int
+container_handle_features(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct utsname utsbuf;
+ struct stat statbuf;
+ void *nsarray, *cgarray;
+
+ if (stat("/sbin/ujail", &statbuf))
+ return UBUS_STATUS_NOT_SUPPORTED;
+
+ if (uname(&utsbuf) < 0)
+ return UBUS_STATUS_UNKNOWN_ERROR;
+
+ blob_buf_init(&b, 0);
+ blobmsg_add_string(&b, "machine", utsbuf.machine);
+
+#ifdef SECCOMP_SUPPORT
+ blobmsg_add_u8(&b, "seccomp", true);
+#else
+ blobmsg_add_u8(&b, "seccomp", false);
+#endif
+
+ cgarray = blobmsg_open_array(&b, "cgroup");
+ put_cgroups(&b);
+ blobmsg_close_array(&b, cgarray);
+
+ nsarray = blobmsg_open_array(&b, "namespaces");
+ put_namespace(&b, "cgroup");
+ put_namespace(&b, "ipc");
+ put_namespace(&b, "mnt");
+ put_namespace(&b, "net");
+ put_namespace(&b, "pid");
+#ifdef CLONE_NEWTIME
+ put_namespace(&b, "time");
+#endif
+ put_namespace(&b, "user");
+ put_namespace(&b, "uts");
+ blobmsg_close_array(&b, nsarray);
+ ubus_send_reply(ctx, req, b.head);
+
+ return UBUS_STATUS_OK;
+}
+
static int
service_handle_set(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
@@ -936,6 +1032,7 @@ static struct ubus_method container_object_methods[] = {
UBUS_METHOD("list", service_handle_list, service_list_attrs),
UBUS_METHOD("delete", service_handle_delete, service_del_attrs),
UBUS_METHOD("state", service_handle_state, service_state_attrs),
+ UBUS_METHOD_NOARG("get_features", container_handle_features),
UBUS_METHOD("console_set", container_handle_console, container_console_policy),
UBUS_METHOD("console_attach", container_handle_console, container_console_policy),
};