Esempio n. 1
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)
{
	uint16_t cpus;
	int rc = SLURM_SUCCESS;
	char *query = NULL;
	char *my_reason;

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

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

	if (slurmctld_conf.fast_schedule && !slurmdbd_conf)
		cpus = node_ptr->config_ptr->cpus;
	else
		cpus = node_ptr->cpus;

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

	debug2("inserting %s(%s) with %u cpus",
	       node_ptr->name, mysql_conn->cluster_name, cpus);

	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, cpu_count, time_start, "
		   "reason, reason_uid) "
		   "values ('%s', %u, %u, %ld, '%s', %u) "
		   "on duplicate key update time_end=0;",
		   mysql_conn->cluster_name, event_table,
		   node_ptr->name, node_ptr->node_state,
		   cpus, event_time, my_reason, reason_uid);
	debug4("%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;
}
Esempio n. 2
0
extern int as_mysql_add_accts(mysql_conn_t *mysql_conn, uint32_t uid,
			      List acct_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_account_rec_t *object = NULL;
	char *cols = NULL, *vals = NULL, *query = NULL, *txn_query = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	char *extra = NULL, *tmp_extra = NULL;

	int affect_rows = 0;
	List assoc_list = list_create(slurmdb_destroy_association_rec);

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

	user_name = uid_to_string((uid_t) uid);
	itr = list_iterator_create(acct_list);
	while ((object = list_next(itr))) {
		if (!object->name || !object->name[0]
		    || !object->description || !object->description[0]
		    || !object->organization || !object->organization[0]) {
			error("We need an account name, description, and "
			      "organization to add. %s %s %s",
			      object->name, object->description,
			      object->organization);
			rc = SLURM_ERROR;
			continue;
		}
		xstrcat(cols, "creation_time, mod_time, name, "
			"description, organization");
		xstrfmtcat(vals, "%ld, %ld, '%s', '%s', '%s'",
			   now, now, object->name,
			   object->description, object->organization);
		xstrfmtcat(extra, ", description='%s', organization='%s'",
			   object->description, object->organization);

		query = xstrdup_printf(
			"insert into %s (%s) values (%s) "
			"on duplicate key update deleted=0, mod_time=%ld %s;",
			acct_table, cols, vals,
			now, extra);
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(cols);
		xfree(vals);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add acct");
			xfree(extra);
			continue;
		}
		affect_rows = last_affected_rows(mysql_conn);
		/* if (debug_flags & DEBUG_FLAG_DB_ASSOC) */
		/* 	DB_DEBUG(mysql_conn->conn, "affected %d", affect_rows); */

		if (!affect_rows) {
			if (debug_flags & DEBUG_FLAG_DB_ASSOC)
				DB_DEBUG(mysql_conn->conn, "nothing changed");
			xfree(extra);
			continue;
		}

		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		if (txn_query)
			xstrfmtcat(txn_query,
				   ", (%ld, %u, '%s', '%s', '%s')",
				   now, DBD_ADD_ACCOUNTS, object->name,
				   user_name, tmp_extra);
		else
			xstrfmtcat(txn_query,
				   "insert into %s "
				   "(timestamp, action, name, actor, info) "
				   "values (%ld, %u, '%s', '%s', '%s')",
				   txn_table,
				   now, DBD_ADD_ACCOUNTS, object->name,
				   user_name, tmp_extra);
		xfree(tmp_extra);
		xfree(extra);

		if (!object->assoc_list)
			continue;

		list_transfer(assoc_list, object->assoc_list);
	}
	list_iterator_destroy(itr);
	xfree(user_name);

	if (rc != SLURM_ERROR) {
		if (txn_query) {
			xstrcat(txn_query, ";");
			rc = mysql_db_query(mysql_conn,
					    txn_query);
			xfree(txn_query);
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add txn");
				rc = SLURM_SUCCESS;
			}
		}
	} else
		xfree(txn_query);

	if (list_count(assoc_list)) {
		if (as_mysql_add_assocs(mysql_conn, uid, assoc_list)
		    == SLURM_ERROR) {
			error("Problem adding user associations");
			rc = SLURM_ERROR;
		}
	}
	list_destroy(assoc_list);

	return rc;
}
Esempio n. 3
0
extern int as_mysql_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
				 List cluster_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_cluster_rec_t *object = NULL;
	char *cols = NULL, *vals = NULL, *extra = NULL,
		*query = NULL, *tmp_extra = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	int affect_rows = 0;
	int added = 0;
	List assoc_list = NULL;
	slurmdb_assoc_rec_t *assoc = NULL;

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

	if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_SUPER_USER))
		return ESLURM_ACCESS_DENIED;

	assoc_list = list_create(slurmdb_destroy_assoc_rec);

	user_name = uid_to_string((uid_t) uid);
	/* Since adding tables make it so you can't roll back, if
	   there is an error there is no way to easily remove entries
	   in the database, so we will create the tables first and
	   then after that works out then add them to the mix.
	*/
	itr = list_iterator_create(cluster_list);
	while ((object = list_next(itr))) {
		if (!object->name || !object->name[0]) {
			error("We need a cluster name to add.");
			rc = SLURM_ERROR;
			list_remove(itr);
			continue;
		}
		if ((rc = create_cluster_tables(mysql_conn,
						object->name))
		    != SLURM_SUCCESS) {
			xfree(extra);
			xfree(cols);
			xfree(vals);
			added = 0;
			if (mysql_errno(mysql_conn->db_conn)
			    == ER_WRONG_TABLE_NAME)
				rc = ESLURM_BAD_NAME;
			goto end_it;
		}
	}

	/* Now that all the tables were created successfully lets go
	   ahead and add it to the system.
	*/
	list_iterator_reset(itr);
	while ((object = list_next(itr))) {
		xstrcat(cols, "creation_time, mod_time, acct");
		xstrfmtcat(vals, "%ld, %ld, 'root'", now, now);
		xstrfmtcat(extra, ", mod_time=%ld", now);
		if (object->root_assoc)
			setup_assoc_limits(object->root_assoc, &cols,
					   &vals, &extra,
					   QOS_LEVEL_SET, 1);
		xstrfmtcat(query,
			   "insert into %s (creation_time, mod_time, "
			   "name, classification) "
			   "values (%ld, %ld, '%s', %u) "
			   "on duplicate key update deleted=0, mod_time=%ld, "
			   "control_host='', control_port=0, "
			   "classification=%u, flags=0",
			   cluster_table,
			   now, now, object->name, object->classification,
			   now, object->classification);
		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) {
			error("Couldn't add cluster %s", object->name);
			xfree(extra);
			xfree(cols);
			xfree(vals);
			added=0;
			break;
		}

		affect_rows = last_affected_rows(mysql_conn);

		if (!affect_rows) {
			debug2("nothing changed %d", affect_rows);
			xfree(extra);
			xfree(cols);
			xfree(vals);
			continue;
		}

		xstrfmtcat(query,
			   "insert into \"%s_%s\" (%s, lft, rgt) "
			   "values (%s, 1, 2) "
			   "on duplicate key update deleted=0, "
			   "id_assoc=LAST_INSERT_ID(id_assoc)%s;",
			   object->name, assoc_table, cols,
			   vals,
			   extra);

		xfree(cols);
		xfree(vals);
		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) {
			error("Couldn't add cluster root assoc");
			xfree(extra);
			added=0;
			break;
		}

		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		xstrfmtcat(query,
			   "insert into %s "
			   "(timestamp, action, name, actor, info) "
			   "values (%ld, %u, '%s', '%s', '%s');",
			   txn_table, now, DBD_ADD_CLUSTERS,
			   object->name, user_name, tmp_extra);
		xfree(tmp_extra);
		xfree(extra);
		debug4("%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) {
			error("Couldn't add txn");
		} else {
			ListIterator check_itr;
			char *tmp_name;

			added++;
			/* add it to the list and sort */
			slurm_mutex_lock(&as_mysql_cluster_list_lock);
			check_itr = list_iterator_create(as_mysql_cluster_list);
			while ((tmp_name = list_next(check_itr))) {
				if (!strcmp(tmp_name, object->name))
					break;
			}
			list_iterator_destroy(check_itr);
			if (!tmp_name) {
				list_append(as_mysql_cluster_list,
					    xstrdup(object->name));
				list_sort(as_mysql_cluster_list,
					  (ListCmpF)slurm_sort_char_list_asc);
			} else
				error("Cluster %s(%s) appears to already be in "
				      "our cache list, not adding.", tmp_name,
				      object->name);
			slurm_mutex_unlock(&as_mysql_cluster_list_lock);
		}
		/* Add user root by default to run from the root
		 * association.  This gets popped off so we need to
		 * read it every time here.
		 */
		assoc = xmalloc(sizeof(slurmdb_assoc_rec_t));
		slurmdb_init_assoc_rec(assoc, 0);
		list_append(assoc_list, assoc);

		assoc->cluster = xstrdup(object->name);
		assoc->user = xstrdup("root");
		assoc->acct = xstrdup("root");
		assoc->is_def = 1;

		if (as_mysql_add_assocs(mysql_conn, uid, assoc_list)
		    == SLURM_ERROR) {
			error("Problem adding root user association");
			rc = SLURM_ERROR;
		}
	}
