/** * @brief * Delete the job from the database * * @param[in] conn - Connection handle * @param[in] obj - Job information * * @return Error code * @retval -1 - Failure * @retval 0 - Success * @retval 1 - Success but no rows deleted * */ int pg_db_delete_job(pbs_db_conn_t *conn, pbs_db_obj_info_t *obj) { pbs_db_job_info_t *pj = obj->pbs_db_un.pbs_db_job; int rc = 0; SET_PARAM_STR(conn, pj->ji_jobid, 0); if (pbs_db_begin_trx(conn, 0, 0) != 0) goto err; if ((rc = pg_db_cmd(conn, STMT_DELETE_JOB, 1)) == -1) goto err; if (pg_db_cmd(conn, STMT_DELETE_JOBSCR, 1) == -1) goto err; if (pbs_db_end_trx(conn, PBS_DB_COMMIT) != 0) goto err; return rc; err: (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); return -1; }
/** * @brief * Save a queue to the database * * @param[in] pque - Pointer to the queue to save * @param[in] mode: * QUE_SAVE_FULL - Save full queue information (update) * QUE_SAVE_NEW - Save new queue information (insert) * * @return Error code * @retval 0 - Success * @retval 1 - Failure * */ int que_save_db(pbs_queue *pque, int mode) { pbs_db_que_info_t dbque; pbs_db_attr_info_t attr_info; pbs_db_obj_info_t obj; pbs_db_conn_t *conn = (pbs_db_conn_t *) svr_db_conn; int flag=0; svr_to_db_que(pque, &dbque); obj.pbs_db_obj_type = PBS_DB_QUEUE; obj.pbs_db_un.pbs_db_que = &dbque; /* load que_qs */ if (pbs_db_begin_trx(conn, 0, 0) !=0) goto db_err; if (mode == QUE_SAVE_NEW) { if (pbs_db_insert_obj(conn, &obj) != 0) goto db_err; flag = 1; } else if (mode == QUE_SAVE_FULL) { /* * Delete the queue and write it afresh * Deleting the queue removes all attributes automatically * Thus when reinserting, we add only the set attributes */ pbs_db_delete_obj(conn, &obj); if (pbs_db_insert_obj(conn, &obj) != 0) goto db_err; flag = 1; } else { /* que_qs*/ if (pbs_db_update_obj(conn, &obj) != 0) goto db_err; } /* que_attrs */ attr_info.parent_obj_type = PARENT_TYPE_QUE_ALL; /* que attr */ attr_info.parent_id = dbque.qu_name; if (save_attr_db(conn, &attr_info, que_attr_def, pque->qu_attr, (int)QA_ATR_LAST, flag) !=0) goto db_err; if (pbs_db_end_trx(conn, PBS_DB_COMMIT) != 0) goto db_err; return (0); db_err: strcpy(log_buffer, "que_save failed "); if (conn->conn_db_err != NULL) strncat(log_buffer, conn->conn_db_err, LOG_BUF_SIZE - strlen(log_buffer) - 1); log_err(-1, __func__, log_buffer); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); panic_stop_db(log_buffer); return (-1); }
int sched_save_db(struct sched *ps, int mode) { pbs_db_conn_t *conn = (pbs_db_conn_t *) svr_db_conn; pbs_db_sched_info_t dbsched; pbs_db_attr_info_t attr_info; pbs_db_obj_info_t obj; int flag=0; svr_to_db_sched(ps, &dbsched); obj.pbs_db_obj_type = PBS_DB_SCHED; obj.pbs_db_un.pbs_db_sched = &dbsched; if (mode == SVR_SAVE_QUICK) { /* save server_qs */ if (pbs_db_update_obj(conn, &obj) != 0) goto db_err; } else { /* SVR_SAVE_FULL Save */ if (pbs_db_begin_trx(conn, 0, 0) !=0) goto db_err; if (mode == SVR_SAVE_NEW) { if (pbs_db_insert_obj(conn, &obj) != 0) goto db_err; flag = 1; } else { /* server_qs */ if (pbs_db_update_obj(conn, &obj) != 0) { if (pbs_db_insert_obj(conn, &obj) != 0) goto db_err; } } /* svr_attrs */ attr_info.parent_obj_type = PARENT_TYPE_SCHED; /* svr attr */ attr_info.parent_id = pbs_server_id; if (save_attr_db(conn, &attr_info, sched_attr_def, ps->sch_attr, (int)SCHED_ATR_LAST, flag) !=0) goto db_err; if (pbs_db_end_trx(conn, PBS_DB_COMMIT) != 0) goto db_err; } return (0); db_err: strcpy(log_buffer, schedemsg); if (conn->conn_db_err != NULL) strncat(log_buffer, conn->conn_db_err, LOG_BUF_SIZE - strlen(log_buffer) - 1); log_err(-1, __func__, log_buffer); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); panic_stop_db(log_buffer); return (-1); }
/** * @brief * Recover a queue from the database * * @param[in] qname - Name of the queue to recover * * @return The recovered queue structure * @retval NULL - Failure * @retval !NULL - Success - address of recovered queue returned * */ pbs_queue * que_recov_db(char *qname) { pbs_queue *pq; pbs_db_que_info_t dbque; pbs_db_attr_info_t attr_info; pbs_db_obj_info_t obj; pbs_db_conn_t *conn = (pbs_db_conn_t *) svr_db_conn; obj.pbs_db_obj_type = PBS_DB_QUEUE; obj.pbs_db_un.pbs_db_que = &dbque; pq = que_alloc(qname); /* allocate & init queue structure space */ if (pq == (pbs_queue *)0) { log_err(-1, "que_recov", "que_alloc failed"); return ((pbs_queue *)0); } /* load server_qs */ strcpy(dbque.qu_name, qname); if (pbs_db_begin_trx(conn, 0, 0) !=0) goto db_err; /* read in job fixed sub-structure */ if (pbs_db_load_obj(conn, &obj) != 0) goto db_err; db_to_svr_que(pq, &dbque); attr_info.parent_id = pq->qu_qs.qu_name; attr_info.parent_obj_type = PARENT_TYPE_QUE_ALL; /* que attr */ /* read in que attributes */ if (recov_attr_db(conn, pq, &attr_info, que_attr_def, pq->qu_attr, (int)QA_ATR_LAST, 0) != 0) goto db_err; if (pbs_db_end_trx(conn, PBS_DB_COMMIT) != 0) goto db_err; /* all done recovering the queue */ return (pq); db_err: log_err(-1, "que_recov", "read of queuedb failed"); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); if (pq) que_free(pq); return 0; }
int sched_recov_db(void) { pbs_db_conn_t *conn = (pbs_db_conn_t *) svr_db_conn; pbs_db_sched_info_t dbsched; pbs_db_attr_info_t attr_info; pbs_db_obj_info_t obj; int rc; int index; /* load server_qs */ strcpy(dbsched.sched_name, pbs_server_id); if (pbs_db_begin_trx(conn, 0, 0) !=0) goto db_err; obj.pbs_db_obj_type = PBS_DB_SCHED; obj.pbs_db_un.pbs_db_sched = &dbsched; /* read in job fixed sub-structure */ if ((rc = pbs_db_load_obj(conn, &obj)) == -1) /* error */ goto db_err; if (rc == 0) { db_to_svr_sched(&scheduler, &dbsched); attr_info.parent_id = pbs_server_id; attr_info.parent_obj_type = PARENT_TYPE_SCHED; /* svr attr */ /* read in server attributes */ if (recov_attr_db(conn, &scheduler, &attr_info, sched_attr_def, scheduler.sch_attr, (int)SCHED_ATR_LAST, 0) != 0) goto db_err; } if (pbs_db_end_trx(conn, PBS_DB_COMMIT) != 0) goto db_err; if (pbs_conf.pbs_use_tcp == 0) { /* check if throughput mode is visible in non-TPP mode, if so make it invisible */ index = find_attr(sched_attr_def, ATTR_throughput_mode, SCHED_ATR_LAST); scheduler.sch_attr[index].at_flags = 0; } return (0); db_err: log_err(-1, "sched_recov", "read of scheduler db failed"); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); return -1; }
/** * @brief * Recover server information and attributes from server database * * @par FunctionalitY: * This function is only called on Server initialization at start up. * * @par Note: * server structure, extern struct server server, must be preallocated and * all default values should already be set. * * @see pbsd_init.c * * @return Error code * @retval 0 : On successful recovery and creation of server structure * @retval -1 : On failutre to open or read file. * */ int svr_recov_db(void) { pbs_db_conn_t *conn = (pbs_db_conn_t *) svr_db_conn; pbs_db_svr_info_t dbsvr; pbs_db_attr_info_t attr_info; pbs_db_obj_info_t obj; /* load server_qs */ strcpy(dbsvr.sv_name, pbs_server_id); if (pbs_db_begin_trx(conn, 0, 0) !=0) goto db_err; obj.pbs_db_obj_type = PBS_DB_SVR; obj.pbs_db_un.pbs_db_svr = &dbsvr; /* read in job fixed sub-structure */ if (pbs_db_load_obj(conn, &obj) != 0) goto db_err; db_to_svr_svr(&server, &dbsvr); attr_info.parent_id = pbs_server_id; attr_info.parent_obj_type = PARENT_TYPE_SERVER; /* svr attr */ /* read in server attributes */ if (recov_attr_db(conn, &server, &attr_info, svr_attr_def, server.sv_attr, (int)SRV_ATR_LAST, 0) != 0) goto db_err; if (pbs_db_end_trx(conn, PBS_DB_COMMIT) != 0) goto db_err; return (0); db_err: log_err(-1, "svr_recov", "error on recovering server attr"); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); return -1; }
/** * @brief * Function to migrate filesystem data to database. * Reads serverdb, scheddb, job files, node, nodestate, queue, resv information * from the filesystem and save them into the database. All the information is * recovered and saved into the database under a single database transaction, * so any failure rolls back all the updates to the database. If all the updates * to the database succeed, only then the respective files are deleted from the * filesystem, else no deletion takes place. * * @return Error code * @retval 0 : success * @retval -1 : Failure * */ int svr_migrate_data_from_fs(void) { int baselen; struct dirent *pdirent; DIR *dir; int had; char *job_suffix = JOB_FILE_SUFFIX; int job_suf_len = strlen(job_suffix); job *pjob = NULL; pbs_queue *pque; resc_resv *presv; char *psuffix; int rc; int recovered = 0; char basen[MAXPATHLEN+1]; char scrfile[MAXPATHLEN+1]; char jobfile[MAXPATHLEN+1]; char origdir[MAXPATHLEN+1]; int fd; struct stat stbuf; char *scrbuf = NULL; pbs_db_jobscr_info_t jobscr; pbs_db_obj_info_t obj; path_svrdb_new = build_path(path_priv, PBS_SERVERDB, new_tag); path_scheddb = build_path(path_priv, PBS_SCHEDDB, NULL); path_scheddb_new = build_path(path_priv, PBS_SCHEDDB, new_tag); path_queues = build_path(path_priv, PBS_QUEDIR, suffix_slash); path_resvs = build_path(path_priv, PBS_RESVDIR, suffix_slash); path_nodes = build_path(path_priv, NODE_DESCRIP, NULL); path_nodestate = build_path(path_priv, NODE_STATUS, NULL); /* If not a "create" initialization, recover server db */ /* and sched db */ if (chk_save_file(path_svrdb) != 0) { fprintf(stderr, "No serverdb found to update to datastore\n"); return (0); } if (setup_resc(1) == -1) { fprintf(stderr, "%s\n", log_buffer); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); return (-1); } init_server_attrs(); /* start a database transation for the whole recovery */ if (pbs_db_begin_trx(svr_db_conn, 0, 0) != 0) return (-1); /* preprocess the nodes file to convert old properties to resources */ if (setup_nodes_fs(1) == -1) { fprintf(stderr, "%s\n", log_buffer); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); return (-1); } /* Open the server database (save file) and read it in */ if (svr_recov_fs(path_svrdb) == -1) { fprintf(stderr, "%s\n", msg_init_baddb); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); return (-1); } /* save server information to database now */ if (svr_save_db(&server, SVR_SAVE_NEW) != 0) { fprintf(stderr, "Could not save server db\n"); if (svr_db_conn->conn_db_err) fprintf(stderr, "[%s]\n", (char*)svr_db_conn->conn_db_err); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); return (-1); } /* now do sched db */ if (sched_recov_fs(path_scheddb) == -1) { fprintf(stderr, "Unable to recover scheddb\n"); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); return (-1); } if (sched_save_db(&scheduler, SVR_SAVE_NEW) != 0) { fprintf(stderr, "Could not save scheduler db\n"); if (svr_db_conn->conn_db_err) fprintf(stderr, "[%s]\n", (char*)svr_db_conn->conn_db_err); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); return (-1); } /* save current working dir before any chdirs */ if (getcwd(origdir, MAXPATHLEN) == NULL) { fprintf(stderr, "getcwd failed\n"); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); return (-1); } if (chdir(path_queues) != 0) { fprintf(stderr, msg_init_chdir, path_queues); fprintf(stderr, "\n"); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); chdir(origdir); return (-1); } had = server.sv_qs.sv_numque; server.sv_qs.sv_numque = 0; dir = opendir("."); if (dir == (DIR *) 0) { fprintf(stderr, "%s\n", msg_init_noqueues); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); chdir(origdir); return (-1); } while (errno = 0, (pdirent = readdir(dir)) != (struct dirent *) 0) { if (chk_save_file(pdirent->d_name) == 0) { if ((pque = que_recov_fs(pdirent->d_name)) != (pbs_queue *) 0) { /* que_recov increments sv_numque */ fprintf(stderr, msg_init_recovque, pque->qu_qs.qu_name); fprintf(stderr, "\n"); if (que_save_db(pque, QUE_SAVE_NEW) != 0) { fprintf(stderr, "Could not save queue info for queue %s\n", pque->qu_qs.qu_name); if (svr_db_conn->conn_db_err) fprintf(stderr, "[%s]\n", (char*)svr_db_conn->conn_db_err); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); (void) closedir(dir); chdir(origdir); return (-1); } } } } if (errno != 0 && errno != ENOENT) { fprintf(stderr, "%s\n", msg_init_noqueues); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); (void) closedir(dir); chdir(origdir); return (-1); } (void) closedir(dir); if (had != server.sv_qs.sv_numque) { fprintf(stderr, msg_init_expctq, had, server.sv_qs.sv_numque); fprintf(stderr, "\n"); } /* Open and read in node list if one exists */ if (setup_nodes_fs(0) == -1) { fprintf(stderr, "%s\n", log_buffer); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); chdir(origdir); return (-1); } /* * Recover reservations. */ if (chdir(path_resvs) != 0) { fprintf(stderr, msg_init_chdir, path_resvs); fprintf(stderr, "\n"); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); chdir(origdir); return (-1); } dir = opendir("."); if (dir == (DIR *) 0) { fprintf(stderr, "%s\n", msg_init_noresvs); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); chdir(origdir); return (-1); } while (errno = 0, (pdirent = readdir(dir)) != (struct dirent *) 0) { if (chk_save_file(pdirent->d_name) == 0) { presv = (resc_resv *) job_or_resv_recov_fs(pdirent->d_name, RESC_RESV_OBJECT); if (presv != (resc_resv *) 0) { if (resv_save_db(presv, SAVERESV_NEW) != 0) { fprintf(stderr, "Could not save resv info for resv %s\n", presv->ri_qs.ri_resvID); if (svr_db_conn->conn_db_err) fprintf(stderr, "[%s]\n", (char*)svr_db_conn->conn_db_err); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); (void) closedir(dir); chdir(origdir); return (-1); } } } } if (errno != 0 && errno != ENOENT) { fprintf(stderr, "%s\n", msg_init_noresvs); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); (void) closedir(dir); chdir(origdir); return (-1); } (void) closedir(dir); /* * Recover jobs */ if (chdir(path_jobs) != 0) { fprintf(stderr, msg_init_chdir, path_jobs); fprintf(stderr, "\n"); chdir(origdir); return (-1); } had = server.sv_qs.sv_numjobs; server.sv_qs.sv_numjobs = 0; recovered = 0; dir = opendir("."); if (dir == (DIR *) 0) { if (had == 0) { fprintf(stderr, msg_init_nojobs); } else { fprintf(stderr, msg_init_exptjobs, had, 0); } fprintf(stderr, "\n"); } else { /* Now, for each job found ... */ while (errno = 0, (pdirent = readdir(dir)) != (struct dirent *) 0) { if (chk_save_file(pdirent->d_name) != 0) continue; /* recover the job */ baselen = strlen(pdirent->d_name) - job_suf_len; psuffix = pdirent->d_name + baselen; if (strcmp(psuffix, job_suffix)) continue; if ((pjob = job_recov_fs(pdirent->d_name, RECOV_SUBJOB)) == NULL) { (void)strcpy(basen, pdirent->d_name); psuffix = basen + baselen; (void)strcpy(psuffix, JOB_BAD_SUFFIX); (void)snprintf(log_buffer, sizeof(log_buffer), "moved bad file to %s", basen); log_event(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, LOG_NOTICE, msg_daemonname, log_buffer); continue; } if (pjob->ji_qs.ji_svrflags & JOB_SVFLG_SCRIPT) { /* load the job script file */ strcpy(scrfile, path_jobs); #ifndef WIN32 /* under WIN32, there's already a prefixed '/' */ (void) strcat(scrfile, "/"); #endif strcat(scrfile, pdirent->d_name); baselen = strlen(scrfile) - strlen(JOB_FILE_SUFFIX); scrfile[baselen] = 0; /* put null char */ strcat(scrfile, JOB_SCRIPT_SUFFIX); rc = 1; #ifdef WIN32 if ((fd = open(scrfile, O_BINARY | O_RDONLY)) != -1) #else if ((fd = open(scrfile, O_RDONLY)) != -1) #endif { /* load the script */ if (fstat(fd, &stbuf) == 0) { if ((scrbuf = malloc(stbuf.st_size + 1))) { if (read(fd, scrbuf, stbuf.st_size) == stbuf.st_size) { scrbuf[stbuf.st_size] = '\0'; /* null character */ rc = 0; /* success loading */ } } } close(fd); } if (rc != 0) { fprintf(stderr, "Could not recover script file for job %s\n", pjob->ji_qs.ji_jobid); (void) strcpy(basen, scrfile); psuffix = basen + strlen(scrfile) - strlen(JOB_SCRIPT_SUFFIX); (void) strcpy(psuffix, JOB_BAD_SUFFIX); (void) strcpy(jobfile, scrfile); psuffix = jobfile + strlen(jobfile) - strlen(JOB_SCRIPT_SUFFIX); (void) strcpy(psuffix, JOB_FILE_SUFFIX); #ifdef WIN32 if (MoveFileEx(jobfile, basen, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0) { errno = GetLastError(); snprintf(log_buffer, sizeof(log_buffer), "MoveFileEx(%s, %s) failed!", jobfile, basen); log_err(errno, "script", log_buffer); } secure_file(basen, "Administrators", READS_MASK | WRITES_MASK | STANDARD_RIGHTS_REQUIRED); #else if (rename(jobfile, basen) == -1) { snprintf(log_buffer, sizeof(log_buffer), "error renaming job file %s", jobfile); log_err(errno, "job_recov", log_buffer); } #endif (void) snprintf(log_buffer, sizeof(log_buffer), "moved bad file to %s", basen); log_event(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, LOG_NOTICE, msg_daemonname, log_buffer); free(scrbuf); scrbuf = NULL; continue; } } /* now save job first */ if (job_save_db(pjob, SAVEJOB_NEW) != 0) { fprintf(stderr, "Could not save job info for jobid %s\n", pjob->ji_qs.ji_jobid); if (svr_db_conn->conn_db_err) fprintf(stderr, "[%s]\n", (char*)svr_db_conn->conn_db_err); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); (void) closedir(dir); chdir(origdir); free(scrbuf); return (-1); } if (pjob->ji_qs.ji_svrflags & JOB_SVFLG_SCRIPT) { /* save job script */ strcpy(jobscr.ji_jobid, pjob->ji_qs.ji_jobid); jobscr.script = scrbuf; obj.pbs_db_obj_type = PBS_DB_JOBSCR; obj.pbs_db_un.pbs_db_jobscr = &jobscr; if (pbs_db_insert_obj(svr_db_conn, &obj) != 0) { fprintf(stderr, "Could not save job script for jobid %s\n", pjob->ji_qs.ji_jobid); if (svr_db_conn->conn_db_err) fprintf(stderr, "[%s]\n", (char*)svr_db_conn->conn_db_err); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); free(scrbuf); (void) closedir(dir); chdir(origdir); return (-1); } free(scrbuf); scrbuf = NULL; } recovered++; } if (errno != 0 && errno != ENOENT) { if (pjob) fprintf(stderr, "readdir error for jobid %s\n", pjob->ji_qs.ji_jobid); else fprintf(stderr, "readdir error\n"); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); free(scrbuf); (void) closedir(dir); chdir(origdir); return (-1); } (void) closedir(dir); if (had != recovered) { fprintf(stderr, msg_init_exptjobs, had, recovered); fprintf(stderr, "\n"); } } if (save_nodes_db(0) != 0) { fprintf(stderr, "Could not save nodes\n"); if (svr_db_conn->conn_db_err) fprintf(stderr, "[%s]\n", (char*)svr_db_conn->conn_db_err); (void) pbs_db_end_trx(svr_db_conn, PBS_DB_ROLLBACK); chdir(origdir); return (-1); } if (pbs_db_end_trx(svr_db_conn, PBS_DB_COMMIT) == 0) { rm_migrated_files(path_priv); chdir(origdir); return (0); } chdir(origdir); return -1; }
int svr_save_db(struct server *ps, int mode) { pbs_db_conn_t *conn = (pbs_db_conn_t *) svr_db_conn; pbs_db_svr_info_t dbsvr; pbs_db_attr_info_t attr_info; pbs_db_obj_info_t obj; int flag=0; ps->sv_qs.sv_savetm = time_now; /* as part of the server save, update svrlive file now, * used in failover */ if (update_svrlive() !=0) return -1; svr_to_db_svr(ps, &dbsvr); obj.pbs_db_obj_type = PBS_DB_SVR; obj.pbs_db_un.pbs_db_svr = &dbsvr; if (mode == SVR_SAVE_QUICK) { /* save server_qs */ if (pbs_db_update_obj(conn, &obj) != 0) goto db_err; } else { /* SVR_SAVE_FULL Save */ if (pbs_db_begin_trx(conn, 0, 0) !=0) goto db_err; if (mode == SVR_SAVE_NEW) { if (pbs_db_insert_obj(conn, &obj) != 0) goto db_err; flag = 1; } else { /* FULL SAVE */ /* * remove all old attributes * and insert them back again */ pg_db_delete_svrattr(conn, &obj); /* server_qs */ if (pbs_db_update_obj(conn, &obj) != 0) goto db_err; flag = 1; /* so all set attributes are re-inserted back */ } /* svr_attrs */ attr_info.parent_obj_type = PARENT_TYPE_SERVER; /* svr attr */ attr_info.parent_id = pbs_server_id; if (save_attr_db(conn, &attr_info, svr_attr_def, ps->sv_attr, (int)SRV_ATR_LAST, flag) !=0) goto db_err; if (pbs_db_end_trx(conn, PBS_DB_COMMIT) != 0) goto db_err; } return (0); db_err: strcpy(log_buffer, msg_svdbnosv); if (conn->conn_db_err != NULL) strncat(log_buffer, conn->conn_db_err, LOG_BUF_SIZE - strlen(log_buffer) - 1); log_err(-1, __func__, log_buffer); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); panic_stop_db(log_buffer); return (-1); }
/** * @brief * The main function in C - entry point * * @param[in] argc - argument count * @param[in] argv - pointer to argument array * * @return int * @retval 0 - success * @retval !0 - error */ int main(int argc, char *argv[]) { int i, rc; char passwd[MAX_PASSWORD_LEN + 1] = {'\0'}; char passwd2[MAX_PASSWORD_LEN + 1]; char *pquoted; char pwd_file[MAXPATHLEN + 1]; char userid[LOGIN_NAME_MAX + 1]; int fd, errflg = 0; int gen_pwd = 0; char sqlbuff[1024]; int db_conn_error=0; char *db_errmsg = NULL; int pmode; int change_user = 0; char *olduser; int update_db = 0; char getopt_format[5]; char prog[]="pbs_ds_password"; char errmsg[PBS_MAX_DB_CONN_INIT_ERR + 1]; conn = NULL; pwd_file_new[0]=0; /*test for real deal or just version and exit*/ PRINT_VERSION_AND_EXIT(argc, argv); /* read configuration file */ if (pbs_loadconf(0) == 0) { fprintf(stderr, "%s: Could not load pbs configuration\n", prog); return (-1); } /* backup old user name */ if ((olduser = pbs_get_dataservice_usr(errmsg, PBS_MAX_DB_CONN_INIT_ERR)) == NULL) { fprintf(stderr, "%s: Could not retrieve current data service user\n", prog); if (strlen(errmsg) > 0) fprintf(stderr, "%s\n", errmsg); return (-1); } if (pbs_conf.pbs_data_service_host == NULL) update_db = 1; userid[0]=0; /* empty user id */ strcpy(getopt_format, "rC:"); while ((i = getopt(argc, argv, getopt_format)) != EOF) { switch (i) { case 'r': gen_pwd = 1; break; case 'C': strcpy(userid, optarg); break; case '?': default: errflg++; } } if (errflg) { fprintf(stderr, "\nusage:\t%s [-r] [-C username]\n", prog); fprintf(stderr, " \t%s --version\n", prog); return (-1); } /* NOTE : This functionality is added just for the automation testing purpose. * Usage: pbs_ds_password <password> */ if (argv[optind] != NULL) { gen_pwd = 0; strncpy(passwd, argv[optind], sizeof(passwd)); passwd[sizeof(passwd) - 1] = '\0'; } /* check admin privileges */ #ifdef WIN32 if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "pbs_ds_password: Must be run by Admin\n"); return (1); } #else if ((getuid() != 0) || (geteuid() != 0)) { fprintf(stderr, "%s: Must be run by root\n", prog); return (1); } #endif /* WIN32 */ change_user = 0; /* if the -C option was specified read the user from pbs.conf */ if (userid[0] != 0) { if (strcmp(olduser, userid) != 0) { change_user = 1; } } if (change_user == 1) { /* check that the supplied user-id exists (and is non-root on unix) */ if (check_user(userid) != 0) { #ifdef WIN32 fprintf(stderr, "\n%s: User-id %s does not exist\n", prog, userid); #else fprintf(stderr, "\n%s: User-id %s does not exist/is root user/home dir is not accessible\n", prog, userid); #endif return (-1); } } atexit(cleanup); if (update_db == 1) { /* then connect to database */ conn = pbs_db_init_connection(NULL, PBS_DB_CNT_TIMEOUT_NORMAL, 1, &db_conn_error, errmsg, PBS_MAX_DB_CONN_INIT_ERR); if (!conn) { get_db_errmsg(db_conn_error, &db_errmsg); fprintf(stderr, "%s: %s\n", prog, db_errmsg); if (strlen(errmsg) > 0) fprintf(stderr, "%s\n", errmsg); return -1; } db_conn_error = pbs_db_connect(conn); if (db_conn_error == PBS_DB_SUCCESS && change_user == 1) { /* able to connect ? Thats bad, PBS or dataservice is running */ fprintf(stderr, "%s: PBS Services and/or PBS Data Service is running\n", prog); fprintf(stderr, " Stop PBS and Data Services before changing Data Service user\n"); return (-1); } if (db_conn_error != PBS_DB_SUCCESS) { if (db_conn_error == PBS_DB_CONNREFUSED) { /* start db only if it was not already running */ if (pbs_startup_db(&db_errmsg) != 0) { if (db_errmsg) fprintf(stderr, "%s: Failed to start PBS dataservice:[%s]\n", prog, db_errmsg); else fprintf(stderr, "%s: Failed to start PBS dataservice\n", prog); return (-1); } started_db = 1; } db_conn_error = pbs_db_connect(conn); if (db_conn_error != PBS_DB_SUCCESS) { get_db_errmsg(db_conn_error, &db_errmsg); if (conn->conn_db_err) fprintf(stderr, "%s: Could not connect to PBS data service:%s:[%s]\n", prog, db_errmsg, (char*)conn->conn_db_err); else fprintf(stderr, "%s: Could not connect to PBS data service:%s\n", prog, db_errmsg); return (-1); } } } if (gen_pwd == 0 && passwd[0] == '\0') { /* ask user to enter password twice */ printf("Enter the password:"******"\nRe-enter the password:"******"\n\n"); if (strcmp(passwd, passwd2) != 0) { fprintf(stderr, "Entered passwords do not match\n"); return (-2); } if (strlen(passwd) == 0) { fprintf(stderr, "Blank password is not allowed\n"); return (-2); } } else if (gen_pwd == 1) { gen_password(passwd, 16); } rc = pbs_encrypt_pwd(passwd, &cred_type, &cred_buf, &cred_len); if (rc != 0) { fprintf(stderr, "%s: Failed to encrypt password\n", prog); return (-1); } /* escape password to use in sql strings later */ if ((pquoted = pbs_db_escape_str(conn, passwd)) == NULL) { fprintf(stderr, "%s: Out of memory\n", prog); return -1; } #ifdef WIN32 sprintf(pwd_file_new, "%s\\server_priv\\db_password.new", pbs_conf.pbs_home_path); sprintf(pwd_file, "%s\\server_priv\\db_password", pbs_conf.pbs_home_path); #else sprintf(pwd_file_new, "%s/server_priv/db_password.new", pbs_conf.pbs_home_path); sprintf(pwd_file, "%s/server_priv/db_password", pbs_conf.pbs_home_path); #endif /* write encrypted password to the password file */ #ifdef WIN32 pmode = _S_IWRITE | _S_IREAD; fix_perms2(pwd_file_new, pwd_file); if ((fd = open(pwd_file_new, O_WRONLY | O_TRUNC | O_CREAT | O_Sync | O_BINARY, pmode)) == -1) #else pmode = 0600; if ((fd = open(pwd_file_new, O_WRONLY | O_TRUNC | O_CREAT | O_Sync, pmode)) == -1) #endif { perror("open/create failed"); fprintf(stderr, "%s: Unable to create file %s\n", prog, pwd_file_new); return (-1); } #ifdef WIN32 secure_file(pwd_file_new, "Administrators", READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED); setmode(fd, O_BINARY); #endif if (update_db == 1) { /* change password only if this config option is not set */ if (pbs_db_begin_trx(conn, 0, 0) != 0) { fprintf(stderr, "%s: Could not start transaction\n", prog); unlink(pwd_file_new); return -1; } if (change_user == 1) { /* check whether user exists */ snprintf(sqlbuff, sizeof(sqlbuff), "select usename from pg_user where usename = '%s'", userid); if (pbs_db_execute_str(conn, sqlbuff) == 1) { /* now attempt to create new user & set the database passwd to the un-encrypted password */ snprintf(sqlbuff, sizeof(sqlbuff), "create user \"%s\" SUPERUSER ENCRYPTED PASSWORD '%s'", userid, pquoted); } else { /* attempt to alter new user & set the database passwd to the un-encrypted password */ snprintf(sqlbuff, sizeof(sqlbuff), "alter user \"%s\" SUPERUSER ENCRYPTED PASSWORD '%s'", userid, pquoted); } memset(passwd, 0, sizeof(passwd)); memset(passwd2, 0, sizeof(passwd2)); memset(pquoted, 0, (sizeof(char) * strlen(pquoted))); if (pbs_db_execute_str(conn, sqlbuff) == -1) { fprintf(stderr, "%s: Failed to create/alter user id %s\n", prog, userid); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); return -1; } } else { /* now attempt to set the database passwd to the un-encrypted password */ /* alter user ${user} SUPERUSER ENCRYPTED PASSWORD '${passwd}' */ sprintf(sqlbuff, "alter user \"%s\" SUPERUSER ENCRYPTED PASSWORD '%s'", olduser, pquoted); memset(passwd, 0, sizeof(passwd)); memset(passwd2, 0, sizeof(passwd2)); memset(pquoted, 0, (sizeof(char) * strlen(pquoted))); if (pbs_db_execute_str(conn, sqlbuff) == -1) { fprintf(stderr, "%s: Failed to create/alter user id %s\n", prog, userid); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); return -1; } } } if (write(fd, cred_buf, cred_len) != cred_len) { perror("write failed"); fprintf(stderr, "%s: Unable to write to file %s\n", prog, pwd_file_new); if (update_db == 1) { (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); } return -1; } close(fd); free(cred_buf); #ifdef WIN32 if (MoveFileEx(pwd_file_new, pwd_file, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0) { errno = GetLastError(); fprintf(stderr, "MoveFileEx(%s, %s) failed!", pwd_file_new, pwd_file); if (update_db == 1) { (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); } return (-1); } #else if (rename(pwd_file_new, pwd_file) != 0) { if (update_db == 1) { (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); } return (-1); } #endif if (update_db == 1) { /* commit to database */ (void) pbs_db_end_trx(conn, PBS_DB_COMMIT); cleanup(); /* cleanup will disconnect and delete tmp file too */ } printf("---> Updated user password\n"); if (update_db == 1 && change_user == 1) { printf("---> Updated user in datastore\n"); printf("---> Stored user password in datastore\n"); } if (change_user == 1) { char usr_file[MAXPATHLEN + 1]; #ifdef WIN32 sprintf(usr_file, "%s\\server_priv\\db_user", pbs_conf.pbs_home_path); #else sprintf(usr_file, "%s/server_priv/db_user", pbs_conf.pbs_home_path); #endif /* update PBS_HOME/server_priv/db_user file with the new user name */ if (update_db_usr(usr_file, userid) != 0) { fprintf(stderr, "Unable to update file %s\n", usr_file); return -1; } printf("---> Updated new user\n"); } if (update_db == 1 && change_user == 1) { char datastore[MAXPATHLEN + 1]; #ifndef WIN32 /* ownership is changed only for Unix users * On windows, these files are allways owned by the user who installed the database * and writable by administrators anyway */ sprintf(datastore, "%s/datastore", pbs_conf.pbs_home_path); /* change ownership of the datastore directories to the new user, so that db can be started again */ if (change_ownership(datastore, userid) != 0) { fprintf(stderr, "%s: Failed to change ownership on path %s\n", prog, datastore); return -1; } printf("---> Changed ownership of %s to user %s\n", datastore, userid); #endif /* reload configuration file */ if (pbs_loadconf(1) == 0) { fprintf(stderr, "%s: Could not load pbs configuration\n", prog); return (-1); } if (pbs_startup_db(&db_errmsg) != 0) { if (db_errmsg) fprintf(stderr, "%s: Failed to start PBS dataservice as new user:[%s]\n", prog, db_errmsg); else fprintf(stderr, "%s: Failed to start PBS dataservice as new user\n", prog); return (-1); } started_db = 1; /* connect again to drop the old user */ conn = pbs_db_init_connection(NULL, PBS_DB_CNT_TIMEOUT_NORMAL, 1, &db_conn_error, errmsg, PBS_MAX_DB_CONN_INIT_ERR); if (!conn) { get_db_errmsg(db_conn_error, &db_errmsg); fprintf(stderr, "%s: %s\n", prog, db_errmsg); if (strlen(errmsg) > 0) fprintf(stderr, "%s\n", errmsg); return -1; } db_conn_error = pbs_db_connect(conn); if (db_conn_error != PBS_DB_SUCCESS) { get_db_errmsg(db_conn_error, &db_errmsg); if (conn->conn_db_err) fprintf(stderr, "%s: Could not connect to PBS data service as new user:%s[%s]\n", prog, db_errmsg, (char*)conn->conn_db_err); else fprintf(stderr, "%s: Could not connect to PBS data service as new user:%s\n", prog, db_errmsg); return (-1); } /* delete the old user from the database */ sprintf(sqlbuff, "drop user \"%s\"", olduser); pbs_db_execute_str(conn, sqlbuff); } printf("---> Success\n"); return (0); }