Ejemplo n.º 1
0
extern int as_mysql_job_complete(mysql_conn_t *mysql_conn,
				 struct job_record *job_ptr)
{
	char *query = NULL;
	int rc = SLURM_SUCCESS, job_state;
	time_t submit_time, end_time;

	if (!job_ptr->db_index
	    && ((!job_ptr->details || !job_ptr->details->submit_time)
		&& !job_ptr->resize_time)) {
		error("as_mysql_job_complete: "
		      "Not inputing this job, it has no submit time.");
		return SLURM_ERROR;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	debug2("as_mysql_slurmdb_job_complete() called");

	if (job_ptr->resize_time)
		submit_time = job_ptr->resize_time;
	else
		submit_time = job_ptr->details->submit_time;

	if (IS_JOB_RESIZING(job_ptr)) {
		end_time = job_ptr->resize_time;
		job_state = JOB_RESIZING;
	} else {
		/* If we get an error with this just fall through to avoid an
		 * infinite loop */
		if (job_ptr->end_time == 0) {
			debug("as_mysql_jobacct: job %u never started",
			      job_ptr->job_id);
			return SLURM_SUCCESS;
		}
		end_time = job_ptr->end_time;
		job_state = job_ptr->job_state & JOB_STATE_BASE;
	}

	slurm_mutex_lock(&rollup_lock);
	if (end_time < global_last_rollup) {
		global_last_rollup = job_ptr->end_time;
		slurm_mutex_unlock(&rollup_lock);

		query = xstrdup_printf("update \"%s_%s\" set "
				       "hourly_rollup=%ld, "
				       "daily_rollup=%ld, monthly_rollup=%ld",
				       mysql_conn->cluster_name,
				       last_ran_table, end_time,
				       end_time, end_time);
		debug3("%d(%s:%d) query\n%s",
		       mysql_conn->conn, THIS_FILE, __LINE__, query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
	} else
		slurm_mutex_unlock(&rollup_lock);

	if (!job_ptr->db_index) {
		if (!(job_ptr->db_index =
		      _get_db_index(mysql_conn,
				    submit_time,
				    job_ptr->job_id,
				    job_ptr->assoc_id))) {
			/* Comment is overloaded in job_start to be
			   the block_id, so we will need to store this
			   for later.
			*/
			char *comment = job_ptr->comment;
			job_ptr->comment = NULL;
			/* If we get an error with this just fall
			 * through to avoid an infinite loop
			 */
			if (as_mysql_job_start(
				    mysql_conn, job_ptr) == SLURM_ERROR) {
				job_ptr->comment = comment;
				error("couldn't add job %u at job completion",
				      job_ptr->job_id);
				return SLURM_SUCCESS;
			}
			job_ptr->comment = comment;
		}
	}

	/*
	 * make sure we handle any quotes that may be in the comment
	 */

	query = xstrdup_printf("update \"%s_%s\" set "
			       "time_end=%ld, state=%d",
			       mysql_conn->cluster_name, job_table,
			       end_time, job_state);

	if (job_ptr->derived_ec != NO_VAL)
		xstrfmtcat(query, ", derived_ec=%u", job_ptr->derived_ec);

	if (job_ptr->comment) {
		char *comment = slurm_add_slash_to_quotes(job_ptr->comment);
		xstrfmtcat(query, ", derived_es='%s'", comment);
		xfree(comment);
	}

	xstrfmtcat(query,
		   ", exit_code=%d, kill_requid=%d where job_db_inx=%d;",
		   job_ptr->exit_code, job_ptr->requid,
		   job_ptr->db_index);

	debug3("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);

	return rc;
}
Ejemplo n.º 2
0
extern List as_mysql_remove_qos(mysql_conn_t *mysql_conn, uint32_t uid,
				slurmdb_qos_cond_t *qos_cond)
{
	ListIterator itr = NULL;
	List ret_list = NULL;
	int rc = SLURM_SUCCESS;
	char *object = NULL;
	char *extra = NULL, *query = NULL,
		*name_char = NULL, *assoc_char = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	int set = 0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;

	if (!qos_cond) {
		error("we need something to change");
		return NULL;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	xstrcat(extra, "where deleted=0");
	if (qos_cond->description_list
	    && list_count(qos_cond->description_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->description_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "description='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (qos_cond->id_list
	    && list_count(qos_cond->id_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->id_list);
		while ((object = list_next(itr))) {
			if (!object[0])
				continue;
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "id='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (qos_cond->name_list
	    && list_count(qos_cond->name_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->name_list);
		while ((object = list_next(itr))) {
			if (!object[0])
				continue;
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "name='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (!extra) {
		error("Nothing to remove");
		return NULL;
	}

	query = xstrdup_printf("select id, name from %s %s;", qos_table, extra);
	xfree(extra);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}

	name_char = NULL;
	ret_list = list_create(slurm_destroy_char);
	while ((row = mysql_fetch_row(result))) {
		slurmdb_qos_rec_t *qos_rec = NULL;

		list_append(ret_list, xstrdup(row[1]));
		if (!name_char)
			xstrfmtcat(name_char, "id='%s'", row[0]);
		else
			xstrfmtcat(name_char, " || id='%s'", row[0]);
		if (!assoc_char)
			xstrfmtcat(assoc_char, "id_qos='%s'", row[0]);
		else
			xstrfmtcat(assoc_char, " || id_qos='%s'", row[0]);
		xstrfmtcat(extra,
			   ", qos=replace(qos, ',%s', '')"
			   ", delta_qos=replace(delta_qos, ',+%s', '')"
			   ", delta_qos=replace(delta_qos, ',-%s', '')",
			   row[0], row[0], row[0]);

		qos_rec = xmalloc(sizeof(slurmdb_qos_rec_t));
		/* we only need id when removing no real need to init */
		qos_rec->id = slurm_atoul(row[0]);
		if (addto_update_list(mysql_conn->update_list,
				      SLURMDB_REMOVE_QOS, qos_rec)
		    != SLURM_SUCCESS)
			slurmdb_destroy_qos_rec(qos_rec);
	}
	mysql_free_result(result);

	if (!list_count(ret_list)) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		debug3("didn't effect anything\n%s", query);
		xfree(query);
		return ret_list;
	}
	xfree(query);

	/* remove this qos from all the users/accts that have it */
	query = xstrdup_printf("update %s set mod_time=%ld %s where deleted=0;",
			       assoc_table, now, extra);
	xfree(extra);
	debug3("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);
	if (rc != SLURM_SUCCESS) {
		reset_mysql_conn(mysql_conn);
		list_destroy(ret_list);
		return NULL;
	}

	user_name = uid_to_string((uid_t) uid);

	slurm_mutex_lock(&as_mysql_cluster_list_lock);
	itr = list_iterator_create(as_mysql_cluster_list);
	while ((object = list_next(itr))) {
		if ((rc = remove_common(mysql_conn, DBD_REMOVE_QOS, now,
					user_name, qos_table, name_char,
					assoc_char, object, NULL, NULL))
		    != SLURM_SUCCESS)
			break;
	}
	list_iterator_destroy(itr);
	slurm_mutex_unlock(&as_mysql_cluster_list_lock);

	xfree(assoc_char);
	xfree(name_char);
	xfree(user_name);
	if (rc == SLURM_ERROR) {
		list_destroy(ret_list);
		return NULL;
	}

	return ret_list;
}
Ejemplo n.º 3
0
extern int archive_write_file(Buf buffer, char *cluster_name,
			      time_t period_start, time_t period_end,
			      char *arch_dir, char *arch_type,
			      uint32_t archive_period)
{
	int fd = 0;
	int rc = SLURM_SUCCESS;
	char *old_file = NULL, *new_file = NULL, *reg_file = NULL;
	static int high_buffer_size = (1024 * 1024);
	static pthread_mutex_t local_file_lock = PTHREAD_MUTEX_INITIALIZER;

	xassert(buffer);

	slurm_mutex_lock(&local_file_lock);

	/* write the buffer to file */
	reg_file = _make_archive_name(period_start, period_end,
				      cluster_name, arch_dir,
				      arch_type, archive_period);

	debug("Storing %s archive for %s at %s",
	      arch_type, cluster_name, reg_file);
	old_file = xstrdup_printf("%s.old", reg_file);
	new_file = xstrdup_printf("%s.new", reg_file);

	fd = creat(new_file, 0600);
	if (fd < 0) {
		error("Can't save archive, create file %s error %m", new_file);
		rc = SLURM_ERROR;
	} else {
		int pos = 0, nwrite = get_buf_offset(buffer), amount;
		char *data = (char *)get_buf_data(buffer);
		high_buffer_size = MAX(nwrite, high_buffer_size);
		while (nwrite > 0) {
			amount = write(fd, &data[pos], nwrite);
			if ((amount < 0) && (errno != EINTR)) {
				error("Error writing file %s, %m", new_file);
				rc = SLURM_ERROR;
				break;
			}
			nwrite -= amount;
			pos    += amount;
		}
		fsync(fd);
		close(fd);
	}

	if (rc)
		(void) unlink(new_file);
	else {			/* file shuffle */
		(void) unlink(old_file);
		if (link(reg_file, old_file))
			debug4("Link(%s, %s): %m", reg_file, old_file);
		(void) unlink(reg_file);
		if (link(new_file, reg_file))
			debug4("Link(%s, %s): %m", new_file, reg_file);
		(void) unlink(new_file);
	}
	xfree(old_file);
	xfree(reg_file);
	xfree(new_file);
	slurm_mutex_unlock(&local_file_lock);

	return rc;
}
Ejemplo n.º 4
0
static int _cluster_remove_wckeys(mysql_conn_t *mysql_conn,
                                  char *extra,
                                  char *cluster_name,
                                  char *user_name,
                                  List ret_list)
{
    int rc = SLURM_SUCCESS;
    MYSQL_RES *result = NULL;
    MYSQL_ROW row;
    char *assoc_char = NULL;
    time_t now = time(NULL);
    char *query = xstrdup_printf("select t1.id_wckey, t1.wckey_name "
                                 "from \"%s_%s\" as t1%s;",
                                 cluster_name, wckey_table, extra);
    if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
        xfree(query);
        return SLURM_ERROR;
    }

    if (!mysql_num_rows(result)) {
        mysql_free_result(result);
        xfree(query);
        return SLURM_SUCCESS;
    }

    while ((row = mysql_fetch_row(result))) {
        slurmdb_wckey_rec_t *wckey_rec = NULL;

        list_append(ret_list, xstrdup(row[1]));
        if (!assoc_char)
            xstrfmtcat(assoc_char, "id_wckey='%s'", row[0]);
        else
            xstrfmtcat(assoc_char, " || id_wckey='%s'", row[0]);

        wckey_rec = xmalloc(sizeof(slurmdb_wckey_rec_t));
        /* we only need id and cluster when removing
           no real need to init */
        wckey_rec->id = slurm_atoul(row[0]);
        wckey_rec->cluster = xstrdup(cluster_name);
        if (addto_update_list(mysql_conn->update_list,
                              SLURMDB_REMOVE_WCKEY, wckey_rec)
                != SLURM_SUCCESS)
            slurmdb_destroy_wckey_rec(wckey_rec);
    }
    mysql_free_result(result);

    if (!list_count(ret_list)) {
        errno = SLURM_NO_CHANGE_IN_DATA;
        if (debug_flags & DEBUG_FLAG_DB_WCKEY)
            DB_DEBUG(mysql_conn->conn,
                     "didn't effect anything\n%s", query);
        xfree(query);
        xfree(assoc_char);
        return SLURM_SUCCESS;
    }

    xfree(query);
    rc = remove_common(mysql_conn, DBD_REMOVE_WCKEYS, now,
                       user_name, wckey_table, assoc_char, assoc_char,
                       cluster_name, NULL, NULL);
    xfree(assoc_char);

    if (rc == SLURM_ERROR) {
        list_destroy(ret_list);
        return SLURM_ERROR;
    }

    return SLURM_SUCCESS;
}
Ejemplo n.º 5
0
extern int slurm_jobcomp_log_record(struct job_record *job_ptr)
{
	int rc = SLURM_SUCCESS;
	char *usr_str = NULL, *grp_str = NULL, lim_str[32];
	char *connect_type = NULL, *reboot = NULL, *rotate = NULL,
		*geometry = NULL, *start = NULL,
		*blockid = NULL;
	enum job_states job_state;
	char *query = NULL;
	uint32_t time_limit, start_time, end_time;

	if(!jobcomp_pgsql_db || PQstatus(jobcomp_pgsql_db) != CONNECTION_OK) {
		char *loc = slurm_get_jobcomp_loc();
		if(slurm_jobcomp_set_location(loc) == SLURM_ERROR) {
			xfree(loc);
			return SLURM_ERROR;
		}
		xfree(loc);
	}

	usr_str = _get_user_name(job_ptr->user_id);
	grp_str = _get_group_name(job_ptr->group_id);

	if ((job_ptr->time_limit == NO_VAL) && job_ptr->part_ptr)
		time_limit = job_ptr->part_ptr->max_time;
	else
		time_limit = job_ptr->time_limit;
	if (time_limit == INFINITE)
		strcpy(lim_str, "UNLIMITED");
	else {
		snprintf(lim_str, sizeof(lim_str), "%lu",
			 (unsigned long) time_limit);
	}

	/* Job will typically be COMPLETING when this is called.
	 * We remove the flags to get the eventual completion state:
	 * JOB_FAILED, JOB_TIMEOUT, etc. */
	if (IS_JOB_RESIZING(job_ptr)) {
		job_state = JOB_RESIZING;
		if (job_ptr->resize_time)
			start_time = job_ptr->resize_time;
		else
			start_time = job_ptr->start_time;
		end_time = time(NULL);
	} else {
		job_state = job_ptr->job_state & JOB_STATE_BASE;
		if (job_ptr->resize_time)
			start_time = job_ptr->resize_time;
		else if (job_ptr->start_time > job_ptr->end_time) {
			/* Job cancelled while pending and
			 * expected start time is in the future. */
			start_time = 0;
		} else
			start_time = job_ptr->start_time;
		end_time = job_ptr->end_time;
	}

	connect_type = select_g_select_jobinfo_xstrdup(job_ptr->select_jobinfo,
						       SELECT_PRINT_CONNECTION);
	reboot = select_g_select_jobinfo_xstrdup(job_ptr->select_jobinfo,
						 SELECT_PRINT_REBOOT);
	rotate = select_g_select_jobinfo_xstrdup(job_ptr->select_jobinfo,
						 SELECT_PRINT_ROTATE);
	geometry = select_g_select_jobinfo_xstrdup(job_ptr->select_jobinfo,
						   SELECT_PRINT_GEOMETRY);
	start = select_g_select_jobinfo_xstrdup(job_ptr->select_jobinfo,
						SELECT_PRINT_START);
#ifdef HAVE_BG
	blockid = select_g_select_jobinfo_xstrdup(job_ptr->select_jobinfo,
						  SELECT_PRINT_BG_ID);
#else
	blockid = select_g_select_jobinfo_xstrdup(job_ptr->select_jobinfo,
						  SELECT_PRINT_RESV_ID);
#endif
	query = xstrdup_printf(
		"insert into %s (jobid, uid, user_name, gid, group_name, "
		"name, state, proc_cnt, partition, timelimit, "
		"starttime, endtime, nodecnt",
		jobcomp_table);

	if(job_ptr->nodes)
		xstrcat(query, ", nodelist");
	if(connect_type)
		xstrcat(query, ", connect_type");
	if(reboot)
		xstrcat(query, ", reboot");
	if(rotate)
		xstrcat(query, ", rotate");
	if(job_ptr->details && (job_ptr->details->max_cpus != NO_VAL))
		xstrcat(query, ", maxprocs");
	if(geometry)
		xstrcat(query, ", geometry");
	if(start)
		xstrcat(query, ", start");
	if(blockid)
		xstrcat(query, ", blockid");

	xstrfmtcat(query, ") values (%u, %u, '%s', %u, '%s', \"%s\", %d, %u, "
		   "'%s', \"%s\", %u, %u,  %u",
		   job_ptr->job_id, job_ptr->user_id, usr_str,
		   job_ptr->group_id, grp_str, job_ptr->name,
		   job_state, job_ptr->total_cpus, job_ptr->partition, lim_str,
		   start_time, end_time, job_ptr->node_cnt);

	if(job_ptr->nodes)
		xstrfmtcat(query, ", '%s'", job_ptr->nodes);

	if(connect_type) {
		xstrfmtcat(query, ", '%s'", connect_type);
		xfree(connect_type);
	}
	if(reboot) {
		xstrfmtcat(query, ", '%s'", reboot);
		xfree(reboot);
	}
	if(rotate) {
		xstrfmtcat(query, ", '%s'", rotate);
		xfree(rotate);
	}
	if(job_ptr->details && (job_ptr->details->max_cpus != NO_VAL))
		xstrfmtcat(query, ", '%u'", job_ptr->details->max_cpus);
	if(geometry) {
		xstrfmtcat(query, ", '%s'", geometry);
		xfree(geometry);
	}
	if(start) {
		xstrfmtcat(query, ", '%s'", start);
		xfree(start);
	}
	if(blockid) {
		xstrfmtcat(query, ", '%s'", blockid);
		xfree(blockid);
	}
	xstrcat(query, ")");
	//info("here is the query %s", query);

	rc = pgsql_db_query(jobcomp_pgsql_db, query);
	xfree(usr_str);

	return rc;
}
Ejemplo n.º 6
0
/* FIXME: This only works for CPUS now */
static List _process_grouped_report(
	void *db_conn, slurmdb_job_cond_t *job_cond, List grouping_list,
	bool flat_view, bool wckey_type, bool both)
{
	int exit_code = 0;
	void *object = NULL, *object2 = NULL;

	ListIterator itr = NULL, itr2 = NULL;
	ListIterator cluster_itr = NULL;
	ListIterator local_itr = NULL;
	ListIterator acct_itr = NULL;
	ListIterator group_itr = NULL;

	slurmdb_job_rec_t *job = NULL;
	slurmdb_report_cluster_grouping_t *cluster_group = NULL;
	slurmdb_report_acct_grouping_t *acct_group = NULL;
	slurmdb_report_job_grouping_t *job_group = NULL;

	List job_list = NULL;
	List cluster_list = NULL;
	List object_list = NULL, object2_list = NULL;

	List tmp_acct_list = NULL;
	bool destroy_job_cond = 0;
	bool destroy_grouping_list = 0;
	bool individual = 0;
	uint32_t tres_id = TRES_CPU;

	uid_t my_uid = getuid();

	/* we don't want to actually query by accounts in the jobs
	   here since we may be looking for sub accounts of a specific
	   account.
	*/
	if (!job_cond) {
		destroy_job_cond = 1;
		job_cond = xmalloc(sizeof(slurmdb_job_cond_t));
	}
	if (!grouping_list) {
		destroy_grouping_list = 1;
		grouping_list = list_create(slurm_destroy_char);
		slurm_addto_char_list(grouping_list, "50,250,500,1000");
	}

	tmp_acct_list = job_cond->acct_list;
	job_cond->acct_list = NULL;

	job_list = jobacct_storage_g_get_jobs_cond(db_conn, my_uid, job_cond);
	job_cond->acct_list = tmp_acct_list;
	tmp_acct_list = NULL;

	if (!job_list) {
		exit_code=1;
		fprintf(stderr, " Problem with job query.\n");
		goto end_it;
	}

	group_itr = list_iterator_create(grouping_list);
	/* make a group for each job size we find. */
	if (!list_count(grouping_list)) {
		char *group = NULL;

		individual = 1;
		itr = list_iterator_create(job_list);
		while ((job = list_next(itr))) {
			char *tmp = NULL;
			uint64_t count;

			if (!job->elapsed)
				continue;

			if ((count = slurmdb_find_tres_count_in_string(
				     job->tres_alloc_str, tres_id))
			    == INFINITE64)
				continue;

			tmp = xstrdup_printf("%"PRIu64, count);

			while ((group = list_next(group_itr))) {
				if (!strcmp(group, tmp)) {
					break;
				}
			}
			if (!group)
				list_append(grouping_list, tmp);
			else
				xfree(tmp);
			list_iterator_reset(group_itr);
		}
		list_iterator_destroy(itr);
		list_sort(grouping_list, (ListCmpF)_sort_group_asc);
	}

	cluster_list = list_create(slurmdb_destroy_report_cluster_grouping);

	cluster_itr = list_iterator_create(cluster_list);

	if (flat_view)
		goto no_objects;

	if (!wckey_type || both) {
		slurmdb_assoc_cond_t assoc_cond;
		memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
		assoc_cond.id_list = job_cond->associd_list;
		assoc_cond.cluster_list = job_cond->cluster_list;
		/* don't limit associations to having the partition_list */
		//assoc_cond.partition_list = job_cond->partition_list;
		if (!job_cond->acct_list || !list_count(job_cond->acct_list)) {
			FREE_NULL_LIST(job_cond->acct_list);
			job_cond->acct_list = list_create(NULL);
			list_append(job_cond->acct_list, "root");
		}
		assoc_cond.parent_acct_list = job_cond->acct_list;
		object_list = acct_storage_g_get_assocs(db_conn, my_uid,
							      &assoc_cond);
	}

	if (wckey_type || both) {
		slurmdb_wckey_cond_t wckey_cond;
		memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t));
		wckey_cond.name_list = job_cond->wckey_list;
		wckey_cond.cluster_list = job_cond->cluster_list;

		object2_list = acct_storage_g_get_wckeys(db_conn, my_uid,
							 &wckey_cond);
		if (!object_list) {
			object_list = object2_list;
			object2_list = NULL;
		}
	}

	if (!object_list) {
		debug2(" No join list given.\n");
		goto no_objects;
	}

	itr = list_iterator_create(object_list);
	if (object2_list)
		itr2 = list_iterator_create(object2_list);
	while ((object = list_next(itr))) {
		char *cluster = NULL;
		slurmdb_wckey_rec_t *wckey = (slurmdb_wckey_rec_t *)object;
		slurmdb_assoc_rec_t *assoc =
			(slurmdb_assoc_rec_t *)object;
		if (!itr2) {
			char *name = NULL;
			if (wckey_type) {
				cluster = wckey->cluster;
				name = wckey->name;
			} else {
				cluster = assoc->cluster;
				name = assoc->acct;
			}
			_check_create_grouping(cluster_list, group_itr,
					       cluster, name, object,
					       individual, wckey_type);
			continue;
		}

		while ((object2 = list_next(itr2))) {
			slurmdb_wckey_rec_t *wckey2 =
				(slurmdb_wckey_rec_t *)object2;
			slurmdb_assoc_rec_t *assoc2 =
				(slurmdb_assoc_rec_t *)object2;
			char name[200];
			if (!wckey_type) {
				if (strcmp(assoc->cluster, wckey2->cluster))
					continue;
				cluster = assoc->cluster;
				snprintf(name, sizeof(name), "%s:%s",
					 assoc->acct, wckey2->name);
			} else {
				if (strcmp(wckey->cluster, assoc2->cluster))
					continue;
				cluster = wckey->cluster;
				snprintf(name, sizeof(name), "%s:%s",
					 wckey2->name, assoc->acct);
			}
			_check_create_grouping(cluster_list, group_itr,
					       cluster, name, object,
					       individual, wckey_type);
		}
		list_iterator_reset(itr2);
	}
	list_iterator_destroy(itr);
	if (itr2)
		list_iterator_destroy(itr2);

no_objects:
	itr = list_iterator_create(job_list);

	while((job = list_next(itr))) {
		char *local_cluster = "UNKNOWN";
		char tmp_acct[200];

		if (!job->elapsed) {
			/* here we don't care about jobs that didn't
			 * really run here */
			continue;
		}
		if (job->cluster)
			local_cluster = job->cluster;

		if (!wckey_type) {
			if (both && job->wckey) {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s:%s",
					 job->account,
					 job->wckey);
			} else {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s", job->account);
			}
		} else {
			if (both && job->account) {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s:%s",
					 job->wckey,
					 job->account);
			} else {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s", job->wckey);
			}
		}

		list_iterator_reset(cluster_itr);
		while((cluster_group = list_next(cluster_itr))) {
			if (!strcmp(local_cluster, cluster_group->cluster))
				break;
		}
		if (!cluster_group) {
			/* here we are only looking for groups that
			 * were added with the associations above
			 */
			if (!flat_view)
				continue;
			cluster_group = xmalloc(
				sizeof(slurmdb_report_cluster_grouping_t));
			cluster_group->cluster = xstrdup(local_cluster);
			cluster_group->acct_list = list_create(
				slurmdb_destroy_report_acct_grouping);
			list_append(cluster_list, cluster_group);
		}

		acct_itr = list_iterator_create(cluster_group->acct_list);
		while((acct_group = list_next(acct_itr))) {
			if (wckey_type) {
				if (!strcmp(tmp_acct, acct_group->acct))
					break;
				continue;
			}

			if (!flat_view
			   && (acct_group->lft != (uint32_t)NO_VAL)
			   && (job->lft != (uint32_t)NO_VAL)) {
				/* keep separate since we don't want
				 * to so a strcmp if we don't have to
				 */
				if (job->lft > acct_group->lft
				    && job->lft < acct_group->rgt) {
					char *mywckey;
					if (!both)
						break;
					mywckey = strstr(acct_group->acct, ":");
					mywckey++;
					if (!job->wckey && !mywckey)
						break;
					else if (!mywckey || !job->wckey)
						continue;
					else if (!strcmp(mywckey, job->wckey))
						break;
				}
			} else if (!strcmp(acct_group->acct, tmp_acct))
				break;
		}
		list_iterator_destroy(acct_itr);

		if (!acct_group) {
			char *group = NULL;
			uint32_t last_size = 0;
			/* here we are only looking for groups that
			 * were added with the associations above
			 */
			if (!flat_view)
				continue;

			acct_group = xmalloc(
				sizeof(slurmdb_report_acct_grouping_t));
			acct_group->acct = xstrdup(tmp_acct);
			acct_group->groups = list_create(
				slurmdb_destroy_report_job_grouping);
			list_append(cluster_group->acct_list, acct_group);

			while((group = list_next(group_itr))) {
				job_group = xmalloc(
					sizeof(slurmdb_report_job_grouping_t));
				job_group->jobs = list_create(NULL);
				if (!individual)
					job_group->min_size = last_size;
				last_size = atoi(group);
				if (!individual)
					job_group->max_size = last_size-1;
				else
					job_group->min_size =
						job_group->max_size = last_size;
				list_append(acct_group->groups, job_group);
			}
			if (last_size && !individual) {
				job_group = xmalloc(
					sizeof(slurmdb_report_job_grouping_t));
				job_group->jobs = list_create(NULL);
				job_group->min_size = last_size;
				if (individual)
					job_group->max_size =
						job_group->min_size;
				else
					job_group->max_size = INFINITE;
				list_append(acct_group->groups, job_group);
			}
			list_iterator_reset(group_itr);
		}

		local_itr = list_iterator_create(acct_group->groups);
		while ((job_group = list_next(local_itr))) {
			uint64_t count;

			if (((count = slurmdb_find_tres_count_in_string(
				      job->tres_alloc_str, tres_id))
			     == INFINITE64) ||
			    (count < job_group->min_size) ||
			    (count > job_group->max_size))
				continue;

			list_append(job_group->jobs, job);
			job_group->count++;
			acct_group->count++;
			cluster_group->count++;

			slurmdb_transfer_tres_time(
				&job_group->tres_list, job->tres_alloc_str,
				job->elapsed);
			slurmdb_transfer_tres_time(
				&acct_group->tres_list, job->tres_alloc_str,
				job->elapsed);
			slurmdb_transfer_tres_time(
				&cluster_group->tres_list, job->tres_alloc_str,
				job->elapsed);
		}
		list_iterator_destroy(local_itr);
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(group_itr);
	list_iterator_reset(cluster_itr);
	while ((cluster_group = list_next(cluster_itr))) {
		ListIterator acct_itr;
		if (!cluster_group->count) {
			list_delete_item(cluster_itr);
			continue;
		}
		acct_itr = list_iterator_create(cluster_group->acct_list);
		while ((acct_group = list_next(acct_itr))) {
			if (!acct_group->count) {
				list_delete_item(acct_itr);
				continue;
			}
		}
		list_iterator_destroy(acct_itr);
	}
	list_iterator_destroy(cluster_itr);

end_it:
	FREE_NULL_LIST(object_list);

	FREE_NULL_LIST(object2_list);

	if (destroy_job_cond)
		slurmdb_destroy_job_cond(job_cond);

	if (destroy_grouping_list)
		FREE_NULL_LIST(grouping_list);

	if (exit_code) {
		FREE_NULL_LIST(cluster_list);
	}

	return cluster_list;
}
Ejemplo n.º 7
0
static bool _isdefault(List qos_list)
{
    int rc = 0;
    slurmdb_association_cond_t assoc_cond;
    slurmdb_association_rec_t *assoc = NULL;
    ListIterator itr;
    List ret_list = NULL;
    char *name = NULL;

    if (!qos_list || !list_count(qos_list))
        return rc;

    /* this needs to happen before any removing takes place so we
       can figure out things correctly */
    xassert(g_qos_list);

    memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
    assoc_cond.without_parent_info = 1;
    assoc_cond.def_qos_id_list = list_create(slurm_destroy_char);

    itr = list_iterator_create(qos_list);
    while ((name = list_next(itr))) {
        uint32_t id = str_2_slurmdb_qos(g_qos_list, name);
        if (id == NO_VAL)
            continue;
        list_append(assoc_cond.def_qos_id_list,
                    xstrdup_printf("%u", id));
    }
    list_iterator_destroy(itr);

    ret_list = acct_storage_g_get_associations(
                   db_conn, my_uid, &assoc_cond);
    list_destroy(assoc_cond.def_qos_id_list);

    if (!ret_list || !list_count(ret_list))
        goto end_it;

    fprintf(stderr," Associations listed below have these "
            "as their Default QOS.\n");
    itr = list_iterator_create(ret_list);
    while((assoc = list_next(itr))) {
        name = slurmdb_qos_str(g_qos_list, assoc->def_qos_id);
        if (!assoc->user) {
            // see if this isn't a user
            fprintf(stderr,
                    "  DefQOS = %-10s C = %-10s A = %-20s\n",
                    name, assoc->cluster, assoc->acct);
        } else if (assoc->partition) {
            // see if there is a partition name
            fprintf(stderr,
                    "  DefQOS = %-10s C = %-10s A = %-20s "
                    "U = %-9s P = %s\n",
                    name, assoc->cluster, assoc->acct,
                    assoc->user, assoc->partition);
        } else {
            fprintf(stderr,
                    "  DefQOS = %-10s C = %-10s A = %-20s "
                    "U = %-9s\n",
                    name, assoc->cluster, assoc->acct, assoc->user);
        }
    }
    list_iterator_destroy(itr);
    rc = 1;
end_it:
    if (ret_list)
        list_destroy(ret_list);

    return rc;
}
Ejemplo n.º 8
0
extern List as_mysql_modify_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
				     slurmdb_cluster_cond_t *cluster_cond,
				     slurmdb_cluster_rec_t *cluster)
{
	List ret_list = NULL;
	int rc = SLURM_SUCCESS;
	char *object = NULL;
	char *vals = NULL, *extra = NULL, *query = NULL,
		*name_char = NULL, *send_char = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	int set = 0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	bool clust_reg = false;

	/* If you need to alter the default values of the cluster use
	 * modify_assocs since this is used only for registering
	 * the controller when it loads
	 */

	if (!cluster_cond || !cluster) {
		error("we need something to change");
		return NULL;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	if (!is_user_min_admin_level(mysql_conn, uid,
				     SLURMDB_ADMIN_SUPER_USER)) {
		errno = ESLURM_ACCESS_DENIED;
		return NULL;
	}

	/* force to only do non-deleted clusters */
	cluster_cond->with_deleted = 0;
	_setup_cluster_cond_limits(cluster_cond, &extra);

	/* Needed if talking to older SLURM versions < 2.2 */
	if (!mysql_conn->cluster_name && cluster_cond->cluster_list
	    && list_count(cluster_cond->cluster_list))
		mysql_conn->cluster_name =
			xstrdup(list_peek(cluster_cond->cluster_list));

	set = 0;
	if (cluster->control_host) {
		xstrfmtcat(vals, ", control_host='%s'", cluster->control_host);
		set++;
		clust_reg = true;
	}

	if (cluster->control_port) {
		xstrfmtcat(vals, ", control_port=%u, last_port=%u",
			   cluster->control_port, cluster->control_port);
		set++;
		clust_reg = true;
	}

	if (cluster->rpc_version) {
		xstrfmtcat(vals, ", rpc_version=%u", cluster->rpc_version);
		set++;
		clust_reg = true;
	}

	if (cluster->dimensions) {
		xstrfmtcat(vals, ", dimensions=%u", cluster->dimensions);
		clust_reg = true;
	}

	if (cluster->plugin_id_select) {
		xstrfmtcat(vals, ", plugin_id_select=%u",
			   cluster->plugin_id_select);
		clust_reg = true;
	}
	if (cluster->flags != NO_VAL) {
		xstrfmtcat(vals, ", flags=%u", cluster->flags);
		clust_reg = true;
	}

	if (cluster->classification) {
		xstrfmtcat(vals, ", classification=%u",
			   cluster->classification);
	}

	if (!vals) {
		xfree(extra);
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("Nothing to change");
		return NULL;
	} else if (clust_reg && (set != 3)) {
		xfree(vals);
		xfree(extra);
		errno = EFAULT;
		error("Need control host, port and rpc version "
		      "to register a cluster");
		return NULL;
	}


	xstrfmtcat(query, "select name, control_port from %s%s;",
		   cluster_table, extra);

	if (debug_flags & DEBUG_FLAG_DB_ASSOC)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		xfree(vals);
		error("no result given for %s", extra);
		xfree(extra);
		return NULL;
	}
	xfree(extra);

	rc = 0;
	ret_list = list_create(slurm_destroy_char);
	while ((row = mysql_fetch_row(result))) {
		object = xstrdup(row[0]);

		list_append(ret_list, object);
		if (!rc) {
			xstrfmtcat(name_char, "name='%s'", object);
			rc = 1;
		} else  {
			xstrfmtcat(name_char, " || name='%s'", object);
		}
	}
	mysql_free_result(result);

	if (!list_count(ret_list)) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn,
				 "didn't effect anything\n%s", query);
		xfree(name_char);
		xfree(vals);
		xfree(query);
		return ret_list;
	}
	xfree(query);

	if (vals) {
		send_char = xstrdup_printf("(%s)", name_char);
		user_name = uid_to_string((uid_t) uid);
		rc = modify_common(mysql_conn, DBD_MODIFY_CLUSTERS, now,
				   user_name, cluster_table,
				   send_char, vals, NULL);
		xfree(user_name);
		if (rc == SLURM_ERROR) {
			error("Couldn't modify cluster 1");
			FREE_NULL_LIST(ret_list);
			ret_list = NULL;
			goto end_it;
		}
	}

