+__cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
+ struct lxc_handler *handler)
+{
+ int len;
+ struct lxc_conf *conf = handler->conf;
+ char pidstr[INTTYPE_TO_STRLEN(pid_t)];
+
+ if (!ops->hierarchies)
+ return;
+
+ len = snprintf(pidstr, sizeof(pidstr), "%d", handler->monitor_pid);
+ if (len < 0 || (size_t)len >= sizeof(pidstr))
+ return;
+
+ for (int i = 0; ops->hierarchies[i]; i++) {
+ __do_free char *pivot_path = NULL;
+ int ret;
+ char *chop;
+ char pivot_cgroup[] = PIVOT_CGROUP;
+ struct hierarchy *h = ops->hierarchies[i];
+
+ if (!h->monitor_full_path)
+ continue;
+
+ if (conf && conf->cgroup_meta.dir)
+ pivot_path = must_make_path(h->mountpoint,
+ h->container_base_path,
+ conf->cgroup_meta.dir,
+ PIVOT_CGROUP,
+ "cgroup.procs", NULL);
+ else
+ pivot_path = must_make_path(h->mountpoint,
+ h->container_base_path,
+ PIVOT_CGROUP,
+ "cgroup.procs", NULL);
+
+ chop = strrchr(pivot_path, '/');
+ if (chop)
+ *chop = '\0';
+
+ /*
+ * Make sure not to pass in the ro string literal PIVOT_CGROUP
+ * here.
+ */
+ if (!cg_legacy_handle_cpuset_hierarchy(h, pivot_cgroup)) {
+ WARN("Failed to handle legacy cpuset controller");
+ continue;
+ }
+
+ ret = mkdir_p(pivot_path, 0755);
+ if (ret < 0 && errno != EEXIST) {
+ SYSWARN("Failed to create cgroup \"%s\"\n", pivot_path);
+ continue;
+ }
+
+ if (chop)
+ *chop = '/';
+
+ /* Move ourselves into the pivot cgroup to delete our own
+ * cgroup.
+ */
+ ret = lxc_write_to_file(pivot_path, pidstr, len, false, 0666);
+ if (ret != 0) {
+ SYSWARN("Failed to move monitor %s to \"%s\"\n", pidstr, pivot_path);
+ continue;
+ }
+
+ ret = recursive_destroy(h->monitor_full_path);
+ if (ret < 0)
+ WARN("Failed to destroy \"%s\"", h->monitor_full_path);
+ }
+}
+