int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { int r, q; assert(pid >= 0); r = cg_create(controller, path, NULL); if (r < 0) return r; q = cg_attach(controller, path, pid); if (q < 0) return q; /* This does not remove the cgroup on failure */ return r; }
// **************************************************************************** _application_h* jobsignaler_registration() { #ifdef _JOBSIGNALER_DEBUG fprintf(stdout, "[registration] started\n"); #endif int application_id = (int) getpid(); // In the environment, get JOBSIGNALER_DIR, which is the directory // there the files about the running applications are stored; if not // present, the call terminates the application to avoid sementation // faults if (getenv("JOBSIGNALER_DIR") == NULL) { #ifdef _JOBSIGNALER_ERROR fprintf(stderr, "[registration] failed, JOBSIGNALER_DIR undefined\n"); #endif exit(EXIT_FAILURE_UNDEFINEDAUTOSIGNALER); } // Creating file to signal the application presence char filename[_H_MAX_FILENAMELENGHT]; sprintf(filename, "%s/%d", getenv("JOBSIGNALER_DIR"), application_id); FILE* fd = fopen(filename, "w"); fclose(fd); // Creating cgroup associated with application name char cgroupname[_H_MAX_FILENAMELENGHT]; sprintf(cgroupname, "app%d", application_id); cg_create(cgroupname); cg_attach(cgroupname, 0); // Creating shared memory segment key_t key = ftok(filename, application_id); int shmid = shmget(key, sizeof(_application_h), 0666 | IPC_CREAT); _application_h* a = (_application_h*) shmat(shmid, (void*) 0, 0); if (a == (_application_h*) -1) { #ifdef _JOBSIGNALER_ERROR fprintf(stderr, "[registration] failed, shared memory failure\n"); #endif exit(EXIT_FAILURE_SHAREDMEMORY); } a->application_id = application_id; #ifdef _JOBSIGNALER_DEBUG fprintf(stdout, "[registration] ended\n"); #endif return a; }
static PyObject * cc_attach (PyObject *self, PyObject *args) { char * ip ; int port, chl, ret ; #ifdef _WIN32 struct WSAData wsa; WSAStartup((unsigned short)0x101, &wsa); #endif if (validate() != 0) { shutdown_cclib(); return Py_BuildValue("i", -1); } if (!PyArg_ParseTuple(args, "sii", &ip, &port, &chl)) { return NULL; } Py_BEGIN_ALLOW_THREADS ret = cg_attach (ip, (unsigned short)port, chl) ; Py_END_ALLOW_THREADS return Py_BuildValue("i", ret); }
int main(int argc, char*argv[]) { char *path; char *c, *p; assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0); assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0); assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b") == 0); assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-c") == 0); assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0) == 0); assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); assert_se(streq(path, "/test-b")); free(path); assert_se(cg_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0) == 0); assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); assert_se(path_equal(path, "/test-a")); free(path); assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", 0) == 0); assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); assert_se(path_equal(path, "/test-b/test-d")); free(path); assert_se(cg_get_path(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", NULL, &path) == 0); assert_se(path_equal(path, "/sys/fs/cgroup/systemd/test-b/test-d")); free(path); assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0); assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0); assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0); assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) == 0); assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) == 0); assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) > 0); assert_se(cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", SYSTEMD_CGROUP_CONTROLLER, "/test-a", false, false) > 0); assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) == 0); assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0); assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) > 0); assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) == 0); cg_trim(SYSTEMD_CGROUP_CONTROLLER, "/", false); assert_se(cg_delete(SYSTEMD_CGROUP_CONTROLLER, "/test-b") < 0); assert_se(cg_delete(SYSTEMD_CGROUP_CONTROLLER, "/test-a") >= 0); assert_se(cg_split_spec("foobar:/", &c, &p) == 0); assert(streq(c, "foobar")); assert(streq(p, "/")); free(c); free(p); assert_se(cg_split_spec("foobar:", &c, &p) < 0); assert_se(cg_split_spec("foobar:asdfd", &c, &p) < 0); assert_se(cg_split_spec(":///", &c, &p) < 0); assert_se(cg_split_spec(":", &c, &p) < 0); assert_se(cg_split_spec("", &c, &p) < 0); assert_se(cg_split_spec("fo/obar:/", &c, &p) < 0); assert_se(cg_split_spec("/", &c, &p) >= 0); assert(c == NULL); assert(streq(p, "/")); free(p); assert_se(cg_split_spec("foo", &c, &p) >= 0); assert(streq(c, "foo")); assert(p == NULL); free(c); return 0; }
int cg_migrate(const char *controller, const char *from, const char *to, bool ignore_self) { bool done = false; Set *s; int r, ret = 0; pid_t my_pid; FILE *f = NULL; assert(controller); assert(from); assert(to); if (!(s = set_new(trivial_hash_func, trivial_compare_func))) return -ENOMEM; my_pid = getpid(); do { pid_t pid = 0; done = true; if ((r = cg_enumerate_tasks(controller, from, &f)) < 0) { if (ret >= 0 && r != -ENOENT) ret = r; goto finish; } while ((r = cg_read_pid(f, &pid)) > 0) { /* This might do weird stuff if we aren't a * single-threaded program. However, we * luckily know we are not */ if (pid == my_pid && ignore_self) continue; if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) continue; if ((r = cg_attach(controller, to, pid)) < 0) { if (ret >= 0 && r != -ESRCH) ret = r; } else if (ret == 0) ret = 1; done = false; if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) { if (ret >= 0) ret = r; goto finish; } } if (r < 0) { if (ret >= 0) ret = r; goto finish; } fclose(f); f = NULL; } while (!done); finish: set_free(s); if (f) fclose(f); return ret; }
int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self) { bool done = false; _cleanup_set_free_ Set *s = NULL; int r, ret = 0; pid_t my_pid; _cleanup_fclose_ FILE *f = NULL; assert(cfrom); assert(pfrom); assert(cto); assert(pto); s = set_new(trivial_hash_func, trivial_compare_func); if (!s) return -ENOMEM; my_pid = getpid(); do { pid_t pid = 0; done = true; r = cg_enumerate_tasks(cfrom, pfrom, &f); if (r < 0) { if (ret >= 0 && r != -ENOENT) ret = r; return ret; } while ((r = cg_read_pid(f, &pid)) > 0) { /* This might do weird stuff if we aren't a * single-threaded program. However, we * luckily know we are not */ if (pid == my_pid && ignore_self) continue; if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) continue; r = cg_attach(cto, pto, pid); if (r < 0) { if (ret >= 0 && r != -ESRCH) ret = r; } else if (ret == 0) ret = 1; done = false; r = set_put(s, LONG_TO_PTR(pid)); if (r < 0) { if (ret >= 0) ret = r; return ret; } } if (r < 0) { if (ret >= 0) ret = r; return ret; } fclose(f); f = NULL; } while (!done); return ret; }