end_it:
	list_iterator_destroy(itr);
	xfree(user_name);

	FREE_NULL_LIST(assoc_list);

	if (!added)
		reset_mysql_conn(mysql_conn);

	return rc;
}
Esempio n. 4
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] &&
	    !strcasecmp(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;
}
Esempio 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], *jname = NULL;
	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_mysql_conn || mysql_db_ping(jobcomp_mysql_conn) != 0) {
		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;
	}

	if (job_ptr->name && job_ptr->name[0])
		jname = slurm_add_slash_to_quotes(job_ptr->name);
	else
		jname = xstrdup("allocation");

	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, jname,
		   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("query = %s", query);
	rc = mysql_db_query(jobcomp_mysql_conn, query);
	xfree(usr_str);
	xfree(grp_str);
	xfree(jname);

	return rc;
}
Esempio n. 6
0
extern int as_mysql_add_users(mysql_conn_t *mysql_conn, uint32_t uid,
			      List user_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_user_rec_t *object = NULL;
	char *cols = NULL, *vals = NULL, *query = NULL, *txn_query = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	char *extra = NULL, *tmp_extra = NULL;
	int affect_rows = 0;
	List assoc_list = list_create(slurmdb_destroy_association_rec);
	List wckey_list = list_create(slurmdb_destroy_wckey_rec);

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

	user_name = uid_to_string((uid_t) uid);
	itr = list_iterator_create(user_list);
	while ((object = list_next(itr))) {
		if (!object->name || !object->name[0]) {
			error("We need a user name and "
			      "default acct to add.");
			rc = SLURM_ERROR;
			continue;
		}
		xstrcat(cols, "creation_time, mod_time, name");
		xstrfmtcat(vals, "%ld, %ld, '%s'",
			   (long)now, (long)now, object->name);

		if (object->admin_level != SLURMDB_ADMIN_NOTSET) {
			xstrcat(cols, ", admin_level");
			xstrfmtcat(vals, ", %u", object->admin_level);
			xstrfmtcat(extra, ", admin_level=%u",
				   object->admin_level);
		} else
			xstrfmtcat(extra, ", admin_level=%u",
				   SLURMDB_ADMIN_NONE);

		query = xstrdup_printf(
			"insert into %s (%s) values (%s) "
			"on duplicate key update deleted=0, mod_time=%ld %s;",
			user_table, cols, vals,
			(long)now, extra);
		xfree(cols);
		xfree(vals);

		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add user %s", object->name);
			xfree(extra);
			continue;
		}

		affect_rows = last_affected_rows(mysql_conn);
		if (!affect_rows) {
			debug("nothing changed");
			xfree(extra);
			continue;
		}

		if (addto_update_list(mysql_conn->update_list, SLURMDB_ADD_USER,
				      object) == SLURM_SUCCESS)
			list_remove(itr);

		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		if (txn_query)
			xstrfmtcat(txn_query,
				   ", (%ld, %u, '%s', '%s', '%s')",
				   (long)now, DBD_ADD_USERS, object->name,
				   user_name, tmp_extra);
		else
			xstrfmtcat(txn_query,
				   "insert into %s "
				   "(timestamp, action, name, actor, info) "
				   "values (%ld, %u, '%s', '%s', '%s')",
				   txn_table,
				   (long)now, DBD_ADD_USERS, object->name,
				   user_name, tmp_extra);
		xfree(tmp_extra);
		xfree(extra);

		/* For < 2.2 systems we need to set the is_def flag in
		   the default association/wckey so as to make sure we get
		   it set correctly.
		*/
		if (object->assoc_list) {
			slurmdb_association_rec_t *assoc = NULL;
			ListIterator assoc_itr =
				list_iterator_create(object->assoc_list);
			while ((assoc = list_next(assoc_itr))) {
				/* We need to mark all of the
				   associations with this account
				   since there could be multiple
				   clusters here.
				*/
				if (!strcmp(assoc->acct, object->default_acct))
					assoc->is_def = 1;
			}
			list_iterator_destroy(assoc_itr);
			list_transfer(assoc_list, object->assoc_list);
		}

		if (object->wckey_list) {
			if (object->default_wckey) {
				slurmdb_wckey_rec_t *wckey = NULL;
				ListIterator wckey_itr = list_iterator_create(
					object->wckey_list);
				while ((wckey = list_next(wckey_itr))) {
					/* We need to mark all of the
					   wckeys with this account
					   since there could be multiple
					   clusters here.
					*/
					if (!strcmp(wckey->name,
						    object->default_wckey))
						wckey->is_def = 1;
				}
				list_iterator_destroy(wckey_itr);
			}
			list_transfer(wckey_list, object->wckey_list);
		}
	}
	list_iterator_destroy(itr);
	xfree(user_name);

	if (rc != SLURM_ERROR) {
		if (txn_query) {
			xstrcat(txn_query, ";");
			rc = mysql_db_query(mysql_conn,
					    txn_query);
			xfree(txn_query);
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add txn");
				rc = SLURM_SUCCESS;
			}
		}
	} else
		xfree(txn_query);

	if (list_count(assoc_list)) {
		if (as_mysql_add_assocs(mysql_conn, uid, assoc_list)
		    == SLURM_ERROR) {
			error("Problem adding user associations");
			rc = SLURM_ERROR;
		}
	}
	list_destroy(assoc_list);

	if (list_count(wckey_list)) {
		if (as_mysql_add_wckeys(mysql_conn, uid, wckey_list)
		    == SLURM_ERROR) {
			error("Problem adding user wckeys");
			rc = SLURM_ERROR;
		}
	}
	list_destroy(wckey_list);
	return rc;
}
Esempio n. 7
0
extern int as_mysql_add_accts(mysql_conn_t *mysql_conn, uint32_t uid,
			      List acct_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_account_rec_t *object = NULL;
	char *cols = NULL, *vals = NULL, *query = NULL, *txn_query = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	char *extra = NULL, *tmp_extra = NULL;

	int affect_rows = 0;
	List assoc_list = list_create(slurmdb_destroy_assoc_rec);

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

	if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) {
		slurmdb_user_rec_t user;

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

		if (!is_user_any_coord(mysql_conn, &user)) {
			error("Only admins/operators/coordinators "
			      "can add accounts");
			return ESLURM_ACCESS_DENIED;
		}
		/* If the user is a coord of any acct they can add
		 * accounts they are only able to make associations to
		 * these accounts if they are coordinators of the
		 * parent they are trying to add to
		 */
	}

	user_name = uid_to_string((uid_t) uid);
	itr = list_iterator_create(acct_list);
	while ((object = list_next(itr))) {
		if (!object->name || !object->name[0]
		    || !object->description || !object->description[0]
		    || !object->organization || !object->organization[0]) {
			error("We need an account name, description, and "
			      "organization to add. %s %s %s",
			      object->name, object->description,
			      object->organization);
			rc = SLURM_ERROR;
			continue;
		}
		xstrcat(cols, "creation_time, mod_time, name, "
			"description, organization");
		xstrfmtcat(vals, "%ld, %ld, '%s', '%s', '%s'",
			   now, now, object->name,
			   object->description, object->organization);
		xstrfmtcat(extra, ", description='%s', organization='%s'",
			   object->description, object->organization);

		query = xstrdup_printf(
			"insert into %s (%s) values (%s) "
			"on duplicate key update deleted=0, mod_time=%ld %s;",
			acct_table, cols, vals,
			now, extra);
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(cols);
		xfree(vals);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add acct");
			xfree(extra);
			continue;
		}
		affect_rows = last_affected_rows(mysql_conn);
		/* if (debug_flags & DEBUG_FLAG_DB_ASSOC) */
		/* 	DB_DEBUG(mysql_conn->conn, "affected %d", affect_rows); */

		if (!affect_rows) {
			if (debug_flags & DEBUG_FLAG_DB_ASSOC)
				DB_DEBUG(mysql_conn->conn, "nothing changed");
			xfree(extra);
			continue;
		}

		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		if (txn_query)
			xstrfmtcat(txn_query,
				   ", (%ld, %u, '%s', '%s', '%s')",
				   now, DBD_ADD_ACCOUNTS, object->name,
				   user_name, tmp_extra);
		else
			xstrfmtcat(txn_query,
				   "insert into %s "
				   "(timestamp, action, name, actor, info) "
				   "values (%ld, %u, '%s', '%s', '%s')",
				   txn_table,
				   now, DBD_ADD_ACCOUNTS, object->name,
				   user_name, tmp_extra);
		xfree(tmp_extra);
		xfree(extra);

		if (!object->assoc_list)
			continue;

		if (!assoc_list)
			assoc_list =
				list_create(slurmdb_destroy_assoc_rec);
		list_transfer(assoc_list, object->assoc_list);
	}
	list_iterator_destroy(itr);
	xfree(user_name);

	if (rc != SLURM_ERROR) {
		if (txn_query) {
			xstrcat(txn_query, ";");
			rc = mysql_db_query(mysql_conn,
					    txn_query);
			xfree(txn_query);
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add txn");
				rc = SLURM_SUCCESS;
			}
		}
	} else
		xfree(txn_query);

	if (assoc_list && list_count(assoc_list)) {
		if ((rc = as_mysql_add_assocs(mysql_conn, uid, assoc_list))
		    != SLURM_SUCCESS)
			error("Problem adding accounts associations");
	}
	FREE_NULL_LIST(assoc_list);

	return rc;
}
Esempio n. 8
0
/* NOTE: Insure that mysql_conn->lock is NOT set on function entry */
static int _mysql_make_table_current(mysql_conn_t *mysql_conn, char *table_name,
				     storage_field_t *fields, char *ending)
{
	char *query = NULL;
	char *correct_query = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	int i = 0;
	List columns = NULL;
	ListIterator itr = NULL;
	char *col = NULL;
	int adding = 0;
	int run_update = 0;
	char *primary_key = NULL;
	char *unique_index = NULL;
	int old_primary = 0;
	char *old_index = NULL;
	char *temp = NULL, *temp2 = NULL;
	List keys_list = NULL;
	db_key_t *db_key = NULL;

	DEF_TIMERS;

	/* figure out the unique keys in the table */
	query = xstrdup_printf("show index from %s where non_unique=0",
			       table_name);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);
	while ((row = mysql_fetch_row(result))) {
		// row[2] is the key name
		if (!strcasecmp(row[2], "PRIMARY"))
			old_primary = 1;
		else if (!old_index)
			old_index = xstrdup(row[2]);
	}
	mysql_free_result(result);

	/* figure out the non-unique keys in the table */
	query = xstrdup_printf("show index from %s where non_unique=1",
			       table_name);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	itr = NULL;
	keys_list = list_create(_destroy_db_key);
	while ((row = mysql_fetch_row(result))) {
		if (!itr)
			itr = list_iterator_create(keys_list);
		else
			list_iterator_reset(itr);
		while ((db_key = list_next(itr))) {
			if (!strcmp(db_key->name, row[2]))
				break;
		}

		if (db_key) {
			xstrfmtcat(db_key->columns, ", %s", row[4]);
		} else {
			db_key = xmalloc(sizeof(db_key_t));
			db_key->name = xstrdup(row[2]); // name
			db_key->columns = xstrdup(row[4]); // column name
			list_append(keys_list, db_key); // don't use list_push
		}
	}
	mysql_free_result(result);

	if (itr) {
		list_iterator_destroy(itr);
		itr = NULL;
	}

	/* figure out the existing columns in the table */
	query = xstrdup_printf("show columns from %s", table_name);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		xfree(old_index);
		FREE_NULL_LIST(keys_list);
		return SLURM_ERROR;
	}
	xfree(query);
	columns = list_create(slurm_destroy_char);
	while ((row = mysql_fetch_row(result))) {
		col = xstrdup(row[0]); //Field
		list_append(columns, col);
	}
	mysql_free_result(result);


	itr = list_iterator_create(columns);
	query = xstrdup_printf("alter ignore table %s", table_name);
	correct_query = xstrdup_printf("alter ignore table %s", table_name);
	START_TIMER;
	while (fields[i].name) {
		int found = 0;

		list_iterator_reset(itr);
		while ((col = list_next(itr))) {
			if (!strcmp(col, fields[i].name)) {
				xstrfmtcat(query, " modify `%s` %s,",
					   fields[i].name,
					   fields[i].options);
				xstrfmtcat(correct_query, " modify `%s` %s,",
					   fields[i].name,
					   fields[i].options);
				list_delete_item(itr);
				found = 1;
				break;
			}
		}
		if (!found) {
			if (i) {
				info("adding column %s after %s in table %s",
				     fields[i].name,
				     fields[i-1].name,
				     table_name);
				xstrfmtcat(query, " add `%s` %s after %s,",
					   fields[i].name,
					   fields[i].options,
					   fields[i-1].name);
				xstrfmtcat(correct_query, " modify `%s` %s,",
					   fields[i].name,
					   fields[i].options);
			} else {
				info("adding column %s at the beginning "
				     "of table %s",
				     fields[i].name,
				     table_name);
				xstrfmtcat(query, " add `%s` %s first,",
					   fields[i].name,
					   fields[i].options);
				xstrfmtcat(correct_query, " modify `%s` %s,",
					   fields[i].name,
					   fields[i].options);
			}
			adding = 1;
		}

		i++;
	}

	list_iterator_reset(itr);
	while ((col = list_next(itr))) {
		adding = 1;
		info("dropping column %s from table %s", col, table_name);
		xstrfmtcat(query, " drop %s,", col);
	}

	list_iterator_destroy(itr);
	list_destroy(columns);

	if ((temp = strstr(ending, "primary key ("))) {
		int open = 0, close =0;
		int end = 0;
		while (temp[end++]) {
			if (temp[end] == '(')
				open++;
			else if (temp[end] == ')')
				close++;
			else
				continue;
			if (open == close)
				break;
		}
		if (temp[end]) {
			end++;
			primary_key = xstrndup(temp, end);
			if (old_primary) {
				xstrcat(query, " drop primary key,");
				xstrcat(correct_query, " drop primary key,");
			}
			xstrfmtcat(query, " add %s,",  primary_key);
			xstrfmtcat(correct_query, " add %s,",  primary_key);

			xfree(primary_key);
		}
	}

	if ((temp = strstr(ending, "unique index ("))) {
		int open = 0, close =0;
		int end = 0;
		while (temp[end++]) {
			if (temp[end] == '(')
				open++;
			else if (temp[end] == ')')
				close++;
			else
				continue;
			if (open == close)
				break;
		}
		if (temp[end]) {
			end++;
			unique_index = xstrndup(temp, end);
			if (old_index) {
				xstrfmtcat(query, " drop index %s,",
					   old_index);
				xstrfmtcat(correct_query, " drop index %s,",
					   old_index);
			}
			xstrfmtcat(query, " add %s,", unique_index);
			xstrfmtcat(correct_query, " add %s,", unique_index);
			xfree(unique_index);
		}
	}
	xfree(old_index);

	temp2 = ending;
	itr = list_iterator_create(keys_list);
	while ((temp = strstr(temp2, ", key "))) {
		int open = 0, close = 0, name_end = 0;
		int end = 5;
		char *new_key_name = NULL, *new_key = NULL;
		while (temp[end++]) {
			if (!name_end && (temp[end] == ' ')) {
				name_end = end;
				continue;
			} else if (temp[end] == '(') {
				open++;
				if (!name_end)
					name_end = end;
			} else if (temp[end] == ')')
				close++;
			else
				continue;
			if (open == close)
				break;
		}
		if (temp[end]) {
			end++;
			new_key_name = xstrndup(temp+6, name_end-6);
			new_key = xstrndup(temp+2, end-2); // skip ', '
			while ((db_key = list_next(itr))) {
				if (!strcmp(db_key->name, new_key_name)) {
					list_remove(itr);
					break;
				}
			}
			list_iterator_reset(itr);
			if (db_key) {
				xstrfmtcat(query,
					   " drop key %s,", db_key->name);
				xstrfmtcat(correct_query,
					   " drop key %s,", db_key->name);
				_destroy_db_key(db_key);
			} else
				info("adding %s to table %s",
				     new_key, table_name);

			xstrfmtcat(query, " add %s,",  new_key);
			xstrfmtcat(correct_query, " add %s,",  new_key);

			xfree(new_key);
			xfree(new_key_name);
		}
		temp2 = temp + end;
	}

	/* flush extra (old) keys */
	while ((db_key = list_next(itr))) {
		info("dropping key %s from table %s", db_key->name, table_name);
		xstrfmtcat(query, " drop key %s,", db_key->name);
	}
	list_iterator_destroy(itr);

	list_destroy(keys_list);

	query[strlen(query)-1] = ';';
	correct_query[strlen(correct_query)-1] = ';';
	//info("%d query\n%s", __LINE__, query);

	/* see if we have already done this definition */
	if (!adding) {
		char *quoted = slurm_add_slash_to_quotes(query);
		char *query2 = xstrdup_printf("select table_name from "
					      "%s where definition='%s'",
					      table_defs_table, quoted);
		MYSQL_RES *result = NULL;
		MYSQL_ROW row;

		xfree(quoted);
		run_update = 1;
		if ((result = mysql_db_query_ret(mysql_conn, query2, 0))) {
			if ((row = mysql_fetch_row(result)))
				run_update = 0;
			mysql_free_result(result);
		}
		xfree(query2);
		if (run_update) {
			run_update = 2;
			query2 = xstrdup_printf("select table_name from "
						"%s where table_name='%s'",
						table_defs_table, table_name);
			if ((result = mysql_db_query_ret(
				     mysql_conn, query2, 0))) {
				if ((row = mysql_fetch_row(result)))
					run_update = 1;
				mysql_free_result(result);
			}
			xfree(query2);
		}
	}

	/* if something has changed run the alter line */
	if (run_update || adding) {
		time_t now = time(NULL);
		char *query2 = NULL;
		char *quoted = NULL;

		if (run_update == 2)
			debug4("Table %s doesn't exist, adding", table_name);
		else
			debug("Table %s has changed.  Updating...", table_name);
		if (mysql_db_query(mysql_conn, query)) {
			xfree(query);
			return SLURM_ERROR;
		}
		quoted = slurm_add_slash_to_quotes(correct_query);
		query2 = xstrdup_printf("insert into %s (creation_time, "
					"mod_time, table_name, definition) "
					"values (%ld, %ld, '%s', '%s') "
					"on duplicate key update "
					"definition='%s', mod_time=%ld;",
					table_defs_table, now, now,
					table_name, quoted,
					quoted, now);
		xfree(quoted);
		if (mysql_db_query(mysql_conn, query2)) {
			xfree(query2);
			return SLURM_ERROR;
		}
		xfree(query2);
	}

	xfree(query);
	xfree(correct_query);
	query = xstrdup_printf("make table current %s", table_name);
	END_TIMER2(query);
	xfree(query);
	return SLURM_SUCCESS;
}
Esempio n. 9
0
static int _setup_resv_limits(slurmdb_reservation_rec_t *resv,
			      char **cols, char **vals,
			      char **extra)
{
	/* strip off the action item from the flags */

	if (resv->assocs) {
		int start = 0;
		int len = strlen(resv->assocs)-1;

		if (strchr(resv->assocs, '-')) {
			int i = 0, i2 = 0;
			char * assocs = xmalloc(sizeof(char) * len);
			/* We will remove the negative's here.  This
			   is here so if we only have negatives in the
			   reservation we don't want to keep track of
			   every other id so don't keep track of any
			   since everyone except a few can use it.
			   These id's are only used to divide up idle
			   time so it isn't that important.
			*/
			while (i < len) {
				if (resv->assocs[i] == ',' &&
				    resv->assocs[i+1] == '-') {
					i+=2;
					while (i < len) {
						i++;
						if (resv->assocs[i] == ',')
							break;
					}
					continue;
				}
				assocs[i2++] = resv->assocs[i++];
			}
			xfree(resv->assocs);
			len = i2-1;
			resv->assocs = assocs;
			assocs = NULL;
		}

		/* strip off extra ,'s */
		if (resv->assocs[0] == ',')
			start = 1;
		if (resv->assocs[len] == ',')
			resv->assocs[len] = '\0';

		xstrcat(*cols, ", assoclist");
		xstrfmtcat(*vals, ", '%s'", resv->assocs+start);
		xstrfmtcat(*extra, ", assoclist='%s'", resv->assocs+start);
	}

	if (resv->flags != NO_VAL) {
		xstrcat(*cols, ", flags");
		xstrfmtcat(*vals, ", %u", resv->flags);
		xstrfmtcat(*extra, ", flags=%u", resv->flags);
	}

	if (resv->name) {
		char *tmp_char = slurm_add_slash_to_quotes(resv->name);
		xstrcat(*cols, ", resv_name");
		xstrfmtcat(*vals, ", '%s'", tmp_char);
		xstrfmtcat(*extra, ", resv_name='%s'", tmp_char);
		xfree(tmp_char);
	}

	if (resv->nodes) {
		xstrcat(*cols, ", nodelist");
		xstrfmtcat(*vals, ", '%s'", resv->nodes);
		xstrfmtcat(*extra, ", nodelist='%s'", resv->nodes);
	}

	if (resv->node_inx) {
		xstrcat(*cols, ", node_inx");
		xstrfmtcat(*vals, ", '%s'", resv->node_inx);
		xstrfmtcat(*extra, ", node_inx='%s'", resv->node_inx);
	}

	if (resv->time_end) {
		xstrcat(*cols, ", time_end");
		xstrfmtcat(*vals, ", %ld", resv->time_end);
		xstrfmtcat(*extra, ", time_end=%ld", resv->time_end);
	}

	if (resv->time_start) {
		xstrcat(*cols, ", time_start");
		xstrfmtcat(*vals, ", %ld", resv->time_start);
		xstrfmtcat(*extra, ", time_start=%ld", resv->time_start);
	}

	if (resv->tres_str) {
		xstrcat(*cols, ", tres");
		xstrfmtcat(*vals, ", '%s'", resv->tres_str);
		xstrfmtcat(*extra, ", tres='%s'", resv->tres_str);
	}

	return SLURM_SUCCESS;
}
Esempio n. 10
0
extern int as_mysql_add_wckeys(mysql_conn_t *mysql_conn, uint32_t uid,
                               List wckey_list)
{
    ListIterator itr = NULL;
    int rc = SLURM_SUCCESS;
    slurmdb_wckey_rec_t *object = NULL;
    char *cols = NULL, *extra = NULL, *vals = NULL, *query = NULL,
          *tmp_extra = NULL;
    time_t now = time(NULL);
    char *user_name = NULL;
    int affect_rows = 0;
    int added = 0;
    List added_user_list = NULL;

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

    if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))
        return ESLURM_ACCESS_DENIED;

    user_name = uid_to_string((uid_t) uid);
    itr = list_iterator_create(wckey_list);
    while ((object = list_next(itr))) {
        if (!object->cluster || !object->cluster[0]
                || !object->user || !object->user[0]
                || !object->name) {
            error("We need a wckey name (%s), cluster (%s), "
                  "and user (%s) to add.",
                  object->name, object->cluster, object->user);
            rc = SLURM_ERROR;
            continue;
        }

        if (!added_user_list)
            added_user_list = list_create(NULL);
        list_append(added_user_list, object->user);
        xstrcat(cols, "creation_time, mod_time, user");
        xstrfmtcat(vals, "%ld, %ld, '%s'",
                   now, now, object->user);
        xstrfmtcat(extra, ", mod_time=%ld, user='******'",
                   now, object->user);

        if (object->name) {
            xstrcat(cols, ", wckey_name");
            xstrfmtcat(vals, ", '%s'", object->name);
            xstrfmtcat(extra, ", wckey_name='%s'", object->name);
        }

        /* When adding, if this isn't a default might as well
           force it to be 0 to avoid confusion since
           uninitialized it is NO_VAL.
        */
        if (object->is_def == 1) {
            xstrcat(cols, ", is_def");
            xstrcat(vals, ", 1");
            xstrcat(extra, ", is_def=1");
        } else {
            object->is_def = 0;
            xstrcat(cols, ", is_def");
            xstrcat(vals, ", 0");
            xstrcat(extra, ", is_def=0");
        }

        xstrfmtcat(query,
                   "insert into \"%s_%s\" (%s) values (%s) "
                   "on duplicate key update deleted=0, "
                   "id_wckey=LAST_INSERT_ID(id_wckey)%s;",
                   object->cluster, wckey_table, cols, vals, extra);

        if (debug_flags & DEBUG_FLAG_DB_WCKEY)
            DB_DEBUG(mysql_conn->conn, "query\n%s", query);
        object->id = mysql_db_insert_ret_id(mysql_conn, query);
        xfree(query);
        if (!object->id) {
            error("Couldn't add wckey %s", object->name);
            added=0;
            xfree(cols);
            xfree(extra);
            xfree(vals);
            break;
        }

        affect_rows = last_affected_rows(mysql_conn);

        if (!affect_rows) {
            debug2("nothing changed %d", affect_rows);
            xfree(cols);
            xfree(extra);
            xfree(vals);
            continue;
        }

        /* we always have a ', ' as the first 2 chars */
        tmp_extra = slurm_add_slash_to_quotes(extra+2);

        xstrfmtcat(query,
                   "insert into %s "
                   "(timestamp, action, name, actor, info, cluster) "
                   "values (%ld, %u, 'id_wckey=%d', '%s', '%s', '%s');",
                   txn_table,
                   now, DBD_ADD_WCKEYS, object->id, user_name,
                   tmp_extra, object->cluster);

        xfree(tmp_extra);
        xfree(cols);
        xfree(extra);
        xfree(vals);
        debug4("query\n%s",query);
        rc = mysql_db_query(mysql_conn, query);
        xfree(query);
        if (rc != SLURM_SUCCESS) {
            error("Couldn't add txn");
        } else {
            if (addto_update_list(mysql_conn->update_list,
                                  SLURMDB_ADD_WCKEY,
                                  object) == SLURM_SUCCESS)
                list_remove(itr);
            added++;
        }

    }
    list_iterator_destroy(itr);
    xfree(user_name);

    if (!added) {
        reset_mysql_conn(mysql_conn);
        goto end_it;
    }

    /* now reset all the other defaults accordingly. (if needed) */
    itr = list_iterator_create(wckey_list);
    while ((object = list_next(itr))) {
        if ((object->is_def != 1) || !object->cluster
                || !object->user || !object->name)
            continue;
        if ((rc = _reset_default_wckey(mysql_conn, object)
                  != SLURM_SUCCESS))
            break;
    }
    list_iterator_destroy(itr);
