len = strlen(entry);
prefixed = must_alloc(len + 6);
- memcpy(prefixed, "name=", sizeof("name=") - 1);
- memcpy(prefixed + sizeof("name=") - 1, entry, len);
+
+ memcpy(prefixed, "name=", STRLITERALLEN("name="));
+ memcpy(prefixed + STRLITERALLEN("name="), entry, len);
prefixed[len + 5] = '\0';
return prefixed;
}
/* Given a handler's cgroup data, return the struct hierarchy for the controller
* @c, or NULL if there is none.
*/
-struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *c)
+struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *controller)
{
int i;
- if (!ops->hierarchies)
+ errno = ENOENT;
+
+ if (!ops->hierarchies) {
+ TRACE("There are no useable cgroup controllers");
return NULL;
+ }
for (i = 0; ops->hierarchies[i]; i++) {
- if (!c) {
+ if (!controller) {
/* This is the empty unified hierarchy. */
if (ops->hierarchies[i]->controllers &&
!ops->hierarchies[i]->controllers[0])
continue;
}
- if (string_in_list(ops->hierarchies[i]->controllers, c))
+ if (string_in_list(ops->hierarchies[i]->controllers, controller))
return ops->hierarchies[i];
}
+ if (controller)
+ WARN("There is no useable %s controller", controller);
+ else
+ WARN("There is no empty unified cgroup hierarchy");
+
return NULL;
}
if (!is_set(i, bitarr))
continue;
- ret = snprintf(numstr, INTTYPE_TO_STRLEN(size_t), "%zu", i);
- if (ret < 0 || (size_t)ret >= INTTYPE_TO_STRLEN(size_t)) {
+ ret = snprintf(numstr, sizeof(numstr), "%zu", i);
+ if (ret < 0 || (size_t)ret >= sizeof(numstr)) {
lxc_free_array((void **)cpulist, free);
return NULL;
}
if (slash)
*slash = '\0';
- cgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
+ cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
if (slash)
*slash = '/';
}
}
- clonechildrenpath =
- must_make_path(cgpath, "cgroup.clone_children", NULL);
+ clonechildrenpath = must_make_path(cgpath, "cgroup.clone_children", NULL);
/* unified hierarchy doesn't have clone_children */
if (!file_exists(clonechildrenpath)) {
free(clonechildrenpath);
}
static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char *mountpoint,
- char *base_cgroup, int type)
+ char *container_base_path, int type)
{
struct hierarchy *new;
int newentry;
new = must_alloc(sizeof(*new));
new->controllers = clist;
new->mountpoint = mountpoint;
- new->base_cgroup = base_cgroup;
- new->fullcgpath = NULL;
+ new->container_base_path = container_base_path;
+ new->container_full_path = NULL;
+ new->monitor_full_path = NULL;
new->version = type;
newentry = append_null_to_list((void ***)h);
int j;
char **cit;
- TRACE(" %d: base_cgroup: %s", i, (*it)->base_cgroup ? (*it)->base_cgroup : "(null)");
+ TRACE(" %d: base_cgroup: %s", i, (*it)->container_base_path ? (*it)->container_base_path : "(null)");
TRACE(" mountpoint: %s", (*it)->mountpoint ? (*it)->mountpoint : "(null)");
TRACE(" controllers:");
for (j = 0, cit = (*it)->controllers; cit && *cit; cit++, j++)
int ret;
struct hierarchy *h = hierarchies[i];
- if (!h->fullcgpath)
+ if (!h->container_full_path)
continue;
- ret = recursive_destroy(h->fullcgpath);
+ ret = recursive_destroy(h->container_full_path);
if (ret < 0)
- WARN("Failed to destroy \"%s\"", h->fullcgpath);
+ WARN("Failed to destroy \"%s\"", h->container_full_path);
- free(h->fullcgpath);
- h->fullcgpath = NULL;
+ free(h->container_full_path);
+ h->container_full_path = NULL;
}
return 0;
return cgroup_rmdir(arg->hierarchies, arg->container_cgroup);
}
-static void cgfsng_destroy(struct cgroup_ops *ops, struct lxc_handler *handler)
+__cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops,
+ struct lxc_handler *handler)
{
int ret;
struct generic_userns_exec_data wrap;
}
}
+__cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
+ struct lxc_handler *handler)
+{
+ int len;
+ char *pivot_path;
+ 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++) {
+ int ret;
+ 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);
+
+ ret = mkdir_p(pivot_path, 0755);
+ if (ret < 0 && errno != EEXIST)
+ goto next;
+
+ /* 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)
+ goto next;
+
+ ret = recursive_destroy(h->monitor_full_path);
+ if (ret < 0)
+ WARN("Failed to destroy \"%s\"", h->monitor_full_path);
+
+ next:
+ free(pivot_path);
+ }
+}
+
static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname)
{
size_t i, parts_len;
if (parts_len > 0)
parts_len--;
- cgroup = must_make_path(h->mountpoint, h->base_cgroup, NULL);
+ cgroup = must_make_path(h->mountpoint, h->container_base_path, NULL);
for (i = 0; i < parts_len; i++) {
int ret;
char *target;
return bret;
}
-static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
+static bool monitor_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
+{
+ int ret;
+
+ h->monitor_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
+ if (dir_exists(h->monitor_full_path))
+ return true;
+
+ if (!cg_legacy_handle_cpuset_hierarchy(h, cgname)) {
+ ERROR("Failed to handle legacy cpuset controller");
+ return false;
+ }
+
+ ret = mkdir_p(h->monitor_full_path, 0755);
+ if (ret < 0) {
+ ERROR("Failed to create cgroup \"%s\"", h->monitor_full_path);
+ return false;
+ }
+
+ return cg_unified_create_cgroup(h, cgname);
+}
+
+static bool container_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
{
int ret;
- h->fullcgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
- if (dir_exists(h->fullcgpath)) {
- ERROR("The cgroup \"%s\" already existed", h->fullcgpath);
+ h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
+ if (dir_exists(h->container_full_path)) {
+ ERROR("The cgroup \"%s\" already existed", h->container_full_path);
return false;
}
return false;
}
- ret = mkdir_p(h->fullcgpath, 0755);
+ ret = mkdir_p(h->container_full_path, 0755);
if (ret < 0) {
- ERROR("Failed to create cgroup \"%s\"", h->fullcgpath);
+ ERROR("Failed to create cgroup \"%s\"", h->container_full_path);
return false;
}
return cg_unified_create_cgroup(h, cgname);
}
-static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname)
+static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname, bool monitor)
{
int ret;
+ char *full_path;
- ret = rmdir(h->fullcgpath);
+ if (monitor)
+ full_path = h->monitor_full_path;
+ else
+ full_path = h->container_full_path;
+
+ ret = rmdir(full_path);
if (ret < 0)
- SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", h->fullcgpath);
+ SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", full_path);
+
+ free(full_path);
- free(h->fullcgpath);
- h->fullcgpath = NULL;
+ if (monitor)
+ h->monitor_full_path = NULL;
+ else
+ h->container_full_path = NULL;
+}
+
+__cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
+ struct lxc_handler *handler)
+{
+ char *monitor_cgroup, *offset, *tmp;
+ int idx = 0;
+ size_t len;
+ bool bret = false;
+ struct lxc_conf *conf = handler->conf;
+
+ if (!conf)
+ return bret;
+
+ if (conf->cgroup_meta.dir)
+ tmp = lxc_string_join("/",
+ (const char *[]){conf->cgroup_meta.dir,
+ ops->monitor_pattern,
+ handler->name, NULL},
+ false);
+ else
+ tmp = must_make_path(ops->monitor_pattern, handler->name, NULL);
+ if (!tmp)
+ return bret;
+
+ len = strlen(tmp) + 5; /* leave room for -NNN\0 */
+ monitor_cgroup = must_alloc(len);
+ (void)strlcpy(monitor_cgroup, tmp, len);
+ free(tmp);
+ offset = monitor_cgroup + len - 5;
+
+ do {
+ if (idx) {
+ int ret = snprintf(offset, 5, "-%d", idx);
+ if (ret < 0 || (size_t)ret >= 5)
+ goto on_error;
+ }
+
+ for (int i = 0; ops->hierarchies[i]; i++) {
+ if (!monitor_create_path_for_hierarchy(ops->hierarchies[i], monitor_cgroup)) {
+ ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->monitor_full_path);
+ free(ops->hierarchies[i]->container_full_path);
+ ops->hierarchies[i]->container_full_path = NULL;
+
+ for (int j = 0; j < i; j++)
+ remove_path_for_hierarchy(ops->hierarchies[j], monitor_cgroup, true);
+
+ idx++;
+ break;
+ }
+ }
+ } while (idx > 0 && idx < 1000);
+
+ if (idx < 1000)
+ bret = true;
+
+on_error:
+ free(monitor_cgroup);
+
+ return bret;
}
/* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern;
* next cgroup_pattern-1, -2, ..., -999.
*/
-static inline bool cgfsng_create(struct cgroup_ops *ops,
- struct lxc_handler *handler)
+__cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
+ struct lxc_handler *handler)
{
int i;
size_t len;
}
for (i = 0; ops->hierarchies[i]; i++) {
- if (!create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) {
- int j;
- ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->fullcgpath);
- free(ops->hierarchies[i]->fullcgpath);
- ops->hierarchies[i]->fullcgpath = NULL;
- for (j = 0; j < i; j++)
- remove_path_for_hierarchy(ops->hierarchies[j], container_cgroup);
+ if (!container_create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) {
+ ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->container_full_path);
+ free(ops->hierarchies[i]->container_full_path);
+ ops->hierarchies[i]->container_full_path = NULL;
+ for (int j = 0; j < i; j++)
+ remove_path_for_hierarchy(ops->hierarchies[j], container_cgroup, false);
idx++;
goto again;
}
return false;
}
-static bool cgfsng_enter(struct cgroup_ops *ops, pid_t pid)
+__cgfsng_ops static bool __do_cgroup_enter(struct cgroup_ops *ops, pid_t pid,
+ bool monitor)
{
- int i, len;
- char pidstr[25];
+ int len;
+ char pidstr[INTTYPE_TO_STRLEN(pid_t)];
- len = snprintf(pidstr, 25, "%d", pid);
- if (len < 0 || len >= 25)
+ len = snprintf(pidstr, sizeof(pidstr), "%d", pid);
+ if (len < 0 || (size_t)len >= sizeof(pidstr))
return false;
- for (i = 0; ops->hierarchies[i]; i++) {
+ for (int i = 0; ops->hierarchies[i]; i++) {
int ret;
- char *fullpath;
+ char *path;
- fullpath = must_make_path(ops->hierarchies[i]->fullcgpath,
- "cgroup.procs", NULL);
- ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666);
+ if (monitor)
+ path = must_make_path(ops->hierarchies[i]->monitor_full_path,
+ "cgroup.procs", NULL);
+ else
+ path = must_make_path(ops->hierarchies[i]->container_full_path,
+ "cgroup.procs", NULL);
+ ret = lxc_write_to_file(path, pidstr, len, false, 0666);
if (ret != 0) {
- SYSERROR("Failed to enter cgroup \"%s\"", fullpath);
- free(fullpath);
+ SYSERROR("Failed to enter cgroup \"%s\"", path);
+ free(path);
return false;
}
- free(fullpath);
+ free(path);
}
return true;
}
+__cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops, pid_t pid)
+{
+ return __do_cgroup_enter(ops, pid, true);
+}
+
+static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid)
+{
+ return __do_cgroup_enter(ops, pid, false);
+}
+
static int chowmod(char *path, uid_t chown_uid, gid_t chown_gid,
mode_t chmod_mode)
{
}
destuid = get_ns_uid(arg->origuid);
+ if (destuid == LXC_INVALID_UID)
+ destuid = 0;
for (i = 0; arg->hierarchies[i]; i++) {
char *fullpath;
- char *path = arg->hierarchies[i]->fullcgpath;
+ char *path = arg->hierarchies[i]->container_full_path;
ret = chowmod(path, destuid, nsgid, 0775);
if (ret < 0)
return 0;
}
-static bool cgfsng_chown(struct cgroup_ops *ops, struct lxc_conf *conf)
+__cgfsng_ops static bool cgfsng_chown(struct cgroup_ops *ops,
+ struct lxc_conf *conf)
{
struct generic_userns_exec_data wrap;
INFO("Remounted %s read-only", controllerpath);
}
- sourcepath = must_make_path(h->mountpoint, h->base_cgroup,
+ sourcepath = must_make_path(h->mountpoint, h->container_base_path,
container_cgroup, NULL);
if (type == LXC_AUTO_CGROUP_RO)
flags |= MS_RDONLY;
return __cg_mount_direct(type, h, controllerpath);
}
-static bool cgfsng_mount(struct cgroup_ops *ops, struct lxc_handler *handler,
- const char *root, int type)
+__cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops,
+ struct lxc_handler *handler,
+ const char *root, int type)
{
int i, ret;
char *tmpfspath = NULL;
continue;
}
- path2 = must_make_path(controllerpath, h->base_cgroup,
+ path2 = must_make_path(controllerpath, h->container_base_path,
ops->container_cgroup, NULL);
ret = mkdir_p(path2, 0755);
if (ret < 0) {
return count;
}
-static int cgfsng_nrtasks(struct cgroup_ops *ops)
+__cgfsng_ops static int cgfsng_nrtasks(struct cgroup_ops *ops)
{
int count;
char *path;
if (!ops->container_cgroup || !ops->hierarchies)
return -1;
- path = must_make_path(ops->hierarchies[0]->fullcgpath, NULL);
+ path = must_make_path(ops->hierarchies[0]->container_full_path, NULL);
count = recursive_count_nrtasks(path);
free(path);
return count;
}
/* Only root needs to escape to the cgroup of its init. */
-static bool cgfsng_escape(const struct cgroup_ops *ops, struct lxc_conf *conf)
+__cgfsng_ops static bool cgfsng_escape(const struct cgroup_ops *ops,
+ struct lxc_conf *conf)
{
int i;
- if (conf->cgroup_meta.keep || geteuid())
+ if (conf->cgroup_meta.relative || geteuid())
return true;
for (i = 0; ops->hierarchies[i]; i++) {
char *fullpath;
fullpath = must_make_path(ops->hierarchies[i]->mountpoint,
- ops->hierarchies[i]->base_cgroup,
+ ops->hierarchies[i]->container_base_path,
"cgroup.procs", NULL);
ret = lxc_write_to_file(fullpath, "0", 2, false, 0666);
if (ret != 0) {
return true;
}
-static int cgfsng_num_hierarchies(struct cgroup_ops *ops)
+__cgfsng_ops static int cgfsng_num_hierarchies(struct cgroup_ops *ops)
{
int i;
return i;
}
-static bool cgfsng_get_hierarchies(struct cgroup_ops *ops, int n, char ***out)
+__cgfsng_ops static bool cgfsng_get_hierarchies(struct cgroup_ops *ops, int n, char ***out)
{
int i;
/* TODO: If the unified cgroup hierarchy grows a freezer controller this needs
* to be adapted.
*/
-static bool cgfsng_unfreeze(struct cgroup_ops *ops)
+__cgfsng_ops static bool cgfsng_unfreeze(struct cgroup_ops *ops)
{
int ret;
char *fullpath;
if (!h)
return false;
- fullpath = must_make_path(h->fullcgpath, "freezer.state", NULL);
+ fullpath = must_make_path(h->container_full_path, "freezer.state", NULL);
ret = lxc_write_to_file(fullpath, THAWED, THAWED_LEN, false, 0666);
free(fullpath);
if (ret < 0)
return true;
}
-static const char *cgfsng_get_cgroup(struct cgroup_ops *ops,
- const char *controller)
+__cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops,
+ const char *controller)
{
struct hierarchy *h;
return NULL;
}
- return h->fullcgpath ? h->fullcgpath + strlen(h->mountpoint) : NULL;
+ return h->container_full_path ? h->container_full_path + strlen(h->mountpoint) : NULL;
}
/* Given a cgroup path returned from lxc_cmd_get_cgroup_path, build a full path,
free(full_path);
- len = strlen(base_path) + sizeof("/lxc-1000") - 1 +
- sizeof("/cgroup-procs") - 1;
+ len = strlen(base_path) + STRLITERALLEN("/lxc-1000") +
+ STRLITERALLEN("/cgroup-procs");
full_path = must_alloc(len + 1);
do {
if (idx)
return fret;
}
-static bool cgfsng_attach(struct cgroup_ops *ops, const char *name,
- const char *lxcpath, pid_t pid)
+__cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name,
+ const char *lxcpath, pid_t pid)
{
int i, len, ret;
- char pidstr[25];
+ char pidstr[INTTYPE_TO_STRLEN(pid_t)];
- len = snprintf(pidstr, 25, "%d", pid);
- if (len < 0 || len >= 25)
+ len = snprintf(pidstr, sizeof(pidstr), "%d", pid);
+ if (len < 0 || (size_t)len >= sizeof(pidstr))
return false;
for (i = 0; ops->hierarchies[i]; i++) {
* don't have a cgroup_data set up, so we ask the running container through the
* commands API for the cgroup path.
*/
-static int cgfsng_get(struct cgroup_ops *ops, const char *filename, char *value,
- size_t len, const char *name, const char *lxcpath)
+__cgfsng_ops static int cgfsng_get(struct cgroup_ops *ops, const char *filename,
+ char *value, size_t len, const char *name,
+ const char *lxcpath)
{
int ret = -1;
size_t controller_len;
* don't have a cgroup_data set up, so we ask the running container through the
* commands API for the cgroup path.
*/
-static int cgfsng_set(struct cgroup_ops *ops, const char *filename,
- const char *value, const char *name, const char *lxcpath)
+__cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops,
+ const char *filename, const char *value,
+ const char *name, const char *lxcpath)
{
int ret = -1;
size_t controller_len;
return -ENOENT;
}
- fullpath = must_make_path(h->fullcgpath, filename, NULL);
+ fullpath = must_make_path(h->container_full_path, filename, NULL);
ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666);
free(fullpath);
return ret;
char *fullpath;
struct lxc_cgroup *cg = iterator->elem;
- fullpath = must_make_path(h->fullcgpath, cg->subsystem, NULL);
+ fullpath = must_make_path(h->container_full_path, cg->subsystem, NULL);
ret = lxc_write_to_file(fullpath, cg->value, strlen(cg->value), false, 0666);
free(fullpath);
if (ret < 0) {
return true;
}
-static bool cgfsng_setup_limits(struct cgroup_ops *ops, struct lxc_conf *conf,
- bool do_devices)
+__cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
+ struct lxc_conf *conf,
+ bool do_devices)
{
bool bret;
/* At startup, parse_hierarchies finds all the info we need about cgroup
* mountpoints and current cgroups, and stores it in @d.
*/
-static bool cg_hybrid_init(struct cgroup_ops *ops, bool keep)
+static bool cg_hybrid_init(struct cgroup_ops *ops, bool relative)
{
int ret;
char *basecginfo;
/* Root spawned containers escape the current cgroup, so use init's
* cgroups as our base in that case.
*/
- if (!keep && (geteuid() == 0))
+ if (!relative && (geteuid() == 0))
basecginfo = read_file("/proc/1/cgroup");
else
basecginfo = read_file("/proc/self/cgroup");
}
/* Get current cgroup from /proc/self/cgroup for the cgroupfs v2 hierarchy. */
-static char *cg_unified_get_current_cgroup(bool keep)
+static char *cg_unified_get_current_cgroup(bool relative)
{
char *basecginfo, *base_cgroup;
char *copy = NULL;
- if (!keep && (geteuid() == 0))
+ if (!relative && (geteuid() == 0))
basecginfo = read_file("/proc/1/cgroup");
else
basecginfo = read_file("/proc/self/cgroup");
return copy;
}
-static int cg_unified_init(struct cgroup_ops *ops, bool keep)
+static int cg_unified_init(struct cgroup_ops *ops, bool relative)
{
int ret;
char *mountpoint, *subtree_path;
if (ret != CGROUP2_SUPER_MAGIC)
return 0;
- base_cgroup = cg_unified_get_current_cgroup(keep);
+ base_cgroup = cg_unified_get_current_cgroup(relative);
if (!base_cgroup)
return -EINVAL;
prune_init_scope(base_cgroup);
{
int ret;
const char *tmp;
- bool keep = conf->cgroup_meta.keep;
+ bool relative = conf->cgroup_meta.relative;
tmp = lxc_global_config_value("lxc.cgroup.use");
if (tmp) {
free(pin);
}
- ret = cg_unified_init(ops, keep);
+ ret = cg_unified_init(ops, relative);
if (ret < 0)
return false;
if (ret == CGROUP2_SUPER_MAGIC)
return true;
- return cg_hybrid_init(ops, keep);
+ return cg_hybrid_init(ops, relative);
}
-static bool cgfsng_data_init(struct cgroup_ops *ops)
+__cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops)
{
const char *cgroup_pattern;
return false;
}
ops->cgroup_pattern = must_copy_string(cgroup_pattern);
+ ops->monitor_pattern = MONITOR_CGROUP;
return true;
}
}
cgfsng_ops->data_init = cgfsng_data_init;
- cgfsng_ops->destroy = cgfsng_destroy;
- cgfsng_ops->create = cgfsng_create;
- cgfsng_ops->enter = cgfsng_enter;
+ cgfsng_ops->payload_destroy = cgfsng_payload_destroy;
+ cgfsng_ops->monitor_destroy = cgfsng_monitor_destroy;
+ cgfsng_ops->monitor_create = cgfsng_monitor_create;
+ cgfsng_ops->monitor_enter = cgfsng_monitor_enter;
+ cgfsng_ops->payload_create = cgfsng_payload_create;
+ cgfsng_ops->payload_enter = cgfsng_payload_enter;
cgfsng_ops->escape = cgfsng_escape;
cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies;
cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies;