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() */
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)); } }
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); }
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); }
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() */
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() */
static int save_jobflags(job *pjob) { save_struct((char*)&pjob->ji_flags,sizeof(pjob->ji_flags)); return 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); }
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); }
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() */
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() */