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;
}
Example #4
0
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;
}