end_it:
    if (rc == SLURM_SUCCESS)
        _make_sure_users_have_default(mysql_conn, added_user_list);
    if (added_user_list)
        list_destroy(added_user_list);

    return rc;
}
Esempio n. 11
0
extern int as_mysql_add_qos(mysql_conn_t *mysql_conn, uint32_t uid,
			    List qos_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_qos_rec_t *object = NULL;
	char *cols = NULL, *extra = NULL, *vals = NULL, *query = NULL,
		*tmp_extra = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	int affect_rows = 0;
	int added = 0;
	char *added_preempt = NULL;

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

	user_name = uid_to_string((uid_t) uid);
	itr = list_iterator_create(qos_list);
	while ((object = list_next(itr))) {
		if (!object->name || !object->name[0]) {
			error("We need a qos name to add.");
			rc = SLURM_ERROR;
			continue;
		}
		xstrcat(cols, "creation_time, mod_time, name");
		xstrfmtcat(vals, "%ld, %ld, '%s'",
			   now, now, object->name);
		xstrfmtcat(extra, ", mod_time=%ld", now);

		_setup_qos_limits(object, &cols, &vals,
				  &extra, &added_preempt, 1);
		if (added_preempt) {
			object->preempt_bitstr = bit_alloc(g_qos_count);
			bit_unfmt(object->preempt_bitstr, added_preempt+1);
			xfree(added_preempt);
		}

		xstrfmtcat(query,
			   "insert into %s (%s) values (%s) "
			   "on duplicate key update deleted=0, "
			   "id=LAST_INSERT_ID(id)%s;",
			   qos_table, cols, vals, extra);


		debug3("%d(%s:%d) query\n%s",
		       mysql_conn->conn, THIS_FILE, __LINE__, query);
		object->id = mysql_db_insert_ret_id(mysql_conn, query);
		xfree(query);
		if (!object->id) {
			error("Couldn't add qos %s", object->name);
			added=0;
			xfree(cols);
			xfree(extra);
			xfree(vals);
			break;
		}

		affect_rows = last_affected_rows(mysql_conn);

		if (!affect_rows) {
			debug2("nothing changed %d", affect_rows);
			xfree(cols);
			xfree(extra);
			xfree(vals);
			continue;
		}

		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		xstrfmtcat(query,
			   "insert into %s "
			   "(timestamp, action, name, actor, info) "
			   "values (%ld, %u, '%s', '%s', '%s');",
			   txn_table,
			   now, DBD_ADD_QOS, object->name, user_name,
			   tmp_extra);

		xfree(tmp_extra);
		xfree(cols);
		xfree(extra);
		xfree(vals);
		debug4("query\n%s",query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add txn");
		} else {
			if (addto_update_list(mysql_conn->update_list,
					      SLURMDB_ADD_QOS,
					      object) == SLURM_SUCCESS)
				list_remove(itr);
			added++;
		}

	}
	list_iterator_destroy(itr);
	xfree(user_name);

	if (!added) {
		reset_mysql_conn(mysql_conn);
	}

	return rc;
}
Esempio n. 12
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;
}
Esempio n. 13
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;
}
Esempio n. 14
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;
}
Esempio n. 15
0
extern int as_mysql_job_start(mysql_conn_t *mysql_conn,
			      struct job_record *job_ptr)
{
	int rc=SLURM_SUCCESS;
	char *nodes = NULL, *jname = NULL, *node_inx = NULL;
	int track_steps = 0;
	char *block_id = NULL, *partition = NULL,
		*gres_req = NULL, *gres_alloc = NULL;
	char *query = NULL;
	int reinit = 0;
	time_t begin_time, check_time, start_time, submit_time;
	uint32_t wckeyid = 0;
	int job_state, node_cnt = 0;
	uint32_t job_db_inx = job_ptr->db_index;