end_it:
	xfree(name_char);
	xfree(vals);
	xfree(send_char);

	return ret_list;
}
Ejemplo n.º 9
0
extern List as_mysql_remove_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
				     slurmdb_cluster_cond_t *cluster_cond)
{
	ListIterator itr = NULL;
	List ret_list = NULL;
	List tmp_list = NULL;
	int rc = SLURM_SUCCESS;
	char *object = NULL;
	char *extra = NULL, *query = NULL, *cluster_name = NULL,
		*name_char = NULL, *assoc_char = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	slurmdb_wckey_cond_t wckey_cond;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	bool jobs_running = 0;

	if (!cluster_cond) {
		error("we need something to change");
		return NULL;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	if (!is_user_min_admin_level(
		    mysql_conn, uid, SLURMDB_ADMIN_SUPER_USER)) {
		errno = ESLURM_ACCESS_DENIED;
		return NULL;
	}

	/* force to only do non-deleted clusters */
	cluster_cond->with_deleted = 0;
	_setup_cluster_cond_limits(cluster_cond, &extra);

	if (!extra) {
		error("Nothing to remove");
		return NULL;
	}

	query = xstrdup_printf("select name from %s%s;", cluster_table, extra);
	xfree(extra);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}
	rc = 0;
	ret_list = list_create(slurm_destroy_char);

	if (!mysql_num_rows(result)) {
		mysql_free_result(result);
		errno = SLURM_NO_CHANGE_IN_DATA;
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn,
				 "didn't effect anything\n%s", query);
		xfree(query);
		return ret_list;
	}
	xfree(query);

	assoc_char = xstrdup_printf("t2.acct='root'");

	user_name = uid_to_string((uid_t) uid);
	while ((row = mysql_fetch_row(result))) {
		char *object = xstrdup(row[0]);
		if (!jobs_running)
			list_append(ret_list, object);

		xfree(name_char);
		xstrfmtcat(name_char, "name='%s'", object);
		if (jobs_running)
			xfree(object);
		/* We should not need to delete any cluster usage just set it
		 * to deleted */
		xstrfmtcat(query,
			   "update \"%s_%s\" set time_end=%ld where time_end=0;"
			   "update \"%s_%s\" set mod_time=%ld, deleted=1;"
			   "update \"%s_%s\" set mod_time=%ld, deleted=1;"
			   "update \"%s_%s\" set mod_time=%ld, deleted=1;",
			   object, event_table, now,
			   object, cluster_day_table, now,
			   object, cluster_hour_table, now,
			   object, cluster_month_table, now);
		if ((rc = remove_common(mysql_conn, DBD_REMOVE_CLUSTERS, now,
					user_name, cluster_table,
					name_char, assoc_char, object,
					ret_list, &jobs_running))
		    != SLURM_SUCCESS)
			break;
	}
	mysql_free_result(result);
	xfree(user_name);
	xfree(name_char);
	xfree(assoc_char);

	if (rc != SLURM_SUCCESS) {
		FREE_NULL_LIST(ret_list);
		return NULL;
	}
	if (!jobs_running) {
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			reset_mysql_conn(mysql_conn);
			FREE_NULL_LIST(ret_list);
			return NULL;
		}

		/* We need to remove these clusters from the wckey table */
		memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t));
		wckey_cond.cluster_list = ret_list;
		tmp_list = as_mysql_remove_wckeys(mysql_conn, uid, &wckey_cond);
		FREE_NULL_LIST(tmp_list);

		itr = list_iterator_create(ret_list);
		while ((object = list_next(itr))) {
			if ((rc = remove_cluster_tables(mysql_conn, object))
			    != SLURM_SUCCESS)
				break;
			cluster_name = xstrdup(object);
			if (addto_update_list(mysql_conn->update_list,
					      SLURMDB_REMOVE_CLUSTER,
					      cluster_name) != SLURM_SUCCESS)
				xfree(cluster_name);
		}
		list_iterator_destroy(itr);

		if (rc != SLURM_SUCCESS) {
			reset_mysql_conn(mysql_conn);
			FREE_NULL_LIST(ret_list);
			errno = rc;
			return NULL;
		}
		errno = SLURM_SUCCESS;
	} else
		errno = ESLURM_JOBS_RUNNING_ON_ASSOC;

	return ret_list;
}
Ejemplo n.º 10
0
extern int as_mysql_fini_ctld(mysql_conn_t *mysql_conn,
			      slurmdb_cluster_rec_t *cluster_rec)
{
	int rc = SLURM_SUCCESS;
	time_t now = time(NULL);
	char *query = NULL;
	bool free_it = false;

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	/* Here we need to check make sure we are updating the entry
	   correctly just incase the backup has already gained
	   control.  If we check the ip and port it is a pretty safe
	   bet we have the right ctld.
	*/
	query = xstrdup_printf(
		"update %s set mod_time=%ld, control_host='', "
		"control_port=0 where name='%s' && "
		"control_host='%s' && control_port=%u;",
		cluster_table, now, cluster_rec->name,
		cluster_rec->control_host, cluster_rec->control_port);
	if (debug_flags & DEBUG_FLAG_DB_EVENT)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);

	if (rc != SLURM_SUCCESS)
		return SLURM_ERROR;

	if (!last_affected_rows(mysql_conn)
	    || (slurmdbd_conf && !slurmdbd_conf->track_ctld))
		return rc;

	/* If tres is NULL we can get the current number of tres by
	   sending NULL for the tres param in the as_mysql_cluster_tres
	   function.
	*/
	if (!cluster_rec->tres_str) {
		free_it = true;
		as_mysql_cluster_tres(
			mysql_conn, cluster_rec->control_host,
			&cluster_rec->tres_str, now);
	}

	/* Since as_mysql_cluster_tres could change the
	   last_affected_rows we can't group this with the above
	   return.
	*/
	if (!cluster_rec->tres_str)
		return rc;

	/* If we affected things we need to now drain the nodes in the
	 * cluster.  This is to give better stats on accounting that
	 * the ctld was gone so no jobs were able to be scheduled.  We
	 * drain the nodes since the rollup functionality understands
	 * how to deal with that and running jobs so we don't get bad
	 * info.
	 */
	query = xstrdup_printf(
		"insert into \"%s_%s\" (tres, state, time_start, reason) "
		"values ('%s', %u, %ld, 'slurmctld disconnect');",
		cluster_rec->name, event_table,
		cluster_rec->tres_str, NODE_STATE_DOWN, (long)now);

	if (free_it)
		xfree(cluster_rec->tres_str);

	if (debug_flags & DEBUG_FLAG_DB_EVENT)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);

	return rc;
}
Ejemplo n.º 11
0
extern int as_mysql_cluster_tres(mysql_conn_t *mysql_conn,
				 char *cluster_nodes, char **tres_str_in,
				 time_t event_time)
{
	char* query;
	int rc = SLURM_SUCCESS;
	int first = 0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;

	xassert(tres_str_in);

 	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	if (!mysql_conn->cluster_name) {
		error("%s:%d no cluster name", THIS_FILE, __LINE__);
		return SLURM_ERROR;
	}

	/* Record the processor count */
	query = xstrdup_printf(
		"select tres, cluster_nodes from \"%s_%s\" where "
		"time_end=0 and node_name='' and state=0 limit 1",
		mysql_conn->cluster_name, event_table);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		if (mysql_errno(mysql_conn->db_conn) == ER_NO_SUCH_TABLE)
			rc = ESLURM_ACCESS_DENIED;
		else
			rc = SLURM_ERROR;
		return rc;
	}
	xfree(query);

	/* we only are checking the first one here */
	if (!(row = mysql_fetch_row(result))) {
		debug("We don't have an entry for this machine %s "
		      "most likely a first time running.",
		      mysql_conn->cluster_name);

		/* Get all nodes in a down state and jobs pending or running.
		 * This is for the first time a cluster registers
		 *
		 * We will return ACCOUNTING_FIRST_REG so this
		 * is taken care of since the message thread
		 * may not be up when we run this in the controller or
		 * in the slurmdbd.
		 */
		if (!*tres_str_in) {
			rc = 0;
			goto end_it;
		}

		first = 1;
		goto add_it;
	}

	/* If tres is NULL we want to return the tres for this cluster */
	if (!*tres_str_in) {
		*tres_str_in = xstrdup(row[0]);
		goto end_it;
	} else if (xstrcmp(*tres_str_in, row[0])) {
		debug("%s has changed tres from %s to %s",
		      mysql_conn->cluster_name,
		      row[0], *tres_str_in);
	} else {
		if (debug_flags & DEBUG_FLAG_DB_EVENT)
			DB_DEBUG(mysql_conn->conn,
				 "We have the same tres as before for %s, "
				 "no need to update the database.",
				 mysql_conn->cluster_name);

		if (cluster_nodes) {
			if (!row[1][0]) {
				debug("Adding cluster nodes '%s' to "
				      "last instance of cluster '%s'.",
				      cluster_nodes, mysql_conn->cluster_name);
				query = xstrdup_printf(
					"update \"%s_%s\" set "
					"cluster_nodes='%s' "
					"where time_end=0 and node_name=''",
					mysql_conn->cluster_name,
					event_table, cluster_nodes);
				(void) mysql_db_query(mysql_conn, query);
				xfree(query);
				goto update_it;
			} else if (!xstrcmp(cluster_nodes, row[1])) {
				if (debug_flags & DEBUG_FLAG_DB_EVENT)
					DB_DEBUG(mysql_conn->conn,
						 "we have the same nodes "
						 "in the cluster "
						 "as before no need to "
						 "update the database.");
				goto update_it;
			}
		}

		goto end_it;
	}

	/* reset all the entries for this cluster since the tres
	   changed some of the downed nodes may have gone away.
	   Request them again with ACCOUNTING_FIRST_REG */
	query = xstrdup_printf(
		"update \"%s_%s\" set time_end=%ld where time_end=0",
		mysql_conn->cluster_name, event_table, event_time);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);
	first = 1;
	if (rc != SLURM_SUCCESS)
		goto end_it;
