/* * acct_get_db_name - get database name of accouting storage * RET: database name, should be free-ed by caller */ extern char *acct_get_db_name(void) { char *db_name = NULL; char *location = slurm_get_accounting_storage_loc(); if (!location) db_name = xstrdup(DEFAULT_ACCOUNTING_DB); else { int i = 0; while(location[i]) { if (location[i] == '.' || location[i] == '/') { debug("%s doesn't look like a database " "name using %s", location, DEFAULT_ACCOUNTING_DB); break; } i++; } if (location[i]) { db_name = xstrdup(DEFAULT_ACCOUNTING_DB); xfree(location); } else db_name = location; } return db_name; }
/* * init() is called when the plugin is loaded, before any other functions * are called. Put global initialization here. */ extern int init ( void ) { static int first = 1; char *log_file = NULL; int rc = SLURM_SUCCESS; mode_t prot = 0600; struct stat statbuf; if (slurmdbd_conf) { fatal("The filetxt plugin should not " "be run from the slurmdbd. " "Please use a database plugin"); } /* This check for the slurm user id is a quick and dirty patch * to see if the controller is calling this, since we open the * file in append mode stats could fail on it if the file * isn't world writable. */ if (first && (getuid() == slurm_get_slurm_user_id())) { debug2("slurmdb_init() called"); log_file = slurm_get_accounting_storage_loc(); if (!log_file) log_file = xstrdup(DEFAULT_STORAGE_LOC); slurm_mutex_lock( &logfile_lock ); if (LOGFILE) fclose(LOGFILE); if (*log_file != '/') fatal("AccountingStorageLoc must specify an " "absolute pathname"); if (stat(log_file, &statbuf)==0)/* preserve current file mode */ prot = statbuf.st_mode; LOGFILE = fopen(log_file, "a"); if (LOGFILE == NULL) { error("open %s: %m", log_file); storage_init = 0; xfree(log_file); slurm_mutex_unlock( &logfile_lock ); return SLURM_ERROR; } else chmod(log_file, prot); xfree(log_file); if (setvbuf(LOGFILE, NULL, _IOLBF, 0)) error("setvbuf() failed"); LOGFILE_FD = fileno(LOGFILE); slurm_mutex_unlock( &logfile_lock ); storage_init = 1; /* since this can be loaded from many different places only tell us once. */ verbose("%s loaded", plugin_name); first = 0; } else { debug4("%s loaded", plugin_name); } return rc; }
static void _load_slurm_config(void) { acct_storage_backup_host = slurm_get_accounting_storage_backup_host(); acct_storage_host = slurm_get_accounting_storage_host(); acct_storage_loc = slurm_get_accounting_storage_loc(); acct_storage_pass = slurm_get_accounting_storage_pass(); acct_storage_port = slurm_get_accounting_storage_port(); acct_storage_type = slurm_get_accounting_storage_type(); acct_storage_user = slurm_get_accounting_storage_user(); auth_type = slurm_get_auth_type(); msg_timeout = slurm_get_msg_timeout(); plugin_dir = slurm_get_plugin_dir(); private_data = slurm_get_private_data(); slurm_user_id = slurm_get_slurm_user_id(); track_wckey = slurm_get_track_wckey(); }
static void _layout_conf_dbd(GtkTreeStore *treestore) { ListIterator itr = NULL; GtkTreeIter iter; config_key_pair_t *key_pair; int update = 0; time_t now = time(NULL); char tmp_str[128], *user_name = NULL; List dbd_config_list = NULL; /* first load accounting parms from slurm.conf */ char *acct_storage_backup_host = slurm_get_accounting_storage_backup_host(); char *acct_storage_host = slurm_get_accounting_storage_host(); char *acct_storage_loc = slurm_get_accounting_storage_loc(); char *acct_storage_pass = slurm_get_accounting_storage_pass(); uint32_t acct_storage_port = slurm_get_accounting_storage_port(); char *acct_storage_type = slurm_get_accounting_storage_type(); char *acct_storage_user = slurm_get_accounting_storage_user(); char *auth_type = slurm_get_auth_type(); uint16_t msg_timeout = slurm_get_msg_timeout(); char *plugin_dir = slurm_get_plugin_dir(); uint16_t private_data = slurm_get_private_data(); uint32_t slurm_user_id = slurm_get_slurm_user_id(); uint16_t track_wckey = slurm_get_track_wckey(); slurm_make_time_str(&now, tmp_str, sizeof(tmp_str)); add_display_treestore_line_with_font( update, treestore, &iter, "SLURM Configuration data as of", tmp_str, "bold"); add_display_treestore_line(update, treestore, &iter, "AccountingStorageBackupHost", acct_storage_backup_host); add_display_treestore_line(update, treestore, &iter, "AccountingStorageHost", acct_storage_host); add_display_treestore_line(update, treestore, &iter, "AccountingStorageLoc", acct_storage_loc); add_display_treestore_line(update, treestore, &iter, "AccountingStoragePass", acct_storage_pass); sprintf(tmp_str, "%u", acct_storage_port); add_display_treestore_line(update, treestore, &iter, "AccountingStoragePort", tmp_str); add_display_treestore_line(update, treestore, &iter, "AccountingStorageType", acct_storage_type); add_display_treestore_line(update, treestore, &iter, "AccountingStorageUser", acct_storage_user); add_display_treestore_line(update, treestore, &iter, "AuthType", auth_type); sprintf(tmp_str, "%u sec", msg_timeout); add_display_treestore_line(update, treestore, &iter, "MessageTimeout", tmp_str); add_display_treestore_line(update, treestore, &iter, "PluginDir", plugin_dir); private_data_string(private_data, tmp_str, sizeof(tmp_str)); add_display_treestore_line(update, treestore, &iter, "PrivateData", tmp_str); user_name = uid_to_string(slurm_user_id); sprintf(tmp_str, "%s(%u)", user_name, slurm_user_id); xfree(user_name); add_display_treestore_line(update, treestore, &iter, "SlurmUserId", tmp_str); add_display_treestore_line(update, treestore, &iter, "SLURM_CONF", default_slurm_config_file); add_display_treestore_line(update, treestore, &iter, "SLURM_VERSION", SLURM_VERSION_STRING); sprintf(tmp_str, "%u", track_wckey); add_display_treestore_line(update, treestore, &iter, "TrackWCKey", tmp_str); xfree(acct_storage_backup_host); xfree(acct_storage_host); xfree(acct_storage_loc); xfree(acct_storage_pass); xfree(acct_storage_type); xfree(acct_storage_user); xfree(auth_type); xfree(plugin_dir); /* now load accounting parms from slurmdbd.conf */ /* second load slurmdbd.conf parms */ if (!(dbd_config_list = slurmdb_config_get(NULL))) return; add_display_treestore_line_with_font( update, treestore, &iter, "\nSlurmDBD Configuration:", NULL, "bold"); itr = list_iterator_create(dbd_config_list); while ((key_pair = list_next(itr))) { add_display_treestore_line(update, treestore, &iter, key_pair->name, key_pair->value); } list_iterator_destroy(itr); }
extern List filetxt_jobacct_process_get_jobs(slurmdb_job_cond_t *job_cond) { char line[BUFFER_SIZE]; char *f[MAX_RECORD_FIELDS+1]; /* End list with null entry and, possibly, more data than we expected */ char *fptr = NULL, *filein = NULL; int i; FILE *fd = NULL; int lc = 0; int rec_type = -1; int job_id = 0, step_id = 0, uid = 0, gid = 0; filetxt_job_rec_t *filetxt_job = NULL; slurmdb_selected_step_t *selected_step = NULL; char *object = NULL; ListIterator itr = NULL, itr2 = NULL; int show_full = 0; List ret_job_list = list_create(slurmdb_destroy_job_rec); List job_list = list_create(_destroy_filetxt_job_rec); filein = slurm_get_accounting_storage_loc(); if (job_cond) { if (!job_cond->duplicates) itr2 = list_iterator_create(ret_job_list); } fd = _open_log_file(filein); while (fgets(line, BUFFER_SIZE, fd)) { lc++; fptr = line; /* break the record into NULL- terminated strings */ for (i = 0; i < MAX_RECORD_FIELDS; i++) { f[i] = fptr; fptr = strstr(fptr, " "); if (fptr == NULL) { fptr = strstr(f[i], "\n"); if (fptr) *fptr = 0; break; } else { *fptr++ = 0; } } if (i < MAX_RECORD_FIELDS) i++; f[i] = 0; if (i < HEADER_LENGTH) { continue; } rec_type = atoi(f[F_RECTYPE]); job_id = atoi(f[F_JOB]); uid = atoi(f[F_UID]); gid = atoi(f[F_GID]); if (rec_type == JOB_STEP) step_id = atoi(f[F_JOBSTEP]); else step_id = NO_VAL; if (!job_cond) { show_full = 1; goto no_cond; } if (job_cond->userid_list && list_count(job_cond->userid_list)) { itr = list_iterator_create(job_cond->userid_list); while((object = list_next(itr))) { if (atoi(object) == uid) { list_iterator_destroy(itr); goto founduid; } } list_iterator_destroy(itr); continue; /* no match */ } founduid: if (job_cond->groupid_list && list_count(job_cond->groupid_list)) { itr = list_iterator_create(job_cond->groupid_list); while((object = list_next(itr))) { if (atoi(object) == gid) { list_iterator_destroy(itr); goto foundgid; } } list_iterator_destroy(itr); continue; /* no match */ } foundgid: if ((rec_type == JOB_START) && job_cond->jobname_list && list_count(job_cond->jobname_list)) { itr = list_iterator_create(job_cond->jobname_list); while((object = list_next(itr))) { if (!strcasecmp(f[F_JOBNAME], object)) { list_iterator_destroy(itr); goto foundjobname; } } list_iterator_destroy(itr); continue; /* no match */ } foundjobname: if (job_cond->step_list && list_count(job_cond->step_list)) { itr = list_iterator_create(job_cond->step_list); while((selected_step = list_next(itr))) { if (selected_step->jobid != job_id) continue; /* job matches; does the step? */ if (selected_step->stepid == NO_VAL) { show_full = 1; list_iterator_destroy(itr); goto foundjob; } else if (rec_type != JOB_STEP || selected_step->stepid == step_id) { list_iterator_destroy(itr); goto foundjob; } } list_iterator_destroy(itr); continue; /* no match */ } else { show_full = 1; } foundjob: if ((rec_type == JOB_START) && job_cond->partition_list && list_count(job_cond->partition_list)) { itr = list_iterator_create(job_cond->partition_list); while((object = list_next(itr))) if (!strcasecmp(f[F_PARTITION], object)) { list_iterator_destroy(itr); goto foundp; } list_iterator_destroy(itr); continue; /* no match */ } foundp: no_cond: /* Build suitable tables with all the data */ switch(rec_type) { case JOB_START: if (i < F_JOB_ACCOUNT) { error("Bad data on a Job Start"); _show_rec(f); } else _process_start(job_list, f, lc, show_full, i); break; case JOB_STEP: if (i < F_MAX_VSIZE) { error("Bad data on a Step entry"); _show_rec(f); } else _process_step(job_list, f, lc, show_full, i); break; case JOB_SUSPEND: if (i < F_JOB_REQUID) { error("Bad data on a Suspend entry"); _show_rec(f); } else _process_suspend(job_list, f, lc, show_full, i); break; case JOB_TERMINATED: if (i < F_JOB_REQUID) { error("Bad data on a Job Term"); _show_rec(f); } else _process_terminated(job_list, f, lc, show_full, i); break; default: debug("Invalid record at line %d of input file", lc); _show_rec(f); break; } } if (ferror(fd)) { perror(filein); exit(1); } fclose(fd); itr = list_iterator_create(job_list); while((filetxt_job = list_next(itr))) { slurmdb_job_rec_t *slurmdb_job = _slurmdb_create_job_rec(filetxt_job, job_cond); if (slurmdb_job) { slurmdb_job_rec_t *curr_job = NULL; if (itr2) { list_iterator_reset(itr2); while((curr_job = list_next(itr2))) { if (curr_job->jobid == slurmdb_job->jobid) { list_delete_item(itr2); info("removing job %d", slurmdb_job->jobid); break; } } } list_append(ret_job_list, slurmdb_job); } } if (itr2) list_iterator_destroy(itr2); list_iterator_destroy(itr); list_destroy(job_list); xfree(filein); return ret_job_list; }
extern int filetxt_jobacct_process_archive(slurmdb_archive_cond_t *arch_cond) { char line[BUFFER_SIZE], *f[EXPIRE_READ_LENGTH], *fptr = NULL, *logfile_name = NULL, *old_logfile_name = NULL, *filein = NULL, *object = NULL; int file_err=0, new_file, i = 0, rc = SLURM_ERROR; expired_rec_t *exp_rec = NULL; expired_rec_t *exp_rec2 = NULL; List keep_list = list_create(_destroy_exp); List exp_list = list_create(_destroy_exp); List other_list = list_create(_destroy_exp); struct stat statbuf; mode_t prot = 0600; uid_t uid; gid_t gid; FILE *expired_logfile = NULL, *new_logfile = NULL; FILE *fd = NULL; int lc=0; int rec_type = -1; ListIterator itr = NULL; ListIterator itr2 = NULL; slurmdb_job_cond_t *job_cond = NULL; /* Figure out our expiration date */ time_t expiry; if (!arch_cond || !arch_cond->job_cond) { error("no job_cond was given for archive"); return SLURM_ERROR; } job_cond = arch_cond->job_cond; if (!arch_cond->archive_script) filein = slurm_get_accounting_storage_loc(); else filein = arch_cond->archive_script; expiry = time(NULL) - job_cond->usage_end; debug("Purging jobs completed prior to %d", (int)expiry); /* Open the current or specified logfile, or quit */ fd = _open_log_file(filein); if (stat(filein, &statbuf)) { perror("stat'ing logfile"); goto finished; } if ((statbuf.st_mode & S_IFLNK) == S_IFLNK) { error("%s is a symbolic link; --expire requires " "a hard-linked file name", filein); goto finished; } if (!(statbuf.st_mode & S_IFREG)) { error("%s is not a regular file; --expire " "only works on accounting log files", filein); goto finished; } prot = statbuf.st_mode & 0777; gid = statbuf.st_gid; uid = statbuf.st_uid; old_logfile_name = _prefix_filename(filein, ".old."); if (stat(old_logfile_name, &statbuf)) { if (errno != ENOENT) { fprintf(stderr,"Error checking for %s: ", old_logfile_name); perror(""); goto finished; } } else { error("Warning! %s exists -- please remove " "or rename it before proceeding", old_logfile_name); goto finished; } /* create our initial buffer */ while (fgets(line, BUFFER_SIZE, fd)) { lc++; fptr = line; /* break the record into NULL- terminated strings */ exp_rec = xmalloc(sizeof(expired_rec_t)); exp_rec->line = xstrdup(line); for (i = 0; i < EXPIRE_READ_LENGTH; i++) f[i] = fptr; /* Initialization for bad data read */ for (i = 0; i < EXPIRE_READ_LENGTH; i++) { f[i] = fptr; fptr = strstr(fptr, " "); if (fptr == NULL) break; else *fptr++ = 0; } exp_rec->job = atoi(f[F_JOB]); exp_rec->job_submit = atoi(f[F_JOB_SUBMIT]); rec_type = atoi(f[F_RECTYPE]); /* Odd, but complain some other time */ if (rec_type == JOB_TERMINATED) { if (expiry < atoi(f[F_TIMESTAMP])) { list_append(keep_list, exp_rec); continue; } if ((rec_type == JOB_START) && job_cond->partition_list && list_count(job_cond->partition_list)) { itr = list_iterator_create( job_cond->partition_list); while((object = list_next(itr))) if (!strcasecmp(f[F_PARTITION], object)) break; list_iterator_destroy(itr); if (!object) continue; /* no match */ } list_append(exp_list, exp_rec); debug2("Selected: %8d %d", exp_rec->job, (int)exp_rec->job_submit); } else { list_append(other_list, exp_rec); } } if (!list_count(exp_list)) { debug3("No job records were purged."); goto finished; } logfile_name = xmalloc(strlen(filein)+sizeof(".expired")); sprintf(logfile_name, "%s.expired", filein); new_file = stat(logfile_name, &statbuf); if ((expired_logfile = fopen(logfile_name, "a"))==NULL) { error("Error while opening %s", logfile_name); perror(""); xfree(logfile_name); goto finished; } if (new_file) { /* By default, the expired file looks like the log */ chmod(logfile_name, prot); if (chown(logfile_name, uid, gid) == -1) error("Couldn't change ownership of %s to %u:%u", logfile_name, uid, gid); } xfree(logfile_name); logfile_name = _prefix_filename(filein, ".new."); if ((new_logfile = fopen(logfile_name, "w"))==NULL) { error("Error while opening %s", logfile_name); perror(""); fclose(expired_logfile); goto finished; } chmod(logfile_name, prot); /* preserve file protection */ if (chown(logfile_name, uid, gid) == -1)/* and ownership */ error("2 Couldn't change ownership of %s to %u:%u", logfile_name, uid, gid); /* Use line buffering to allow us to safely write * to the log file at the same time as slurmctld. */ if (setvbuf(new_logfile, NULL, _IOLBF, 0)) { perror("setvbuf()"); fclose(expired_logfile); goto finished2; } list_sort(exp_list, (ListCmpF) _cmp_jrec); list_sort(keep_list, (ListCmpF) _cmp_jrec); /* if (params->opt_verbose > 2) { */ /* error("--- contents of exp_list ---"); */ /* itr = list_iterator_create(exp_list); */ /* while((exp_rec = list_next(itr))) */ /* error("%d", exp_rec->job); */ /* error("---- end of exp_list ---"); */ /* list_iterator_destroy(itr); */ /* } */ /* write the expired file */ itr = list_iterator_create(exp_list); while((exp_rec = list_next(itr))) { itr2 = list_iterator_create(other_list); while((exp_rec2 = list_next(itr2))) { if ((exp_rec2->job != exp_rec->job) || (exp_rec2->job_submit != exp_rec->job_submit)) continue; if (fputs(exp_rec2->line, expired_logfile)<0) { perror("writing expired_logfile"); list_iterator_destroy(itr2); list_iterator_destroy(itr); fclose(expired_logfile); goto finished2; } list_remove(itr2); _destroy_exp(exp_rec2); } list_iterator_destroy(itr2); if (fputs(exp_rec->line, expired_logfile)<0) { perror("writing expired_logfile"); list_iterator_destroy(itr); fclose(expired_logfile); goto finished2; } } list_iterator_destroy(itr); fclose(expired_logfile); /* write the new log */ itr = list_iterator_create(keep_list); while((exp_rec = list_next(itr))) { itr2 = list_iterator_create(other_list); while((exp_rec2 = list_next(itr2))) { if (exp_rec2->job != exp_rec->job) continue; if (fputs(exp_rec2->line, new_logfile)<0) { perror("writing keep_logfile"); list_iterator_destroy(itr2); list_iterator_destroy(itr); goto finished2; } list_remove(itr2); _destroy_exp(exp_rec2); } list_iterator_destroy(itr2); if (fputs(exp_rec->line, new_logfile)<0) { perror("writing keep_logfile"); list_iterator_destroy(itr); goto finished2; } } list_iterator_destroy(itr); /* write records in other_list to new log */ itr = list_iterator_create(other_list); while((exp_rec = list_next(itr))) { if (fputs(exp_rec->line, new_logfile)<0) { perror("writing keep_logfile"); list_iterator_destroy(itr); goto finished2; } } list_iterator_destroy(itr); if (rename(filein, old_logfile_name)) { perror("renaming logfile to .old."); goto finished2; } if (rename(logfile_name, filein)) { perror("renaming new logfile"); /* undo it? */ if (!rename(old_logfile_name, filein)) error("Please correct the problem " "and try again"); else error("SEVERE ERROR: Current accounting " "log may have been renamed %s;\n" "please rename it to \"%s\" if necessary, " "and try again", old_logfile_name, filein); goto finished2; } fflush(new_logfile); /* Flush the buffers before forking */ fflush(fd); file_err = slurm_reconfigure(); if (file_err) { file_err = 1; error("Error: Attempt to reconfigure SLURM failed."); if (rename(old_logfile_name, filein)) { perror("renaming logfile from .old."); goto finished2; } } if (fseek(fd, 0, SEEK_CUR)) { /* clear EOF */ perror("looking for late-arriving records"); goto finished2; } /* reopen new logfile in append mode, since slurmctld may write it */ if (freopen(filein, "a", new_logfile) == NULL) { perror("reopening new logfile"); goto finished2; } while (fgets(line, BUFFER_SIZE, fd)) { if (fputs(line, new_logfile)<0) { perror("writing final records"); goto finished2; } } rc = SLURM_SUCCESS; printf("%d jobs expired.\n", list_count(exp_list)); finished2: fclose(new_logfile); if (!file_err) { if (unlink(old_logfile_name) == -1) error("Unable to unlink old logfile %s: %m", old_logfile_name); } finished: xfree(filein); fclose(fd); list_destroy(exp_list); list_destroy(keep_list); list_destroy(other_list); xfree(old_logfile_name); xfree(logfile_name); return rc; }