	if ((!job_ptr->details || !job_ptr->details->submit_time)
	    && !job_ptr->resize_time) {
		error("as_mysql_job_start: "
		      "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_start() called");

	job_state = job_ptr->job_state;

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

	/* Since we need a new db_inx make sure the old db_inx
	 * removed. This is most likely the only time we are going to
	 * be notified of the change also so make the state without
	 * the resize. */
	if (IS_JOB_RESIZING(job_ptr)) {
		/* If we have a db_index lets end the previous record. */
		if (!job_ptr->db_index) {
			error("We don't have a db_index for job %u, "
			      "this should only happen when resizing "
			      "jobs and the database interface was down.",
			      job_ptr->job_id);
			job_ptr->db_index = _get_db_index(mysql_conn,
							  job_ptr->details->
							  submit_time,
							  job_ptr->job_id,
							  job_ptr->assoc_id);
		}

		if (job_ptr->db_index)
			as_mysql_job_complete(mysql_conn, job_ptr);

		job_state &= (~JOB_RESIZING);
		job_ptr->db_index = 0;
	}

	job_state &= JOB_STATE_BASE;

	/* See what we are hearing about here if no start time. If
	 * this job latest time is before the last roll up we will
	 * need to reset it to look at this job. */
	if (start_time)
		check_time = start_time;
	else if (begin_time)
		check_time = begin_time;
	else
		check_time = submit_time;

	slurm_mutex_lock(&rollup_lock);
	if (check_time < global_last_rollup) {
		MYSQL_RES *result = NULL;
		MYSQL_ROW row;

		/* check to see if we are hearing about this time for the
		 * first time.
		 */
		query = xstrdup_printf("select job_db_inx "
				       "from \"%s_%s\" where id_job=%u and "
				       "time_submit=%ld and time_eligible=%ld "
				       "and time_start=%ld;",
				       mysql_conn->cluster_name,
				       job_table, job_ptr->job_id,
				       submit_time, begin_time, start_time);
		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);
			slurm_mutex_unlock(&rollup_lock);
			return SLURM_ERROR;
		}
		xfree(query);
		if ((row = mysql_fetch_row(result))) {
			mysql_free_result(result);
			debug4("revieved an update for a "
			       "job (%u) already known about",
			       job_ptr->job_id);
			slurm_mutex_unlock(&rollup_lock);
			goto no_rollup_change;
		}
		mysql_free_result(result);