add_it:
	query = xstrdup_printf(
		"insert into \"%s_%s\" (cluster_nodes, tres, "
		"time_start, reason) "
		"values ('%s', '%s', %ld, 'Cluster Registered TRES');",
		mysql_conn->cluster_name, event_table,
		cluster_nodes, *tres_str_in, event_time);
	(void) mysql_db_query(mysql_conn, query);
	xfree(query);
update_it:
	query = xstrdup_printf(
		"update \"%s_%s\" set time_end=%ld where time_end=0 "
		"and state=%u and node_name='';",
		mysql_conn->cluster_name, event_table, event_time,
		NODE_STATE_DOWN);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);
end_it:
	mysql_free_result(result);
	if (first && rc == SLURM_SUCCESS)
		rc = ACCOUNTING_FIRST_REG;

	return rc;
}
Ejemplo n.º 12
0
extern int as_mysql_node_down(mysql_conn_t *mysql_conn,
			      struct node_record *node_ptr,
			      time_t event_time, char *reason,
			      uint32_t reason_uid)
{
	int rc = SLURM_SUCCESS;
	char *query = NULL;
	char *my_reason;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	if (!mysql_conn->cluster_name) {
		error("%s:%d no cluster name", THIS_FILE, __LINE__);
		return SLURM_ERROR;
	}

	if (!node_ptr) {
		error("No node_ptr given!");
		return SLURM_ERROR;
	}

	if (!node_ptr->tres_str) {
		error("node ptr has no tres_list!");
		return SLURM_ERROR;
	}

	query = xstrdup_printf("select state, reason from \"%s_%s\" where "
			       "time_end=0 and node_name='%s';",
			       mysql_conn->cluster_name, event_table,
			       node_ptr->name);
	/* info("%d(%s:%d) query\n%s", */
	/*        mysql_conn->conn, THIS_FILE, __LINE__, query); */
	result = mysql_db_query_ret(mysql_conn, query, 0);
	xfree(query);

	if (!result)
		return SLURM_ERROR;

	if (reason)
		my_reason = slurm_add_slash_to_quotes(reason);
	else
		my_reason = slurm_add_slash_to_quotes(node_ptr->reason);

	row = mysql_fetch_row(result);
	if (row && (node_ptr->node_state == slurm_atoul(row[0])) &&
	    my_reason && row[1] &&
	    !xstrcasecmp(my_reason, row[1])) {
		debug("as_mysql_node_down: no change needed %u == %s "
		      "and %s == %s",
		     node_ptr->node_state, row[0], my_reason, row[1]);
		xfree(my_reason);
		mysql_free_result(result);
		return SLURM_SUCCESS;
	}
	mysql_free_result(result);

	debug2("inserting %s(%s) with tres of '%s'",
	       node_ptr->name, mysql_conn->cluster_name, node_ptr->tres_str);

	query = xstrdup_printf(
		"update \"%s_%s\" set time_end=%ld where "
		"time_end=0 and node_name='%s';",
		mysql_conn->cluster_name, event_table,
		event_time, node_ptr->name);
	/* If you are clean-restarting the controller over and over again you
	 * could get records that are duplicates in the database.  If
	 * this is the case we will zero out the time_end we are
	 * just filled in.  This will cause the last time to be erased
	 * from the last restart, but if you are restarting things
	 * this often the pervious one didn't mean anything anyway.
	 * This way we only get one for the last time we let it run.
	 */
	xstrfmtcat(query,
		   "insert into \"%s_%s\" "
		   "(node_name, state, tres, time_start, "
		   "reason, reason_uid) "
		   "values ('%s', %u, '%s', %ld, '%s', %u) "
		   "on duplicate key update time_end=0;",
		   mysql_conn->cluster_name, event_table,
		   node_ptr->name, node_ptr->node_state,
		   node_ptr->tres_str, event_time, my_reason, reason_uid);
	debug2("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);
	xfree(my_reason);
	return rc;
}
Ejemplo n.º 13
0
extern int as_mysql_step_complete(mysql_conn_t *mysql_conn,
				  struct step_record *step_ptr)
{
	time_t now;
	int comp_status;
	int tasks = 0;
	struct jobacctinfo *jobacct = (struct jobacctinfo *)step_ptr->jobacct;
	struct jobacctinfo dummy_jobacct;
	double ave_vsize = NO_VAL, ave_rss = NO_VAL, ave_pages = NO_VAL;
	double ave_disk_read =  (double)NO_VAL;
	double ave_disk_write = (double)NO_VAL;
	double ave_cpu = (double)NO_VAL;
	char *query = NULL;
	int rc =SLURM_SUCCESS;
	uint32_t exit_code = 0;
	time_t submit_time;

	if (!step_ptr->job_ptr->db_index
	    && ((!step_ptr->job_ptr->details
		 || !step_ptr->job_ptr->details->submit_time)
		&& !step_ptr->job_ptr->resize_time)) {
		error("as_mysql_step_complete: "
		      "Not inputing this job, it has no submit time.");
		return SLURM_ERROR;
	}

	if (step_ptr->job_ptr->resize_time)
		submit_time = step_ptr->job_ptr->resize_time;
	else
		submit_time = step_ptr->job_ptr->details->submit_time;

	if (jobacct == NULL) {
		/* JobAcctGather=jobacct_gather/none, no data to process */
		memset(&dummy_jobacct, 0, sizeof(dummy_jobacct));
		jobacct = &dummy_jobacct;
		jobacct->min_cpu = NO_VAL;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	if (slurmdbd_conf) {
		now = step_ptr->job_ptr->end_time;
		if (step_ptr->job_ptr->details)
			tasks = step_ptr->job_ptr->details->num_tasks;
		else
			tasks = step_ptr->cpu_count;
	} else if (step_ptr->step_id == SLURM_BATCH_SCRIPT) {
		now = time(NULL);
		tasks = 1;
	} else {
		now = time(NULL);
#ifdef HAVE_BG_L_P
		/* Only L and P use this code */
		tasks = step_ptr->job_ptr->details->min_cpus;
#else
		if (!step_ptr->step_layout || !step_ptr->step_layout->task_cnt)
			tasks = step_ptr->job_ptr->total_cpus;
		else
			tasks = step_ptr->step_layout->task_cnt;
#endif
	}

	exit_code = step_ptr->exit_code;
	if (WIFSIGNALED(exit_code)) {
		comp_status = JOB_CANCELLED;
	} else if (exit_code)
		comp_status = JOB_FAILED;
	else {
		step_ptr->requid = -1;
		comp_status = JOB_COMPLETE;
	}

	/* figure out the ave of the totals sent */
	if ((jobacct->min_cpu != NO_VAL) && tasks > 0) {
		ave_vsize = (double)jobacct->tot_vsize;
		ave_vsize /= (double)tasks;
		ave_rss = (double)jobacct->tot_rss;
		ave_rss /= (double)tasks;
		ave_pages = (double)jobacct->tot_pages;
		ave_pages /= (double)tasks;
		ave_cpu = (double)jobacct->tot_cpu;
		ave_cpu /= (double)tasks;
		ave_disk_read = (double)jobacct->tot_disk_read;
		ave_disk_read /= (double)tasks;
		ave_disk_write = (double)jobacct->tot_disk_write;
		ave_disk_write /= (double)tasks;
	}

	if (!step_ptr->job_ptr->db_index) {
		if (!(step_ptr->job_ptr->db_index =
		      _get_db_index(mysql_conn,
				    submit_time,
				    step_ptr->job_ptr->job_id,
				    step_ptr->job_ptr->assoc_id))) {
			/* If we get an error with this just fall
			 * through to avoid an infinite loop
			 */
			if (as_mysql_job_start(mysql_conn, step_ptr->job_ptr)
			    == SLURM_ERROR) {
				error("couldn't add job %u "
				      "at step completion",
				      step_ptr->job_ptr->job_id);
				return SLURM_SUCCESS;
			}
		}
	}

	/* The stepid could be -2 so use %d not %u */
	query = xstrdup_printf(
		"update \"%s_%s\" set time_end=%d, state=%d, "
		"kill_requid=%d, exit_code=%d, "
		"user_sec=%u, user_usec=%u, "
		"sys_sec=%u, sys_usec=%u, "
		"max_disk_read=%f, max_disk_read_task=%u, "
		"max_disk_read_node=%u, ave_disk_read=%f, "
		"max_disk_write=%f, max_disk_write_task=%u, "
		"max_disk_write_node=%u, ave_disk_write=%f, "
		"max_vsize=%"PRIu64", max_vsize_task=%u, "
		"max_vsize_node=%u, ave_vsize=%f, "
		"max_rss=%"PRIu64", max_rss_task=%u, "
		"max_rss_node=%u, ave_rss=%f, "
		"max_pages=%"PRIu64", max_pages_task=%u, "
		"max_pages_node=%u, ave_pages=%f, "
		"min_cpu=%u, min_cpu_task=%u, "
		"min_cpu_node=%u, ave_cpu=%f, "
		"act_cpufreq=%u, consumed_energy=%u "
		"where job_db_inx=%d and id_step=%d",
		mysql_conn->cluster_name, step_table, (int)now,
		comp_status,
		step_ptr->requid,
		exit_code,
		/* user seconds */
		jobacct->user_cpu_sec,
		/* user microseconds */
		jobacct->user_cpu_usec,
		/* system seconds */
		jobacct->sys_cpu_sec,
		/* system microsecs */
		jobacct->sys_cpu_usec,
		/* max disk_read */
		jobacct->max_disk_read,
		/* max disk_read task */
		jobacct->max_disk_read_id.taskid,
		/* max disk_read node */
		jobacct->max_disk_read_id.nodeid,
		/* ave disk_read */
		ave_disk_read,
		/* max disk_write */
		jobacct->max_disk_write,
		/* max disk_write task */
		jobacct->max_disk_write_id.taskid,
		/* max disk_write node */
		jobacct->max_disk_write_id.nodeid,
		/* ave disk_write */
		ave_disk_write,
		jobacct->max_vsize,	/* max vsize */
		jobacct->max_vsize_id.taskid,	/* max vsize task */
		jobacct->max_vsize_id.nodeid,	/* max vsize node */
		ave_vsize,	/* ave vsize */
		jobacct->max_rss,	/* max vsize */
		jobacct->max_rss_id.taskid,	/* max rss task */
		jobacct->max_rss_id.nodeid,	/* max rss node */
		ave_rss,	/* ave rss */
		jobacct->max_pages,	/* max pages */
		jobacct->max_pages_id.taskid,	/* max pages task */
		jobacct->max_pages_id.nodeid,	/* max pages node */
		ave_pages,	/* ave pages */
		jobacct->min_cpu,	/* min cpu */
		jobacct->min_cpu_id.taskid,	/* min cpu task */
		jobacct->min_cpu_id.nodeid,	/* min cpu node */
		ave_cpu,	/* ave cpu */
		jobacct->act_cpufreq,
		jobacct->energy.consumed_energy,
		step_ptr->job_ptr->db_index, step_ptr->step_id);
	debug3("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);

	return rc;
}
Ejemplo n.º 14
0
extern int as_mysql_step_start(mysql_conn_t *mysql_conn,
			       struct step_record *step_ptr)
{
	int cpus = 0, tasks = 0, nodes = 0, task_dist = 0;
	int rc=SLURM_SUCCESS;
	char node_list[BUFFER_SIZE];
	char *node_inx = NULL, *step_name = NULL;
	time_t start_time, submit_time;
	char *query = NULL;

	if (!step_ptr->job_ptr->db_index
	    && ((!step_ptr->job_ptr->details
		 || !step_ptr->job_ptr->details->submit_time)
		&& !step_ptr->job_ptr->resize_time)) {
		error("as_mysql_step_start: "
		      "Not inputing this job, it has no submit time.");
		return SLURM_ERROR;
	}

	if (step_ptr->job_ptr->resize_time) {
		submit_time = start_time = step_ptr->job_ptr->resize_time;
		if (step_ptr->start_time > submit_time)
			start_time = step_ptr->start_time;
	} else {
		start_time = step_ptr->start_time;
		submit_time = step_ptr->job_ptr->details->submit_time;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;
	if (slurmdbd_conf) {
		cpus = step_ptr->cpu_count;
		if (step_ptr->job_ptr->details)
			tasks = step_ptr->job_ptr->details->num_tasks;
		else
			tasks = cpus;
		snprintf(node_list, BUFFER_SIZE, "%s",
			 step_ptr->job_ptr->nodes);
		nodes = step_ptr->step_layout->node_cnt;
		task_dist = step_ptr->step_layout->task_dist;
		node_inx = step_ptr->network;
	} else if (step_ptr->step_id == SLURM_BATCH_SCRIPT) {
		char temp_bit[BUF_SIZE];

		if (step_ptr->step_node_bitmap) {
			node_inx = bit_fmt(temp_bit, sizeof(temp_bit),
					   step_ptr->step_node_bitmap);
		}
		/* We overload gres with the node name of where the
		   script was running.
		*/
		snprintf(node_list, BUFFER_SIZE, "%s", step_ptr->gres);
		nodes = cpus = tasks = 1;
	} else {
		char *ionodes = NULL, *temp_nodes = NULL;
		char temp_bit[BUF_SIZE];

		if (step_ptr->step_node_bitmap) {
			node_inx = bit_fmt(temp_bit, sizeof(temp_bit),
					   step_ptr->step_node_bitmap);
		}
#ifdef HAVE_BG_L_P
		/* Only L and P use this code */
		if (step_ptr->job_ptr->details)
			tasks = cpus = step_ptr->job_ptr->details->min_cpus;
		else
			tasks = cpus = step_ptr->job_ptr->cpu_cnt;
		select_g_select_jobinfo_get(step_ptr->job_ptr->select_jobinfo,
					    SELECT_JOBDATA_NODE_CNT,
					    &nodes);
		temp_nodes = step_ptr->job_ptr->nodes;
#else
		if (!step_ptr->step_layout
		    || !step_ptr->step_layout->task_cnt) {
			tasks = cpus = step_ptr->job_ptr->total_cpus;
			nodes = step_ptr->job_ptr->total_nodes;
			temp_nodes = step_ptr->job_ptr->nodes;
		} else {
			cpus = step_ptr->cpu_count;
			tasks = step_ptr->step_layout->task_cnt;
#ifdef HAVE_BGQ
			select_g_select_jobinfo_get(step_ptr->select_jobinfo,
						    SELECT_JOBDATA_NODE_CNT,
						    &nodes);
#else
			nodes = step_ptr->step_layout->node_cnt;
#endif
			task_dist = step_ptr->step_layout->task_dist;
			temp_nodes = step_ptr->step_layout->node_list;
		}
#endif
		select_g_select_jobinfo_get(step_ptr->select_jobinfo,
					    SELECT_JOBDATA_IONODES,
					    &ionodes);
		if (ionodes) {
			snprintf(node_list, BUFFER_SIZE, "%s[%s]",
				 temp_nodes, ionodes);
			xfree(ionodes);
		} else
			snprintf(node_list, BUFFER_SIZE, "%s", temp_nodes);
	}

	if (!step_ptr->job_ptr->db_index) {
		if (!(step_ptr->job_ptr->db_index =
		      _get_db_index(mysql_conn,
				    submit_time,
				    step_ptr->job_ptr->job_id,
				    step_ptr->job_ptr->assoc_id))) {
			/* If we get an error with this just fall
			 * through to avoid an infinite loop
			 */
			if (as_mysql_job_start(mysql_conn, step_ptr->job_ptr)
			    == SLURM_ERROR) {
				error("couldn't add job %u at step start",
				      step_ptr->job_ptr->job_id);
				return SLURM_SUCCESS;
			}
		}
	}

	step_name = slurm_add_slash_to_quotes(step_ptr->name);

	/* we want to print a -1 for the requid so leave it a
	   %d */
	/* The stepid could be -2 so use %d not %u */
	query = xstrdup_printf(
		"insert into \"%s_%s\" (job_db_inx, id_step, time_start, "
		"step_name, state, "
		"cpus_alloc, nodes_alloc, task_cnt, nodelist, "
		"node_inx, task_dist, req_cpufreq) "
		"values (%d, %d, %d, '%s', %d, %d, %d, %d, "
		"'%s', '%s', %d, %u) "
		"on duplicate key update cpus_alloc=%d, nodes_alloc=%d, "
		"task_cnt=%d, time_end=0, state=%d, "
		"nodelist='%s', node_inx='%s', task_dist=%d, req_cpufreq=%u",
		mysql_conn->cluster_name, step_table,
		step_ptr->job_ptr->db_index,
		step_ptr->step_id,
		(int)start_time, step_name,
		JOB_RUNNING, cpus, nodes, tasks, node_list, node_inx, task_dist,
		step_ptr->cpu_freq, cpus, nodes, tasks, JOB_RUNNING,
		node_list, node_inx, task_dist, step_ptr->cpu_freq);
	debug3("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	rc = mysql_db_query(mysql_conn, query);
	xfree(query);
	xfree(step_name);

	return rc;
}
Ejemplo n.º 15
0
void print_fields(type_t type, void *object)
{
	if (!object) {
		fatal ("Job or step record is NULL");
		return;
	}

	slurmdb_job_rec_t *job = (slurmdb_job_rec_t *)object;
	slurmdb_step_rec_t *step = (slurmdb_step_rec_t *)object;
	jobcomp_job_rec_t *job_comp = (jobcomp_job_rec_t *)object;
	print_field_t *field = NULL;
	int curr_inx = 1;
	struct passwd *pw = NULL;
	struct	group *gr = NULL;
	char outbuf[FORMAT_STRING_SIZE];
	bool got_stats = false;
	int cpu_tres_rec_count = 0;
	int step_cpu_tres_rec_count = 0;

	switch(type) {
	case JOB:
		step = NULL;
		if (!job->track_steps)
			step = (slurmdb_step_rec_t *)job->first_step_ptr;
		/* set this to avoid printing out info for things that
		   don't mean anything.  Like an allocation that never
		   ran anything.
		*/
		if (!step)
			job->track_steps = 1;
		else
			step_cpu_tres_rec_count =
				slurmdb_find_tres_count_in_string(
					step->tres_alloc_str, TRES_CPU);

		if (job->stats.cpu_min != NO_VAL)
			got_stats = true;

		job_comp = NULL;
		cpu_tres_rec_count = slurmdb_find_tres_count_in_string(
			(job->tres_alloc_str && job->tres_alloc_str[0]) ?
			job->tres_alloc_str : job->tres_req_str,
			TRES_CPU);
		break;
	case JOBSTEP:
		job = step->job_ptr;

		if (step->stats.cpu_min != NO_VAL)
			got_stats = true;

		if ((step_cpu_tres_rec_count =
		     slurmdb_find_tres_count_in_string(
			     step->tres_alloc_str, TRES_CPU)) == INFINITE64)
			step_cpu_tres_rec_count =
				slurmdb_find_tres_count_in_string(
					(job->tres_alloc_str &&
					 job->tres_alloc_str[0]) ?
					job->tres_alloc_str : job->tres_req_str,
					TRES_CPU);

		job_comp = NULL;
		break;
	case JOBCOMP:
		job = NULL;
		step = NULL;
		break;
	default:
		break;
	}

	if ((uint64_t)cpu_tres_rec_count == INFINITE64)
		cpu_tres_rec_count = 0;

	if ((uint64_t)step_cpu_tres_rec_count == INFINITE64)
		step_cpu_tres_rec_count = 0;

	list_iterator_reset(print_fields_itr);
	while((field = list_next(print_fields_itr))) {
		char *tmp_char = NULL, id[FORMAT_STRING_SIZE];
		int tmp_int = NO_VAL, tmp_int2 = NO_VAL;
		double tmp_dub = (double)NO_VAL; /* don't use NO_VAL64
						    unless we can
						    confirm the values
						    coming in are
						    NO_VAL64 */
		uint32_t tmp_uint32 = NO_VAL;
		uint64_t tmp_uint64 = NO_VAL64;

		memset(&outbuf, 0, sizeof(outbuf));
		switch(field->type) {
		case PRINT_ALLOC_CPUS:
			switch(type) {
			case JOB:
				tmp_int = cpu_tres_rec_count;

				// we want to use the step info
				if (!step)
					break;
			case JOBSTEP:
				tmp_int = step_cpu_tres_rec_count;
				break;
			case JOBCOMP:
			default:
				tmp_int = job_comp->proc_cnt;
				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_ALLOC_GRES:
			switch(type) {
			case JOB:
				tmp_char = job->alloc_gres;
				break;
			case JOBSTEP:
				tmp_char = step->job_ptr->alloc_gres;
				break;
			case JOBCOMP:
			default:
				tmp_char = NULL;
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_ALLOC_NODES:
			switch(type) {
			case JOB:
				tmp_int = job->alloc_nodes;
				tmp_char = job->tres_alloc_str;
				break;
			case JOBSTEP:
				tmp_int = step->nnodes;
				tmp_char = step->tres_alloc_str;
				break;
			case JOBCOMP:
				tmp_int = job_comp->node_cnt;
				break;
			default:
				break;
			}

			if (!tmp_int && tmp_char) {
				if ((tmp_uint64 =
				     slurmdb_find_tres_count_in_string(
					     tmp_char, TRES_NODE))
				    != INFINITE64)
					tmp_int = tmp_uint64;
			}
			convert_num_unit((double)tmp_int, outbuf,
					 sizeof(outbuf), UNIT_NONE, NO_VAL,
					 params.convert_flags);
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_ACCOUNT:
			switch(type) {
			case JOB:
				tmp_char = job->account;
				break;
			case JOBSTEP:
				tmp_char = step->job_ptr->account;
				break;
			case JOBCOMP:
			default:
				tmp_char = "n/a";
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_ACT_CPUFREQ:
			if (got_stats) {
				switch (type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub =
							step->stats.act_cpufreq;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.act_cpufreq;
					break;
				default:
					break;
				}
			}
			if (!fuzzy_equal(tmp_dub, NO_VAL))
				convert_num_unit2((double)tmp_dub, outbuf,
						  sizeof(outbuf), UNIT_KILO,
						  params.units, 1000,
						  params.convert_flags &
						  (~CONVERT_NUM_UNIT_EXACT));

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_ASSOCID:
			switch(type) {
			case JOB:
				tmp_int = job->associd;
				break;
			case JOBSTEP:
				tmp_int = step->job_ptr->associd;
				break;
			case JOBCOMP:
			default:
				tmp_int = NO_VAL;
				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_AVECPU:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->stats.cpu_ave;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.cpu_ave;
					break;
				case JOBCOMP:
				default:
					break;
				}
			}

			if (!fuzzy_equal(tmp_dub, NO_VAL))
				tmp_char = _elapsed_time((long)tmp_dub, 0);

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_AVEDISKREAD:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->
							stats.disk_read_ave;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.disk_read_ave;
					break;
				case JOBCOMP:
				default:
					break;
				}
			}
			_print_small_double(outbuf, sizeof(outbuf),
					    tmp_dub, UNIT_MEGA);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_AVEDISKWRITE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->
							stats.disk_write_ave;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.disk_write_ave;
					break;
				case JOBCOMP:
				default:
					break;
				}
			}
			_print_small_double(outbuf, sizeof(outbuf),
					    tmp_dub, UNIT_MEGA);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_AVEPAGES:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->stats.pages_ave;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.pages_ave;
					break;
				case JOBCOMP:
				default:
					break;
				}
			}
			if (!fuzzy_equal(tmp_dub, NO_VAL))
				convert_num_unit((double)tmp_dub, outbuf,
						 sizeof(outbuf), UNIT_KILO,
						 params.units,
						 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_AVERSS:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->stats.rss_ave;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.rss_ave;
					break;
				case JOBCOMP:
				default:
					break;
				}
			}
			if (!fuzzy_equal(tmp_dub, NO_VAL))
				convert_num_unit((double)tmp_dub, outbuf,
						 sizeof(outbuf), UNIT_KILO,
						 params.units,
						 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_AVEVSIZE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->stats.vsize_ave;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.vsize_ave;
					break;
				case JOBCOMP:
				default:
					break;
				}
			}

			if (!fuzzy_equal(tmp_dub, NO_VAL))
				convert_num_unit((double)tmp_dub, outbuf,
						 sizeof(outbuf), UNIT_KILO,
						 params.units,
						 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_BLOCKID:
			switch(type) {
			case JOB:
				tmp_char = job->blockid;
				break;
			case JOBSTEP:
				break;
			case JOBCOMP:
				tmp_char = job_comp->blockid;
				break;
			default:
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_CLUSTER:
			switch(type) {
			case JOB:
				tmp_char = job->cluster;
				break;
			case JOBSTEP:
				tmp_char = step->job_ptr->cluster;
				break;
			case JOBCOMP:
			default:
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_COMMENT:
			switch(type) {
			case JOB:
				tmp_char = job->derived_es;
				break;
			case JOBSTEP:
			case JOBCOMP:
			default:
				tmp_char = NULL;
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_CONSUMED_ENERGY:
			if (got_stats) {
				switch (type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = step->
							stats.consumed_energy;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.consumed_energy;
					break;
				default:
					break;
				}
			}
			if (!fuzzy_equal(tmp_dub, NO_VAL))
				convert_num_unit2((double)tmp_dub, outbuf,
						  sizeof(outbuf), UNIT_NONE,
						  params.units, 1000,
						  params.convert_flags &
						  (~CONVERT_NUM_UNIT_EXACT));

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_CONSUMED_ENERGY_RAW:
			if (got_stats) {
				switch (type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = step->
							stats.consumed_energy;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.consumed_energy;
					break;
				default:
					break;
				}
			}

			field->print_routine(field,
					     tmp_dub,
					     (curr_inx == field_count));
			break;
		case PRINT_CPU_TIME:
			switch(type) {
			case JOB:
				tmp_uint64 = (uint64_t)job->elapsed
					* (uint64_t)cpu_tres_rec_count;
				break;
			case JOBSTEP:
				tmp_uint64 = (uint64_t)step->elapsed
					* (uint64_t)step_cpu_tres_rec_count;
				break;
			case JOBCOMP:
				break;
			default:
				break;
			}
			field->print_routine(field,
					     tmp_uint64,
					     (curr_inx == field_count));
			break;
		case PRINT_CPU_TIME_RAW:
			switch(type) {
			case JOB:
				tmp_uint64 = (uint64_t)job->elapsed
					* (uint64_t)cpu_tres_rec_count;
				break;
			case JOBSTEP:
				tmp_uint64 = (uint64_t)step->elapsed
					* (uint64_t)step_cpu_tres_rec_count;
				break;
			case JOBCOMP:
				break;
			default:
				break;
			}
			field->print_routine(field,
					     tmp_uint64,
					     (curr_inx == field_count));
			break;
		case PRINT_DERIVED_EC:
			tmp_int2 = 0;
			switch(type) {
			case JOB:
				tmp_int = job->derived_ec;
				if (tmp_int == NO_VAL)
					tmp_int = 0;
				if (WIFSIGNALED(tmp_int))
					tmp_int2 = WTERMSIG(tmp_int);

				snprintf(outbuf, sizeof(outbuf), "%d:%d",
					 WEXITSTATUS(tmp_int), tmp_int2);
				break;
			case JOBSTEP:
			case JOBCOMP:
			default:
				outbuf[0] = '\0';
				break;
			}

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_ELAPSED:
			switch(type) {
			case JOB:
				tmp_int = job->elapsed;
				break;
			case JOBSTEP:
				tmp_int = step->elapsed;
				break;
			case JOBCOMP:
				tmp_int = job_comp->elapsed_time;
				break;
			default:
				tmp_int = NO_VAL;
				break;
			}
			field->print_routine(field,
					     (uint64_t)tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_ELIGIBLE:
			switch(type) {
			case JOB:
				tmp_int = job->eligible;
				break;
			case JOBSTEP:
				tmp_int = step->start;
				break;
			case JOBCOMP:
				break;
			default:
				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_END:
			switch(type) {
			case JOB:
				tmp_int = job->end;
				break;
			case JOBSTEP:
				tmp_int = step->end;
				break;
			case JOBCOMP:
				tmp_int = parse_time(job_comp->end_time, 1);
				break;
			default:
				tmp_int = NO_VAL;
				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_EXITCODE:
			tmp_int = 0;
			tmp_int2 = 0;
			switch(type) {
			case JOB:
				tmp_int = job->exitcode;
				break;
			case JOBSTEP:
				tmp_int = step->exitcode;
				break;
			case JOBCOMP:
			default:
				break;
			}
			if (tmp_int != NO_VAL) {
				if (WIFSIGNALED(tmp_int))
					tmp_int2 = WTERMSIG(tmp_int);
				tmp_int = WEXITSTATUS(tmp_int);
				if (tmp_int >= 128)
					tmp_int -= 128;
			}
			snprintf(outbuf, sizeof(outbuf), "%d:%d",
				 tmp_int, tmp_int2);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_GID:
			switch(type) {
			case JOB:
				tmp_int = job->gid;
				break;
			case JOBSTEP:
				tmp_int = NO_VAL;
				break;
			case JOBCOMP:
				tmp_int = job_comp->gid;
				break;
			default:
				tmp_int = NO_VAL;
				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_GROUP:
			switch(type) {
			case JOB:
				tmp_int = job->gid;
				break;
			case JOBSTEP:
				tmp_int = NO_VAL;
				break;
			case JOBCOMP:
				tmp_int = job_comp->gid;
				break;
			default:
				tmp_int = NO_VAL;
				break;
			}
			tmp_char = NULL;
			if ((gr=getgrgid(tmp_int)))
				tmp_char=gr->gr_name;

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_JOBID:
			if (type == JOBSTEP)
				job = step->job_ptr;

			if (job) {
				if (job->array_task_str) {
					_xlate_task_str(job);
					snprintf(id, FORMAT_STRING_SIZE,
						 "%u_[%s]",
						 job->array_job_id,
						 job->array_task_str);
				} else if (job->array_task_id != NO_VAL)
					snprintf(id, FORMAT_STRING_SIZE,
						 "%u_%u",
						 job->array_job_id,
						 job->array_task_id);
				else
					snprintf(id, FORMAT_STRING_SIZE,
						 "%u",
						 job->jobid);
			}

			switch (type) {
			case JOB:
				tmp_char = xstrdup(id);
				break;
			case JOBSTEP:
				if (step->stepid == SLURM_BATCH_SCRIPT) {
					tmp_char = xstrdup_printf(
						"%s.batch", id);
				} else if (step->stepid == SLURM_EXTERN_CONT) {
					tmp_char = xstrdup_printf(
						"%s.extern", id);
				} else {
					tmp_char = xstrdup_printf(
						"%s.%u",
						id, step->stepid);
				}
				break;
			case JOBCOMP:
				tmp_char = xstrdup_printf("%u",
							  job_comp->jobid);
				break;
			default:
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_JOBIDRAW:
			switch (type) {
			case JOB:
				tmp_char = xstrdup_printf("%u", job->jobid);
				break;
			case JOBSTEP:
				if (step->stepid == SLURM_BATCH_SCRIPT) {
					tmp_char = xstrdup_printf(
						"%u.batch",
						step->job_ptr->jobid);
				} else if (step->stepid == SLURM_EXTERN_CONT) {
					tmp_char = xstrdup_printf(
						"%u.extern",
						step->job_ptr->jobid);
				} else {
					tmp_char = xstrdup_printf(
						"%u.%u",
						step->job_ptr->jobid,
						step->stepid);
				}
				break;
			case JOBCOMP:
				tmp_char = xstrdup_printf("%u",
							  job_comp->jobid);
				break;
			default:
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_JOBNAME:
			switch(type) {
			case JOB:
				tmp_char = job->jobname;
				break;
			case JOBSTEP:
				tmp_char = step->stepname;
				break;
			case JOBCOMP:
				tmp_char = job_comp->jobname;
				break;
			default:
				tmp_char = NULL;
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_LAYOUT:
			switch(type) {
			case JOB:
				/* below really should be step.  It is
				   not a typo */
				if (!job->track_steps)
					tmp_char = slurm_step_layout_type_name(
						step->task_dist);
				break;
			case JOBSTEP:
				tmp_char = slurm_step_layout_type_name(
					step->task_dist);
				break;
			case JOBCOMP:
				break;
			default:
				tmp_char = NULL;
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXDISKREAD:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->
							stats.disk_read_max;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.disk_read_max;
					break;
				case JOBCOMP:
				default:
					break;
				}
			}
			_print_small_double(outbuf, sizeof(outbuf),
					    tmp_dub, UNIT_MEGA);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXDISKREADNODE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_char = find_hostname(
							job->stats.
							disk_read_max_nodeid,
							job->nodes);
					break;
				case JOBSTEP:
					tmp_char = find_hostname(
						step->stats.
						disk_read_max_nodeid,
						step->nodes);
					break;
				case JOBCOMP:
				default:
					tmp_char = NULL;
					break;
				}
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXDISKREADTASK:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint32 =
							job->stats.
							disk_read_max_taskid;
					break;
				case JOBSTEP:
					tmp_uint32 = step->stats.
						disk_read_max_taskid;
					break;
				case JOBCOMP:
				default:
					tmp_uint32 = NO_VAL;
					break;
				}
			}
			if (tmp_uint32 == (uint32_t)NO_VAL)
				tmp_uint32 = NO_VAL;
			field->print_routine(field,
					     tmp_uint32,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXDISKWRITE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->stats.
							disk_write_max;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.disk_write_max;
					break;
				case JOBCOMP:
				default:
					break;
				}
			}
			_print_small_double(outbuf, sizeof(outbuf),
					    tmp_dub, UNIT_MEGA);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXDISKWRITENODE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_char = find_hostname(
							job->stats.
							disk_write_max_nodeid,
							job->nodes);
					break;
				case JOBSTEP:
					tmp_char = find_hostname(
						step->stats.
						disk_write_max_nodeid,
						step->nodes);
					break;
				case JOBCOMP:
				default:
					tmp_char = NULL;
					break;
				}
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXDISKWRITETASK:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint32 =
							job->stats.
							disk_write_max_taskid;
					break;
				case JOBSTEP:
					tmp_uint32 = step->stats.
						disk_write_max_taskid;
					break;
				case JOBCOMP:
				default:
					tmp_uint32 = NO_VAL;
					break;
				}
				if (tmp_uint32 == (uint32_t)NO_VAL)
					tmp_uint32 = NO_VAL;
			}
			field->print_routine(field,
					     tmp_uint32,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXPAGES:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint64 =
							job->stats.pages_max;
					break;
				case JOBSTEP:
					tmp_uint64 = step->stats.pages_max;
					break;
				case JOBCOMP:
				default:
					break;
				}
				if (tmp_uint64 != (uint64_t)NO_VAL64)
					convert_num_unit(
						(double)tmp_uint64,
						outbuf, sizeof(outbuf),
						UNIT_KILO, params.units,
						params.convert_flags);
			}

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXPAGESNODE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_char = find_hostname(
							job->stats.
							pages_max_nodeid,
							job->nodes);
					break;
				case JOBSTEP:
					tmp_char = find_hostname(
						step->stats.pages_max_nodeid,
						step->nodes);
					break;
				case JOBCOMP:
				default:
					tmp_char = NULL;
					break;
				}
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXPAGESTASK:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint32 =
							job->stats.
							pages_max_taskid;
					break;
				case JOBSTEP:
					tmp_uint32 = step->stats.
						pages_max_taskid;
					break;
				case JOBCOMP:
				default:
					tmp_uint32 = NO_VAL;
					break;
				}
				if (tmp_uint32 == (uint32_t)NO_VAL)
					tmp_uint32 = NO_VAL;
			}

			field->print_routine(field,
					     tmp_uint32,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXRSS:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint64 = job->stats.rss_max;
					break;
				case JOBSTEP:
					tmp_uint64 = step->stats.rss_max;
					break;
				case JOBCOMP:
				default:
					break;
				}
				if (tmp_uint64 != (uint64_t)NO_VAL64)
					convert_num_unit(
						(double)tmp_uint64,
						outbuf, sizeof(outbuf),
						UNIT_KILO, params.units,
						params.convert_flags);
			}

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXRSSNODE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_char = find_hostname(
							job->stats.
							rss_max_nodeid,
							job->nodes);
					break;
				case JOBSTEP:
					tmp_char = find_hostname(
						step->stats.rss_max_nodeid,
						step->nodes);
					break;
				case JOBCOMP:
				default:
					tmp_char = NULL;
					break;
				}
			}

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXRSSTASK:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint32 = job->stats.
							rss_max_taskid;
					break;
				case JOBSTEP:
					tmp_uint32 = step->stats.rss_max_taskid;
					break;
				case JOBCOMP:
				default:
					tmp_uint32 = NO_VAL;
					break;
				}
				if (tmp_uint32 == (uint32_t)NO_VAL)
					tmp_uint32 = NO_VAL;
			}

			field->print_routine(field,
					     tmp_uint32,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXVSIZE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint64 = job->stats.
							vsize_max;
					break;
				case JOBSTEP:
					tmp_uint64 = step->stats.vsize_max;
					break;
				case JOBCOMP:
				default:
					tmp_uint64 = (uint64_t)NO_VAL64;
					break;
				}

				if (tmp_uint64 != (uint64_t)NO_VAL64)
					convert_num_unit(
						(double)tmp_uint64,
						outbuf, sizeof(outbuf),
						UNIT_KILO, params.units,
						params.convert_flags);
			}

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXVSIZENODE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_char = find_hostname(
							job->stats.
							vsize_max_nodeid,
							job->nodes);
					break;
				case JOBSTEP:
					tmp_char = find_hostname(
						step->stats.vsize_max_nodeid,
						step->nodes);
					break;
				case JOBCOMP:
				default:
					tmp_char = NULL;
					break;
				}
			}

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXVSIZETASK:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint32 =
							job->stats.
							vsize_max_taskid;
					break;
				case JOBSTEP:
					tmp_uint32 = step->stats.
						vsize_max_taskid;
					break;
				case JOBCOMP:
				default:
					tmp_uint32 = NO_VAL;
					break;
				}
				if (tmp_uint32 == (uint32_t)NO_VAL)
					tmp_uint32 = NO_VAL;
			}

			field->print_routine(field,
					     tmp_uint32,
					     (curr_inx == field_count));
			break;
		case PRINT_MINCPU:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_dub = job->stats.cpu_min;
					break;
				case JOBSTEP:
					tmp_dub = step->stats.cpu_min;
					break;
				case JOBCOMP:
				default:
					break;
				}
				if (!fuzzy_equal(tmp_dub, NO_VAL))
					tmp_char = _elapsed_time(
						(long)tmp_dub, 0);
			}

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MINCPUNODE:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_char = find_hostname(
							job->stats.
							cpu_min_nodeid,
							job->nodes);
					break;
				case JOBSTEP:
					tmp_char = find_hostname(
						step->stats.cpu_min_nodeid,
						step->nodes);
					break;
				case JOBCOMP:
				default:
					tmp_char = NULL;
					break;
				}
			}

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MINCPUTASK:
			if (got_stats) {
				switch(type) {
				case JOB:
					if (!job->track_steps)
						tmp_uint32 = job->stats.
							cpu_min_taskid;
					break;
				case JOBSTEP:
					tmp_uint32 = step->stats.cpu_min_taskid;
					break;
				case JOBCOMP:
				default:
					tmp_uint32 = NO_VAL;
					break;
				}
				if (tmp_uint32 == (uint32_t)NO_VAL)
					tmp_uint32 = NO_VAL;
			}

			field->print_routine(field,
					     tmp_uint32,
					     (curr_inx == field_count));
			break;
		case PRINT_NODELIST:
			switch(type) {
			case JOB:
				tmp_char = job->nodes;
				break;
			case JOBSTEP:
				tmp_char = step->nodes;
				break;
			case JOBCOMP:
				tmp_char = job_comp->nodelist;
				break;
			default:
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_NNODES:
			switch(type) {
			case JOB:
				tmp_int = job->alloc_nodes;
				tmp_char = (job->tres_alloc_str &&
					    job->tres_alloc_str[0])
					? job->tres_alloc_str :
					job->tres_req_str;
				break;
			case JOBSTEP:
				tmp_int = step->nnodes;
				tmp_char = step->tres_alloc_str;
				break;
			case JOBCOMP:
				tmp_int = job_comp->node_cnt;
				break;
			default:
				break;
			}

			if (!tmp_int && tmp_char) {
				if ((tmp_uint64 =
				     slurmdb_find_tres_count_in_string(
					     tmp_char, TRES_NODE))
				    != INFINITE64)
					tmp_int = tmp_uint64;
			}
			convert_num_unit((double)tmp_int, outbuf,
					 sizeof(outbuf), UNIT_NONE,
					 params.units, params.convert_flags);
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_NTASKS:
			switch(type) {
			case JOB:
				if (!job->track_steps && !step)
					tmp_int = cpu_tres_rec_count;
				// we want to use the step info
				if (!step)
					break;
			case JOBSTEP:
				tmp_int = step->ntasks;
				break;
			case JOBCOMP:
			default:

				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_PRIO:
			switch(type) {
			case JOB:
				tmp_int = job->priority;
				break;
			case JOBSTEP:

				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_PARTITION:
			switch(type) {
			case JOB:
				tmp_char = job->partition;
				break;
			case JOBSTEP:

				break;
			case JOBCOMP:
				tmp_char = job_comp->partition;
				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_QOS:
			switch(type) {
			case JOB:
				tmp_int = job->qosid;
				break;
			case JOBSTEP:

				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			if (!g_qos_list) {
				slurmdb_qos_cond_t qos_cond;
				memset(&qos_cond, 0,
				       sizeof(slurmdb_qos_cond_t));
				qos_cond.with_deleted = 1;
				g_qos_list = slurmdb_qos_get(
					acct_db_conn, &qos_cond);
			}

			tmp_char = _find_qos_name_from_list(g_qos_list,
							    tmp_int);
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_QOSRAW:
			switch(type) {
			case JOB:
				tmp_int = job->qosid;
				break;
			case JOBSTEP:

				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_CPUFREQ_MIN:
			switch (type) {
			case JOB:
				if (!job->track_steps && !step)
					tmp_dub = NO_VAL;
				// we want to use the step info
				if (!step)
					break;
			case JOBSTEP:
				tmp_dub = step->req_cpufreq_min;
				break;
			default:
				break;
			}
			cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_dub);
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_CPUFREQ_MAX:
			switch (type) {
			case JOB:
				if (!job->track_steps && !step)
					tmp_dub = NO_VAL;
				// we want to use the step info
				if (!step)
					break;
			case JOBSTEP:
				tmp_dub = step->req_cpufreq_max;
				break;
			default:
				break;
			}
			cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_dub);
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_CPUFREQ_GOV:
			switch (type) {
			case JOB:
				if (!job->track_steps && !step)
					tmp_dub = NO_VAL;
				// we want to use the step info
				if (!step)
					break;
			case JOBSTEP:
				tmp_dub = step->req_cpufreq_gov;
				break;
			default:
				break;
			}
			cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_dub);
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_CPUS:
			switch(type) {
			case JOB:
				tmp_int = job->req_cpus;
				break;
			case JOBSTEP:
				tmp_int = step_cpu_tres_rec_count;
				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_GRES:
			switch(type) {
			case JOB:
				tmp_char = job->req_gres;
				break;
			case JOBSTEP:
				tmp_char = step->job_ptr->req_gres;
				break;
			case JOBCOMP:
			default:
				tmp_char = NULL;
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_MEM:
			switch(type) {
			case JOB:
				tmp_uint32 = job->req_mem;
				break;
			case JOBSTEP:
				tmp_uint32 = step->job_ptr->req_mem;
				break;
			case JOBCOMP:
			default:
				tmp_uint32 = NO_VAL;
				break;
			}

			if (tmp_uint32 != (uint32_t)NO_VAL) {
				bool per_cpu = false;
				if (tmp_uint32 & MEM_PER_CPU) {
					tmp_uint32 &= (~MEM_PER_CPU);
					per_cpu = true;
				}
				convert_num_unit((double)tmp_uint32,
						 outbuf, sizeof(outbuf),
						 UNIT_MEGA, params.units,
						 params.convert_flags);
				if (per_cpu)
					sprintf(outbuf+strlen(outbuf), "c");
				else
					sprintf(outbuf+strlen(outbuf), "n");
			}
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_NODES:
			switch(type) {
			case JOB:
				tmp_int = 0;
				tmp_char = job->tres_req_str;
				break;
			case JOBSTEP:
				tmp_int = step->nnodes;
				tmp_char = step->tres_alloc_str;
				break;
			case JOBCOMP:
				tmp_int = job_comp->node_cnt;
				break;
			default:
				break;
			}

			if (!tmp_int && tmp_char) {
				if ((tmp_uint64 =
				     slurmdb_find_tres_count_in_string(
					     tmp_char, TRES_NODE))
				    != INFINITE64)
					tmp_int = tmp_uint64;
			}
			convert_num_unit((double)tmp_int, outbuf,
					 sizeof(outbuf), UNIT_NONE,
					 params.units, params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_RESERVATION:
			switch(type) {
			case JOB:
				if (job->resv_name) {
					tmp_char = job->resv_name;
				} else {
					tmp_char = NULL;
				}
				break;
			case JOBSTEP:
				tmp_char = NULL;
				break;
			case JOBCOMP:
				tmp_char = NULL;
				break;
			default:
				tmp_char = NULL;
				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_RESERVATION_ID:
			switch(type) {
			case JOB:
				if (job->resvid)
					tmp_uint32 = job->resvid;
				else
					tmp_uint32 = NO_VAL;
				break;
			case JOBSTEP:
				tmp_uint32 = NO_VAL;
				break;
			case JOBCOMP:
				tmp_uint32 = NO_VAL;
				break;
			default:
				tmp_uint32 = NO_VAL;
				break;
			}
			if (tmp_uint32 == (uint32_t)NO_VAL)
				tmp_uint32 = NO_VAL;
			field->print_routine(field,
					     tmp_uint32,
					     (curr_inx == field_count));
			break;
		case PRINT_RESV:
			switch(type) {
			case JOB:
				if (job->start)
					tmp_int = job->start - job->eligible;
				else
					tmp_int = time(NULL) - job->eligible;
				break;
			case JOBSTEP:
				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     (uint64_t)tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_RESV_CPU:
			switch(type) {
			case JOB:
				if (job->start)
					tmp_int = (job->start - job->eligible)
						* job->req_cpus;
				else
					tmp_int = (time(NULL) - job->eligible)
						* job->req_cpus;
				break;
			case JOBSTEP:
				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     (uint64_t)tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_RESV_CPU_RAW:
			switch(type) {
			case JOB:
				if (job->start)
					tmp_int = (job->start - job->eligible)
						* job->req_cpus;
				else
					tmp_int = (time(NULL) - job->eligible)
						* job->req_cpus;
				break;
			case JOBSTEP:
				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_START:
			switch(type) {
			case JOB:
				tmp_int = job->start;
				break;
			case JOBSTEP:
				tmp_int = step->start;
				break;
			case JOBCOMP:
				tmp_int = parse_time(job_comp->start_time, 1);
				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_STATE:
			switch(type) {
			case JOB:
				tmp_int = job->state;
				tmp_int2 = job->requid;
				break;
			case JOBSTEP:
				tmp_int = step->state;
				tmp_int2 = step->requid;
				break;
			case JOBCOMP:
				tmp_char = job_comp->state;
				break;
			default:

				break;
			}

			if (((tmp_int & JOB_STATE_BASE) == JOB_CANCELLED) &&
			    (tmp_int2 != -1))
				snprintf(outbuf, FORMAT_STRING_SIZE,
					 "%s by %d",
					 job_state_string(tmp_int),
					 tmp_int2);
			else if (tmp_int != NO_VAL)
				snprintf(outbuf, FORMAT_STRING_SIZE,
					 "%s",
					 job_state_string(tmp_int));
			else if (tmp_char)
				snprintf(outbuf, FORMAT_STRING_SIZE,
					 "%s",
					 tmp_char);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_SUBMIT:
			switch(type) {
			case JOB:
				tmp_int = job->submit;
				break;
			case JOBSTEP:
				tmp_int = step->start;
				break;
			case JOBCOMP:
				tmp_int = parse_time(job_comp->start_time, 1);
				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_SUSPENDED:
			switch(type) {
			case JOB:
				tmp_int = job->suspended;
				break;
			case JOBSTEP:
				tmp_int = step->suspended;
				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     (uint64_t)tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_SYSTEMCPU:
			if (got_stats) {
				switch(type) {
				case JOB:
					tmp_int = job->sys_cpu_sec;
					tmp_int2 = job->sys_cpu_usec;
					break;
				case JOBSTEP:
					tmp_int = step->sys_cpu_sec;
					tmp_int2 = step->sys_cpu_usec;
					break;
				case JOBCOMP:
				default:
					break;
				}
				tmp_char = _elapsed_time(tmp_int, tmp_int2);
			}

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_TIMELIMIT:
			switch(type) {
			case JOB:
				if (job->timelimit == INFINITE)
					tmp_char = "UNLIMITED";
				else if (job->timelimit == NO_VAL)
					tmp_char = "Partition_Limit";
				else if (job->timelimit) {
					char tmp1[128];
					mins2time_str(job->timelimit,
						      tmp1, sizeof(tmp1));
					tmp_char = tmp1;
				}
				break;
			case JOBSTEP:
				break;
			case JOBCOMP:
				tmp_char = job_comp->timelimit;
				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_TOTALCPU:
			switch(type) {
			case JOB:
				tmp_int = job->tot_cpu_sec;
				tmp_int2 = job->tot_cpu_usec;
				break;
			case JOBSTEP:
				tmp_int = step->tot_cpu_sec;
				tmp_int2 = step->tot_cpu_usec;
				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			tmp_char = _elapsed_time(tmp_int, tmp_int2);

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_TRESA:
			switch(type) {
			case JOB:
				tmp_char = job->tres_alloc_str;
				break;
			case JOBSTEP:
				tmp_char = step->tres_alloc_str;
				break;
			case JOBCOMP:
			default:
				tmp_char = NULL;
				break;
			}

			if (!g_tres_list) {
				slurmdb_tres_cond_t tres_cond;
				memset(&tres_cond, 0,
				       sizeof(slurmdb_tres_cond_t));
				tres_cond.with_deleted = 1;
				g_tres_list = slurmdb_tres_get(
					acct_db_conn, &tres_cond);
			}

			tmp_char = slurmdb_make_tres_string_from_simple(
				tmp_char, g_tres_list, params.units,
				params.convert_flags);

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_TRESR:
			switch(type) {
			case JOB:
				tmp_char = job->tres_req_str;
				break;
			case JOBSTEP:
			case JOBCOMP:
			default:
				tmp_char = NULL;
				break;
			}

			if (!g_tres_list) {
				slurmdb_tres_cond_t tres_cond;
				memset(&tres_cond, 0,
				       sizeof(slurmdb_tres_cond_t));
				tres_cond.with_deleted = 1;
				g_tres_list = slurmdb_tres_get(
					acct_db_conn, &tres_cond);
			}

			tmp_char = slurmdb_make_tres_string_from_simple(
				tmp_char, g_tres_list, params.units,
				params.convert_flags);

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_UID:
			switch(type) {
			case JOB:
				if (job->user) {
					if ((pw=getpwnam(job->user)))
						tmp_int = pw->pw_uid;
				} else
					tmp_int = job->uid;
				break;
			case JOBSTEP:
				break;
			case JOBCOMP:
				tmp_int = job_comp->uid;
				break;
			default:

				break;
			}

			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		case PRINT_USER:
			switch(type) {
			case JOB:
				if (job->user)
					tmp_char = job->user;
				else if (job->uid != -1) {
					if ((pw=getpwuid(job->uid)))
						tmp_char = pw->pw_name;
				}
				break;
			case JOBSTEP:

				break;
			case JOBCOMP:
				tmp_char = job_comp->uid_name;
				break;
			default:

				break;
			}

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_USERCPU:
			if (got_stats) {
				switch(type) {
				case JOB:
					tmp_int = job->user_cpu_sec;
					tmp_int2 = job->user_cpu_usec;
					break;
				case JOBSTEP:
					tmp_int = step->user_cpu_sec;
					tmp_int2 = step->user_cpu_usec;
					break;
				case JOBCOMP:
				default:
					break;
				}
				tmp_char = _elapsed_time(tmp_int, tmp_int2);
			}

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_WCKEY:
			switch(type) {
			case JOB:
				tmp_char = job->wckey;
				break;
			case JOBSTEP:

				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			break;
		case PRINT_WCKEYID:
			switch(type) {
			case JOB:
				tmp_int = job->wckeyid;
				break;
			case JOBSTEP:

				break;
			case JOBCOMP:

				break;
			default:

				break;
			}
			field->print_routine(field,
					     tmp_int,
					     (curr_inx == field_count));
			break;
		default:
			break;
		}
		curr_inx++;
	}
	printf("\n");
}
Ejemplo n.º 16
0
extern List as_mysql_get_clusters(mysql_conn_t *mysql_conn, uid_t uid,
				  slurmdb_cluster_cond_t *cluster_cond)
{
	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	List cluster_list = NULL;
	ListIterator itr = NULL;
	int i=0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	slurmdb_assoc_cond_t assoc_cond;
	ListIterator assoc_itr = NULL;
	slurmdb_cluster_rec_t *cluster = NULL;
	slurmdb_assoc_rec_t *assoc = NULL;
	List assoc_list = NULL;

	/* if this changes you will need to edit the corresponding enum */
	char *cluster_req_inx[] = {
		"name",
		"classification",
		"control_host",
		"control_port",
		"rpc_version",
		"dimensions",
		"flags",
		"plugin_id_select"
	};
	enum {
		CLUSTER_REQ_NAME,
		CLUSTER_REQ_CLASS,
		CLUSTER_REQ_CH,
		CLUSTER_REQ_CP,
		CLUSTER_REQ_VERSION,
		CLUSTER_REQ_DIMS,
		CLUSTER_REQ_FLAGS,
		CLUSTER_REQ_PI_SELECT,
		CLUSTER_REQ_COUNT
	};

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;


	if (!cluster_cond) {
		xstrcat(extra, " where deleted=0");
		goto empty;
	}

	_setup_cluster_cond_limits(cluster_cond, &extra);

empty:

	xfree(tmp);
	i=0;
	xstrfmtcat(tmp, "%s", cluster_req_inx[i]);
	for(i=1; i<CLUSTER_REQ_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", cluster_req_inx[i]);
	}

	query = xstrdup_printf("select %s from %s%s",
			       tmp, cluster_table, extra);
	xfree(tmp);
	xfree(extra);

	if (debug_flags & DEBUG_FLAG_DB_ASSOC)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}
	xfree(query);

	cluster_list = list_create(slurmdb_destroy_cluster_rec);

	memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));

	if (cluster_cond) {
		/* I don't think we want the with_usage flag here.
		 * We do need the with_deleted though. */
		//assoc_cond.with_usage = cluster_cond->with_usage;
		assoc_cond.with_deleted = cluster_cond->with_deleted;
	}
	assoc_cond.cluster_list = list_create(NULL);

	while ((row = mysql_fetch_row(result))) {
		MYSQL_RES *result2 = NULL;
		MYSQL_ROW row2;
		cluster = xmalloc(sizeof(slurmdb_cluster_rec_t));
		list_append(cluster_list, cluster);

		cluster->name = xstrdup(row[CLUSTER_REQ_NAME]);

		list_append(assoc_cond.cluster_list, cluster->name);

		cluster->classification = slurm_atoul(row[CLUSTER_REQ_CLASS]);
		cluster->control_host = xstrdup(row[CLUSTER_REQ_CH]);
		cluster->control_port = slurm_atoul(row[CLUSTER_REQ_CP]);
		cluster->rpc_version = slurm_atoul(row[CLUSTER_REQ_VERSION]);
		cluster->dimensions = slurm_atoul(row[CLUSTER_REQ_DIMS]);
		cluster->flags = slurm_atoul(row[CLUSTER_REQ_FLAGS]);
		cluster->plugin_id_select =
			slurm_atoul(row[CLUSTER_REQ_PI_SELECT]);

		query = xstrdup_printf(
			"select tres, cluster_nodes from "
			"\"%s_%s\" where time_end=0 and node_name='' limit 1",
			cluster->name, event_table);
		if (debug_flags & DEBUG_FLAG_DB_TRES)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		if (!(result2 = mysql_db_query_ret(mysql_conn, query, 0))) {
			xfree(query);
			continue;
		}
		xfree(query);
		if ((row2 = mysql_fetch_row(result2))) {
			cluster->tres_str = xstrdup(row2[0]);
			if (row2[1] && row2[1][0])
				cluster->nodes = xstrdup(row2[1]);
		}
		mysql_free_result(result2);

		/* get the usage if requested */
		if (cluster_cond && cluster_cond->with_usage) {
			as_mysql_get_usage(
				mysql_conn, uid, cluster,
				DBD_GET_CLUSTER_USAGE,
				cluster_cond->usage_start,
				cluster_cond->usage_end);
		}

	}
	mysql_free_result(result);

	if (!list_count(assoc_cond.cluster_list)) {
		FREE_NULL_LIST(assoc_cond.cluster_list);
		return cluster_list;
	}

	assoc_cond.acct_list = list_create(NULL);
	list_append(assoc_cond.acct_list, "root");

	assoc_cond.user_list = list_create(NULL);
	list_append(assoc_cond.user_list, "");

	assoc_list = as_mysql_get_assocs(mysql_conn, uid, &assoc_cond);
	FREE_NULL_LIST(assoc_cond.cluster_list);
	FREE_NULL_LIST(assoc_cond.acct_list);
	FREE_NULL_LIST(assoc_cond.user_list);

	if (!assoc_list)
		return cluster_list;

	itr = list_iterator_create(cluster_list);
	assoc_itr = list_iterator_create(assoc_list);
	while ((cluster = list_next(itr))) {
		while ((assoc = list_next(assoc_itr))) {
			if (xstrcmp(assoc->cluster, cluster->name))
				continue;

			if (cluster->root_assoc) {
				debug("This cluster %s already has "
				      "an association.", cluster->name);
				continue;
			}
			cluster->root_assoc = assoc;
			list_remove(assoc_itr);
		}
		list_iterator_reset(assoc_itr);
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(assoc_itr);
	if (list_count(assoc_list))
		error("I have %d left over associations",
		      list_count(assoc_list));
	FREE_NULL_LIST(assoc_list);

	return cluster_list;
}
Ejemplo n.º 17
0
extern bg_record_t *create_small_record(bg_record_t *bg_record,
					bitstr_t *ionodes, int size)
{
	bg_record_t *found_record = NULL;
	ba_mp_t *new_ba_mp = NULL;
	ba_mp_t *ba_mp = NULL;

	found_record = (bg_record_t*) xmalloc(sizeof(bg_record_t));
	found_record->magic = BLOCK_MAGIC;

	/* This will be a list containing jobs running on this
	   block */
	if (bg_conf->sub_blocks)
		found_record->job_list = list_create(NULL);
	found_record->job_running = NO_JOB_RUNNING;

#ifdef HAVE_BGL
	found_record->node_use = SELECT_COPROCESSOR_MODE;
	found_record->blrtsimage = xstrdup(bg_record->blrtsimage);
#endif
#ifdef HAVE_BG_L_P
	found_record->linuximage = xstrdup(bg_record->linuximage);
	found_record->ramdiskimage = xstrdup(bg_record->ramdiskimage);
#endif
	found_record->mloaderimage = xstrdup(bg_record->mloaderimage);

	if (bg_record->conn_type[0] >= SELECT_SMALL)
		found_record->conn_type[0] = bg_record->conn_type[0];
	else
		found_record->conn_type[0] = SELECT_SMALL;

	xassert(bg_conf->cpu_ratio);
	found_record->cpu_cnt = bg_conf->cpu_ratio * size;
	found_record->cnode_cnt = size;

	found_record->ionode_bitmap = bit_copy(ionodes);
	ba_set_ionode_str(found_record);

	found_record->ba_mp_list = list_create(destroy_ba_mp);

	slurm_mutex_lock(&ba_system_mutex);
	if (bg_record->ba_mp_list)
		ba_mp = list_peek(bg_record->ba_mp_list);
	if (!ba_mp) {
		if (bg_record->mp_str) {
			int j = 0, dim;
			char *nodes = bg_record->mp_str;
			uint16_t coords[SYSTEM_DIMENSIONS];
			while (nodes[j] != '\0') {
				if ((nodes[j] >= '0' && nodes[j] <= '9')
				    || (nodes[j] >= 'A' && nodes[j] <= 'Z')) {
					break;
				}
				j++;
			}
			if (nodes[j] && ((strlen(nodes)
					  - (j + SYSTEM_DIMENSIONS)) >= 0)) {
				for (dim = 0; dim < SYSTEM_DIMENSIONS;
				     dim++, j++)
					coords[dim] = select_char2coord(
						nodes[j]);
				ba_mp = coord2ba_mp(coords);
			}
			error("you gave me a list with no ba_mps using %s",
			      ba_mp->coord_str);
		} else {
			ba_mp = coord2ba_mp(found_record->start);
			error("you gave me a record with no ba_mps "
			      "and no nodes either using %s",
			      ba_mp->coord_str);
		}
	}

	xassert(ba_mp);

	new_ba_mp = ba_copy_mp(ba_mp);
	slurm_mutex_unlock(&ba_system_mutex);
	/* We need to have this node wrapped in Q to handle
	   wires correctly when creating around the midplane.
	*/
	ba_setup_mp(new_ba_mp, false, true);

	new_ba_mp->used = BA_MP_USED_TRUE;

	/* Create these now so we can deal with error cnodes if/when
	   they happen.  Since this is the easiest place to figure it
	   out for blocks that don't use the entire block */
	if ((new_ba_mp->cnode_bitmap =
	     ba_create_ba_mp_cnode_bitmap(found_record))) {
		new_ba_mp->cnode_err_bitmap = bit_alloc(bg_conf->mp_cnode_cnt);
		new_ba_mp->cnode_usable_bitmap =
			bit_copy(new_ba_mp->cnode_bitmap);
	}

	list_append(found_record->ba_mp_list, new_ba_mp);
	found_record->mp_count = 1;
	found_record->mp_str = xstrdup_printf(
		"%s%s",
		bg_conf->slurm_node_prefix, new_ba_mp->coord_str);

	process_nodes(found_record, false);

	/* Force small blocks to always be non-full system blocks.
	 * This really only plays a part on sub-midplane systems. */
	found_record->full_block = 0;

	if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK)
		info("made small block of %s[%s]",
		     found_record->mp_str, found_record->ionode_str);

	return found_record;
}
Ejemplo n.º 18
0
extern List as_mysql_get_cluster_events(mysql_conn_t *mysql_conn, uint32_t uid,
					slurmdb_event_cond_t *event_cond)
{
	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	List ret_list = NULL;
	ListIterator itr = NULL;
	char *object = NULL;
	int set = 0;
	int i=0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	time_t now = time(NULL);
	List use_cluster_list = as_mysql_cluster_list;

	/* if this changes you will need to edit the corresponding enum */
	char *event_req_inx[] = {
		"cluster_nodes",
		"node_name",
		"state",
		"time_start",
		"time_end",
		"reason",
		"reason_uid",
		"tres",
	};

	enum {
		EVENT_REQ_CNODES,
		EVENT_REQ_NODE,
		EVENT_REQ_STATE,
		EVENT_REQ_START,
		EVENT_REQ_END,
		EVENT_REQ_REASON,
		EVENT_REQ_REASON_UID,
		EVENT_REQ_TRES,
		EVENT_REQ_COUNT
	};

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	if (!event_cond)
		goto empty;

	if (event_cond->cpus_min) {
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");

		if (event_cond->cpus_max) {
			xstrfmtcat(extra, "count between %u and %u)",
				   event_cond->cpus_min, event_cond->cpus_max);

		} else {
			xstrfmtcat(extra, "count='%u')",
				   event_cond->cpus_min);

		}
	}

	switch(event_cond->event_type) {
	case SLURMDB_EVENT_ALL:
		break;
	case SLURMDB_EVENT_CLUSTER:
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");
		xstrcat(extra, "node_name = '')");

		break;
	case SLURMDB_EVENT_NODE:
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");
		xstrcat(extra, "node_name != '')");

		break;
	default:
		error("Unknown event %u doing all", event_cond->event_type);
		break;
	}

	if (event_cond->node_list
	    && list_count(event_cond->node_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");
		itr = list_iterator_create(event_cond->node_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "node_name='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (event_cond->period_start) {
		if (!event_cond->period_end)
			event_cond->period_end = now;

		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");

		xstrfmtcat(extra,
			   "(time_start < %ld) "
			   "&& (time_end >= %ld || time_end = 0))",
			   event_cond->period_end, event_cond->period_start);
	}

	if (event_cond->reason_list
	    && list_count(event_cond->reason_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");
		itr = list_iterator_create(event_cond->reason_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "reason like '%%%s%%'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (event_cond->reason_uid_list
	    && list_count(event_cond->reason_uid_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");
		itr = list_iterator_create(event_cond->reason_uid_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "reason_uid='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (event_cond->state_list
	    && list_count(event_cond->state_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");
		itr = list_iterator_create(event_cond->state_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "state='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (event_cond->cluster_list && list_count(event_cond->cluster_list))
		use_cluster_list = event_cond->cluster_list;
empty:
	xfree(tmp);
	xstrfmtcat(tmp, "%s", event_req_inx[0]);
	for(i=1; i<EVENT_REQ_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", event_req_inx[i]);
	}

	if (use_cluster_list == as_mysql_cluster_list)
		slurm_mutex_lock(&as_mysql_cluster_list_lock);

	ret_list = list_create(slurmdb_destroy_event_rec);

	itr = list_iterator_create(use_cluster_list);
	while ((object = list_next(itr))) {
		query = xstrdup_printf("select %s from \"%s_%s\"",
				       tmp, object, event_table);
		if (extra)
			xstrfmtcat(query, " %s", extra);

		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		if (!(result = mysql_db_query_ret(
			      mysql_conn, query, 0))) {
			xfree(query);
			if (mysql_errno(mysql_conn->db_conn)
			    != ER_NO_SUCH_TABLE) {
				FREE_NULL_LIST(ret_list);
				ret_list = NULL;
			}
			break;
		}
		xfree(query);

		while ((row = mysql_fetch_row(result))) {
			slurmdb_event_rec_t *event =
				xmalloc(sizeof(slurmdb_event_rec_t));

			list_append(ret_list, event);

			event->cluster = xstrdup(object);

			if (row[EVENT_REQ_NODE] && row[EVENT_REQ_NODE][0]) {
				event->node_name = xstrdup(row[EVENT_REQ_NODE]);
				event->event_type = SLURMDB_EVENT_NODE;
			} else
				event->event_type = SLURMDB_EVENT_CLUSTER;

			event->state = slurm_atoul(row[EVENT_REQ_STATE]);
			event->period_start = slurm_atoul(row[EVENT_REQ_START]);
			event->period_end = slurm_atoul(row[EVENT_REQ_END]);

			if (row[EVENT_REQ_REASON] && row[EVENT_REQ_REASON][0])
				event->reason = xstrdup(row[EVENT_REQ_REASON]);
			event->reason_uid =
				slurm_atoul(row[EVENT_REQ_REASON_UID]);

			if (row[EVENT_REQ_CNODES] && row[EVENT_REQ_CNODES][0])
				event->cluster_nodes =
					xstrdup(row[EVENT_REQ_CNODES]);

			if (row[EVENT_REQ_TRES] && row[EVENT_REQ_TRES][0])
				event->tres_str = xstrdup(row[EVENT_REQ_TRES]);
		}
		mysql_free_result(result);
	}
	list_iterator_destroy(itr);
	xfree(tmp);
	xfree(extra);

	if (use_cluster_list == as_mysql_cluster_list)
		slurm_mutex_unlock(&as_mysql_cluster_list_lock);

	return ret_list;
}
Ejemplo n.º 19
0
extern List mysql_jobcomp_process_get_jobs(slurmdb_job_cond_t *job_cond)
{

	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	char *selected_part = NULL;
	slurmdb_selected_step_t *selected_step = NULL;
	ListIterator itr = NULL;
	int set = 0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	int i;
	int lc = 0;
	jobcomp_job_rec_t *job = NULL;
	char time_str[32];
	time_t temp_time;
	List job_list = list_create(jobcomp_destroy_job);

	if (job_cond->step_list && list_count(job_cond->step_list)) {
		set = 0;
		xstrcat(extra, " where (");
		itr = list_iterator_create(job_cond->step_list);
		while((selected_step = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			tmp = xstrdup_printf("jobid=%d",
					      selected_step->jobid);
			xstrcat(extra, tmp);
			set = 1;
			xfree(tmp);
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (job_cond->partition_list && list_count(job_cond->partition_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, " where (");

		itr = list_iterator_create(job_cond->partition_list);
		while((selected_part = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			tmp = xstrdup_printf("`partition`='%s'",
					      selected_part);
			xstrcat(extra, tmp);
			set = 1;
			xfree(tmp);
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	i = 0;
	while(jobcomp_table_fields[i].name) {
		if (i)
			xstrcat(tmp, ", ");
		xstrcat(tmp, jobcomp_table_fields[i].name);
		i++;
	}

	query = xstrdup_printf("select %s from %s", tmp, jobcomp_table);
	xfree(tmp);

	if (extra) {
		xstrcat(query, extra);
		xfree(extra);
	}

	//info("query = %s", query);
	if (!(result =
	     mysql_db_query_ret(jobcomp_mysql_conn, query, 0))) {
		xfree(query);
		list_destroy(job_list);
		return NULL;
	}
	xfree(query);

	while((row = mysql_fetch_row(result))) {
		lc++;

		job = xmalloc(sizeof(jobcomp_job_rec_t));
		if (row[JOBCOMP_REQ_JOBID])
			job->jobid = slurm_atoul(row[JOBCOMP_REQ_JOBID]);
		job->partition = xstrdup(row[JOBCOMP_REQ_PARTITION]);
		temp_time = atoi(row[JOBCOMP_REQ_STARTTIME]);
		slurm_make_time_str(&temp_time,
				    time_str,
				    sizeof(time_str));

		job->start_time = xstrdup(time_str);
		temp_time = atoi(row[JOBCOMP_REQ_ENDTIME]);
		slurm_make_time_str(&temp_time,
				    time_str,
				    sizeof(time_str));

		job->elapsed_time = atoi(row[JOBCOMP_REQ_ENDTIME])
			- atoi(row[JOBCOMP_REQ_STARTTIME]);

		job->end_time = xstrdup(time_str);
		if (row[JOBCOMP_REQ_UID])
			job->uid = slurm_atoul(row[JOBCOMP_REQ_UID]);
		job->uid_name = xstrdup(row[JOBCOMP_REQ_USER_NAME]);
		if (row[JOBCOMP_REQ_GID])
			job->gid = slurm_atoul(row[JOBCOMP_REQ_GID]);
		job->gid_name = xstrdup(row[JOBCOMP_REQ_GROUP_NAME]);
		job->jobname = xstrdup(row[JOBCOMP_REQ_NAME]);
		job->nodelist = xstrdup(row[JOBCOMP_REQ_NODELIST]);
		if (row[JOBCOMP_REQ_NODECNT])
			job->node_cnt = slurm_atoul(row[JOBCOMP_REQ_NODECNT]);
		if (row[JOBCOMP_REQ_STATE]) {
			i = atoi(row[JOBCOMP_REQ_STATE]);
			job->state = xstrdup(job_state_string(i));
		}
		job->timelimit = xstrdup(row[JOBCOMP_REQ_TIMELIMIT]);
		if (row[JOBCOMP_REQ_MAXPROCS])
			job->max_procs = slurm_atoul(row[JOBCOMP_REQ_MAXPROCS]);
		job->connection = xstrdup(row[JOBCOMP_REQ_CONNECTION]);
		job->reboot = xstrdup(row[JOBCOMP_REQ_REBOOT]);
		job->rotate = xstrdup(row[JOBCOMP_REQ_ROTATE]);
		job->geo = xstrdup(row[JOBCOMP_REQ_GEOMETRY]);
		job->bg_start_point = xstrdup(row[JOBCOMP_REQ_START]);
		job->blockid = xstrdup(row[JOBCOMP_REQ_BLOCKID]);
		list_append(job_list, job);
	}

	mysql_free_result(result);

	return job_list;
}
Ejemplo n.º 20
0
static int _get_cluster_usage(mysql_conn_t *mysql_conn, uid_t uid,
			      slurmdb_cluster_rec_t *cluster_rec,
			      slurmdbd_msg_type_t type,
			      time_t start, time_t end)
{
	int rc = SLURM_SUCCESS;
	int i=0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	char *tmp = NULL;
	char *my_usage_table = cluster_day_table;
	char *query = NULL;
	char *cluster_req_inx[] = {
		"alloc_cpu_secs",
		"down_cpu_secs",
		"pdown_cpu_secs",
		"idle_cpu_secs",
		"resv_cpu_secs",
		"over_cpu_secs",
		"cpu_count",
		"time_start",
		"consumed_energy"
	};

	enum {
		CLUSTER_ACPU,
		CLUSTER_DCPU,
		CLUSTER_PDCPU,
		CLUSTER_ICPU,
		CLUSTER_RCPU,
		CLUSTER_OCPU,
		CLUSTER_CPU_COUNT,
		CLUSTER_START,
		CLUSTER_ENERGY,
		CLUSTER_COUNT
	};

	if (!cluster_rec->name || !cluster_rec->name[0]) {
		error("We need a cluster name to set data for");
		return SLURM_ERROR;
	}

	if (set_usage_information(&my_usage_table, type, &start, &end)
	    != SLURM_SUCCESS) {
		return SLURM_ERROR;
	}

	xfree(tmp);
	i=0;
	xstrfmtcat(tmp, "%s", cluster_req_inx[i]);
	for(i=1; i<CLUSTER_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", cluster_req_inx[i]);
	}

	query = xstrdup_printf(
		"select %s from \"%s_%s\" where (time_start < %ld "
		"&& time_start >= %ld)",
		tmp, cluster_rec->name, my_usage_table, end, start);

	xfree(tmp);
	debug4("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);

	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	if (!cluster_rec->accounting_list)
		cluster_rec->accounting_list =
			list_create(slurmdb_destroy_cluster_accounting_rec);

	while ((row = mysql_fetch_row(result))) {
		slurmdb_cluster_accounting_rec_t *accounting_rec =
			xmalloc(sizeof(slurmdb_cluster_accounting_rec_t));
		accounting_rec->alloc_secs = slurm_atoull(row[CLUSTER_ACPU]);
		accounting_rec->down_secs = slurm_atoull(row[CLUSTER_DCPU]);
		accounting_rec->pdown_secs = slurm_atoull(row[CLUSTER_PDCPU]);
		accounting_rec->idle_secs = slurm_atoull(row[CLUSTER_ICPU]);
		accounting_rec->over_secs = slurm_atoull(row[CLUSTER_OCPU]);
		accounting_rec->resv_secs = slurm_atoull(row[CLUSTER_RCPU]);
		accounting_rec->cpu_count = slurm_atoul(row[CLUSTER_CPU_COUNT]);
		accounting_rec->period_start = slurm_atoul(row[CLUSTER_START]);
		accounting_rec->consumed_energy = slurm_atoull(row[CLUSTER_ENERGY]);
		list_append(cluster_rec->accounting_list, accounting_rec);
	}
	mysql_free_result(result);
	return rc;
}
Ejemplo n.º 21
0
/* This needs to happen to make since 2.1 code doesn't have enough
 * smarts to figure out it isn't adding a default wckey if just
 * adding a new wckey for a user that has never been on the cluster before.
 */
static int _make_sure_users_have_default(
    mysql_conn_t *mysql_conn, List user_list)
{
    char *query = NULL, *cluster = NULL, *user = NULL;
    ListIterator itr = NULL, clus_itr = NULL;
    int rc = SLURM_SUCCESS;

    if (!user_list)
        return SLURM_SUCCESS;

    slurm_mutex_lock(&as_mysql_cluster_list_lock);

    clus_itr = list_iterator_create(as_mysql_cluster_list);
    itr = list_iterator_create(user_list);

    while ((user = list_next(itr))) {
        while ((cluster = list_next(clus_itr))) {
            MYSQL_RES *result = NULL;
            MYSQL_ROW row;
            char *wckey = NULL;
            /* only look at non * and non deleted ones */
            query = xstrdup_printf(
                        "select distinct is_def, wckey_name from "
                        "\"%s_%s\" where user='******' and wckey_name "
                        "not like '*%%' and deleted=0 FOR UPDATE;",
                        cluster, wckey_table, user);
            debug4("%d(%s:%d) query\n%s",
                   mysql_conn->conn, THIS_FILE, __LINE__, query);
            if (!(result = mysql_db_query_ret(
                               mysql_conn, query, 0))) {
                xfree(query);
                error("couldn't query the database");
                rc = SLURM_ERROR;
                break;
            }
            xfree(query);
            /* Check to see if the user is even added to
               the cluster.
            */
            if (!mysql_num_rows(result)) {
                mysql_free_result(result);
                continue;
            }
            while ((row = mysql_fetch_row(result))) {
                if (row[0][0] == '1')
                    break;
                if (!wckey)
                    wckey = xstrdup(row[1]);
            }
            mysql_free_result(result);

            /* we found one so just continue */
            if (row || !wckey) {
                xfree(wckey);
                continue;
            }
            query = xstrdup_printf(
                        "update \"%s_%s\" set is_def=1 where "
                        "user='******' and wckey_name='%s';",
                        cluster, wckey_table, user, wckey);
            xfree(wckey);
            if (debug_flags & DEBUG_FLAG_DB_WCKEY)
                DB_DEBUG(mysql_conn->conn, "query\n%s", query);
            rc = mysql_db_query(mysql_conn, query);
            xfree(query);
            if (rc != SLURM_SUCCESS) {
                error("problem with update query");
                rc = SLURM_ERROR;
                break;
            }
        }
        if (!rc != SLURM_SUCCESS)
            break;
        list_iterator_reset(clus_itr);
    }
    list_iterator_destroy(itr);
    list_iterator_destroy(clus_itr);
    slurm_mutex_unlock(&as_mysql_cluster_list_lock);

    return rc;
}
Ejemplo n.º 22
0
/* checks should already be done before this to see if this is a valid
   user or not.
*/
extern int get_usage_for_list(mysql_conn_t *mysql_conn,
			      slurmdbd_msg_type_t type, List object_list,
			      char *cluster_name, time_t start, time_t end)
{
	int rc = SLURM_SUCCESS;
	int i=0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	char *tmp = NULL;
	char *my_usage_table = NULL;
	char *query = NULL;
	List usage_list = NULL;
	char *id_str = NULL;
	ListIterator itr = NULL, u_itr = NULL;
	void *object = NULL;
	slurmdb_association_rec_t *assoc = NULL;
	slurmdb_wckey_rec_t *wckey = NULL;
	slurmdb_accounting_rec_t *accounting_rec = NULL;

	/* Since for id in association table we
	   use t3 and in wckey table we use t1 we can't define it here */
	char **usage_req_inx = NULL;

	enum {
		USAGE_ID,
		USAGE_START,
		USAGE_ACPU,
		USAGE_ENERGY,
		USAGE_COUNT
	};


	if (!object_list) {
		error("We need an object to set data for getting usage");
		return SLURM_ERROR;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	switch (type) {
	case DBD_GET_ASSOC_USAGE:
	{
		char *temp_usage[] = {
			"t3.id_assoc",
			"t1.time_start",
			"t1.alloc_cpu_secs",
			"t1.consumed_energy",
		};
		usage_req_inx = temp_usage;

		itr = list_iterator_create(object_list);
		while ((assoc = list_next(itr))) {
			if (id_str)
				xstrfmtcat(id_str, " || t3.id_assoc=%d",
					   assoc->id);
			else
				xstrfmtcat(id_str, "t3.id_assoc=%d", assoc->id);
		}
		list_iterator_destroy(itr);

		my_usage_table = assoc_day_table;
		break;
	}
	case DBD_GET_WCKEY_USAGE:
	{
		char *temp_usage[] = {
			"id_wckey",
			"time_start",
			"alloc_cpu_secs",
			"consumed_energy"
		};
		usage_req_inx = temp_usage;

		itr = list_iterator_create(object_list);
		while ((wckey = list_next(itr))) {
			if (id_str)
				xstrfmtcat(id_str, " || id_wckey=%d",
					   wckey->id);
			else
				xstrfmtcat(id_str, "id_wckey=%d", wckey->id);
		}
		list_iterator_destroy(itr);

		my_usage_table = wckey_day_table;
		break;
	}
	default:
		error("Unknown usage type %d", type);
		return SLURM_ERROR;
		break;
	}

	if (set_usage_information(&my_usage_table, type, &start, &end)
	    != SLURM_SUCCESS) {
		xfree(id_str);
		return SLURM_ERROR;
	}

	xfree(tmp);
	i=0;
	xstrfmtcat(tmp, "%s", usage_req_inx[i]);
	for(i=1; i<USAGE_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", usage_req_inx[i]);
	}
	switch (type) {
	case DBD_GET_ASSOC_USAGE:
		query = xstrdup_printf(
			"select %s from \"%s_%s\" as t1, "
			"\"%s_%s\" as t2, \"%s_%s\" as t3 "
			"where (t1.time_start < %ld && t1.time_start >= %ld) "
			"&& t1.id_assoc=t2.id_assoc && (%s) && "
			"t2.lft between t3.lft and t3.rgt "
			"order by t3.id_assoc, time_start;",
			tmp, cluster_name, my_usage_table,
			cluster_name, assoc_table, cluster_name, assoc_table,
			end, start, id_str);
		break;
	case DBD_GET_WCKEY_USAGE:
		query = xstrdup_printf(
			"select %s from \"%s_%s\" "
			"where (time_start < %ld && time_start >= %ld) "
			"&& (%s) order by id_wckey, time_start;",
			tmp, cluster_name, my_usage_table, end, start, id_str);
		break;
	default:
		error("Unknown usage type %d", type);
		xfree(id_str);
		xfree(tmp);
		return SLURM_ERROR;
		break;
	}
	xfree(id_str);
	xfree(tmp);

	debug4("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	usage_list = list_create(slurmdb_destroy_accounting_rec);

	while ((row = mysql_fetch_row(result))) {
		slurmdb_accounting_rec_t *accounting_rec =
			xmalloc(sizeof(slurmdb_accounting_rec_t));
		accounting_rec->id = slurm_atoul(row[USAGE_ID]);
		accounting_rec->period_start = slurm_atoul(row[USAGE_START]);
		accounting_rec->alloc_secs = slurm_atoull(row[USAGE_ACPU]);
		accounting_rec->consumed_energy = slurm_atoull(row[USAGE_ENERGY]);
		list_append(usage_list, accounting_rec);
	}
	mysql_free_result(result);

	u_itr = list_iterator_create(usage_list);
	itr = list_iterator_create(object_list);
	while ((object = list_next(itr))) {
		int found = 0;
		int id = 0;
		List acct_list = NULL;

		switch (type) {
		case DBD_GET_ASSOC_USAGE:
			assoc = (slurmdb_association_rec_t *)object;
			if (!assoc->accounting_list)
				assoc->accounting_list = list_create(
					slurmdb_destroy_accounting_rec);
			acct_list = assoc->accounting_list;
			id = assoc->id;
			break;
		case DBD_GET_WCKEY_USAGE:
			wckey = (slurmdb_wckey_rec_t *)object;
			if (!wckey->accounting_list)
				wckey->accounting_list = list_create(
					slurmdb_destroy_accounting_rec);
			acct_list = wckey->accounting_list;
			id = wckey->id;
			break;
		default:
			continue;
			break;
		}

		while ((accounting_rec = list_next(u_itr))) {
			if (id == accounting_rec->id) {
				list_append(acct_list, accounting_rec);
				list_remove(u_itr);
				found = 1;
			} else if (found) {
				/* here we know the
				   list is in id order so
				   if the next record
				   isn't the correct id
				   just continue since
				   there is no reason to
				   go through the rest of
				   the list when we know
				   it isn't going to be
				   the correct id */
				break;
			}
		}
		list_iterator_reset(u_itr);
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(u_itr);

	if (list_count(usage_list))
		error("we have %d records not added "
		      "to the association list",
		      list_count(usage_list));
	list_destroy(usage_list);


	return rc;
}
Ejemplo n.º 23
0
static int _cluster_modify_wckeys(mysql_conn_t *mysql_conn,
                                  slurmdb_wckey_rec_t *wckey,
                                  char *cluster_name, char *extra,
                                  char *vals, char *user_name,
                                  List ret_list)
{
    int rc = SLURM_SUCCESS;
    MYSQL_RES *result = NULL;
    MYSQL_ROW row;
    char *wckey_char = NULL;
    time_t now = time(NULL);
    char *query = NULL;

    query = xstrdup_printf("select t1.id_wckey, t1.wckey_name, t1.user "
                           "from \"%s_%s\" as t1%s;",
                           cluster_name, wckey_table, extra);
    if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
        xfree(query);
        return SLURM_ERROR;
    }

    /* This key doesn't exist on this cluster, that is ok. */
    if (!mysql_num_rows(result))
        return SLURM_SUCCESS;

    while ((row = mysql_fetch_row(result))) {
        slurmdb_wckey_rec_t *wckey_rec = NULL;
        char *object = xstrdup_printf(
                           "C = %-10s W = %-20s U = %-9s",
                           cluster_name, row[1], row[2]);
        list_append(ret_list, object);
        if (!wckey_char)
            xstrfmtcat(wckey_char, "id_wckey='%s'", row[0]);
        else
            xstrfmtcat(wckey_char, " || id_wckey='%s'", row[0]);

        wckey_rec = xmalloc(sizeof(slurmdb_wckey_rec_t));
        /* we only need id and cluster when removing
           no real need to init */
        wckey_rec->id = slurm_atoul(row[0]);
        wckey_rec->cluster = xstrdup(cluster_name);
        wckey_rec->is_def = wckey->is_def;
        if (addto_update_list(mysql_conn->update_list,
                              SLURMDB_MODIFY_WCKEY, wckey_rec)
                != SLURM_SUCCESS)
            slurmdb_destroy_wckey_rec(wckey_rec);

        if (wckey->is_def == 1) {
            /* Use fresh one here so we don't have to
               worry about dealing with bad values.
            */
            slurmdb_wckey_rec_t tmp_wckey;
            slurmdb_init_wckey_rec(&tmp_wckey, 0);
            tmp_wckey.is_def = 1;
            tmp_wckey.cluster = cluster_name;
            tmp_wckey.name = row[1];
            tmp_wckey.user = row[2];
            if ((rc = _reset_default_wckey(mysql_conn, &tmp_wckey))
                    != SLURM_SUCCESS)
                break;
        }
    }
    mysql_free_result(result);

    if (!list_count(ret_list)) {
        errno = SLURM_NO_CHANGE_IN_DATA;
        if (debug_flags & DEBUG_FLAG_DB_WCKEY)
            DB_DEBUG(mysql_conn->conn,
                     "didn't effect anything\n%s", query);
        xfree(query);
        xfree(wckey_char);
        return SLURM_SUCCESS;
    }

    xfree(query);
    rc = modify_common(mysql_conn, DBD_MODIFY_WCKEYS, now,
                       user_name, wckey_table, wckey_char,
                       vals, cluster_name);
    xfree(wckey_char);

    return rc;
}
Ejemplo n.º 24
0
static void *_cluster_rollup_usage(void *arg)
{
	local_rollup_t *local_rollup = (local_rollup_t *)arg;
	int rc = SLURM_SUCCESS;
	char timer_str[128];
	mysql_conn_t mysql_conn;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	char *query = NULL;
	struct tm start_tm;
	struct tm end_tm;
	time_t my_time = local_rollup->sent_end;
	time_t last_hour = local_rollup->sent_start;
	time_t last_day = local_rollup->sent_start;
	time_t last_month = local_rollup->sent_start;
	time_t hour_start;
	time_t hour_end;
	time_t day_start;
	time_t day_end;
	time_t month_start;
	time_t month_end;
	DEF_TIMERS;

	char *update_req_inx[] = {
		"hourly_rollup",
		"daily_rollup",
		"monthly_rollup"
	};

	enum {
		UPDATE_HOUR,
		UPDATE_DAY,
		UPDATE_MONTH,
		UPDATE_COUNT
	};


	memset(&mysql_conn, 0, sizeof(mysql_conn_t));
	mysql_conn.rollback = 1;
	mysql_conn.conn = local_rollup->mysql_conn->conn;
	slurm_mutex_init(&mysql_conn.lock);

	/* Each thread needs it's own connection we can't use the one
	 * sent from the parent thread. */
	rc = check_connection(&mysql_conn);

	if (rc != SLURM_SUCCESS)
		goto end_it;

	if (!local_rollup->sent_start) {
		char *tmp = NULL;
		int i=0;
		xstrfmtcat(tmp, "%s", update_req_inx[i]);
		for(i=1; i<UPDATE_COUNT; i++) {
			xstrfmtcat(tmp, ", %s", update_req_inx[i]);
		}
		query = xstrdup_printf("select %s from \"%s_%s\"",
				       tmp, local_rollup->cluster_name,
				       last_ran_table);
		xfree(tmp);

		debug4("%d(%s:%d) query\n%s", mysql_conn.conn,
		       THIS_FILE, __LINE__, query);
		if (!(result = mysql_db_query_ret(&mysql_conn, query, 0))) {
			xfree(query);
			rc = SLURM_ERROR;
			goto end_it;
		}

		xfree(query);
		row = mysql_fetch_row(result);
		if (row) {
			last_hour = slurm_atoul(row[UPDATE_HOUR]);
			last_day = slurm_atoul(row[UPDATE_DAY]);
			last_month = slurm_atoul(row[UPDATE_MONTH]);
			mysql_free_result(result);
		} else {
			time_t now = time(NULL);
			time_t lowest = now;

			mysql_free_result(result);

			query = xstrdup_printf(
				"select time_start from \"%s_%s\" "
				"where node_name='' order by "
				"time_start asc limit 1;",
				local_rollup->cluster_name, event_table);
			debug3("%d(%s:%d) query\n%s", mysql_conn.conn,
			       THIS_FILE, __LINE__, query);
			if (!(result = mysql_db_query_ret(
				      &mysql_conn, query, 0))) {
				xfree(query);
				rc = SLURM_ERROR;
				goto end_it;
			}
			xfree(query);
			if ((row = mysql_fetch_row(result))) {
				time_t check = slurm_atoul(row[0]);
				if (check < lowest)
					lowest = check;
			}
			mysql_free_result(result);

			/* If we don't have any events like adding a
			 * cluster this will not work correctly, so we
			 * will insert now as a starting point.
			 */

			query = xstrdup_printf(
				"insert into \"%s_%s\" "
				"(hourly_rollup, daily_rollup, monthly_rollup) "
				"values (%ld, %ld, %ld);",
				local_rollup->cluster_name, last_ran_table,
				lowest, lowest, lowest);

			debug3("%d(%s:%d) query\n%s", mysql_conn.conn,
			       THIS_FILE, __LINE__, query);
			rc = mysql_db_query(&mysql_conn, query);
			xfree(query);
			if (rc != SLURM_SUCCESS) {
				rc = SLURM_ERROR;
				goto end_it;
			}

			if (lowest == now) {
				debug("Cluster %s not registered, "
				      "not doing rollup",
				      local_rollup->cluster_name);
				rc = SLURM_SUCCESS;
				goto end_it;
			}

			last_hour = last_day = last_month = lowest;
		}
	}

	if (!my_time)
		my_time = time(NULL);

	/* test month gap */
/* 	last_hour = 1212299999; */
/* 	last_day = 1212217200; */
/* 	last_month = 1212217200; */
/* 	my_time = 1212307200; */

/* 	last_hour = 1211475599; */
/* 	last_day = 1211475599; */
/* 	last_month = 1211475599; */

//	last_hour = 1211403599;
	//	last_hour = 1206946800;
//	last_day = 1207033199;
//	last_day = 1197033199;
//	last_month = 1204358399;

	if (!localtime_r(&last_hour, &start_tm)) {
		error("Couldn't get localtime from hour start %ld", last_hour);
		rc = SLURM_ERROR;
		goto end_it;
	}

	if (!localtime_r(&my_time, &end_tm)) {
		error("Couldn't get localtime from hour end %ld", my_time);
		rc = SLURM_ERROR;
		goto end_it;
	}

	/* Below and anywhere in a rollup plugin when dealing with
	 * epoch times we need to set the tm_isdst = -1 so we don't
	 * have to worry about the time changes.  Not setting it to -1
	 * will cause problems in the day and month with the date change.
	 */

	start_tm.tm_sec = 0;
	start_tm.tm_min = 0;
	start_tm.tm_isdst = -1;
	hour_start = mktime(&start_tm);

	end_tm.tm_sec = 0;
	end_tm.tm_min = 0;
	end_tm.tm_isdst = -1;
	hour_end = mktime(&end_tm);

/* 	info("hour start %s", slurm_ctime(&hour_start)); */
/* 	info("hour end %s", slurm_ctime(&hour_end)); */
/* 	info("diff is %d", hour_end-hour_start); */

	slurm_mutex_lock(&rollup_lock);
	global_last_rollup = hour_end;
	slurm_mutex_unlock(&rollup_lock);

	/* set up the day period */
	if (!localtime_r(&last_day, &start_tm)) {
		error("Couldn't get localtime from day %ld", last_day);
		rc = SLURM_ERROR;
		goto end_it;
	}

	start_tm.tm_sec = 0;
	start_tm.tm_min = 0;
	start_tm.tm_hour = 0;
	start_tm.tm_isdst = -1;
	day_start = mktime(&start_tm);

	end_tm.tm_hour = 0;
	end_tm.tm_isdst = -1;
	day_end = mktime(&end_tm);

/* 	info("day start %s", slurm_ctime(&day_start)); */
/* 	info("day end %s", slurm_ctime(&day_end)); */
/* 	info("diff is %d", day_end-day_start); */

	/* set up the month period */
	if (!localtime_r(&last_month, &start_tm)) {
		error("Couldn't get localtime from month %ld", last_month);
		rc = SLURM_ERROR;
		goto end_it;
	}

	start_tm.tm_sec = 0;
	start_tm.tm_min = 0;
	start_tm.tm_hour = 0;
	start_tm.tm_mday = 1;
	start_tm.tm_isdst = -1;
	month_start = mktime(&start_tm);

	end_tm.tm_sec = 0;
	end_tm.tm_min = 0;
	end_tm.tm_hour = 0;
	end_tm.tm_mday = 1;
	end_tm.tm_isdst = -1;
	month_end = mktime(&end_tm);

/* 	info("month start %s", slurm_ctime(&month_start)); */
/* 	info("month end %s", slurm_ctime(&month_end)); */
/* 	info("diff is %d", month_end-month_start); */

	if ((hour_end - hour_start) > 0) {
		START_TIMER;
		rc = as_mysql_hourly_rollup(&mysql_conn,
					    local_rollup->cluster_name,
					    hour_start,
					    hour_end,
					    local_rollup->archive_data);
		snprintf(timer_str, sizeof(timer_str),
			 "hourly_rollup for %s", local_rollup->cluster_name);
		END_TIMER3(timer_str, 5000000);
		if (rc != SLURM_SUCCESS)
			goto end_it;
	}

	if ((day_end - day_start) > 0) {
		START_TIMER;
		rc = as_mysql_daily_rollup(&mysql_conn,
					   local_rollup->cluster_name,
					   day_start,
					   day_end,
					   local_rollup->archive_data);
		snprintf(timer_str, sizeof(timer_str),
			 "daily_rollup for %s", local_rollup->cluster_name);
		END_TIMER3(timer_str, 5000000);
		if (rc != SLURM_SUCCESS)
			goto end_it;
	}

	if ((month_end - month_start) > 0) {
		START_TIMER;
		rc = as_mysql_monthly_rollup(&mysql_conn,
					     local_rollup->cluster_name,
					     month_start,
					     month_end,
					     local_rollup->archive_data);
		snprintf(timer_str, sizeof(timer_str),
			 "monthly_rollup for %s", local_rollup->cluster_name);
		END_TIMER3(timer_str, 5000000);
		if (rc != SLURM_SUCCESS)
			goto end_it;
	}

	if ((hour_end - hour_start) > 0) {
		/* If we have a sent_end do not update the last_run_table */
		if (!local_rollup->sent_end)
			query = xstrdup_printf(
				"update \"%s_%s\" set hourly_rollup=%ld",
				local_rollup->cluster_name,
				last_ran_table, hour_end);
	} else
		debug2("No need to roll cluster %s this hour %ld <= %ld",
		       local_rollup->cluster_name, hour_end, hour_start);

	if ((day_end - day_start) > 0) {
		if (query && !local_rollup->sent_end)
			xstrfmtcat(query, ", daily_rollup=%ld", day_end);
		else if (!local_rollup->sent_end)
			query = xstrdup_printf(
				"update \"%s_%s\" set daily_rollup=%ld",
				local_rollup->cluster_name,
				last_ran_table, day_end);
	} else
		debug2("No need to roll cluster %s this day %ld <= %ld",
		       local_rollup->cluster_name, day_end, day_start);

	if ((month_end - month_start) > 0) {
		if (query && !local_rollup->sent_end)
			xstrfmtcat(query, ", monthly_rollup=%ld", month_end);
		else if (!local_rollup->sent_end)
			query = xstrdup_printf(
				"update \"%s_%s\" set monthly_rollup=%ld",
				local_rollup->cluster_name,
				last_ran_table, month_end);
	} else
		debug2("No need to roll cluster %s this month %ld <= %ld",
		       local_rollup->cluster_name, month_end, month_start);

	if (query) {
		debug3("%d(%s:%d) query\n%s",
		       mysql_conn.conn, THIS_FILE, __LINE__, query);
		rc = mysql_db_query(&mysql_conn, query);
		xfree(query);
	}
end_it:
	if (rc == SLURM_SUCCESS) {
		if (mysql_db_commit(&mysql_conn)) {
			error("Couldn't commit rollup of cluster %s",
			      local_rollup->cluster_name);
			rc = SLURM_ERROR;
		}
	} else {
		error("Cluster %s rollup failed", local_rollup->cluster_name);
		if (mysql_db_rollback(&mysql_conn))
			error("rollback failed");
	}

	mysql_db_close_db_connection(&mysql_conn);
	slurm_mutex_destroy(&mysql_conn.lock);

	slurm_mutex_lock(local_rollup->rolledup_lock);
	(*local_rollup->rolledup)++;
	if ((rc != SLURM_SUCCESS) && ((*local_rollup->rc) == SLURM_SUCCESS))
		(*local_rollup->rc) = rc;
	pthread_cond_signal(local_rollup->rolledup_cond);
	slurm_mutex_unlock(local_rollup->rolledup_lock);
	xfree(local_rollup);

	return NULL;
}
Ejemplo n.º 25
0
extern List as_mysql_modify_qos(mysql_conn_t *mysql_conn, uint32_t uid,
				slurmdb_qos_cond_t *qos_cond,
				slurmdb_qos_rec_t *qos)
{
	ListIterator itr = NULL;
	List ret_list = NULL;
	int rc = SLURM_SUCCESS;
	char *object = NULL;
	char *vals = NULL, *extra = NULL, *query = NULL, *name_char = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	int set = 0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	char *tmp_char1=NULL, *tmp_char2=NULL;
	bitstr_t *preempt_bitstr = NULL;
	char *added_preempt = NULL;

	if (!qos_cond || !qos) {
		error("we need something to change");
		return NULL;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	xstrcat(extra, "where deleted=0");

	if (qos_cond->description_list
	    && list_count(qos_cond->description_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->description_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "description='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (qos_cond->id_list
	    && list_count(qos_cond->id_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->id_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "id='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (qos_cond->name_list
	    && list_count(qos_cond->name_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->name_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "name='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	_setup_qos_limits(qos, &tmp_char1, &tmp_char2,
			  &vals, &added_preempt, 0);
	if (added_preempt) {
		preempt_bitstr = bit_alloc(g_qos_count);
		bit_unfmt(preempt_bitstr, added_preempt+1);
		xfree(added_preempt);
	}
	xfree(tmp_char1);
	xfree(tmp_char2);

	if (!extra || !vals) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		FREE_NULL_BITMAP(preempt_bitstr);
		error("Nothing to change");
		return NULL;
	}
	query = xstrdup_printf("select name, preempt, id from %s %s;",
			       qos_table, extra);
	xfree(extra);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		FREE_NULL_BITMAP(preempt_bitstr);
		return NULL;
	}

	rc = 0;
	ret_list = list_create(slurm_destroy_char);
	while ((row = mysql_fetch_row(result))) {
		slurmdb_qos_rec_t *qos_rec = NULL;
		uint32_t id = slurm_atoul(row[2]);
		if (preempt_bitstr) {
			if (_preemption_loop(mysql_conn, id, preempt_bitstr))
				break;
		}
		object = xstrdup(row[0]);
		list_append(ret_list, object);
		if (!rc) {
			xstrfmtcat(name_char, "(name='%s'", object);
			rc = 1;
		} else  {
			xstrfmtcat(name_char, " || name='%s'", object);
		}

		qos_rec = xmalloc(sizeof(slurmdb_qos_rec_t));
		qos_rec->name = xstrdup(object);
		qos_rec->id = id;
		qos_rec->flags = qos->flags;

		qos_rec->grp_cpus = qos->grp_cpus;
		qos_rec->grace_time = qos->grace_time;
		qos_rec->grp_cpu_mins = qos->grp_cpu_mins;
		qos_rec->grp_cpu_run_mins = qos->grp_cpu_run_mins;
		qos_rec->grp_jobs = qos->grp_jobs;
		qos_rec->grp_nodes = qos->grp_nodes;
		qos_rec->grp_submit_jobs = qos->grp_submit_jobs;
		qos_rec->grp_wall = qos->grp_wall;

		qos_rec->max_cpus_pj = qos->max_cpus_pj;
		qos_rec->max_cpu_mins_pj = qos->max_cpu_mins_pj;
		qos_rec->max_cpu_run_mins_pu = qos->max_cpu_run_mins_pu;
		qos_rec->max_jobs_pu  = qos->max_jobs_pu;
		qos_rec->max_nodes_pj = qos->max_nodes_pj;
		qos_rec->max_submit_jobs_pu  = qos->max_submit_jobs_pu;
		qos_rec->max_wall_pj = qos->max_wall_pj;

		qos_rec->preempt_mode = qos->preempt_mode;
		qos_rec->priority = qos->priority;

		if (qos->preempt_list) {
			ListIterator new_preempt_itr =
				list_iterator_create(qos->preempt_list);
			char *new_preempt = NULL;

			qos_rec->preempt_bitstr = bit_alloc(g_qos_count);
			if (row[1] && row[1][0])
				bit_unfmt(qos_rec->preempt_bitstr, row[1]+1);

			while ((new_preempt = list_next(new_preempt_itr))) {
				bool cleared = 0;
				if (new_preempt[0] == '-') {
					bit_clear(qos_rec->preempt_bitstr,
						  atol(new_preempt+1));
				} else if (new_preempt[0] == '+') {
					bit_set(qos_rec->preempt_bitstr,
						atol(new_preempt+1));
				} else {
					if (!cleared) {
						cleared = 1;
						bit_nclear(
							qos_rec->preempt_bitstr,
							0,
							g_qos_count-1);
					}

					bit_set(qos_rec->preempt_bitstr,
						atol(new_preempt));
				}
			}
			list_iterator_destroy(new_preempt_itr);
		}

		qos_rec->usage_factor = qos->usage_factor;
		qos_rec->usage_thres = qos->usage_thres;

		if (addto_update_list(mysql_conn->update_list,
				      SLURMDB_MODIFY_QOS, qos_rec)
		    != SLURM_SUCCESS)
			slurmdb_destroy_qos_rec(qos_rec);
	}
	mysql_free_result(result);

	FREE_NULL_BITMAP(preempt_bitstr);

	if (row) {
		xfree(vals);
		xfree(name_char);
		xfree(query);
		list_destroy(ret_list);
		ret_list = NULL;
		errno = ESLURM_QOS_PREEMPTION_LOOP;
		return ret_list;
	}

	if (!list_count(ret_list)) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		debug3("didn't effect anything\n%s", query);
		xfree(vals);
		xfree(query);
		return ret_list;
	}
	xfree(query);
	xstrcat(name_char, ")");

	user_name = uid_to_string((uid_t) uid);
	rc = modify_common(mysql_conn, DBD_MODIFY_QOS, now,
			   user_name, qos_table, name_char, vals, NULL);
	xfree(user_name);
	xfree(name_char);
	xfree(vals);
	if (rc == SLURM_ERROR) {
		error("Couldn't modify qos");
		list_destroy(ret_list);
		ret_list = NULL;
	}

	return ret_list;
}
Ejemplo n.º 26
0
extern int as_mysql_get_usage(mysql_conn_t *mysql_conn, uid_t uid,
			      void *in, slurmdbd_msg_type_t type,
			      time_t start, time_t end)
{
	int rc = SLURM_SUCCESS;
	int i=0, is_admin=1;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	char *tmp = NULL;
	char *my_usage_table = NULL;
	slurmdb_association_rec_t *slurmdb_assoc = in;
	slurmdb_wckey_rec_t *slurmdb_wckey = in;
	char *query = NULL;
	char *username = NULL;
	uint16_t private_data = 0;
	slurmdb_user_rec_t user;
	List *my_list;
	uint32_t id = NO_VAL;
	char *cluster_name = NULL;
	char **usage_req_inx = NULL;

	enum {
		USAGE_ID,
		USAGE_START,
		USAGE_ACPU,
		USAGE_COUNT,
		USAGE_ENERGY
	};

	switch (type) {
	case DBD_GET_ASSOC_USAGE:
	{
		char *temp_usage[] = {
			"t3.id_assoc",
			"t1.time_start",
			"t1.alloc_cpu_secs"
		};
		usage_req_inx = temp_usage;

		id = slurmdb_assoc->id;
		cluster_name = slurmdb_assoc->cluster;
		username = slurmdb_assoc->user;
		my_list = &slurmdb_assoc->accounting_list;
		my_usage_table = assoc_day_table;
		break;
	}
	case DBD_GET_WCKEY_USAGE:
	{
		char *temp_usage[] = {
			"id_wckey",
			"time_start",
			"alloc_cpu_secs"
		};
		usage_req_inx = temp_usage;

		id = slurmdb_wckey->id;
		cluster_name = slurmdb_wckey->cluster;
		username = slurmdb_wckey->user;
		my_list = &slurmdb_wckey->accounting_list;
		my_usage_table = wckey_day_table;
		break;
	}
	case DBD_GET_CLUSTER_USAGE:
	{
		return _get_cluster_usage(mysql_conn, uid, in,
					  type, start, end);
		break;
	}
	default:
		error("Unknown usage type %d", type);
		return SLURM_ERROR;
		break;
	}

	if (!id) {
		error("We need an id to set data for getting usage");
		return SLURM_ERROR;
	} else if (!cluster_name) {
		error("We need a cluster_name to set data for getting usage");
		return SLURM_ERROR;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	memset(&user, 0, sizeof(slurmdb_user_rec_t));
	user.uid = uid;

	private_data = slurm_get_private_data();
	if (private_data & PRIVATE_DATA_USAGE) {
		if (!(is_admin = is_user_min_admin_level(
			      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
			ListIterator itr = NULL;
			slurmdb_coord_rec_t *coord = NULL;

			if (username && !strcmp(slurmdb_assoc->user, user.name))
				goto is_user;

			if (type != DBD_GET_ASSOC_USAGE)
				goto bad_user;

			if (!slurmdb_assoc->acct) {
				debug("No account name given "
				      "in association.");
				goto bad_user;
			}

			if (!is_user_any_coord(mysql_conn, &user)) {
				debug4("This user is not a coordinator.");
				goto bad_user;
			}

			/* Existance of user.coord_accts is checked in
			   is_user_any_coord.
			*/
			itr = list_iterator_create(user.coord_accts);
			while ((coord = list_next(itr)))
				if (!strcasecmp(coord->name,
						slurmdb_assoc->acct))
					break;
			list_iterator_destroy(itr);

			if (coord)
				goto is_user;

		bad_user:
			errno = ESLURM_ACCESS_DENIED;
			return SLURM_ERROR;
		}
	}
is_user:

	if (set_usage_information(&my_usage_table, type, &start, &end)
	    != SLURM_SUCCESS) {
		return SLURM_ERROR;
	}

	xfree(tmp);
	i=0;
	xstrfmtcat(tmp, "%s", usage_req_inx[i]);
	for(i=1; i<USAGE_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", usage_req_inx[i]);
	}
	switch (type) {
	case DBD_GET_ASSOC_USAGE:
		query = xstrdup_printf(
			"select %s from \"%s_%s\" as t1, "
			"\"%s_%s\" as t2, \"%s_%s\" as t3 "
			"where (t1.time_start < %ld && t1.time_start >= %ld) "
			"&& t1.id_assoc=t2.id_assoc && t3.id_assoc=%d && "
			"t2.lft between t3.lft and t3.rgt "
			"order by t3.id_assoc, time_start;",
			tmp, cluster_name, my_usage_table,
			cluster_name, cluster_name, assoc_table, assoc_table,
			end, start, id);
		break;
	case DBD_GET_WCKEY_USAGE:
		query = xstrdup_printf(
			"select %s from \"%s_%s\" "
			"where (time_start < %ld && time_start >= %ld) "
			"&& id_wckey=%d order by id_wckey, time_start;",
			tmp, cluster_name, my_usage_table, end, start, id);
		break;
	default:
		error("Unknown usage type %d", type);
		return SLURM_ERROR;
		break;
	}

	xfree(tmp);
	debug4("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	if (!(*my_list))
		(*my_list) = list_create(slurmdb_destroy_accounting_rec);

	while ((row = mysql_fetch_row(result))) {
		slurmdb_accounting_rec_t *accounting_rec =
			xmalloc(sizeof(slurmdb_accounting_rec_t));
		accounting_rec->id = slurm_atoul(row[USAGE_ID]);
		accounting_rec->period_start = slurm_atoul(row[USAGE_START]);
		accounting_rec->alloc_secs = slurm_atoull(row[USAGE_ACPU]);
		accounting_rec->consumed_energy = slurm_atoull(row[USAGE_ENERGY]);
		list_append((*my_list), accounting_rec);
	}
	mysql_free_result(result);

	return rc;
}
Ejemplo n.º 27
0
extern List as_mysql_get_qos(mysql_conn_t *mysql_conn, uid_t uid,
			     slurmdb_qos_cond_t *qos_cond)
{
	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	List qos_list = NULL;
	ListIterator itr = NULL;
	char *object = NULL;
	int set = 0;
	int i=0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;

	/* if this changes you will need to edit the corresponding enum */
	char *qos_req_inx[] = {
		"name",
		"description",
		"id",
		"flags",
		"grace_time",
		"grp_cpu_mins",
		"grp_cpu_run_mins",
		"grp_cpus",
		"grp_jobs",
		"grp_nodes",
		"grp_submit_jobs",
		"grp_wall",
		"max_cpu_mins_per_job",
		"max_cpu_run_mins_per_user",
		"max_cpus_per_job",
		"max_jobs_per_user",
		"max_nodes_per_job",
		"max_submit_jobs_per_user",
		"max_wall_duration_per_job",
		"preempt",
		"preempt_mode",
		"priority",
		"usage_factor",
		"usage_thres",
	};
	enum {
		QOS_REQ_NAME,
		QOS_REQ_DESC,
		QOS_REQ_ID,
		QOS_REQ_FLAGS,
		QOS_REQ_GRACE,
		QOS_REQ_GCM,
		QOS_REQ_GCRM,
		QOS_REQ_GC,
		QOS_REQ_GJ,
		QOS_REQ_GN,
		QOS_REQ_GSJ,
		QOS_REQ_GW,
		QOS_REQ_MCMPJ,
		QOS_REQ_MCRM,
		QOS_REQ_MCPJ,
		QOS_REQ_MJPU,
		QOS_REQ_MNPJ,
		QOS_REQ_MSJPU,
		QOS_REQ_MWPJ,
		QOS_REQ_PREE,
		QOS_REQ_PREEM,
		QOS_REQ_PRIO,
		QOS_REQ_UF,
		QOS_REQ_UT,
		QOS_REQ_COUNT
	};

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	if (!qos_cond) {
		xstrcat(extra, "where deleted=0");
		goto empty;
	}

	if (qos_cond->with_deleted)
		xstrcat(extra, "where (deleted=0 || deleted=1)");
	else
		xstrcat(extra, "where deleted=0");


	if (qos_cond->description_list
	    && list_count(qos_cond->description_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->description_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "description='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (qos_cond->id_list
	    && list_count(qos_cond->id_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->id_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "id='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (qos_cond->name_list
	    && list_count(qos_cond->name_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(qos_cond->name_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "name='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

empty:

	xfree(tmp);
	xstrfmtcat(tmp, "%s", qos_req_inx[i]);
	for(i=1; i<QOS_REQ_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", qos_req_inx[i]);
	}

	query = xstrdup_printf("select %s from %s %s", tmp, qos_table, extra);
	xfree(tmp);
	xfree(extra);

	debug3("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}
	xfree(query);

	qos_list = list_create(slurmdb_destroy_qos_rec);

	while ((row = mysql_fetch_row(result))) {
		slurmdb_qos_rec_t *qos = xmalloc(sizeof(slurmdb_qos_rec_t));
		list_append(qos_list, qos);

		if (row[QOS_REQ_DESC] && row[QOS_REQ_DESC][0])
			qos->description = xstrdup(row[QOS_REQ_DESC]);

		qos->id = slurm_atoul(row[QOS_REQ_ID]);

		qos->flags = slurm_atoul(row[QOS_REQ_FLAGS]);

		if (row[QOS_REQ_NAME] && row[QOS_REQ_NAME][0])
			qos->name = xstrdup(row[QOS_REQ_NAME]);

		if (row[QOS_REQ_GRACE])
			qos->grace_time = slurm_atoul(row[QOS_REQ_GRACE]);
		else
			qos->grace_time = (uint32_t)NO_VAL;

		if (row[QOS_REQ_GCM])
			qos->grp_cpu_mins = slurm_atoull(row[QOS_REQ_GCM]);
		else
			qos->grp_cpu_mins = INFINITE;
		if (row[QOS_REQ_GCRM])
			qos->grp_cpu_run_mins = slurm_atoull(row[QOS_REQ_GCRM]);
		else
			qos->grp_cpu_run_mins = INFINITE;
		if (row[QOS_REQ_GC])
			qos->grp_cpus = slurm_atoul(row[QOS_REQ_GC]);
		else
			qos->grp_cpus = INFINITE;
		if (row[QOS_REQ_GJ])
			qos->grp_jobs = slurm_atoul(row[QOS_REQ_GJ]);
		else
			qos->grp_jobs = INFINITE;
		if (row[QOS_REQ_GN])
			qos->grp_nodes = slurm_atoul(row[QOS_REQ_GN]);
		else
			qos->grp_nodes = INFINITE;
		if (row[QOS_REQ_GSJ])
			qos->grp_submit_jobs = slurm_atoul(row[QOS_REQ_GSJ]);
		else
			qos->grp_submit_jobs = INFINITE;
		if (row[QOS_REQ_GW])
			qos->grp_wall = slurm_atoul(row[QOS_REQ_GW]);
		else
			qos->grp_wall = INFINITE;

		if (row[QOS_REQ_MCMPJ])
			qos->max_cpu_mins_pj = slurm_atoull(row[QOS_REQ_MCMPJ]);
		else
			qos->max_cpu_mins_pj = (uint64_t)INFINITE;
		if (row[QOS_REQ_MCRM])
			qos->max_cpu_run_mins_pu =
				slurm_atoull(row[QOS_REQ_MCRM]);
		else
			qos->max_cpu_run_mins_pu = (uint64_t)INFINITE;
		if (row[QOS_REQ_MCPJ])
			qos->max_cpus_pj = slurm_atoul(row[QOS_REQ_MCPJ]);
		else
			qos->max_cpus_pj = INFINITE;
		if (row[QOS_REQ_MJPU])
			qos->max_jobs_pu = slurm_atoul(row[QOS_REQ_MJPU]);
		else
			qos->max_jobs_pu = INFINITE;
		if (row[QOS_REQ_MNPJ])
			qos->max_nodes_pj = slurm_atoul(row[QOS_REQ_MNPJ]);
		else
			qos->max_nodes_pj = INFINITE;
		if (row[QOS_REQ_MSJPU])
			qos->max_submit_jobs_pu =
				slurm_atoul(row[QOS_REQ_MSJPU]);
		else
			qos->max_submit_jobs_pu = INFINITE;
		if (row[QOS_REQ_MWPJ])
			qos->max_wall_pj = slurm_atoul(row[QOS_REQ_MWPJ]);
		else
			qos->max_wall_pj = INFINITE;

		if (row[QOS_REQ_PREE] && row[QOS_REQ_PREE][0]) {
			if (!qos->preempt_bitstr)
				qos->preempt_bitstr = bit_alloc(g_qos_count);
			bit_unfmt(qos->preempt_bitstr, row[QOS_REQ_PREE]+1);
		}
		if (row[QOS_REQ_PREEM])
			qos->preempt_mode = slurm_atoul(row[QOS_REQ_PREEM]);
		if (row[QOS_REQ_PRIO])
			qos->priority = slurm_atoul(row[QOS_REQ_PRIO]);

		if (row[QOS_REQ_UF])
			qos->usage_factor = atof(row[QOS_REQ_UF]);

		if (row[QOS_REQ_UT])
			qos->usage_thres = atof(row[QOS_REQ_UT]);
		else
			qos->usage_thres = (double)INFINITE;

	}
	mysql_free_result(result);

	return qos_list;
}
Ejemplo n.º 28
0
static void _set_options(const int argc, char **argv)
{
	int option_index = 0, c;
	log_options_t logopt = LOG_OPTS_STDERR_ONLY;
	char *next_str = NULL;
	uid_t uid = -1;

	static struct option long_options[] = {
		{"extract", no_argument, 0, 'E'},
		{"help", no_argument, 0, 'h'},
		{"job", required_argument, 0, 'j'},
		{"input", required_argument, 0, 'i'},
		{"level", required_argument, 0, 'l'},
		{"node", required_argument, 0, 'N'},
		{"output", required_argument, 0, 'o'},
		{"profiledir", required_argument, 0, 'p'},
		{"series", required_argument, 0, 's'},
		{"savefiles", no_argument, 0, 'S'},
		{"usage", 0, &params.help, 3},
		{"user", required_argument, 0, 'u'},
		{"verbose", no_argument, 0, 'v'},
		{"version", no_argument, 0, 'V'},
		{0, 0, 0, 0}};

	log_init(xbasename(argv[0]), logopt, 0, NULL);

	_init_opts();

	while (1) {		/* now cycle through the command line */
		c = getopt_long(argc, argv, "Ehi:j:l:N:o:p:s:Su:vV",
				long_options, &option_index);
		if (c == -1)
			break;
		switch (c) {
		case 'E':
			params.mode = SH5UTIL_MODE_EXTRACT;
			break;
		case 'h':
			params.help = 1;
			break;
		case 'i':
			params.input = xstrdup(optarg);
			break;
		case 'j':
			params.job_id = strtol(optarg, &next_str, 10);
			if (next_str[0] == '.')
				params.step_id =
					strtol(next_str+1, NULL, 10);
			break;
		case 'l':
			params.level = xstrdup(optarg);
			break;
		case 'N':
			params.node = xstrdup(optarg);
			break;
		case 'o':
			params.output = xstrdup(optarg);
			break;
		case 'p':
			params.dir = xstrdup(optarg);
			break;
		case 's':
			params.series = xstrdup(optarg);
			break;
		case 'S':
			params.keepfiles = 1;
			break;
		case 'u':
			if (uid_from_string (optarg, &uid) < 0) {
				error("--uid=\"%s\" invalid", optarg);
				exit(1);
			}
			break;
		case (int)'v':
			params.verbose++;
			break;
		case (int)'V':
			print_slurm_version();
			exit(0);
			break;
		case ':':
		case '?': /* getopt() has explained it */
			exit(1);
		}
	}

	if (params.help) {
		switch (params.help) {
		case 1:
		case 3:
			_help_msg();
			break;
		default:
			fprintf(stderr, "bug: --help=%d\n",
				params.help);
		}
		exit(0);
	}

	if (params.job_id == -1)
		fatal("You need to supply a --jobs value.");

	if (uid == -1)
		uid = getuid();

	params.user = uid_to_string(uid);

	if (!params.dir)
		acct_gather_profile_g_get(ACCT_GATHER_PROFILE_DIR, &params.dir);

	if (!params.dir)
		fatal("You need to supply a --profiledir or be on a "
		      "node with a valid acct_gather.conf");

	if (params.verbose) {
		logopt.stderr_level += params.verbose;
		log_alter(logopt, SYSLOG_FACILITY_USER, NULL);
	}

	/* FIXME : For now all these only work for extract.  Seems
	 * like it would be easy to add the logic to "merge" as well.
	 */
	if (params.input || params.level || params.node
	    || (params.step_id != -1) || params.series)
		params.mode = SH5UTIL_MODE_EXTRACT;

	if (params.mode == SH5UTIL_MODE_EXTRACT) {
		if (!params.level)
			params.level = xstrdup("Node:Totals");
		if (!params.input)
			params.input = xstrdup_printf(
				"./job_%d.h5", params.job_id);
		if (!params.output)
			params.output = xstrdup_printf(
				"./extract_%d.csv", params.job_id);

	}

	if (!params.output)
		params.output = xstrdup_printf("./job_%d.h5", params.job_id);

}
Ejemplo n.º 29
0
static List _create_front_end_info_list(
	front_end_info_msg_t *front_end_info_ptr, int changed)
{
	char *upper = NULL;
	char user[32], time_str[32];
	static List info_list = NULL;
	List last_list = NULL;
	ListIterator last_list_itr = NULL;
	int i = 0;
	sview_front_end_info_t *sview_front_end_info_ptr = NULL;
	front_end_info_t *front_end_ptr = NULL;

	if (!changed && info_list)
		goto update_color;

	if (info_list)
		last_list = info_list;

	info_list = list_create(_front_end_info_list_del);

	if (last_list)
		last_list_itr = list_iterator_create(last_list);
	for (i = 0; i < front_end_info_ptr->record_count; i++) {
		front_end_ptr = &(front_end_info_ptr->front_end_array[i]);

		sview_front_end_info_ptr = NULL;

		if (last_list_itr) {
			while ((sview_front_end_info_ptr =
				list_next(last_list_itr))) {
				if (!xstrcmp(sview_front_end_info_ptr->
					     front_end_name,
					     front_end_ptr->name)) {
					list_remove(last_list_itr);
					_front_end_info_free(
						sview_front_end_info_ptr);
					break;
				}
			}
			list_iterator_reset(last_list_itr);
		}
		if (!sview_front_end_info_ptr)
			sview_front_end_info_ptr =
				xmalloc(sizeof(sview_front_end_info_t));
		sview_front_end_info_ptr->pos = i;
		sview_front_end_info_ptr->front_end_name = front_end_ptr->name;
		sview_front_end_info_ptr->front_end_ptr = front_end_ptr;
		sview_front_end_info_ptr->color_inx = i % sview_colors_cnt;
		if (g_node_info_ptr) {
			sview_front_end_info_ptr->node_inx[0] = 0;
			sview_front_end_info_ptr->node_inx[1] =
				g_node_info_ptr->record_count - 1;
			sview_front_end_info_ptr->node_inx[2] = -1;
		} else
			sview_front_end_info_ptr->node_inx[0] = -1;
		if (front_end_ptr->boot_time) {
			slurm_make_time_str(&front_end_ptr->boot_time,
					    time_str, sizeof(time_str));
			sview_front_end_info_ptr->boot_time =
				xstrdup(time_str);
		}
		if (front_end_ptr->slurmd_start_time) {
			slurm_make_time_str(&front_end_ptr->slurmd_start_time,
					    time_str, sizeof(time_str));
			sview_front_end_info_ptr->slurmd_start_time =
				xstrdup(time_str);
		}
		upper = node_state_string(front_end_ptr->node_state);
		sview_front_end_info_ptr->state = str_tolower(upper);

		if (front_end_ptr->reason && front_end_ptr->reason_time &&
		    (front_end_ptr->reason_uid != NO_VAL)) {
			struct passwd *pw = NULL;

			if ((pw=getpwuid(front_end_ptr->reason_uid)))
				snprintf(user, sizeof(user), "%s", pw->pw_name);
			else
				snprintf(user, sizeof(user), "Unk(%u)",
					 front_end_ptr->reason_uid);
			slurm_make_time_str(&front_end_ptr->reason_time,
					    time_str, sizeof(time_str));
			sview_front_end_info_ptr->reason =
				xstrdup_printf("%s [%s@%s]",
					       front_end_ptr->reason, user,
					       time_str);
		} else {
			sview_front_end_info_ptr->reason =
				xstrdup(front_end_ptr->reason);
		}

		list_append(info_list, sview_front_end_info_ptr);
	}

	if (last_list) {
		list_iterator_destroy(last_list_itr);
		FREE_NULL_LIST(last_list);
	}

update_color:
	return info_list;
}
Ejemplo n.º 30
0
extern List as_mysql_modify_job(mysql_conn_t *mysql_conn, uint32_t uid,
				slurmdb_job_modify_cond_t *job_cond,
				slurmdb_job_rec_t *job)
{
	List ret_list = NULL;
	int rc = SLURM_SUCCESS;
	char *object = NULL;
	char *vals = NULL, *query = NULL, *cond_char = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;

	if (!job_cond || !job) {
		error("we need something to change");
		return NULL;
	} else if (job_cond->job_id == NO_VAL) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("Job ID was not specified for job modification\n");
		return NULL;
	} else if (!job_cond->cluster) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("Cluster was not specified for job modification\n");
		return NULL;
	} else if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	if (job->derived_ec != NO_VAL)
		xstrfmtcat(vals, ", derived_ec=%u", job->derived_ec);

	if (job->derived_es) {
		char *derived_es = slurm_add_slash_to_quotes(job->derived_es);
		xstrfmtcat(vals, ", derived_es='%s'", derived_es);
		xfree(derived_es);
	}
	if (!vals) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("No change specified for job modification");
		return NULL;
	}

	/* Here we want to get the last job submitted here */
	query = xstrdup_printf("select job_db_inx, id_job, time_submit, "
			       "id_user "
			       "from \"%s_%s\" where deleted=0 "
			       "&& id_job=%u "
			       "order by time_submit desc limit 1;",
			       job_cond->cluster, job_table,
			       job_cond->job_id);

	debug3("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(vals);
		xfree(query);
		return NULL;
	}

	if ((row = mysql_fetch_row(result))) {
		char tmp_char[25];
		time_t time_submit = atol(row[2]);

		if ((uid != atoi(row[3])) &&
		    !is_user_min_admin_level(mysql_conn, uid,
					     SLURMDB_ADMIN_OPERATOR)) {
			errno = ESLURM_ACCESS_DENIED;
			xfree(vals);
			xfree(query);
			mysql_free_result(result);
			return NULL;
		}

		slurm_make_time_str(&time_submit, tmp_char, sizeof(tmp_char));

		xstrfmtcat(cond_char, "job_db_inx=%s", row[0]);
		object = xstrdup_printf("%s submitted at %s", row[1], tmp_char);

		ret_list = list_create(slurm_destroy_char);
		list_append(ret_list, object);
		mysql_free_result(result);
	} else {
		errno = ESLURM_INVALID_JOB_ID;
		debug3("as_mysql_modify_job: Job not found\n%s", query);
		xfree(vals);
		xfree(query);
		mysql_free_result(result);
		return NULL;
	}
	xfree(query);

	user_name = uid_to_string((uid_t) uid);
	rc = modify_common(mysql_conn, DBD_MODIFY_JOB, now, user_name,
			   job_table, cond_char, vals, job_cond->cluster);
	xfree(user_name);
	xfree(cond_char);
	xfree(vals);
	if (rc == SLURM_ERROR) {
		error("Couldn't modify job");
		list_destroy(ret_list);
		ret_list = NULL;
	}

	return ret_list;
}