Exemplo n.º 1
0
/****** uti/io/sge_filecmp() **************************************************
*  NAME
*     sge_filecmp() -- Compare two files
*
*  SYNOPSIS
*     int sge_filecmp(const char *name0, const char *name1)
*
*  FUNCTION
*     Compare two files. They are equal if:
*        - both of them have the same name
*        - if a stat() succeeds for both files and
*          i-node/device-id are equal
*
*     we are not sure
*     - if stat() failes for at least one of the files
*       (It could be that both pathes direct to the same
*       file not existing)
*
*  INPUTS
*     const char *name0 - 1st filename
*     const char *name1 - 2nd filename
*
*  RESULT
*     int - Identical?
*         0 - Yes.
*         1 - No they are not equivalent.
*
*  NOTES
*     MT-NOTE: sge_filecmp() is MT safe
******************************************************************************/
int sge_filecmp(const char *name0, const char *name1)
{
   SGE_STRUCT_STAT buf0, buf1;
 
   DENTER(TOP_LAYER, "filecmp");
 
   if (!strcmp(name0, name1)) {
      DEXIT;
      return 0;
   }
 
   if (SGE_STAT(name0, &buf0)<0) {
      DEXIT;
      return 1;
   }
 
   if (SGE_STAT(name1, &buf1)<0) {
      DEXIT;
      return 1;
   }
 
   if (buf0.st_ino == buf1.st_ino && buf0.st_dev == buf1.st_dev) {
      DEXIT;
      return 0;
   } else {
      DEXIT;
      return 1;
   }
}          
Exemplo n.º 2
0
/****** uti/afsutil/sge_get_token_cmd() ***************************************
*  NAME
*     sge_get_token_cmd() -- Check if 'tokencmdname' is executable 
*
*  SYNOPSIS
*     int sge_get_token_cmd(const char *tokencmdname, char *buf, size_t lbuf)
*
*  FUNCTION
*     Check if 'tokencmdname' exists and is executable. If an error
*     occures write a error message into 'buf' if not NULL. 
*     Otherwise write error messages to stderr.
*
*  INPUTS
*     const char *tokencmdname - command 
*     char *buf                - NULL or buffer for error message
*     size_t lbuf              - size of buf
*
*  NOTES
*     MT-NOTE: sge_get_token_cmd() is MT safe 
*
*  RESULT
*     int - error state
*         0 - OK
*         1 - Error
******************************************************************************/
int sge_get_token_cmd(const char *tokencmdname, char *buf, size_t lbuf)
{
    SGE_STRUCT_STAT sb;

    if (!tokencmdname || !strlen(tokencmdname)) {
       if (!buf) {
          fprintf(stderr, "%s\n", MSG_COMMAND_NOPATHFORTOKEN);
       } else {   
          sge_strlcpy(buf, MSG_COMMAND_NOPATHFORTOKEN, lbuf);
       }
       return 1;
    }   
    
    if (SGE_STAT(tokencmdname, &sb) == -1) {
       if (!buf) {
          fprintf(stderr, MSG_COMMAND_NOFILESTATUS_S , tokencmdname);
          fprintf(stderr, "\n");
       } else {
          snprintf(buf, lbuf, MSG_COMMAND_NOFILESTATUS_S , tokencmdname);
       }
       return 1;
    }   
    
    if (!(sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) {
       if (!buf) {
          fprintf(stderr, MSG_COMMAND_NOTEXECUTABLE_S , tokencmdname);
          fprintf(stderr, "\n");
       } else {
          snprintf(buf, lbuf, MSG_COMMAND_NOTEXECUTABLE_S , tokencmdname);
       }
       return 1;
    }
    
    return 0;
}
Exemplo n.º 3
0
/****** count_exit_status *****************************************************
*  NAME
*     count_exit_status() -- Return the number of lines in the exit status file
*
*  SYNOPSIS
*     int count_exit_status(void)
*
*  FUNCTION
*     Returns the number of lines in the exit_status file.
*     Each pe_start, prolog, job, epilog and pe_stop write a line to the
*     exit_status file.
*     This function is used to detect where the shepherd fails.
*
*  INPUTS
*     void - none
*
*  RESULT
*     int - Number of lines in the exit_status file.
*******************************************************************************/
int count_exit_status(void)
{
   int n = 0;
   SGE_STRUCT_STAT sbuf;

   if (!SGE_STAT("exit_status", &sbuf) && sbuf.st_size)
   {
      FILE *fp;

      if ((fp = fopen("exit_status", "r")))
      {
         char buf[1024];
         while (fgets(buf, sizeof(buf), fp))
         {
            int dummy;
            if (sscanf(buf, "%d\n", &dummy) == 1) {
               n++;
            }
         }
         FCLOSE(fp);
      } 
   }
FCLOSE_ERROR:
   return n;
}
Exemplo n.º 4
0
/****** uti/prog/sge_get_alias_path() *****************************************
*  NAME
*     sge_get_alias_path() -- Return the path of the 'alias_file' 
*
*  SYNOPSIS
*     const char* sge_get_alias_path(void) 
*
*  FUNCTION
*     Return the path of the 'alias_file' 
*
*  NOTES
*     MT-NOTE: sge_get_alias_path() is MT safe
*
******************************************************************************/
const char *sge_get_alias_path(void) 
{
   const char *sge_root, *sge_cell;
   char *cp;
   int len;
   SGE_STRUCT_STAT sbuf;

   DENTER_(TOP_LAYER, "sge_get_alias_path");

   sge_root = sge_get_root_dir(1, NULL, 0, 1);
   sge_cell = sge_get_default_cell();

   if (SGE_STAT(sge_root, &sbuf)) {
      CRITICAL((SGE_EVENT, MSG_SGETEXT_SGEROOTNOTFOUND_S , sge_root));
      SGE_EXIT(NULL, 1);
   }

   len = strlen(sge_root) + strlen(sge_cell) + strlen(COMMON_DIR) + strlen(ALIAS_FILE) + 5;
   if (!(cp = malloc(len))) {
      CRITICAL((SGE_EVENT, MSG_MEMORY_MALLOCFAILEDFORPATHTOHOSTALIASFILE ));
      SGE_EXIT(NULL, 1);
   }

   sprintf(cp, "%s/%s/%s/%s", sge_root, sge_cell, COMMON_DIR, ALIAS_FILE);
   DRETURN_(cp);
}
Exemplo n.º 5
0
char *qmonReadText(const char *filename, lList **alpp)
{
   char *text = NULL;
   SGE_STRUCT_STAT statb;
   FILE *fp = NULL;

   DENTER(GUI_LAYER, "qmonReadText");

   if (filename == NULL) {
      answer_list_add_sprintf(alpp, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR,
                              "No filename specified");
      DRETURN(NULL);
   }

   /* 
   ** make sure the file is a regular text file and open it 
   */
   if (SGE_STAT(filename, &statb) == -1 
       || (statb.st_mode & S_IFMT) != S_IFREG 
       || !(fp = fopen(filename, "r"))) {
      answer_list_add_sprintf(alpp, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR,
                      MSG_FILE_OPENFAILED_S, filename);
      DRETURN(NULL);
   }

   /* 
   ** put the contents of the file in the Text widget by allocating
   ** enough space for the entire file, reading the file into the
   ** allocated space, and using XmTextFieldSetString() to show the file.
   */
   if ((text = XtMalloc((unsigned)(statb.st_size + 1))) == NULL) {
      answer_list_add_sprintf(alpp, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR,
                              "%s", MSG_MEMORY_MALLOCFAILED);
      FCLOSE(fp);
      DRETURN(NULL);
   }

   if (!fread(text, sizeof (char), statb.st_size + 1, fp)) {
      answer_list_add_sprintf(alpp, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR,
                              MSG_FILE_FREADFAILED_SS, filename, strerror(errno));
   }

   text[statb.st_size] = 0; /* be sure to NULL-terminate */

   FCLOSE(fp);
   DRETURN(text);

FCLOSE_ERROR:
   XtFree(text);
   answer_list_add_sprintf(alpp, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR,
                           MSG_FILE_NOCLOSE_SS, filename, strerror(errno));
   DRETURN(NULL);
}
/******* execd/loadsensor/sge_ls_create_ls() **********************************
*  NAME
*     sge_ls_create_ls -- creates a new CULL loadsensor element 
*
*  SYNOPSIS
*     static lListElem* sge_ls_create_ls(const char *qualified_hostname,
*                                        char *name, const char *scriptfile)
*
*  FUNCTION
*     The function creates a new CULL element of type LS_Type and
*     returns a pointer to this object. The loadsensor will be
*     started immediately.
*     If it cannot be started then, LS_has_to_restart is set to 
*     true so that it will be attempted to be restarted in the next load interval
*
*  INPUTS
*     qualified_hostname - qualified host name
*     name - pseudo name of the ls
*              "extern" for user defined loadsensors
*              "intern" for qidle and qloadsensor
*     scriptfile - absolute path to the ls scriptfile
*
*  RESULT
*     new CULL element of type LS_Type will be returned
*     and a new loadsensor process will be created by this function
******************************************************************************/
static lListElem *sge_ls_create_ls(const char *qualified_hostname, char *name, const char *scriptfile)
{
   lListElem *new_ls = NULL;    /* LS_Type */
   SGE_STRUCT_STAT st;

   DENTER(TOP_LAYER, "sge_ls_create_ls");

   if (scriptfile != NULL) {
      if (SGE_STAT(scriptfile, &st) != 0) {
         if (strcmp(name, "extern") == 0) {
            WARNING((SGE_EVENT, MSG_LS_NOMODTIME_SS, scriptfile,
                   strerror(errno)));
         }
         DRETURN(NULL);
      }

      new_ls = lCreateElem(LS_Type);
      if (new_ls) {
         /* initialize all attributes */
         lSetString(new_ls, LS_name, name);
         lSetString(new_ls, LS_command, scriptfile);
         sge_ls_set_pid(new_ls, -1);
         lSetRef(new_ls, LS_in, NULL);
         lSetRef(new_ls, LS_out, NULL);
         lSetRef(new_ls, LS_err, NULL);
         lSetBool(new_ls, LS_has_to_restart, false);
         lSetUlong(new_ls, LS_tag, 0);
         lSetList(new_ls, LS_incomplete, lCreateList("", LR_Type));
         lSetList(new_ls, LS_complete, lCreateList("", LR_Type));
         lSetUlong(new_ls, LS_last_mod, st.st_mtime);

         /* start loadsensor, if couldn't set the restart flag so that we
          * restart it in the next load interval
          */
         if (sge_ls_start_ls(qualified_hostname, new_ls) != LS_OK) {
            lSetBool(new_ls, LS_has_to_restart, true);
         }
      }
   }
   DRETURN(new_ls);
}
Exemplo n.º 7
0
/****** uti/afsutil/sge_read_token() ******************************************
*  NAME
*     sge_read_token() -- read token from file 
*
*  SYNOPSIS
*     char* sge_read_token(const char *file) 
*
*  FUNCTION
*     Read token from file, malloc buffer, add '\0' byte and
*     return pointer to buffer.
*
*  INPUTS
*     const char *file - filename 
*
*  NOTES
*     MT-NOTE: sge_read_token() is MT safe
*
*  RESULT
*     char* - pointer to a malloced buffer or 
*             NULL if error occured
******************************************************************************/
char *sge_read_token(const char *file) 
{
   SGE_STRUCT_STAT sb;
   int fd;
   char *tokenbuf;
   size_t size;

   DENTER(TOP_LAYER, "sge_read_token");

   if (SGE_STAT(file, &sb)) {
      DTRACE;
      return NULL;
   }

   size = sb.st_size + 1;
   if (((SGE_OFF_T)size != sb.st_size + 1)
       || (tokenbuf = (char *) malloc(size)) == NULL) {
      DTRACE;
      return NULL;
   }

   if ((fd = SGE_OPEN2(file, O_RDONLY)) == -1) {
      DTRACE;
      return NULL;
   }

   if (read(fd, tokenbuf, sb.st_size) != sb.st_size) {
      DTRACE;
      close(fd);
      return NULL;
   }

   tokenbuf[sb.st_size] = '\0';

   close(fd);
   DEXIT;
   return tokenbuf;
}
Exemplo n.º 8
0
int pt_dispatch_proc_to_job(
lnk_link_t *job_list,
int time_stamp,
time_t last_time
) {
   char procnam[128];
   int fd = -1;
#if defined(LINUX)
   char buffer[BIGLINE];
   lListElem *pr = NULL;
   SGE_STRUCT_STAT fst;
   unsigned long utime, stime, vsize, pid;
   int pos_pid = lGetPosInDescr(PRO_Type, PRO_pid);
   int pos_utime = lGetPosInDescr(PRO_Type, PRO_utime);
   int pos_stime = lGetPosInDescr(PRO_Type, PRO_stime);
   int pos_vsize = lGetPosInDescr(PRO_Type, PRO_vsize);
   int pos_groups = lGetPosInDescr(PRO_Type, PRO_groups);
   int pos_rel = lGetPosInDescr(PRO_Type, PRO_rel);
   int pos_run = lGetPosInDescr(PRO_Type, PRO_run);
   int pos_io = lGetPosInDescr(PRO_Type, PRO_io);
   int pos_group = lGetPosInDescr(GR_Type, GR_group);
#else
   prstatus_t pr;
   prpsinfo_t pri;
#endif

#if defined(SOLARIS) || defined(ALPHA)   
   prcred_t proc_cred;
#endif

   int ret;
   u_long32 max_groups;
   gid_t *list;
   int groups=0;
   int pid_tmp;

   proc_elem_t *proc_elem = NULL;
   job_elem_t *job_elem = NULL;
   lnk_link_t *curr;
   double old_time = 0;
   uint64 old_vmem = 0;

   DENTER(TOP_LAYER, "pt_dispatch_proc_to_job");

   max_groups = sge_sysconf(SGE_SYSCONF_NGROUPS_MAX);
   if (max_groups <= 0) {
      ERROR((SGE_EVENT, SFNMAX, MSG_SGE_NGROUPS_MAXOSRECONFIGURATIONNECESSARY));
      DEXIT;
      return 1;  
   }   

   list = (gid_t*) malloc(max_groups*sizeof(gid_t));
   if (list == NULL) {
      ERROR((SGE_EVENT, SFNMAX, MSG_SGE_PTDISPATCHPROCTOJOBMALLOCFAILED));
      DEXIT;
      return 1;
   }

   /* find next valid entry in procfs */ 
   while ((dent = readdir(cwd))) {
      char *pidname;

      if (!dent->d_name)
         continue;
      if (!dent->d_name[0])
         continue;

      if (!strcmp(dent->d_name, "..") || !strcmp(dent->d_name, "."))
         continue;

      if (dent->d_name[0] == '.')
          pidname = &dent->d_name[1];
      else
          pidname = dent->d_name;

      if (atoi(pidname) == 0)
         continue;

#if defined(LINUX)
      /* check only processes which belongs to a GE job */
      if ((pr = get_pr(atoi(pidname))) != NULL) {
         /* set process as still running */
         lSetPosBool(pr, pos_run, true);
         if (lGetPosBool(pr, pos_rel) != true) {
            continue;
         }
      }
      sprintf(procnam, PROC_DIR "/%s/stat", dent->d_name);

      if (SGE_STAT(procnam, &fst)) {
         if (errno != ENOENT) {
#ifdef MONITOR_PDC
            INFO((SGE_EVENT, "could not stat %s: %s\n", procnam, strerror(errno)));
#endif
            touch_time_stamp(dent->d_name, time_stamp, job_list);
         }
         continue;
      }
      /* TODO (SH): This does not work with Linux 2.6. I'm looking for a workaround.
       * If the stat file was not changed since our last parsing there is no need to do it again
       */
      /*if (pr == NULL || fst.st_mtime > last_time) {*/
      {
#else
         sprintf(procnam, "%s/%s", PROC_DIR, dent->d_name);
#endif
         if ((fd = open(procnam, O_RDONLY, 0)) == -1) {
            if (errno != ENOENT) {
#ifdef MONITOR_PDC
               if (errno == EACCES)
                  INFO((SGE_EVENT, "(uid:"gid_t_fmt" euid:"gid_t_fmt") could not open %s: %s\n",
                           getuid(), geteuid(), procnam, strerror(errno)));
               else
                  INFO((SGE_EVENT, "could not open %s: %s\n", procnam, strerror(errno)));
#endif
                  touch_time_stamp(dent->d_name, time_stamp, job_list);
            }
            continue;
         }

         /** 
          ** get a list of supplementary group ids to decide
          ** whether this process will be needed;
          ** read also prstatus
          **/

#  if defined(LINUX)

         /* 
          * Read the line and append a 0-Byte 
          */
         if ((ret = read(fd, buffer, BIGLINE-1))<=0) {
            close(fd);
            if (ret == -1 && errno != ENOENT) {
#ifdef MONITOR_PDC
               INFO((SGE_EVENT, "could not read %s: %s\n", procnam, strerror(errno)));
#endif
               touch_time_stamp(dent->d_name, time_stamp, job_list);
            }
            continue;
         }
         buffer[BIGLINE-1] = '\0';

         /* 
          * get prstatus
          */
         ret = sscanf(buffer, "%lu %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu %*d %*d %*d %*d %*d %*d %*u %lu",
                      &pid,
                      &utime,
                      &stime,
                      &vsize);

         if (ret != 4) {
            close(fd);
            continue;
         }

         if (pr == NULL) {
            pr = lCreateElem(PRO_Type);
            lSetPosUlong(pr, pos_pid, pid);
            lSetPosBool(pr, pos_rel, false);
            append_pr(pr);
         }
         
         lSetPosUlong(pr, pos_utime, utime);
         lSetPosUlong(pr, pos_stime, stime);
         lSetPosUlong(pr, pos_vsize, vsize);
         
         close(fd);
      }
      /* mark this proc as running */
      lSetPosBool(pr, pos_run, true);

      /* 
       * get number of groups; 
       * get list of supplementary groups 
       */
      {
         char procnam[256];
         lList *groupTable = lGetPosList(pr, pos_groups);

         sprintf(procnam, PROC_DIR "/%s/status", dent->d_name);
         if (SGE_STAT(procnam, &fst) != 0) {
            if (errno != ENOENT) {
#ifdef MONITOR_PDC
               INFO((SGE_EVENT, "could not stat %s: %s\n", procnam, strerror(errno)));
#endif
               touch_time_stamp(dent->d_name, time_stamp, job_list);
            }
            continue;
         }

         groups = 0;
         if (fst.st_mtime < last_time && groupTable != NULL) {
            lListElem *group;

            for_each(group, groupTable) {
               list[groups] = lGetPosUlong(group, pos_group);
               groups++;
            }
         } else {
Exemplo n.º 9
0
/****** sge/opt/append_opts_from_default_files() *******************************
*  NAME
*     append_opts_from_default_files() -- parse default files 
*
*  SYNOPSIS
*     void append_opts_from_default_files(lList **pcmdline, 
*                                         lList **answer_list
*                                         char **envp,
*                                         char *def_files) 
*
*  FUNCTION
*     This function reads the defaults files pointed to by def_files[] if they
*     exist and parses them into an options list. 
*
*  INPUTS
*     lList **pcmdline - pointer to SPA_Type list, if list is NULL, it is
*                        created if the files contain any options 
*     lList* - answer list, AN_Type or NULL if everything ok
*        possible errors:
*           STATUS_ENOSUCHUSER - could not retrieve passwd info on me.user_name
*           STATUS_EDISK       - home directory for user is missing or cwd 
*                                cannot be read or file could not be opened 
*                                (is just a warning)
*           STATUS_EEXIST      - (parse_script_file), (is just a warning)
*           STATUS_EUNKNOWN    - (parse_script_file), error opening or 
*                                reading from existing file, (is just a warning)
*                                plus all other error stati returned by 
*                                parse_script_file, see there
*     char **envp      - environment pointer 
*     char **def_files - paths to default files
*
*******************************************************************************/
static void append_opts_from_default_files(u_long32 prog_number, 
                                           lList **pcmdline, 
                                           lList **answer_list,
                                           char **envp,
                                           char **def_files) 
{
   lList *alp;
   lListElem *aep;
   char **pstr;
   char **ppstr;
   SGE_STRUCT_STAT buf;
   int do_exit = 0;
   
   DENTER(TOP_LAYER, "append_opts_from_default_files");

   for (pstr = def_files; *pstr; pstr++) {
      int already_read;

      if (SGE_STAT(*pstr, &buf)<0) {
         DPRINTF(("-- defaults file %s does not exist\n", *pstr));
         continue;
      }

      already_read = 0; 
      for (ppstr = def_files; *ppstr != *pstr; ppstr++) {
         if (!sge_filecmp(*ppstr, *pstr)) {
            DPRINTF(("-- skipping %s as defaults file - already read as %s\n", 
               *pstr, *ppstr));
            already_read = 1; 
            break;
         }
      }
      if (already_read) {
         continue;
      }
      DPRINTF(("-- defaults file: %s\n", *pstr));

      alp = parse_script_file(prog_number, *pstr, "", pcmdline, envp, 
         FLG_HIGHER_PRIOR | FLG_USE_NO_PSEUDOS);

      for_each(aep, alp) {
         u_long32 status;
         answer_quality_t quality;

         status = lGetUlong(aep, AN_status);
         quality = (answer_quality_t)lGetUlong(aep, AN_quality);

         if (quality == ANSWER_QUALITY_ERROR) {
            DPRINTF(("%s", lGetString(aep, AN_text)));
            if (status == STATUS_EDISK) {
               /*
               ** we turn this error into a warning here
               */
               quality = ANSWER_QUALITY_WARNING;
            } else {
               do_exit = 1;
            }
         } else {
            DPRINTF(("Warning: Error: %s\n", lGetString(aep, AN_text)));
         }
         answer_list_add(answer_list, lGetString(aep, AN_text), status, 
                         quality);
      }
      lFreeList(&alp);

      if (do_exit) {
         for (pstr = def_files; *pstr; pstr++) {
            sge_free(pstr);
         }
         DRETURN_VOID;
      }
   }
Exemplo n.º 10
0
int 
checkpointed_file_exists(void)
{
   SGE_STRUCT_STAT buf;
   return !SGE_STAT("checkpointed", &buf);
}
Exemplo n.º 11
0
/****** uti/io/sge_file2string() **********************************************
*  NAME
*     sge_file2string() -- Load file into string
*
*  SYNOPSIS
*     char* sge_file2string(const char *fname, int *len)
*
*  FUNCTION
*     Load file into string. Returns a pointer to a string buffer containing
*     the file contents and the size of the buffer (= number of bytes read)
*     in the variable len.
*     If the file cannot be read (doesn't exist, permissions etc.), NULL is
*     returned as buffer and len is set to 0.
*
*  INPUTS
*     const char *fname - filename
*     int *len          - number of bytes read
*
*  RESULT
*     char* - malloced string buffer
*
*  SEE ALSO
*     uti/io/sge_string2file()
*     uti/io/sge_stream2string()
*
*  NOTES
*     MT-NOTE: sge_file2string() is MT safe
******************************************************************************/
char *sge_file2string(const char *fname, int *len)
{
   FILE *fp;
   SGE_STRUCT_STAT statbuf;
   int size, i;
   char *str;
 
   DENTER(CULL_LAYER, "sge_file2string");

   /* initialize len - in case of errors we want to return 0 
    * JG: TODO: it would be better to return -1. Check if calling
    * functions would handle this situation.
    */
   if (len != NULL) {
      *len = 0;
   }

   /* try file access, read file info */
   if (SGE_STAT(fname, &statbuf)) {
      DEXIT;
      return NULL;
   }
 
   size = statbuf.st_size;
 
   if ((fp = fopen(fname, "r")) == NULL) {
      ERROR((SGE_EVENT, MSG_FILE_FOPENFAILED_SS, fname, strerror(errno)));
      DEXIT;
      return NULL;
   }
 
   if ((str = malloc(size+1)) == NULL) {
      FCLOSE(fp);
      DEXIT;
      return NULL;
   }

   str[0] = '\0';

   /*
   ** With fread(..., size, 1, ...),
   ** Windows cannot read <size> bytes here, because in
   ** text mode the trailing ^Z is ignored.
   ** CRLF -> LF conversion reduces size even further.
   ** Therefore, the file has less than size-1 bytes if read
   ** in text (ascii) mode.
   ** Correctly, fread returns 0, because 0 elements of
   ** size <size> were read.
   */
   if (size > 0) {
#ifdef WIN32 /* fread call and evaluation of return value is different */
      i = fread(str, 1, size, fp);
      if (i == 0) {
         sge_free(&str);
         FCLOSE(fp);
         DEXIT;
         return NULL;
      }
      str[i] = '\0';    /* delimit this string */   
      if (len != NULL) {
         *len = i;
      }
#else
      i = fread(str, size, 1, fp);
      if (i != 1) {
         ERROR((SGE_EVENT, MSG_FILE_FREADFAILED_SS, fname, strerror(errno)));
         sge_free(&str);
         FCLOSE(fp);
         DEXIT;
         return NULL;
      }
      str[size] = '\0';    /* delimit this string */
      if (len != NULL) {
         *len = size;
      }
#endif
   } 
 
   FCLOSE(fp);

   DEXIT;
   return str;
FCLOSE_ERROR:
   sge_free(&str);
   DEXIT;
   return NULL;
}
Exemplo n.º 12
0
/****** err_trace/shepherd_trace_init_intern() *******************************
*  NAME
*     shepherd_trace_init_intern() -- Initialize shepherd's tracing. 
*
*  SYNOPSIS
*     static FILE* shepherd_trace_init(char *trace_file_path,
*													char *trace_file_name)
*
*  FUNCTION
*     Opens the shepherd's trace file and sets the FD_CLOEXEC-flag so it will
*     be closed automatically in an exec()-call.
*     Must be called with euid=admin user to work properly!
*
*  INPUTS
*     char *trace_file_path - either the whole path of the trace file (including
*                             the file itself)
*                             or NULL to retrieve the file pointer of an already
*                             opened trace file.
*     char *trace_file_name - the name of the trace file itself. Ignored when
*                             *trace_file_path is NULL.
* 
*  RESULT
*     FILE* - If successfully opened, the file pointer of shepherd's trace file.
*           - Otherwise NULL.
*******************************************************************************/
static FILE* shepherd_trace_init_intern(st_shepherd_file_t shepherd_file)
{
   static char     path[SGE_PATH_MAX];
   static bool     called = false;
   SGE_STRUCT_STAT statbuf;
   dstring         ds;
   char            buffer[SGE_PATH_MAX+128];
   char            tmppath[SGE_PATH_MAX];
   int             fd       = -1;
   FILE            *fp      = NULL;
   int             do_chown = 0;

  	/* 
  	 *  after changing into the jobs cwd we need an 
  	 *  absolute path to the error/trace file 
  	 */
	if (called == false) { 
      getcwd(path, sizeof(path)); 
		called=true;
	}

  	snprintf(tmppath, SGE_PATH_MAX,"%s/%s",path, g_shepherd_file_name[shepherd_file]);
   sge_strlcpy(g_shepherd_file_path[shepherd_file], tmppath, SGE_PATH_MAX);

	/* If the file does not exist, create it. Otherwise just open it. */
	if (SGE_STAT(tmppath, &statbuf)) {
	  fd = SGE_OPEN3(tmppath, O_RDWR | O_CREAT | O_APPEND, 0644);
      if (fd<0) {
         sge_dstring_init(&ds, buffer, sizeof(buffer));
         sge_dstring_sprintf(&ds, "creat(%s) failed: %s", tmppath, strerror(errno));
         shepherd_panic(buffer);
      }

      if (getuid() == SGE_SUPERUSER_UID) {
         /* We must give the file to the job owner later */
			do_chown = 1;
		} else {
         /* We are not root, so we have to own all files anyway. */
         do_chown = 0;
		}
	} else {
      /* The file already exists. We get here when
       * a) a exec() failed or
       * b) after the execution of prolog/job, when the job/epilog
       * tries to init the error/exit status files.
       *
       * In a root system we can just open the file, because we are either
       * root or the job user who owns the file.
       * In a admin user system we must set our euid to root to open it, then
       * it is the same as the root system.
       * In a test user system we are the owner of the file and can open it.
       *
       * When we are root (masked or not), we gave this file to the
       * prolog user/job user right after its creation. But we can have
       * 3 different users for prolog, job and epilog, so we must give
       * the file here to the next user.
       * This must be done via shepherd_trace_chown() in the shepherd
       * before we switch to this user there.
       * It can't be done here because we don't know if we are in 
       * case a) (exec failed) or case b) (after execution of prolog/job).
       */
      int  old_euid = SGE_SUPERUSER_UID;

      /*
       * Work around for CR 6293411:
       * See shepherd_trace_exit() for details.
       */
      if (getuid() == SGE_SUPERUSER_UID) {
         old_euid = geteuid();
         seteuid(SGE_SUPERUSER_UID);
      }

      fd = SGE_OPEN2(tmppath, O_RDWR | O_APPEND);
      if (fd<0) {
         sge_dstring_init(&ds, buffer, sizeof(buffer));
         sge_dstring_sprintf(&ds, "open(%s) failed: %s",
                             tmppath, strerror(errno));
         shepherd_panic(buffer);
      }
      do_chown = 0;

      /*
       * Switch back to admin user?
       */
      if (old_euid != SGE_SUPERUSER_UID) {
         seteuid(old_euid);
      }
	}

	/* Something went wrong. */
	if (fd<0) {
		return NULL;
	}

	/* To avoid to block stdin, stdout or stderr, dup the fd until it is >= 3 */
	if (fd<3) {
		dup_fd(&fd);
	}

	/* Set FD_CLOEXEC flag to automatically close the file in an exec() */
	if (!set_cloexec(fd)) {
      shepherd_panic("set_cloexec() failed");
		return NULL;
	}

   /*
	 * Now open a FILE* from the file descriptor, so we can use fprintf().
    */
	fp = fdopen(fd, "a");
   if (!fp) {
      sge_dstring_init(&ds, buffer, sizeof(buffer));
      sge_dstring_sprintf(&ds, "can't open %s file \"%s\": %s\n",
				              g_shepherd_file_name[shepherd_file], tmppath, 
                          strerror(errno));
      shepherd_panic(buffer);
      return NULL;
   }
	if (do_chown && strlen(g_job_owner) > 0) {
		shepherd_trace_chown_intern(g_job_owner, fp, shepherd_file);
	}
	return fp;
}
Exemplo n.º 13
0
/****** Interactive/qrsh/setEnvironment() ***************************************
*
*  NAME
*     setEnvironment() -- set environment from file
*
*  SYNOPSIS
*     static char *setEnvironment(const char *jobdir, char **wrapper);
*
*  FUNCTION
*     Reads environment variables and their values from file <envFileName>
*     and sets them in the actual process environment.
*     The file format conforms to the sge environment file format:
*     Each line contains a tuple:
*        <name>=<value>
*     Special handling for variable PWD: tries to change to named
*     directory.
*     Special handling for variable QRSH_COMMAND: is the command to be executed
*     by qrsh_starter. The value of this variable will be returned as command,
*     or NULL, if an error occurs.
*     Special handling for variable QRSH_WRAPPER: this is a wrapper to be called
*     instead of a shell to execute the command.
*     If this variable is contained in the environment, it will be returned in
*     the parameter wrapper. Memory will be allocated to hold the variable, it 
*     is in the responsibility of the caller to free this memory.
*     Special handling for variable DISPLAY: if it is already set, do not 
*     overwrite it. Usually  it is not set, but if ssh is used as transport
*     mechanism for qrsh, the ssh -X option can be used to enable 
*     X11 forwarding.
*
*  INPUTS
*     jobdir - the jobs spool directory
*     wrapper - buffer to take the path and name of a wrapper script
*
*  RESULT
*     command, if all actions could be performed
*     NULL,    if an error occured; possible errors are:
*                 - the environment file cannot be opened
*                 - a PWD entry is found, but changing to the named directory fails
*                 - necessary memory cannot be allocated
*                 - the variable QRSH_COMMAND is not found
*
****************************************************************************
*/
static char *setEnvironment(const char *jobdir, char **wrapper)
{
   char envFileName[SGE_PATH_MAX];
   FILE *envFile = NULL;
   char *line = NULL;
   char *command   = NULL;
   SGE_STRUCT_STAT statbuf;
   int size;
   bool set_display = true;

   *wrapper = NULL;

   /* don't set DISPLAY, if it is already set (e.g. by ssh) */
   if (getenv("DISPLAY") != NULL) {
      set_display = false;
   }

   snprintf(envFileName, SGE_PATH_MAX, "%s/environment", jobdir);
  
   /* check if environment file exists and
    * retrieve file size. We will take file size as maximum possible line length
    */
   if (SGE_STAT(envFileName, &statbuf) != 0) {
      qrsh_error(MSG_QRSH_STARTER_CANNOTOPENFILE_SS, envFileName, strerror(errno));
      return NULL;
   } 
   
   size = statbuf.st_size;
   line = (char *)malloc(size + 1);
   if (line == NULL) {
      qrsh_error(MSG_QRSH_STARTER_MALLOCFAILED_S, strerror(errno));
      return NULL;
   }

   /* open sge environment file */
   if ((envFile = fopen(envFileName, "r")) == NULL) {
      qrsh_error(MSG_QRSH_STARTER_CANNOTOPENFILE_SS, envFileName, strerror(errno));
      sge_free(&line);
      return NULL;
   }

   /* set all environment variables, change to directory named by PWD */
   while (fgets(line, size, envFile) != NULL) {
      /* clean trailing garbage (\n, \r, EOF ...) */
      char *c = &line[strlen(line)];
      while (iscntrl(*(--c))) {
         *c = 0;
      }

      /* skip setting of display variable */
      if (strncmp(line, "DISPLAY=", 8) == 0 && !set_display) {
         continue;
      }
      
      if (strncmp(line, "QRSH_COMMAND=", 13) == 0) {
         if ((command = (char *)malloc(strlen(line) - 13 + 1)) == NULL) {
            qrsh_error(MSG_QRSH_STARTER_MALLOCFAILED_S, strerror(errno));
            sge_free(&line);
            FCLOSE(envFile);
            return NULL;
         }
         strcpy(command, line + 13);
      } else if (strncmp(line, "QRSH_WRAPPER=", 13) == 0) {
         if (*(line + 13) == 0) {
            fprintf(stderr, "%s\n", MSG_QRSH_STARTER_EMPTY_WRAPPER);
         } else {
            if ((*wrapper = (char *)malloc(strlen(line) - 13 + 1)) == NULL) {
               qrsh_error(MSG_QRSH_STARTER_MALLOCFAILED_S, strerror(errno));
               sge_free(&line);
               FCLOSE(envFile); 
               return NULL;
            }
            strcpy(*wrapper, line + 13);
         }
      } else {
         const char *new_line = sge_replace_substring(line, "\\n", "\n");
         int put_ret;
         /* set variable */
         if (new_line != NULL) {
            put_ret = sge_putenv(new_line);
            sge_free(&new_line);
         } else {
            put_ret = sge_putenv(line);
         }
         if (put_ret == 0) {
            sge_free(&line);
            FCLOSE(envFile); 
            return NULL;
         }
      }
   }

   sge_free(&line);
   FCLOSE(envFile); 

   /* 
    * Use starter_method if it is supplied
    * and not overridden by QRSH_WRAPPER
    */
    
   if (*wrapper == NULL) {
      char *starter_method = get_conf_val("starter_method");
      if (starter_method != NULL && strcasecmp(starter_method, "none") != 0) { 
         char buffer[128];
         *wrapper = starter_method;
         snprintf(buffer, 128, "%s=%s", "SGE_STARTER_SHELL_PATH", ""); sge_putenv(buffer);
         snprintf(buffer, 128, "%s=%s", "SGE_STARTER_SHELL_START_MODE", "unix_behavior"); sge_putenv(buffer);
         snprintf(buffer, 128, "%s=%s", "SGE_STARTER_USE_LOGIN_SHELL", "false"); sge_putenv(buffer);
      } 
   }
   
   return command;
FCLOSE_ERROR:
   qrsh_error(MSG_FILE_ERRORCLOSEINGXY_SS, envFileName, strerror(errno));
   return NULL;
}