		if (job_ptr->start_time)
			debug("Need to reroll usage from %sJob %u "
			      "from %s started then and we are just "
			      "now hearing about it.",
			      slurm_ctime(&check_time),
			      job_ptr->job_id, mysql_conn->cluster_name);
		else if (begin_time)
			debug("Need to reroll usage from %sJob %u "
			      "from %s became eligible then and we are just "
			      "now hearing about it.",
			      slurm_ctime(&check_time),
			      job_ptr->job_id, mysql_conn->cluster_name);
		else
			debug("Need to reroll usage from %sJob %u "
			      "from %s was submitted then and we are just "
			      "now hearing about it.",
			      slurm_ctime(&check_time),
			      job_ptr->job_id, mysql_conn->cluster_name);

		global_last_rollup = check_time;
		slurm_mutex_unlock(&rollup_lock);

		/* If the times here are later than the daily_rollup
		   or monthly rollup it isn't a big deal since they
		   are always shrunk down to the beginning of each
		   time period.
		*/
		query = xstrdup_printf("update \"%s_%s\" set "
				       "hourly_rollup=%ld, "
				       "daily_rollup=%ld, monthly_rollup=%ld",
				       mysql_conn->cluster_name,
				       last_ran_table, check_time,
				       check_time, check_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);

no_rollup_change:

