Beispiel #1
0
int save_tmsock(

  job *pjob)  /* pointer to job structure */
  {
  static int sizeofint = sizeof(int);

  if ((pjob->ji_stdout > 0) && (pjob->ji_stdout < 1024))
    {
    /* We don't have real port numbers (yet), so don't bother */

    return(0);
    }

  DBPRT(("saving extra job info stdout=%d stderr=%d taskid=%u nodeid=%u\n",

         pjob->ji_stdout,
         pjob->ji_stderr,
         pjob->ji_taskid,
         pjob->ji_nodeid));

  /* FIXME: need error checking here */

  save_struct((char *)&pjob->ji_stdout, sizeofint);
  save_struct((char *)&pjob->ji_stderr, sizeofint);
  save_struct((char *)&pjob->ji_taskid, sizeof(tm_task_id));
  save_struct((char *)&pjob->ji_nodeid, sizeof(tm_node_id));

  return(0);
  }  /* END save_tmsock() */
Beispiel #2
0
void feed::save_state(entry& rd) const
{
	// feed properties
	save_struct(rd, this, feed_map, sizeof(feed_map)/sizeof(feed_map[0]));

	// items
	entry::list_type& items = rd["items"].list();
	for (std::vector<feed_item>::const_iterator i = m_items.begin()
		, end(m_items.end()); i != end; ++i)
	{
		items.push_back(entry());
		entry& item = items.back();
		save_struct(item, &*i, feed_item_map, sizeof(feed_item_map)/sizeof(feed_item_map[0]));
	}
	
	// settings
	feed_settings sett_def;
	save_struct(rd, &m_settings, feed_settings_map
		, sizeof(feed_settings_map)/sizeof(feed_settings_map[0]), &sett_def);
	entry& add = rd["add_params"];
	add_torrent_params add_def;
	save_struct(add, &m_settings.add_args, add_torrent_map
		, sizeof(add_torrent_map)/sizeof(add_torrent_map[0]), &add_def);

	entry::list_type& history = rd["history"].list();
	for (std::map<std::string, time_t>::const_iterator i = m_added.begin()
		, end(m_added.end()); i != end; ++i)
	{
		history.push_back(entry());
		entry::list_type& item = history.back().list();
		item.push_back(entry(i->first));
		item.push_back(entry(i->second));
	}
}
Beispiel #3
0
int
job_or_resv_save_fs(void *pobj, int updatetype, int objtype)
{
	int	fds;
	int	openflags;
	int	redo;
	char	*filename;
	char	namebuf1[MAXPATHLEN+1];
	char	namebuf2[MAXPATHLEN+1];

	char		*path = (char*)0;
	char		*err_msg = (char*)0;
	char		*err_msgl = (char*)0;
	char		*prefix = (char*)0;
	char		*suffix = (char*)0;
	char		*cpsuffix = (char*)0;

	char		*p_oid = (char*)0;
	long		*p_mtime = (long*)0;
	int		*p_modified = (int*)0;
	void		*pfixed = (void*)0;
	ssize_t		i;
	size_t		fixed_size;
	attribute_def	*p_attr_def = (attribute_def*)0;
	attribute	*wattr = (attribute*)0;
	int		final_attr;
	int		eventclass;
	int		pmode;

#ifdef WIN32
	pmode = _S_IWRITE | _S_IREAD;
#else
	pmode = 0600;
#endif

	if (objtype == RESC_RESV_OBJECT || objtype == RESV_JOB_OBJECT) {
#ifndef PBS_MOM	/* MOM knows not of resc_resv structs */
		resc_resv  *presv;
		presv = (resc_resv *)pobj;
		err_msg = "reservation_save";
		err_msgl = "Link in reservation_save failed";
		path = path_resvs;
		prefix = presv->ri_qs.ri_fileprefix;
		suffix = RESV_FILE_SUFFIX;
		cpsuffix = RESV_FILE_COPY;
		p_modified = &presv->ri_modified;
		pfixed = (void *)&presv->ri_qs;
		fixed_size = sizeof(struct resvfix);
		p_attr_def = resv_attr_def;
		wattr = presv->ri_wattr;
		final_attr = RESV_ATR_LAST;
		p_mtime = &presv->ri_wattr[RESV_ATR_mtime].at_val.at_long;
		p_oid = presv->ri_qs.ri_resvID;
		eventclass = PBS_EVENTCLASS_RESV;
#else	/* PBS_MOM only: Execution will never come here for MOM */
		return (-1);
#endif
	}
	else if (objtype == JOB_OBJECT) {
		job   *pj = (job *)pobj;

#ifndef PBS_MOM	/*MOM knows not of resc_resv structs*/
		if (pj->ji_resvp) {
			int	rc = 0;

			if (updatetype == SAVEJOB_QUICK)
				rc = job_or_resv_save((void *)pj->ji_resvp,
					SAVERESV_QUICK,
					RESC_RESV_OBJECT);
			else if ((updatetype == SAVEJOB_FULL) ||
				(updatetype == SAVEJOB_FULLFORCE)  ||
				(updatetype == SAVEJOB_NEW))
				rc = job_or_resv_save((void *)pj->ji_resvp,
					SAVERESV_FULL,
					RESC_RESV_OBJECT);
			if (rc)
				return (rc);
		}
#endif
		err_msg = "job_save";
		err_msgl = "Link in job_save failed";
		path = path_jobs;
		if (*pj->ji_qs.ji_fileprefix != '\0')
			prefix = pj->ji_qs.ji_fileprefix;
		else
			prefix = pj->ji_qs.ji_jobid;
		suffix = JOB_FILE_SUFFIX;
		cpsuffix = JOB_FILE_COPY;
		p_modified = &pj->ji_modified;
		pfixed = (void *)&pj->ji_qs;
		fixed_size = sizeof(struct jobfix);
		p_attr_def = job_attr_def;
		wattr = pj->ji_wattr;
		final_attr = JOB_ATR_LAST;
		p_mtime = &pj->ji_wattr[JOB_ATR_mtime].at_val.at_long;
		p_oid = pj->ji_qs.ji_jobid;
		eventclass = PBS_EVENTCLASS_JOB;
		return (job_save_fs(pj, updatetype));
	} else {
		/*Don't expect to get here; incorrect object type*/
		return (-1);
	}

	(void)strcpy(namebuf1, path);		/* directory path */
	(void)strcat(namebuf1, prefix);
	(void)strcpy(namebuf2, namebuf1);	/* setup for later */
	(void)strcat(namebuf1, suffix);

	/*if an attribute changed (modified==1) update mtime*/

	if (*p_modified) {
		*p_mtime = time_now;
	}

	if (updatetype == SAVEJOB_QUICK || updatetype == SAVERESV_QUICK) {

		openflags =  O_WRONLY | O_Sync;
		fds = open(namebuf1, openflags, pmode);
		if (fds < 0) {
			log_err(errno, err_msg, "error on open");
			return (-1);
		}
#ifdef WIN32
		secure_file(namebuf1, "Administrators",
			READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
		setmode(fds, O_BINARY);
#endif
		/* just write the "critical" base structure to the file */

		while ((i = write(fds, (char *)pfixed, fixed_size)) !=
			fixed_size) {
			if ((i < 0) && (errno == EINTR)) {
				/* retry the write */
				if (lseek(fds, (off_t)0, SEEK_SET) < 0) {
					log_err(errno, err_msg, "lseek");
					(void)close(fds);
					return (-1);
				}
				continue;
			} else {
				log_err(errno, err_msg, "quickwrite");
				(void)close(fds);
				return (-1);
			}
		}
#ifdef WIN32
		if (_commit(fds) != 0) {
			log_err(errno, err_msg,
				"flushing job file to disk failed!");
			(void)close(fds);
			return (-1);
		}
#endif
		(void)close(fds);

	} else {

		/*
		 * write the whole structure to the file.
		 * For a update, this is done to a new file to protect the
		 * old against crashs.
		 * The file is written in four parts:
		 * (1) the job (resc_resv) structure,
		 * (2) the attributes in "encoded" form,
		 * (3) the attributes in the "external" form, and last
		 * (4) the dependency list.
		 */

		(void)strcat(namebuf2, cpsuffix);
		openflags =  O_CREAT | O_WRONLY | O_Sync;
#ifdef WIN32
		fix_perms2(namebuf2, namebuf1);
#endif
		if (updatetype == SAVEJOB_NEW || updatetype == SAVERESV_NEW)
			filename = namebuf1;
		else
			filename = namebuf2;

		fds = open(filename, openflags, pmode);
		if (fds < 0) {
			log_err(errno, err_msg, "open for full save");
			return (-1);
		}

#ifdef WIN32
		secure_file(filename, "Administrators",
			READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
		setmode(fds, O_BINARY);
#endif

		redo = 0;	/* try to save twice */
		do {
			save_setup(fds);
			if (save_struct((char *)pfixed, fixed_size) != 0) {
				redo++;
			} else if (save_attr_fs(p_attr_def, wattr, final_attr) != 0) {
				redo++;
			} else if (save_flush() != 0) {
				redo++;
			}
			if (redo != 0) {
				if (lseek(fds, (off_t)0, SEEK_SET) < 0) {
					log_err(errno, err_msg, "full lseek");
					redo++;
				}
			}
		} while (redo == 1);

#ifdef WIN32
		if (_commit(fds) != 0) {
			log_err(errno, err_msg,
				"flush job file to disk failed!");
			close(fds);
			return (-1);
		}
#endif

		(void)close(fds);
		if (redo > 1) {
			if (updatetype == SAVEJOB_FULL ||
				updatetype == SAVEJOB_FULLFORCE ||
				updatetype == SAVERESV_FULL)
				(void)unlink(namebuf2);
			return (-1);
		}

		if (updatetype == SAVEJOB_FULL ||
			updatetype == SAVEJOB_FULLFORCE ||
			updatetype == SAVERESV_FULL) {

#ifdef WIN32
			if (MoveFileEx(namebuf2, namebuf1,
				MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH) ==
				0) {
				errno = GetLastError();
				sprintf(log_buffer, "MoveFileEx(%s,%s) failed!",
					namebuf2, namebuf1);
				log_err(errno, err_msg, log_buffer);
			}
			secure_file(namebuf1, "Administrators",
				READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
#else
			if (rename(namebuf2, namebuf1) == -1) {
				log_event(PBSEVENT_ERROR|PBSEVENT_SECURITY,
					eventclass, LOG_ERR, p_oid, err_msgl);
			}
#endif
		}
		*p_modified = 0;
	}
	return (0);
}
Beispiel #4
0
int
job_save_fs(job *pjob, int updatetype)
{
#ifndef	PBS_MOM
	int	isarray = 0;
#endif	/* PBS_MOM */
	int	fds;
	int	i;
	char	*filename;
	char	namebuf1[MAXPATHLEN+1];
	char	namebuf2[MAXPATHLEN+1];
	int	openflags;
	int	redo;
	int	pmode;

#ifdef WIN32
	pmode = _S_IWRITE | _S_IREAD;
#else
	pmode = 0600;
#endif

	(void)strcpy(namebuf1, path_jobs);	/* job directory path */
	if (*pjob->ji_qs.ji_fileprefix != '\0')
		(void)strcat(namebuf1, pjob->ji_qs.ji_fileprefix);
	else
		(void)strcat(namebuf1, pjob->ji_qs.ji_jobid);
	(void)strcpy(namebuf2, namebuf1);	/* setup for later */
	(void)strcat(namebuf1, JOB_FILE_SUFFIX);

	/* if ji_modified is set, ie an attribute changed, then update mtime */

	if (pjob->ji_modified) {
		pjob->ji_wattr[JOB_ATR_mtime].at_val.at_long = time_now;
		pjob->ji_wattr[JOB_ATR_mtime].at_flags |= ATR_VFLAG_MODCACHE;

	}

	/* don't save if SubJob unless FULLFORCE.  This is done by Windows    */
	/* Server when ready to run job since separate send_job program needs */
	/* needs to be able to read up job structure from disk, not sharing   */
	/* the memory structures                                              */
	if ((pjob->ji_qs.ji_svrflags & JOB_SVFLG_SubJob) &&
		(updatetype != SAVEJOB_FULLFORCE)) {
		pjob->ji_modified = 0;
		return 0;	/* don't save subjob */
	}

	if (pjob->ji_qs.ji_jsversion != JSVERSION) {
		/* version of job structure changed, force full write */
		pjob->ji_qs.ji_jsversion = JSVERSION;
		updatetype = SAVEJOB_FULLFORCE;
	}

	if (updatetype == SAVEJOB_QUICK) {

		openflags =  O_WRONLY | O_Sync;
		fds = open(namebuf1, openflags, pmode);
		if (fds < 0) {
			log_err(errno, "job_save", "error on open");
			return (-1);
		}
#ifdef WIN32
		secure_file(namebuf1, "Administrators",
			READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
		setmode(fds, O_BINARY);
#endif

		/* just write the "critical" base structure to the file */

		save_setup(fds);
		if ((save_struct((char *)&pjob->ji_qs, fixedsize) == 0) &&
			(save_struct((char *)&pjob->ji_extended, extndsize) == 0) &&
			(save_flush() == 0)) {
#ifdef WIN32
			/* since the open() POSIX call provided does not */
			/* have O_Sync for synchronous writes, the following */
			/* will force flushing things onto disk */
			if (_commit(fds) != 0) {
				log_err(errno, "job_save",
					"flushing file to disk failed!");
				(void)close(fds);
				return (-1);
			}
#endif
			(void)close(fds);
		} else {
			log_err(errno, "job_save", "error quickwrite");
			(void)close(fds);
			return (-1);
		}

	} else {

		/*
		 * write the whole structure to the file.
		 * For a update, this is done to a new file to protect the
		 * old against crashs.
		 * The file is written in four parts:
		 * (1) the job structure,
		 * (2) the extended area,
		 * (3) if a Array Job, the index tracking table
		 * (4) the attributes in the "encoded "external form, and last
		 * (5) the dependency list.
		 */
#ifndef PBS_MOM
		/*
		 * For an Array Job, we only update it to disk periodically,
		 * otherwise we would be spending way too much time writting.
		 */

		isarray = (pjob->ji_qs.ji_svrflags & JOB_SVFLG_ArrayJob);
		if (isarray) {
			if ((pjob->ji_modifyct > 0) &&
				(updatetype != SAVEJOB_FULLFORCE)) {
				pjob->ji_modifyct--;
				return 0;
			} else {
				/* reset count and do write this time */
				pjob->ji_modifyct = 600;
			}
		}
#endif

		(void)strcat(namebuf2, JOB_FILE_COPY);
		openflags =  O_CREAT | O_WRONLY | O_Sync;

#ifdef WIN32
		fix_perms2(namebuf2, namebuf1);
#endif

		if (updatetype == SAVEJOB_NEW)
			filename = namebuf1;
		else
			filename = namebuf2;

		fds = open(filename, openflags, pmode);
		if (fds < 0) {
			log_err(errno, "job_save",
				"error opening for full save");
			return (-1);
		}

#ifdef WIN32
		secure_file(filename, "Administrators",
			READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
		setmode(fds, O_BINARY);
#endif

		for (i=0; i<MAX_SAVE_TRIES; ++i) {
			redo = 0;	/* try to save twice */
			save_setup(fds);
			if (save_struct((char *)&pjob->ji_qs, fixedsize)
				!= 0) {
				redo++;
			} else if (save_struct((char *)&pjob->ji_extended,
				extndsize) != 0) {
				redo++;
#ifndef PBS_MOM
			} else if (isarray &&
				(save_struct((char *)pjob->ji_ajtrk,
				pjob->ji_ajtrk->tkm_size) != 0)) {
				redo++;
#endif
			} else if (save_attr_fs(job_attr_def, pjob->ji_wattr,
				(int)JOB_ATR_LAST) != 0) {
				redo++;
			} else if (save_flush() != 0) {
				redo++;
			}
			if (redo != 0) {
				if (lseek(fds, (off_t)0, SEEK_SET) < 0) {
					log_err(errno, "job_save", "error lseek");
				}
			} else
				break;
		}

#ifdef WIN32
		if (_commit(fds) != 0) {
			log_err(errno, "job_save",
				"flushing file to disk failed!");
			(void)close(fds);
			return (-1);
		}
#endif

		(void)close(fds);
		if (i >= MAX_SAVE_TRIES) {
			if ((updatetype == SAVEJOB_FULL) ||
				(updatetype == SAVEJOB_FULLFORCE))
				(void)unlink(namebuf2);
			return (-1);
		}

		if ((updatetype == SAVEJOB_FULL) ||
			(updatetype == SAVEJOB_FULLFORCE)) {
#ifdef WIN32
			if (MoveFileEx(namebuf2, namebuf1,
				MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH) == 0) {

				errno = GetLastError();
				sprintf(log_buffer, "MoveFileEx(%s,%s) failed!",
					namebuf2, namebuf1);
				log_err(errno, "job_save", log_buffer);
			}
			secure_file(namebuf1, "Administrators",
				READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
#else
			if (rename(namebuf2, namebuf1) == -1) {
				log_event(PBSEVENT_ERROR|PBSEVENT_SECURITY,
					PBS_EVENTCLASS_JOB, LOG_ERR,
					pjob->ji_qs.ji_jobid,
					"rename in job_save failed");
			}
#endif
		}
		pjob->ji_modified = 0;
	}
	return (0);
}
Beispiel #5
0
int save_attr(

  struct attribute_def *padef,           /* pbs_attribute definition array */
  pbs_attribute        *pattr,           /* ptr to pbs_attribute value array */
  int                   numattr,         /* number of attributes in array */
  int                   fds,
  char                 *buf_ptr,         /* M */
  size_t               *space_remaining, /* O */
  size_t                buf_size)        /* I */

  {
  svrattrl    dummy;
  int         errct = 0;
  tlist_head  lhead;
  int         i;
  int         resc_access_perm = ATR_DFLAG_ACCESS;
  svrattrl   *pal;
  int         rc;

  /* encode each pbs_attribute which has a value (not non-set) */

  CLEAR_HEAD(lhead);

  for (i = 0;i < numattr;i++)
    {
    if ((padef + i)->at_type != ATR_TYPE_ACL)
      {
      /* NOTE: access lists are not saved this way */

      rc = (padef + i)->at_encode(
          pattr + i,
          &lhead,
          (padef + i)->at_name,
          NULL,
          ATR_ENCODE_SAVE,
          resc_access_perm);

      if (rc < 0)
        errct++;

      (pattr + i)->at_flags &= ~ATR_VFLAG_MODIFY;

      /* now that it has been encoded, block and save it */

      while ((pal = (svrattrl *)GET_NEXT(lhead)) != NULL)
        {
        if (save_struct((char *)pal, pal->al_tsize, fds, buf_ptr, space_remaining, buf_size) < 0)
          errct++;

        delete_link(&pal->al_link);

        free(pal);
        }
      }
    }  /* END for (i) */

  /* indicate last of attributes by writing dummy entry */

  memset(&dummy, 0, sizeof(dummy));

  dummy.al_tsize = ENDATTRIBUTES;

  if (save_struct((char *)&dummy, sizeof(dummy), fds, buf_ptr, space_remaining, buf_size) < 0)
    errct++;

  if (errct != 0)
    {
    return(-1);
    }

  /* SUCCESS */

  return(0);
  }  /* END save_attr() */
Beispiel #6
0
int job_save(

  job *pjob,  /* pointer to job structure */
  int  updatetype) /* 0=quick, 1=full     */

  {
  int fds;
  int i;
  char namebuf1[MAXPATHLEN];
  char namebuf2[MAXPATHLEN];
  int openflags;
  int redo;

  strcpy(namebuf1, path_jobs); /* job directory path */
  strcat(namebuf1, pjob->ji_qs.ji_fileprefix);
  strcpy(namebuf2, namebuf1); /* setup for later */

#ifdef PBS_MOM
  strcat(namebuf1, JOB_FILE_SUFFIX);
#else

  if (pjob->ji_isparent == TRUE)
    {
    strcat(namebuf1, JOB_FILE_TMP_SUFFIX);
    }
  else
    {
    strcat(namebuf1, JOB_FILE_SUFFIX);
    }

#endif

  /* if ji_modified is set, ie an attribute changed, then update mtime */

  if (pjob->ji_modified)
    {
    pjob->ji_wattr[JOB_ATR_mtime].at_val.at_long = time_now;
    }

  if (updatetype == SAVEJOB_QUICK)
    {
    openflags = O_WRONLY | O_Sync;

    /* NOTE:  open, do not create */

    fds = open(namebuf1, openflags, 0600);

    if (fds < 0)
      {
      char tmpLine[1024];

      snprintf(tmpLine, sizeof(tmpLine), "cannot open file '%s' for job %s in state %s (%s)",
               namebuf1,
               pjob->ji_qs.ji_jobid,
               PJobSubState[MAX(0,pjob->ji_qs.ji_substate)],
               (updatetype == 0) ? "quick" : "full");

      log_err(errno, "job_save", tmpLine);

      /* FAILURE */

      return(-1);
      }

    /* just write the "critical" base structure to the file */

    while ((i = write(fds, (char *) & pjob->ji_qs, quicksize)) != (ssize_t)quicksize)
      {
      if ((i < 0) && (errno == EINTR))
        {
        /* retry the write */

        if (lseek(fds, (off_t)0, SEEK_SET) < 0)
          {
          log_err(errno, "job_save", "lseek");

          fsync(fds);
          close(fds);

          return(-1);
          }

        continue;
        }
      else
        {
        log_err(errno, "job_save", "quickwrite");

        fsync(fds);
        close(fds);

        /* FAILURE */

        return(-1);
        }
      }

    fsync(fds);
    close(fds);
    }
  else /* SAVEJOB_FULL, SAVEJOB_NEW, SAVEJOB_ARY */
    {
    /*
     * write the whole structure to the file.
     * For a update, this is done to a new file to protect the
     * old against crashs.
     * The file is written in four parts:
     * (1) the job structure,
     * (2) the attribtes in "encoded" form,
     * (3) the attributes in the "external" form, and last
     * (4) the dependency list.
     */

    strcat(namebuf2, JOB_FILE_COPY);

    openflags = O_CREAT | O_WRONLY | O_Sync;

    /* NOTE:  create file if required */

    if (updatetype == SAVEJOB_NEW)
      fds = open(namebuf1, openflags, 0600);
    else
      fds = open(namebuf2, openflags, 0600);

    if (fds < 0)
      {
      log_err(errno, "job_save", "open for full save");

      return(-1);
      }

    for (i = 0;i < MAX_SAVE_TRIES;++i)
      {
      redo = 0; /* try to save twice */

      save_setup(fds);

      if (save_struct((char *)&pjob->ji_qs, (size_t)quicksize) != 0)
        {
        redo++;
        }
      else if (save_attr(job_attr_def, pjob->ji_wattr, (int)JOB_ATR_LAST) != 0)
        {
        redo++;
        }

#ifdef PBS_MOM
      else if (save_tmsock(pjob) != 0)
        {
        redo++;
        }
      else if (save_roottask(pjob) != 0)
        {
        redo++;
        }
      else if (save_jobflags(pjob) != 0)
        {
        redo++;
        }

#endif  /* PBS_MOM */
      else if (save_flush() != 0)
        {
        redo++;
        }

      if (redo != 0)
        {
        if (lseek(fds, (off_t)0, SEEK_SET) < 0)
          {
          log_err(errno, "job_save", "full lseek");
          }
        }
      else
        {
        break;
        }
      }  /* END for (i) */

    fsync(fds);
    close(fds);

    if (i >= MAX_SAVE_TRIES)
      {
      if (updatetype == SAVEJOB_FULL)
        unlink(namebuf2);

      return(-1);
      }

    if (updatetype == SAVEJOB_FULL)
      {
      unlink(namebuf1);

      if (rename(namebuf2,namebuf1) != 0)
        {
        LOG_EVENT(
          PBSEVENT_ERROR | PBSEVENT_SECURITY,
          PBS_EVENTCLASS_JOB,
          pjob->ji_qs.ji_jobid,
          "Link in job_save failed");
        }
      }

    pjob->ji_modified = 0;
    }  /* END (updatetype == SAVEJOB_QUICK) */

  return(0);
  }  /* END job_save() */
Beispiel #7
0
static int save_jobflags(job *pjob)
  {
  save_struct((char*)&pjob->ji_flags,sizeof(pjob->ji_flags));
  return 0;
  }
Beispiel #8
0
int
job_save_fs(job *pjob, int updatetype)
{
	int	fds;
	int	i;
	char	*filename;
	char	namebuf1[MAXPATHLEN+1];
	char	namebuf2[MAXPATHLEN+1];
	int	openflags;
	int	redo;
	int	pmode;

#ifdef WIN32
	pmode = _S_IWRITE | _S_IREAD;
#else
	pmode = 0600;
#endif

	(void)strcpy(namebuf1, path_jobs);	/* job directory path */
	if (*pjob->ji_qs.ji_fileprefix != '\0')
		(void)strcat(namebuf1, pjob->ji_qs.ji_fileprefix);
	else
		(void)strcat(namebuf1, pjob->ji_qs.ji_jobid);
	(void)strcpy(namebuf2, namebuf1);	/* setup for later */
	(void)strcat(namebuf1, JOB_FILE_SUFFIX);

	/* if ji_modified is set, ie an attribute changed, then update mtime */

	if (pjob->ji_modified) {
		pjob->ji_wattr[JOB_ATR_mtime].at_val.at_long = time_now;
		pjob->ji_wattr[JOB_ATR_mtime].at_flags |= ATR_VFLAG_MODCACHE;

	}

	if (pjob->ji_qs.ji_jsversion != JSVERSION) {
		/* version of job structure changed, force full write */
		pjob->ji_qs.ji_jsversion = JSVERSION;
		updatetype = SAVEJOB_FULLFORCE;
	}

	if (updatetype == SAVEJOB_QUICK) {

		openflags =  O_WRONLY;
		fds = open(namebuf1, openflags, pmode);
		if (fds < 0) {
			log_err(errno, "job_save", "error on open");
			return (-1);
		}
#ifdef WIN32
		secure_file(namebuf1, "Administrators",
			READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
		setmode(fds, O_BINARY);
#endif

		/* just write the "critical" base structure to the file */

		save_setup(fds);
		if ((save_struct((char *)&pjob->ji_qs, fixedsize) == 0) &&
			(save_struct((char *)&pjob->ji_extended, extndsize) == 0) &&
			(save_flush() == 0)) {
			(void)close(fds);
		} else {
			log_err(errno, "job_save", "error quickwrite");
			(void)close(fds);
			return (-1);
		}

	} else {

		/*
		 * write the whole structure to the file.
		 * For a update, this is done to a new file to protect the
		 * old against crashs.
		 * The file is written in four parts:
		 * (1) the job structure,
		 * (2) the extended area,
		 * (3) if a Array Job, the index tracking table
		 * (4) the attributes in the "encoded "external form, and last
		 * (5) the dependency list.
		 */

		(void)strcat(namebuf2, JOB_FILE_COPY);
		openflags =  O_CREAT | O_WRONLY;

#ifdef WIN32
		fix_perms2(namebuf2, namebuf1);
#endif

		if (updatetype == SAVEJOB_NEW)
			filename = namebuf1;
		else
			filename = namebuf2;

		fds = open(filename, openflags, pmode);
		if (fds < 0) {
			log_err(errno, "job_save",
				"error opening for full save");
			return (-1);
		}

#ifdef WIN32
		secure_file(filename, "Administrators",
			READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
		setmode(fds, O_BINARY);
#endif

		for (i=0; i<MAX_SAVE_TRIES; ++i) {
			redo = 0;	/* try to save twice */
			save_setup(fds);
			if (save_struct((char *)&pjob->ji_qs, fixedsize)
				!= 0) {
				redo++;
			} else if (save_struct((char *)&pjob->ji_extended,
				extndsize) != 0) {
				redo++;
#ifndef PBS_MOM
			} else if ((pjob->ji_qs.ji_svrflags & JOB_SVFLG_ArrayJob) &&
				(save_struct((char *)pjob->ji_ajtrk,
				pjob->ji_ajtrk->tkm_size) != 0)) {
				redo++;
#endif
			} else if (save_attr_fs(job_attr_def, pjob->ji_wattr,
				(int)JOB_ATR_LAST) != 0) {
				redo++;
			} else if (save_flush() != 0) {
				redo++;
			}
			if (redo != 0) {
				if (lseek(fds, (off_t)0, SEEK_SET) < 0) {
					log_err(errno, "job_save", "error lseek");
				}
			} else
				break;
		}


		(void)close(fds);
		if (i >= MAX_SAVE_TRIES) {
			if ((updatetype == SAVEJOB_FULL) ||
				(updatetype == SAVEJOB_FULLFORCE))
				(void)unlink(namebuf2);
			return (-1);
		}

		if ((updatetype == SAVEJOB_FULL) ||
			(updatetype == SAVEJOB_FULLFORCE)) {
#ifdef WIN32
			if (MoveFileEx(namebuf2, namebuf1,
				MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH) == 0) {

				errno = GetLastError();
				sprintf(log_buffer, "MoveFileEx(%s,%s) failed!",
					namebuf2, namebuf1);
				log_err(errno, "job_save", log_buffer);
			}
			secure_file(namebuf1, "Administrators",
				READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
#else
			if (rename(namebuf2, namebuf1) == -1) {
				log_event(PBSEVENT_ERROR|PBSEVENT_SECURITY,
					PBS_EVENTCLASS_JOB, LOG_ERR,
					pjob->ji_qs.ji_jobid,
					"rename in job_save failed");
			}
#endif
		}
		pjob->ji_modified = 0;
	}
	return (0);
}
Beispiel #9
0
int
que_save_fs(pbs_queue	*pque)
{
	int	fds;
	int	i;
	char	namebuf1[MAXPATHLEN];
	char	namebuf2[MAXPATHLEN];

	(void)strcpy(namebuf1, path_queues);
	(void)strcat(namebuf1, pque->qu_qs.qu_name);
	(void)strcpy(namebuf2, namebuf1);
	(void)strcat(namebuf2, ".new");

#ifdef WIN32
	fix_perms2(namebuf2, namebuf1);
#endif

	fds = open(namebuf2, O_CREAT | O_WRONLY | O_Sync, 0600);
	if (fds < 0) {
		sprintf(log_buffer, "error opening %s", namebuf2);
		log_err(errno, __func__, log_buffer);
		return (-1);
	}
#ifdef WIN32
	secure_file(namebuf2, "Administrators", READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
	setmode(fds, O_BINARY);
#endif

	/* set up save buffering system */

	save_setup(fds);

	/* save basic queue structure (fixed length stuff) */

	if (save_struct((char *)&pque->qu_qs, sizeof(struct queuefix)) != 0) {
		log_err(-1, __func__, "save_struct failed");
		(void)close(fds);
		return (-1);
	}

	/* save queue attributes  */

	if (save_attr_fs(que_attr_def, pque->qu_attr, (int)QA_ATR_LAST) != 0) {
		log_err(-1, __func__, "save_attr failed");
		(void)close(fds);
		return (-1);
	}

	if (save_flush() != 0) {	/* flush the save buffer */
		log_err(-1, __func__, "save_flush failed");
		(void)close(fds);
		return (-1);
	}

#ifdef WIN32
	if (_commit(fds) != 0) {
		log_err(errno, __func__, "flush queue file to disk failed!");
		close(fds);
		return (-1);
	}
#endif
	(void)close(fds);

#ifdef WIN32
	if (MoveFileEx(namebuf2, namebuf1,
		MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0) {

		errno = GetLastError();
		sprintf(log_buffer, "MoveFileEx(%s, %s) failed!",
			namebuf2, namebuf1);
		log_err(errno, __func__, log_buffer);
	}
	secure_file(namebuf1, "Administrators",
		READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
#else
	if (rename(namebuf2, namebuf1) < 0)
		log_err(errno, __func__, "unable to rename queue name");
#endif

	/*
	 * now search queue's attributes for access control lists,
	 * they are saved separately in their own file:
	 * ../priv/(attr name)/(queue name)
	 */

	for (i=0; i < (int)QA_ATR_LAST; i++) {
		if (pque->qu_attr[i].at_type == ATR_TYPE_ACL) {
			save_acl(&pque->qu_attr[i], &que_attr_def[i],
				que_attr_def[i].at_name, pque->qu_qs.qu_name);
		}
	}

	return (0);
}
Beispiel #10
0
int svr_save(

  struct server *ps,
  int            mode)

  {
#ifndef SERVER_XML
  static char *this_function_name = "svr_save";
  int i;
  int sdb;
  int save_acl(attribute *, attribute_def *, char *, char *);
#endif /* ndef SERVER_XML */

  /* save the server in xml only if configured */
#ifdef SERVER_XML
      return(svr_save_xml(ps,mode));
#endif /* def SERVER_XML */

#ifndef SERVER_XML
  if (mode == SVR_SAVE_QUICK)
    {
    sdb = open(path_svrdb, O_WRONLY | O_CREAT | O_Sync, 0600);

    if (sdb < 0)
      {
      log_err(errno, this_function_name, msg_svdbopen);

      return(-1);
      }

    while ((i = write(
                  sdb,
                  &ps->sv_qs,
                  sizeof(struct server_qs))) != sizeof(struct server_qs))
      {
      if ((i == -1) && (errno == EINTR))
        continue;

      log_err(errno, this_function_name, msg_svdbnosv);

      return(-1);
      }

    close(sdb);
    }
  else
    {
    /* SVR_SAVE_FULL Save */

    sdb = open(path_svrdb_new, O_WRONLY | O_CREAT | O_Sync, 0600);

    if (sdb < 0)
      {
      log_err(errno, this_function_name, msg_svdbopen);

      return(-1);
      }

    ps->sv_qs.sv_savetm = time_now;

    save_setup(sdb);

    if (save_struct((char *)&ps->sv_qs, sizeof(struct server_qs)) != 0)
      {
      snprintf(log_buffer, 1024, "cannot save data into server db, errno=%d (%s)",
               errno,
               pbs_strerror(errno));

      log_err(errno, this_function_name, log_buffer);

      close(sdb);

      return(-1);
      }

    if (save_attr(svr_attr_def, ps->sv_attr, (int)SRV_ATR_LAST) != 0)
      {
      close(sdb);

      return(-1);
      }

    if (save_flush() != 0)
      {
      close(sdb);

      return(-1);
      }

    /* new db successfully created, remove original db */

    close(sdb);

    unlink(path_svrdb);

    if (link(path_svrdb_new, path_svrdb) == -1)
      {
      snprintf(log_buffer, 1024, "cannot move new database to default database location, errno=%d (%s)",
               errno,
               pbs_strerror(errno));

      log_err(errno, this_function_name, log_buffer);
      }
    else
      {
      unlink(path_svrdb_new);
      }

    /* save the server acls to their own files: */
    /*  priv/svracl/(attr name)   */

    for (i = 0;i < SRV_ATR_LAST;i++)
      {
      if (ps->sv_attr[i].at_type == ATR_TYPE_ACL)
        save_acl(&ps->sv_attr[i], &svr_attr_def[i],
                 PBS_SVRACL, svr_attr_def[i].at_name);
      }
    }    /* END else (mode == SVR_SAVE_QUICK) */

  return(0);
#endif /* ndef SERVER_XML */
  }  /* END svr_save() */
Beispiel #11
0
int job_save(

  job *pjob,  /* pointer to job structure */
  int  updatetype, /* 0=quick, 1=full, 2=new     */
  int  mom_port)   /* if 0 ignore otherwise append to end of job name. this is for multi-mom mode */

  {
  int     fds;
  int     i;
  char    namebuf1[MAXPATHLEN];
  char    namebuf2[MAXPATHLEN];
  char    save_buf[SAVEJOB_BUF_SIZE];
  const char   *tmp_ptr = NULL;
  size_t  buf_remaining = sizeof(save_buf);

  int     openflags;
  int     redo;
  time_t  time_now = time(NULL);


#ifdef PBS_MOM
  tmp_ptr = JOB_FILE_SUFFIX;
#else
  if (pjob->ji_is_array_template == TRUE)
    tmp_ptr = (char *)JOB_FILE_TMP_SUFFIX;
  else
    tmp_ptr = (char *)JOB_FILE_SUFFIX;
#endif

  if (mom_port)
    {
    snprintf(namebuf1, MAXPATHLEN, "%s%s%d%s",
        path_jobs, pjob->ji_qs.ji_fileprefix, mom_port, tmp_ptr);
    snprintf(namebuf2, MAXPATHLEN, "%s%s%d%s",
        path_jobs, pjob->ji_qs.ji_fileprefix, mom_port, JOB_FILE_COPY);
    }
  else
    {
    snprintf(namebuf1, MAXPATHLEN, "%s%s%s",
        path_jobs, pjob->ji_qs.ji_fileprefix, tmp_ptr);
    snprintf(namebuf2, MAXPATHLEN, "%s%s%s",
        path_jobs, pjob->ji_qs.ji_fileprefix, JOB_FILE_COPY);
    }

  /* if ji_modified is set, ie an pbs_attribute changed, then update mtime */

  if (pjob->ji_modified)
    {
    pjob->ji_wattr[JOB_ATR_mtime].at_val.at_long = time_now;
    }

  if (updatetype == SAVEJOB_QUICK)
    {
    openflags = O_WRONLY | O_Sync;

    /* NOTE:  open, do not create */

    fds = open(namebuf1, openflags, 0600);

    if (fds < 0)
      {
      char tmpLine[1024];

      snprintf(tmpLine, sizeof(tmpLine), "cannot open file '%s' for job %s in state %s (%s)",
               namebuf1,
               pjob->ji_qs.ji_jobid,
               PJobSubState[MAX(0,pjob->ji_qs.ji_substate)],
               (updatetype == 0) ? "quick" : "full");

      log_err(errno, "job_save", tmpLine);

      /* FAILURE */

      return(-1);
      }

    /* just write the "critical" base structure to the file */

    while ((i = write_ac_socket(fds, (char *)&pjob->ji_qs, sizeof(pjob->ji_qs))) != sizeof(pjob->ji_qs))
      {
      if ((i < 0) && (errno == EINTR))
        {
        /* retry the write */

        if (lseek(fds, (off_t)0, SEEK_SET) < 0)
          {
          log_err(errno, "job_save", (char *)"lseek");

          close(fds);

          return(-1);
          }

        continue;
        }
      else
        {
        log_err(errno, "job_save", (char *)"quickwrite");

        close(fds);

        /* FAILURE */

        return(-1);
        }
      }

    close(fds);
    }
  else /* SAVEJOB_FULL, SAVEJOB_NEW, SAVEJOB_ARY */
    {
    /*
     * write the whole structure to the file.
     * For a update, this is done to a new file to protect the
     * old against crashs.
     * The file is written in four parts:
     * (1) the job structure,
     * (2) the attribtes in "encoded" form,
     * (3) the attributes in the "external" form, and last
     * (4) the dependency list.
     */

    openflags = O_CREAT | O_WRONLY | O_Sync;

    /* NOTE:  create file if required */

    if (updatetype == SAVEJOB_NEW)
      fds = open(namebuf1, openflags, 0600);
    else
      fds = open(namebuf2, openflags, 0600);

    if (fds < 0)
      {
      log_err(errno, "job_save", (char *)"open for full save");

      return(-1);
      }

    for (i = 0; i < MAX_SAVE_TRIES; i++)
      {
      redo = 0; /* try to save twice */

#ifndef PBS_MOM
      lock_ss();
#endif

      if (save_struct((char *)&pjob->ji_qs, sizeof(pjob->ji_qs), fds, save_buf, &buf_remaining, sizeof(save_buf)) != PBSE_NONE)
        {
        redo++;
        }
      else if (save_attr(job_attr_def,
            pjob->ji_wattr,
            JOB_ATR_LAST,
            fds,
            save_buf,
            &buf_remaining,
            sizeof(save_buf)) != PBSE_NONE)
        {
        redo++;
        }

#ifdef PBS_MOM
      else if (save_tmsock(pjob, fds, save_buf, &buf_remaining, sizeof(save_buf)) != PBSE_NONE)
        {
        redo++;
        }

#endif  /* PBS_MOM */
      else if (write_buffer(save_buf, sizeof(save_buf) - buf_remaining, fds) != PBSE_NONE)
        {
        redo++;
        }

#ifndef PBS_MOM
      unlock_ss();
#endif

      if (redo != 0)
        {
        if (lseek(fds, (off_t)0, SEEK_SET) < 0)
          {
          log_err(errno, "job_save", (char *)"full lseek");
          }
        }
      else
        {
        break;
        }
      }  /* END for (i) */

    close(fds);

    if (i >= MAX_SAVE_TRIES)
      {
      if (updatetype == SAVEJOB_FULL)
        unlink(namebuf2);

      return(-1);
      }

    if (updatetype == SAVEJOB_FULL)
      {
      unlink(namebuf1);

      if (link(namebuf2, namebuf1) == -1)
        {
        log_event(
          PBSEVENT_ERROR | PBSEVENT_SECURITY,
          PBS_EVENTCLASS_JOB,
          pjob->ji_qs.ji_jobid,
          (char *)"Link in job_save failed");
        }
      else
        {
        unlink(namebuf2);
        }
      }

    pjob->ji_modified = 0;
    }  /* END (updatetype == SAVEJOB_QUICK) */

  return(PBSE_NONE);
  }  /* END job_save() */