bool make_sub_cgroup(cgroup_t group, char *parent, char *child) { char child_dir[SGE_PATH_MAX]; DENTER(TOP_LAYER, "make_sub_cgroup"); build_path(child_dir, parent, child); if (!sge_is_directory(child_dir)) { errno = 0; if (mkdir(child_dir, 0755) != 0) { WARNING((SGE_EVENT, MSG_FILE_CREATEDIRFAILED_SS, child_dir, strerror(errno))); DRETURN(false); } } /* You need to populate the mems and cpus before you can use the cpuset -- they're not inherited. Checkme: it looks as if clone_children can deal with this (present in Ubuntu's Linux 3.2, at least). */ if (cg_cpuset == group) { DRETURN(copy_from_parent(child_dir, "mems") && copy_from_parent(child_dir, "cpus")); } DRETURN(true); }
/* Remove the job task cpuset directory after first removing shepherd sub-directories. */ bool remove_job_cpuset(u_long32 job, u_long32 task) { #if ! __linux__ return true; #else /* using non-portable dirent-isms */ char dirpath[SGE_PATH_MAX]; DIR *dir; struct dirent *dent; DENTER(TOP_LAYER, "remove_job_cpuset"); snprintf(dirpath, sizeof dirpath, "%s/"sge_u32"."sge_u32, cgroup_dir(cg_cpuset), job, task); INFO((SGE_EVENT, "removing task cpuset "SFN, dirpath)); if (!sge_is_directory(dirpath)) return true; errno = 0; /* Maybe this should be made reentrant, though there's existing code which does the same sort of thing in the same context. */ if ((dir = opendir(dirpath)) == NULL) { ERROR((SGE_EVENT, MSG_FILE_CANTOPENDIRECTORYX_SS, dirpath, strerror(errno))); DRETURN(false); } while ((dent = readdir(dir))) if ((DT_DIR == dent->d_type) && sge_strisint(dent->d_name)) remove_shepherd_cpuset(job, task, atoi(dent->d_name)); closedir(dir); if (rmdir(dirpath) != 0) { ERROR((SGE_EVENT, MSG_FILE_RMDIRFAILED_SS, dirpath, strerror(errno))); DRETURN(false); } DRETURN(true); #endif /* !__linux__ */ }
/* look for an "sge" directory under a mount point of the cgroup */ static bool find_cgroup_dir(cgroup_t group, char *dir, size_t ldir) { FILE *fp; char path[2048], fstype[64], options[256]; bool ret = false, is_cpuset = (cg_cpuset == group); *dir = '\0'; if ((fp = fopen("/proc/self/mounts", "r")) == NULL) return ret; while (fscanf(fp, "%*s %2047s %63s %255s %*d %*d\n", path, fstype, options) == 3) { if (is_cpuset && strcmp(fstype, "cpuset") == 0) { ret = true; break; } else if ((strcmp(fstype, "cgroup") == 0)) { char *s = options, *tok, *save = NULL; bool rw = false, got_type = is_cpuset; while ((tok = strtok_r(s, ",", &save))) { if (strcmp(tok, "rw") == 0) rw = true; if (strcmp(tok, group_name[group]) == 0) got_type = true; if (rw && got_type) break; s = NULL; } sge_strlcat(path, "/sge", sizeof path); ret = rw && got_type && sge_is_directory(path); if (ret) break; } } fclose(fp); if (ret) sge_strlcpy(dir, path, ldir); return ret; }
static int elect_path(dstring *aBuffer) { const char *d; d = getenv("TMPDIR"); if ((d != NULL) && sge_is_directory(d)) { sge_dstring_append(aBuffer, d); return 0; } else if (sge_is_directory(P_tmpdir)) { sge_dstring_append(aBuffer, P_tmpdir); return 0; } else if (sge_is_directory("/tmp")) { sge_dstring_append(aBuffer, "/tmp/"); return 0; } return -1; }
/* Does the controller directory for the job exist? */ bool have_cgroup_job_dir(cgroup_t group, u_long32 job, u_long32 task) { char dir[SGE_PATH_MAX]; if (!get_cgroup_job_dir(group, dir, sizeof dir, job, task)) return false; return *dir && sge_is_directory(dir); }
/* Put PROC (string version of pid) into the controller DIR */ static bool reparent_proc(const char *proc, char *dir) { char path[SGE_PATH_MAX]; pid_t pid = atoi(proc); if (!pid) return false; /* Don't fail if the process no longer exists. */ build_path(path, "/proc", proc); if (!sge_is_directory(path)) return true; return set_pid_cgroup(pid, dir); }
/* Return the directory for the given controller GROUP of JOB and TASK in buffer DIR of length LDIR (e.g. /dev/cpuset/sge/123.1). DIR is zero-length on failure. */ bool get_cgroup_job_dir(cgroup_t group, char *dir, size_t ldir, u_long32 job, u_long32 task) { const char *cdir; DENTER(TOP_LAYER, "get_cgroup_job_dir"); dir[0] = '\0'; cdir = cgroup_dir(group); if (*cdir == '\0') DRETURN(false); if (snprintf(dir, ldir, "%s/"sge_u32"."sge_u32, cdir, job, task) >= ldir) { WARNING((SGE_EVENT, "Can't build cgroup_job_dir value")); DRETURN(false); } if (!sge_is_directory(dir)) { dir[0] = '\0'; DRETURN(false); } DRETURN(true); }
/* Move the shepherd tasks to the job cpuset 0 and remove the shepherd cpuset. */ bool empty_shepherd_cpuset(u_long32 job, u_long32 task, pid_t pid) { char dir[SGE_PATH_MAX], taskfile[SGE_PATH_MAX], taskfile0[SGE_PATH_MAX]; bool ret; snprintf(dir, sizeof dir, "%s/"sge_u32"."sge_u32"/"pid_t_fmt, cgroup_dir(cg_cpuset), job, task, pid); if (!sge_is_directory(dir)) return true; build_path(taskfile, dir, "tasks"); snprintf(taskfile0, sizeof taskfile0, "%s/"sge_u32"."sge_u32"/0/tasks", cgroup_dir(cg_cpuset), job, task); errno = 0; sge_seteuid(SGE_SUPERUSER_UID); /* This could fail at least if a task is respawning. It needs to be done task-wise (line-wise) according to cpuset(7). */ ret = copy_linewise(taskfile, taskfile0); if (sge_switch2admin_user() != 0) abort(); if (!ret) return false; /* If rmdir fails, execd will try to kill it. */ return rmdir(dir) ? false : true; }