	if (job_ptr->name && job_ptr->name[0])
		jname = slurm_add_slash_to_quotes(job_ptr->name);
	else {
		jname = xstrdup("allocation");
		track_steps = 1;
	}

	if (job_ptr->nodes && job_ptr->nodes[0])
		nodes = job_ptr->nodes;
	else
		nodes = "None assigned";

	if (job_ptr->batch_flag)
		track_steps = 1;

	if (slurmdbd_conf) {
		block_id = xstrdup(job_ptr->comment);
		node_cnt = job_ptr->total_nodes;
		node_inx = job_ptr->network;
	} else {
		char temp_bit[BUF_SIZE];

		if (job_ptr->node_bitmap) {
			node_inx = bit_fmt(temp_bit, sizeof(temp_bit),
					   job_ptr->node_bitmap);
		}
#ifdef HAVE_BG
		select_g_select_jobinfo_get(job_ptr->select_jobinfo,
					    SELECT_JOBDATA_BLOCK_ID,
					    &block_id);
		select_g_select_jobinfo_get(job_ptr->select_jobinfo,
					    SELECT_JOBDATA_NODE_CNT,
					    &node_cnt);
#else
		node_cnt = job_ptr->total_nodes;
#endif
	}

	/* If there is a start_time get the wckeyid.  If the job is
	 * cancelled before the job starts we also want to grab it. */
	if (job_ptr->assoc_id
	    && (job_ptr->start_time || IS_JOB_CANCELLED(job_ptr)))
		wckeyid = _get_wckeyid(mysql_conn, &job_ptr->wckey,
				       job_ptr->user_id,
				       mysql_conn->cluster_name,
				       job_ptr->assoc_id);

