summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrew Clayton <a.clayton@nginx.com>2022-10-24 17:35:04 +0100
committerAndrew Clayton <a.clayton@nginx.com>2022-12-10 14:00:20 +0000
commit867a839f103bf7859b76eb98cfc28e7f0155dd1b (patch)
tree0c1dc40c4e54211ced9b318d2ff51f624ec3f23d
parent7d177faf3b8a483fd7ef958e884ec5625e058ca0 (diff)
downloadunit-867a839f103bf7859b76eb98cfc28e7f0155dd1b.tar.gz
unit-867a839f103bf7859b76eb98cfc28e7f0155dd1b.tar.bz2
Isolation: wired up per-application cgroup support internally.
This commit hooks into the cgroup infrastructure added in the previous commit to create per-application cgroups. It does this by adding each "prototype process" into its own cgroup, then each child process inherits its parents cgroup. If we fail to create a cgroup we simply fail the process. This behaviour may get enhanced in the future. This won't actually do anything yet. Subsequent commits will hook this up to the build and config systems. Reviewed-by: Alejandro Colomar <alx@nginx.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
-rw-r--r--src/nxt_isolation.c50
-rw-r--r--src/nxt_main_process.c4
-rw-r--r--src/nxt_process.c12
-rw-r--r--src/nxt_process.h13
4 files changed, 79 insertions, 0 deletions
diff --git a/src/nxt_isolation.c b/src/nxt_isolation.c
index 796da4c6..b6b13c59 100644
--- a/src/nxt_isolation.c
+++ b/src/nxt_isolation.c
@@ -6,6 +6,7 @@
#include <nxt_application.h>
#include <nxt_process.h>
#include <nxt_isolation.h>
+#include <nxt_cgroup.h>
#if (NXT_HAVE_MNTENT_H)
#include <mntent.h>
@@ -15,6 +16,11 @@
static nxt_int_t nxt_isolation_set(nxt_task_t *task,
nxt_conf_value_t *isolation, nxt_process_t *process);
+#if (NXT_HAVE_CGROUP)
+static nxt_int_t nxt_isolation_set_cgroup(nxt_task_t *task,
+ nxt_conf_value_t *isolation, nxt_process_t *process);
+#endif
+
#if (NXT_HAVE_CLONE)
static nxt_int_t nxt_isolation_set_namespaces(nxt_task_t *task,
nxt_conf_value_t *isolation, nxt_process_t *process);
@@ -155,6 +161,14 @@ static nxt_int_t
nxt_isolation_set(nxt_task_t *task, nxt_conf_value_t *isolation,
nxt_process_t *process)
{
+#if (NXT_HAVE_CGROUP)
+ if (nxt_slow_path(nxt_isolation_set_cgroup(task, isolation, process)
+ != NXT_OK))
+ {
+ return NXT_ERROR;
+ }
+#endif
+
#if (NXT_HAVE_CLONE)
if (nxt_slow_path(nxt_isolation_set_namespaces(task, isolation, process)
!= NXT_OK))
@@ -197,6 +211,42 @@ nxt_isolation_set(nxt_task_t *task, nxt_conf_value_t *isolation,
}
+#if (NXT_HAVE_CGROUP)
+
+static nxt_int_t
+nxt_isolation_set_cgroup(nxt_task_t *task, nxt_conf_value_t *isolation,
+ nxt_process_t *process)
+{
+ nxt_str_t str;
+ nxt_conf_value_t *obj;
+
+ static nxt_str_t cgname = nxt_string("cgroup");
+ static nxt_str_t path = nxt_string("path");
+
+ obj = nxt_conf_get_object_member(isolation, &cgname, NULL);
+ if (obj == NULL) {
+ return NXT_OK;
+ }
+
+ obj = nxt_conf_get_object_member(obj, &path, NULL);
+ if (obj == NULL) {
+ return NXT_ERROR;
+ }
+
+ nxt_conf_get_string(obj, &str);
+ process->isolation.cgroup.path = nxt_mp_alloc(process->mem_pool,
+ str.length + 1);
+ nxt_memcpy(process->isolation.cgroup.path, str.start, str.length);
+ process->isolation.cgroup.path[str.length] = '\0';
+
+ process->isolation.cgroup_cleanup = nxt_cgroup_cleanup;
+
+ return NXT_OK;
+}
+
+#endif
+
+
#if (NXT_HAVE_CLONE)
static nxt_int_t
diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c
index f21482d5..de41e8d7 100644
--- a/src/nxt_main_process.c
+++ b/src/nxt_main_process.c
@@ -1007,6 +1007,10 @@ nxt_main_process_cleanup(nxt_task_t *task, nxt_process_t *process)
if (process->isolation.cleanup != NULL) {
process->isolation.cleanup(task, process);
}
+
+ if (process->isolation.cgroup_cleanup != NULL) {
+ process->isolation.cgroup_cleanup(task, process);
+ }
}
diff --git a/src/nxt_process.c b/src/nxt_process.c
index 738a03bf..d8836ad2 100644
--- a/src/nxt_process.c
+++ b/src/nxt_process.c
@@ -5,6 +5,7 @@
*/
#include <nxt_main.h>
+#include <nxt_cgroup.h>
#if (NXT_HAVE_CLONE)
#include <nxt_clone.h>
@@ -378,6 +379,17 @@ nxt_process_create(nxt_task_t *task, nxt_process_t *process)
nxt_runtime_process_add(task, process);
}
+#if (NXT_HAVE_CGROUP)
+ ret = nxt_cgroup_proc_add(task, process);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ nxt_alert(task, "cgroup: failed to add process %s to %s %E",
+ process->name, process->isolation.cgroup.path, nxt_errno);
+ nxt_cgroup_cleanup(task, process);
+ kill(pid, SIGTERM);
+ return -1;
+ }
+#endif
+
return pid;
}
diff --git a/src/nxt_process.h b/src/nxt_process.h
index 15fd4e7f..0db68d45 100644
--- a/src/nxt_process.h
+++ b/src/nxt_process.h
@@ -61,8 +61,11 @@ typedef enum {
typedef struct nxt_port_mmap_s nxt_port_mmap_t;
typedef struct nxt_process_s nxt_process_t;
+typedef struct nxt_cgroup_s nxt_cgroup_t;
typedef void (*nxt_isolation_cleanup_t)(nxt_task_t *task,
nxt_process_t *process);
+typedef void (*nxt_cgroup_cleanup_t)(nxt_task_t *task,
+ const nxt_process_t *process);
typedef struct {
@@ -80,6 +83,11 @@ typedef struct {
} nxt_process_automount_t;
+struct nxt_cgroup_s {
+ char *path;
+};
+
+
typedef struct {
u_char *rootfs;
nxt_process_automount_t automount;
@@ -87,6 +95,11 @@ typedef struct {
nxt_isolation_cleanup_t cleanup;
+ nxt_cgroup_cleanup_t cgroup_cleanup;
+#if (NXT_HAVE_CGROUP)
+ nxt_cgroup_t cgroup;
+#endif
+
#if (NXT_HAVE_CLONE)
nxt_clone_t clone;
#endif