	if (job_ptr->partition)
		partition = slurm_add_slash_to_quotes(job_ptr->partition);

	if (job_ptr->gres_req)
		gres_req = slurm_add_slash_to_quotes(job_ptr->gres_req);

	if (job_ptr->gres_alloc)
		gres_alloc = slurm_add_slash_to_quotes(job_ptr->gres_alloc);

	if (!job_ptr->db_index) {
		if (!begin_time)
			begin_time = submit_time;
		query = xstrdup_printf(
			"insert into \"%s_%s\" "
			"(id_job, id_array_job, id_array_task, "
			"id_assoc, id_qos, id_wckey, id_user, "
			"id_group, nodelist, id_resv, timelimit, "
			"time_eligible, time_submit, time_start, "
			"job_name, track_steps, state, priority, cpus_req, "
			"cpus_alloc, nodes_alloc, mem_req",
			mysql_conn->cluster_name, job_table);

		if (job_ptr->account)
			xstrcat(query, ", account");
		if (partition)
			xstrcat(query, ", `partition`");
		if (block_id)
			xstrcat(query, ", id_block");
		if (job_ptr->wckey)
			xstrcat(query, ", wckey");
		if (node_inx)
			xstrcat(query, ", node_inx");
		if (gres_req)
			xstrcat(query, ", gres_req");
		if (gres_alloc)
			xstrcat(query, ", gres_alloc");

		xstrfmtcat(query,
			   ") values (%u, %u, %u, %u, %u, %u, %u, %u, "
			   "'%s', %u, %u, %ld, %ld, %ld, "
			   "'%s', %u, %u, %u, %u, %u, %u, %u",
			   job_ptr->job_id, job_ptr->array_job_id,
			   job_ptr->array_task_id, job_ptr->assoc_id,
			   job_ptr->qos_id, wckeyid,
			   job_ptr->user_id, job_ptr->group_id, nodes,
			   job_ptr->resv_id, job_ptr->time_limit,
			   begin_time, submit_time, start_time,
			   jname, track_steps, job_state,
			   job_ptr->priority, job_ptr->details->min_cpus,
			   job_ptr->total_cpus, node_cnt,
			   job_ptr->details->pn_min_memory);

		if (job_ptr->account)
			xstrfmtcat(query, ", '%s'", job_ptr->account);
		if (partition)
			xstrfmtcat(query, ", '%s'", partition);
		if (block_id)
			xstrfmtcat(query, ", '%s'", block_id);
		if (job_ptr->wckey)
			xstrfmtcat(query, ", '%s'", job_ptr->wckey);
		if (node_inx)
			xstrfmtcat(query, ", '%s'", node_inx);
		if (gres_req)
			xstrfmtcat(query, ", '%s'", gres_req);
		if (gres_alloc)
			xstrfmtcat(query, ", '%s'", gres_alloc);

		xstrfmtcat(query,
			   ") on duplicate key update "
			   "job_db_inx=LAST_INSERT_ID(job_db_inx), "
			   "id_wckey=%u, id_user=%u, id_group=%u, "
			   "nodelist='%s', id_resv=%u, timelimit=%u, "
			   "time_submit=%ld, time_start=%ld, "
			   "job_name='%s', track_steps=%u, id_qos=%u, "
			   "state=greatest(state, %u), priority=%u, "
			   "cpus_req=%u, cpus_alloc=%u, nodes_alloc=%u, "
			   "mem_req=%u, id_array_job=%u, id_array_task=%u",
			   wckeyid, job_ptr->user_id, job_ptr->group_id, nodes,
			   job_ptr->resv_id, job_ptr->time_limit,
			   submit_time, start_time,
			   jname, track_steps, job_ptr->qos_id, job_state,
			   job_ptr->priority, job_ptr->details->min_cpus,
			   job_ptr->total_cpus, node_cnt,
			   job_ptr->details->pn_min_memory,
			   job_ptr->array_job_id,
			   job_ptr->array_task_id);

		if (job_ptr->account)
			xstrfmtcat(query, ", account='%s'", job_ptr->account);
		if (partition)
			xstrfmtcat(query, ", `partition`='%s'", partition);
		if (block_id)
			xstrfmtcat(query, ", id_block='%s'", block_id);
		if (job_ptr->wckey)
			xstrfmtcat(query, ", wckey='%s'", job_ptr->wckey);
		if (node_inx)
			xstrfmtcat(query, ", node_inx='%s'", node_inx);
		if (gres_req)
			xstrfmtcat(query, ", gres_req='%s'", gres_req);
		if (gres_alloc)
			xstrfmtcat(query, ", gres_alloc='%s'", gres_alloc);

		debug3("%d(%s:%d) query\n%s",
		       mysql_conn->conn, THIS_FILE, __LINE__, query);
	try_again:
		if (!(job_ptr->db_index = mysql_db_insert_ret_id(
			      mysql_conn, query))) {
			if (!reinit) {
				error("It looks like the storage has gone "
				      "away trying to reconnect");
				mysql_db_close_db_connection(
					mysql_conn);
				/* reconnect */
				check_connection(mysql_conn);
				reinit = 1;
				goto try_again;
			} else
				rc = SLURM_ERROR;
		}
	} else {
		query = xstrdup_printf("update \"%s_%s\" set nodelist='%s', ",
				       mysql_conn->cluster_name,
				       job_table, nodes);

		if (job_ptr->account)
			xstrfmtcat(query, "account='%s', ", job_ptr->account);
		if (partition)
			xstrfmtcat(query, "`partition`='%s', ", partition);
		if (block_id)
			xstrfmtcat(query, "id_block='%s', ", block_id);
		if (job_ptr->wckey)
			xstrfmtcat(query, "wckey='%s', ", job_ptr->wckey);
		if (node_inx)
			xstrfmtcat(query, "node_inx='%s', ", node_inx);
		if (gres_req)
			xstrfmtcat(query, "gres_req='%s', ", gres_req);
		if (gres_alloc)
			xstrfmtcat(query, "gres_alloc='%s', ", gres_alloc);

		xstrfmtcat(query, "time_start=%ld, job_name='%s', state=%u, "
			   "cpus_alloc=%u, nodes_alloc=%u, id_qos=%u, "
			   "id_assoc=%u, id_wckey=%u, id_resv=%u, "
			   "timelimit=%u, mem_req=%u, "
			   "id_array_job=%u, id_array_task=%u, "
			   "time_eligible=%ld where job_db_inx=%d",
			   start_time, jname, job_state,
			   job_ptr->total_cpus, node_cnt, job_ptr->qos_id,
			   job_ptr->assoc_id, wckeyid,
			   job_ptr->resv_id, job_ptr->time_limit,
			   job_ptr->details->pn_min_memory,
			   job_ptr->array_job_id,
			   job_ptr->array_task_id,
			   begin_time, 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(block_id);
	xfree(partition);
	xfree(gres_req);
	xfree(gres_alloc);
	xfree(jname);
	xfree(query);

	/* now we will reset all the steps */
	if (IS_JOB_RESIZING(job_ptr)) {
		/* FIXME : Verify this is still needed */
		if (IS_JOB_SUSPENDED(job_ptr))
			as_mysql_suspend(mysql_conn, job_db_inx, job_ptr);
	}

	return rc;
}
extern int as_mysql_add_federations(mysql_conn_t *mysql_conn, uint32_t uid,
				    List federation_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_federation_rec_t *object = NULL;
	char *cols = NULL, *vals = NULL, *extra = NULL, *query = NULL,
	     *tmp_extra = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	int affect_rows = 0;
	int added = 0;

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

	if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_SUPER_USER))
		return ESLURM_ACCESS_DENIED;

	user_name = uid_to_string((uid_t) uid);

	itr = list_iterator_create(federation_list);
	while ((object = list_next(itr))) {
		if (object->cluster_list &&
		    (list_count(federation_list) > 1)) {
			xfree(user_name);
			error("Clusters can only be assigned to one "
			      "federation");
			errno = ESLURM_FED_CLUSTER_MULTIPLE_ASSIGNMENT;
			return  ESLURM_FED_CLUSTER_MULTIPLE_ASSIGNMENT;
		}

		xstrcat(cols, "creation_time, mod_time, name");
		xstrfmtcat(vals, "%ld, %ld, '%s'", now, now, object->name);
		xstrfmtcat(extra, ", mod_time=%ld", now);

		_setup_federation_rec_limits(object, &cols, &vals, &extra);

		xstrfmtcat(query,
			   "insert into %s (%s) values (%s) "
			   "on duplicate key update deleted=0%s",
			   federation_table, cols, vals, extra);
		if (debug_flags & DEBUG_FLAG_FEDR)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add federation %s", object->name);
			xfree(cols);
			xfree(vals);
			xfree(extra);
			added = 0;
			break;
		}

		affect_rows = last_affected_rows(mysql_conn);
		if (!affect_rows) {
			debug2("nothing changed %d", affect_rows);
			xfree(cols);
			xfree(vals);
			xfree(extra);
			continue;
		}

		if (object->cluster_list &&
		    _assign_clusters_to_federation(mysql_conn, object->name,
						   object->cluster_list)) {
			xfree(cols);
			xfree(vals);
			xfree(extra);
			xfree(user_name);
			return SLURM_ERROR;
		}

		/* Add Transaction */
		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		xstrfmtcat(query,
			   "insert into %s "
			   "(timestamp, action, name, actor, info) "
			   "values (%ld, %u, '%s', '%s', '%s');",
			   txn_table, now, DBD_ADD_FEDERATIONS,
			   object->name, user_name, tmp_extra);
		xfree(cols);
		xfree(vals);
		xfree(tmp_extra);
		xfree(extra);
		debug4("%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) {
			error("Couldn't add txn");
		} else {
			added++;
		}
	}
	list_iterator_destroy(itr);
	xfree(user_name);

	if (!added)
		reset_mysql_conn(mysql_conn);
	else
		as_mysql_add_feds_to_update_list(mysql_conn);

	return rc;
}