Beispiel #1
0
int ftnmsgid(char *msgid, char **s, unsigned int *n, char *areaname)
{
    char	    *buf, *l, *r, *p;
    unsigned int    nid = 0L;
    faddr	    *tmp;
    static int	    ftnorigin = 0;

    Syslog('m', "Make ftn msgid from \"%s\"", MBSE_SS(msgid));

    if (msgid == NULL) {
	*s = NULL;
	*n = 0L;
	return ftnorigin;
    }

    buf = malloc(strlen(msgid)+65);
    strcpy(buf, msgid);
    if ((l = strchr(buf,'<'))) 
	l++;
    else 
	l = buf;
    while (isspace(*l)) 
	l++;
    if ((r = strchr(l,'>'))) 
	*r = '\0';
    r = l + strlen(l) - 1;
    while (isspace(*r) && (r > l)) 
	(*r--)='\0';
    if ((tmp = parsefaddr(l))) {
	if (tmp->name) {
	    if (strspn(tmp->name,"0123456789") == strlen(tmp->name))
		nid = atoul(tmp->name);
	    else 
		nid = 0xffffffff;
	    if (nid == 0xffffffff) {
		hash_update_s(&nid, tmp->name);
	    } else
		ftnorigin = 1;
	} else {
	    hash_update_s(&nid,l);
	}
	*s = xstrcpy(ascfnode(tmp, 0x1f));
	tidy_faddr(tmp);
    } else {
	if ((r=strchr(l,'@')) == NULL) { /* should never happen */
	    Syslog('!', "ftnmsgid: should never happen: %s", printable(l, 0));
	    *s = xstrcpy(l);
	    hash_update_s(&nid,l);
	/* <*****@*****.**> */
	} else if (strncmp(l,"MSGID_",6) == 0) {
	    *r = '\0';
	    r = strrchr(l+6,'_');
            if (r) 
		*r++ = '\0';
            *s = xstrcpy(l+6);
	    if (r) 
		sscanf(r,"%x",&nid);
	    ftnorigin = 1;
	/* <*****@*****.**> */
	} else if (strncmp(l,"NOMSGID_",8) == 0) {
	    *s = NULL;
	    *n = 0L;
	    ftnorigin = 1;
	    return ftnorigin;
	/* <[email protected]> */
	} else if (strncmp(l,"ftn_",4) == 0) {
	    *r = '\0';
	    if ((r = strchr(l+4,'$')) || (r=strchr(l+4,'#'))) {
		if (*r=='$') 
		    *r='@';
		if ((r=strchr(l+4,'.')))
		    *r=':';
		if ((r=strchr(l+4,'.')))
		    *r='/';
	    }
	    while ((r=strrchr(l+4,'_')) != strchr(l+4,'_')) 
		*r='\0';
	    r=strchr(l+4,'_');
	    *r++='\0';
	    *s=xstrcpy(l+4);
	    sscanf(r,"%x",&nid);
	    ftnorigin=1;
	/* <[email protected]> */
	} else if (strncmp(l,"wgcid$",6) == 0) {
	    *r='\0';
	    if ((r=strstr(l+6,"$g"))) {
		*r='\0';
		*s=xstrcpy(l+6);
		*s=xstrcat(*s,(char *)":");
		l=r+2;
	    }
	    if ((r=strstr(l,"$h"))) {
		*r++='\0';
		*s=xstrcat(*s,l);
		*s=xstrcat(*s,(char *)"/");
		l=r+2;
	    }
	    if ((r=strstr(l,"$i"))) {
		*r='\0';
		*s=xstrcat(*s,l);
		*s=xstrcat(*s,(char *)".");
		l=r+2;
	    }
	    if ((r=strstr(l,"$k"))) {
		*r='\0';
		*s=xstrcat(*s,l);
		*s=xstrcat(*s,(char *)"@");
		l=r+2;
	    }
	    if ((r=strstr(l,"$j"))) {
		*r='\0';
		*s=xstrcat(*s,l);
		sscanf(r+2,"%x",&nid);
	    }
	} else {
	    *r='\0';
	    if ((p=strchr(l,'%'))) {
		*p='\0';
		if (strspn(l,"0123456789") == strlen(l)) {
		    *r='@';
		    r=p;
		} else 
		    *p='%';
	    }
	    r++;
	    if (strspn(l,"0123456789") == strlen(l))
		nid = atoul(l);
	    else 
		nid = 0xffffffff;
	    if (nid == 0xffffffff)
		hash_update_s(&nid,l);
	    *s=xstrcpy(r);
	}
    }
    *n=nid;

    free(buf);
    return ftnorigin;
}
Beispiel #2
0
static char *	_will_run_test2(uint32_t jobid, time_t start_time,
				char *node_list,
				uint32_t *preemptee, int preemptee_cnt,
				int *err_code, char **err_msg)
{
	struct job_record *job_ptr = NULL, *pre_ptr;
	struct part_record *part_ptr;
	bitstr_t *avail_bitmap = NULL, *resv_bitmap = NULL;
	time_t start_res;
	uint32_t min_nodes, max_nodes, req_nodes;
	List preemptee_candidates = NULL, preempted_jobs = NULL;
	time_t orig_start_time;
	char *reply_msg = NULL;
	int i, rc;

	xassert(node_list);
	debug2("wiki2: will_run2 job_id=%u start_time=%u node_list=%s",
		jobid, (uint32_t)start_time, node_list);

	job_ptr = find_job_record(jobid);
	if (job_ptr == NULL) {
		*err_code = -700;
		*err_msg = "No such job";
		error("wiki: Failed to find job %u", jobid);
		return NULL;
	}
	if ((job_ptr->details == NULL) || (!IS_JOB_PENDING(job_ptr))) {
		*err_code = -700;
		*err_msg = "WillRun not applicable to non-pending job";
		error("wiki: WillRun on non-pending job %u", jobid);
		return NULL;
	}

	part_ptr = job_ptr->part_ptr;
	if (part_ptr == NULL) {
		*err_code = -700;
		*err_msg = "Job lacks a partition";
		error("wiki: Job %u lacks a partition", jobid);
		return NULL;
	}

	if (node_name2bitmap(node_list, false, &avail_bitmap) != 0) {
		*err_code = -700;
		*err_msg = "Invalid available nodes value";
		error("wiki: Attempt to set invalid available node "
		      "list for job %u, %s", jobid, node_list);
		return NULL;
	}

	/* Enforce reservation: access control, time and nodes */
	start_res = start_time;
	rc = job_test_resv(job_ptr, &start_res, true, &resv_bitmap);
	if (rc != SLURM_SUCCESS) {
		*err_code = -730;
		*err_msg = "Job denied access to reservation";
		error("wiki: reservation access denied for job %u", jobid);
		FREE_NULL_BITMAP(avail_bitmap);
		return NULL;
	}
	start_time = MAX(start_time, start_res);
	bit_and(avail_bitmap, resv_bitmap);
	FREE_NULL_BITMAP(resv_bitmap);

	/* Only consider nodes that are not DOWN or DRAINED */
	bit_and(avail_bitmap, avail_node_bitmap);

	/* Consider only nodes in this job's partition */
	if (part_ptr->node_bitmap)
		bit_and(avail_bitmap, part_ptr->node_bitmap);
	else {
		*err_code = -730;
		*err_msg = "Job's partition has no nodes";
		error("wiki: no nodes in partition %s for job %u",
			part_ptr->name, jobid);
		FREE_NULL_BITMAP(avail_bitmap);
		return NULL;
	}

	if (job_req_node_filter(job_ptr, avail_bitmap) != SLURM_SUCCESS) {
		/* Job probably has invalid feature list */
		*err_code = -730;
		*err_msg = "Job's required features not available "
			   "on selected nodes";
		error("wiki: job %u not runnable on hosts=%s",
			jobid, node_list);
		FREE_NULL_BITMAP(avail_bitmap);
		return NULL;
	}
	if (job_ptr->details->exc_node_bitmap) {
		bit_not(job_ptr->details->exc_node_bitmap);
		bit_and(avail_bitmap, job_ptr->details->exc_node_bitmap);
		bit_not(job_ptr->details->exc_node_bitmap);
	}
	if ((job_ptr->details->req_node_bitmap) &&
	    (!bit_super_set(job_ptr->details->req_node_bitmap,
			    avail_bitmap))) {
		*err_code = -730;
		*err_msg = "Job's required nodes not available";
		error("wiki: job %u not runnable on hosts=%s",
			jobid, node_list);
		FREE_NULL_BITMAP(avail_bitmap);
		return NULL;
	}

	min_nodes = MAX(job_ptr->details->min_nodes, part_ptr->min_nodes);
	if (job_ptr->details->max_nodes == 0)
		max_nodes = part_ptr->max_nodes;
	else
		max_nodes = MIN(job_ptr->details->max_nodes,
				part_ptr->max_nodes);
	max_nodes = MIN(max_nodes, 500000); /* prevent overflows */
	if (job_ptr->details->max_nodes)
		req_nodes = max_nodes;
	else
		req_nodes = min_nodes;
	if (min_nodes > max_nodes) {
		/* job's min_nodes exceeds partitions max_nodes */
		*err_code = -730;
		*err_msg = "Job's min_nodes > max_nodes";
		error("wiki: job %u not runnable on hosts=%s",
			jobid, node_list);
		FREE_NULL_BITMAP(avail_bitmap);
		return NULL;
	}

	if (preemptee_cnt) {
		preemptee_candidates = list_create(NULL);
		for (i=0; i<preemptee_cnt; i++) {
			if ((pre_ptr = find_job_record(preemptee[i])))
				list_append(preemptee_candidates, pre_ptr);
		}
	}

	orig_start_time = job_ptr->start_time;
	rc = select_g_job_test(job_ptr, avail_bitmap, min_nodes, max_nodes,
			       req_nodes, SELECT_MODE_WILL_RUN,
			       preemptee_candidates, &preempted_jobs);
	if (preemptee_candidates)
		list_destroy(preemptee_candidates);

	if (rc == SLURM_SUCCESS) {
		char *hostlist, *sep, tmp_str[128];
		uint32_t pre_cnt = 0, proc_cnt = 0;

#ifdef HAVE_BG
		select_g_select_jobinfo_get(job_ptr->select_jobinfo,
				     SELECT_JOBDATA_NODE_CNT, &proc_cnt);
#else
		proc_cnt = job_ptr->total_cpus;
#endif
		snprintf(tmp_str, sizeof(tmp_str),
			 "STARTINFO=%u TASKS=%u STARTTIME=%u NODES=",
			 job_ptr->job_id, proc_cnt,
			 (uint32_t) job_ptr->start_time);
		xstrcat(reply_msg, tmp_str);
		hostlist = bitmap2node_name(avail_bitmap);
		xstrcat(reply_msg, hostlist);
		xfree(hostlist);

		if (preempted_jobs) {
			while ((pre_ptr = list_pop(preempted_jobs))) {
				if (pre_cnt++)
					sep = ",";
				else
					sep = " PREEMPT=";
				snprintf(tmp_str, sizeof(tmp_str), "%s%u",
					 sep, pre_ptr->job_id);
				xstrcat(reply_msg, tmp_str);
			}
			list_destroy(preempted_jobs);
		}
	} else {
		xstrcat(reply_msg, "Jobs not runable on selected nodes");
		error("wiki: jobs not runnable on nodes");
	}

	/* Restore pending job's expected start time */
	job_ptr->start_time = orig_start_time;

	FREE_NULL_BITMAP(avail_bitmap);
	return reply_msg;
}
Beispiel #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 (!xstrcmp(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;
}
Beispiel #4
0
extern List as_mysql_remove_accts(mysql_conn_t *mysql_conn, uint32_t uid,
				  slurmdb_account_cond_t *acct_cond)
{
	ListIterator itr = NULL;
	List ret_list = NULL;
	List coord_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;
	bool jobs_running = 0;

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

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

	xstrcat(extra, "where deleted=0");
	if (acct_cond->assoc_cond
	    && acct_cond->assoc_cond->acct_list
	    && list_count(acct_cond->assoc_cond->acct_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->assoc_cond->acct_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 (acct_cond->description_list
	    && list_count(acct_cond->description_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_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 (acct_cond->organization_list
	    && list_count(acct_cond->organization_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->organization_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "organization='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

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

	query = xstrdup_printf("select name from %s %s;", acct_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);
	while ((row = mysql_fetch_row(result))) {
		char *object = xstrdup(row[0]);
		list_append(ret_list, object);
		if (!rc) {
			xstrfmtcat(name_char, "name='%s'", object);
			xstrfmtcat(assoc_char, "t2.acct='%s'", object);
			rc = 1;
		} else  {
			xstrfmtcat(name_char, " || name='%s'", object);
			xstrfmtcat(assoc_char, " || t2.acct='%s'", object);
		}
	}
	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);

	/* We need to remove these accounts from the coord's that have it */
	coord_list = as_mysql_remove_coord(
		mysql_conn, uid, ret_list, NULL);
	if (coord_list)
		list_destroy(coord_list);

	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_ACCOUNTS, now,
					user_name, acct_table, name_char,
					assoc_char, object, ret_list,
					&jobs_running))
		    != SLURM_SUCCESS)
			break;
	}
	list_iterator_destroy(itr);
	slurm_mutex_unlock(&as_mysql_cluster_list_lock);

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

	if (jobs_running)
		errno = ESLURM_JOBS_RUNNING_ON_ASSOC;
	else
		errno = SLURM_SUCCESS;
	return ret_list;
}
Beispiel #5
0
extern List as_mysql_get_accts(mysql_conn_t *mysql_conn, uid_t uid,
			       slurmdb_account_cond_t *acct_cond)
{
	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	List acct_list = NULL;
	ListIterator itr = NULL;
	char *object = NULL;
	int set = 0;
	int i=0, is_admin=1;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	uint16_t private_data = 0;
	slurmdb_user_rec_t user;

	/* if this changes you will need to edit the corresponding enum */
	char *acct_req_inx[] = {
		"name",
		"description",
		"organization"
	};
	enum {
		SLURMDB_REQ_NAME,
		SLURMDB_REQ_DESC,
		SLURMDB_REQ_ORG,
		SLURMDB_REQ_COUNT
	};

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

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

	private_data = slurm_get_private_data();

	if (private_data & PRIVATE_DATA_ACCOUNTS) {
		if (!(is_admin = is_user_min_admin_level(
			      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
			if (!is_user_any_coord(mysql_conn, &user)) {
				error("Only admins/coordinators "
				      "can look at account usage");
				errno = ESLURM_ACCESS_DENIED;
				return NULL;
			}
		}
	}

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

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

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

	if (acct_cond->description_list
	    && list_count(acct_cond->description_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_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 (acct_cond->organization_list
	    && list_count(acct_cond->organization_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->organization_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "organization='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

empty:

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

	/* This is here to make sure we are looking at only this user
	 * if this flag is set.  We also include any accounts they may be
	 * coordinator of.
	 */
	if (!is_admin && (private_data & PRIVATE_DATA_ACCOUNTS)) {
		slurmdb_coord_rec_t *coord = NULL;
		set = 0;
		itr = list_iterator_create(user.coord_accts);
		while ((coord = list_next(itr))) {
			if (set) {
				xstrfmtcat(extra, " || name='%s'",
					   coord->name);
			} else {
				set = 1;
				xstrfmtcat(extra, " && (name='%s'",
					   coord->name);
			}
		}
		list_iterator_destroy(itr);
		if (set)
			xstrcat(extra,")");
	}

	query = xstrdup_printf("select %s from %s %s", tmp, acct_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);

	acct_list = list_create(slurmdb_destroy_account_rec);

	if (acct_cond && acct_cond->assoc_cond && acct_cond->with_assocs) {
		/* We are going to be freeing the inners of
		   this list in the acct->name so we don't
		   free it here
		*/
		if (acct_cond->assoc_cond->acct_list)
			list_destroy(acct_cond->assoc_cond->acct_list);
		acct_cond->assoc_cond->acct_list = list_create(NULL);
		acct_cond->assoc_cond->with_deleted = acct_cond->with_deleted;
	}

	while ((row = mysql_fetch_row(result))) {
		slurmdb_account_rec_t *acct =
			xmalloc(sizeof(slurmdb_account_rec_t));
		list_append(acct_list, acct);

		acct->name =  xstrdup(row[SLURMDB_REQ_NAME]);
		acct->description = xstrdup(row[SLURMDB_REQ_DESC]);
		acct->organization = xstrdup(row[SLURMDB_REQ_ORG]);

		if (acct_cond && acct_cond->with_coords) {
			_get_account_coords(mysql_conn, acct);
		}

		if (acct_cond && acct_cond->with_assocs) {
			if (!acct_cond->assoc_cond) {
				acct_cond->assoc_cond = xmalloc(
					sizeof(slurmdb_association_cond_t));
			}

			list_append(acct_cond->assoc_cond->acct_list,
				    acct->name);
		}
	}
	mysql_free_result(result);

	if (acct_cond && acct_cond->with_assocs && acct_cond->assoc_cond
	    && list_count(acct_cond->assoc_cond->acct_list)) {
		ListIterator assoc_itr = NULL;
		slurmdb_account_rec_t *acct = NULL;
		slurmdb_association_rec_t *assoc = NULL;
		List assoc_list = as_mysql_get_assocs(
			mysql_conn, uid, acct_cond->assoc_cond);

		if (!assoc_list) {
			error("no associations");
			return acct_list;
		}

		itr = list_iterator_create(acct_list);
		assoc_itr = list_iterator_create(assoc_list);
		while ((acct = list_next(itr))) {
			while ((assoc = list_next(assoc_itr))) {
				if (strcmp(assoc->acct, acct->name))
					continue;

				if (!acct->assoc_list)
					acct->assoc_list = list_create(
						slurmdb_destroy_association_rec);
				list_append(acct->assoc_list, assoc);
				list_remove(assoc_itr);
			}
			list_iterator_reset(assoc_itr);
			if (!acct->assoc_list)
				list_remove(itr);
		}
		list_iterator_destroy(itr);
		list_iterator_destroy(assoc_itr);

		list_destroy(assoc_list);
	}

	return acct_list;
}
Beispiel #6
0
extern List as_mysql_remove_users(mysql_conn_t *mysql_conn, uint32_t uid,
				  slurmdb_user_cond_t *user_cond)
{
	ListIterator itr = NULL;
	List ret_list = NULL;
	List coord_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;
	slurmdb_user_cond_t user_coord_cond;
	slurmdb_assoc_cond_t assoc_cond;
	slurmdb_wckey_cond_t wckey_cond;
	bool jobs_running = 0;

	if (!user_cond) {
		error("we need something to remove");
		return NULL;
	}

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

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

	if (user_cond->assoc_cond && user_cond->assoc_cond->user_list
	    && list_count(user_cond->assoc_cond->user_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(user_cond->assoc_cond->user_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, ")");
	}

	ret_list = _get_other_user_names_to_mod(mysql_conn, uid, user_cond);

	if (user_cond->admin_level != SLURMDB_ADMIN_NOTSET) {
		xstrfmtcat(extra, " && admin_level=%u", user_cond->admin_level);
	}

	if (!extra && !ret_list) {
		error("Nothing to remove");
		return NULL;
	} else if (!extra) {
		/* means we got a ret_list and don't need to look at
		   the user_table. */
		goto no_user_table;
	}

	/* Only handle this if we need to actually query the
	   user_table.  If a request comes in stating they want to
	   remove all users with default account of whatever then that
	   doesn't deal with the user_table.
	*/
	query = xstrdup_printf("select name from %s where deleted=0 %s;",
			       user_table, extra);
	xfree(extra);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}

	if (!ret_list)
		ret_list = list_create(slurm_destroy_char);
	while ((row = mysql_fetch_row(result)))
		slurm_addto_char_list(ret_list, row[0]);
	mysql_free_result(result);

no_user_table:

	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(query);
		return ret_list;
	}
	xfree(query);

	memset(&user_coord_cond, 0, sizeof(slurmdb_user_cond_t));
	memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
	/* we do not need to free the objects we put in here since
	   they are also placed in a list that will be freed
	*/
	assoc_cond.user_list = list_create(NULL);
	user_coord_cond.assoc_cond = &assoc_cond;

	itr = list_iterator_create(ret_list);
	while ((object = list_next(itr))) {
		slurmdb_user_rec_t *user_rec =
			xmalloc(sizeof(slurmdb_user_rec_t));
		list_append(assoc_cond.user_list, object);

		if (name_char) {
			xstrfmtcat(name_char, " || name='%s'", object);
			xstrfmtcat(assoc_char, " || t2.user='******'", object);
		} else {
			xstrfmtcat(name_char, "name='%s'", object);
			xstrfmtcat(assoc_char, "t2.user='******'", object);
		}

		user_rec->name = xstrdup(object);
		if (addto_update_list(mysql_conn->update_list,
				      SLURMDB_REMOVE_USER, user_rec)
		    != SLURM_SUCCESS)
			slurmdb_destroy_user_rec(user_rec);
	}
	list_iterator_destroy(itr);

	/* We need to remove these accounts from the coord's that have it */
	coord_list = as_mysql_remove_coord(
		mysql_conn, uid, NULL, &user_coord_cond);
	FREE_NULL_LIST(coord_list);

	/* We need to remove these users from the wckey table */
	memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t));
	wckey_cond.user_list = assoc_cond.user_list;
	coord_list = as_mysql_remove_wckeys(mysql_conn, uid, &wckey_cond);
	FREE_NULL_LIST(coord_list);

	FREE_NULL_LIST(assoc_cond.user_list);

	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_USERS, now,
					user_name, user_table, name_char,
					assoc_char, object, ret_list,
					&jobs_running))
		    != SLURM_SUCCESS)
			break;
	}
	list_iterator_destroy(itr);
	slurm_mutex_unlock(&as_mysql_cluster_list_lock);

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

	query = xstrdup_printf(
		"update %s as t2 set deleted=1, mod_time=%ld where %s",
		acct_coord_table, (long)now, assoc_char);
	xfree(assoc_char);

	rc = mysql_db_query(mysql_conn, query);
	xfree(query);
	if (rc != SLURM_SUCCESS) {
		error("Couldn't remove user coordinators");
		FREE_NULL_LIST(ret_list);
		return NULL;
	}

	if (jobs_running)
		errno = ESLURM_JOBS_RUNNING_ON_ASSOC;
	else
		errno = SLURM_SUCCESS;
	return ret_list;
}
Beispiel #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_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);
		debug3("%d(%s:%d) query\n%s",
		       mysql_conn->conn, THIS_FILE, __LINE__, 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);
/* 		debug3("affected %d", affect_rows); */

		if (!affect_rows) {
			debug3("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;
}
Beispiel #8
0
/*
 * slurm_print_burst_buffer_record - output information about a specific Slurm
 *	burst_buffer record based upon message as loaded using
 *	slurm_load_burst_buffer_info()
 * IN out - file to write to
 * IN burst_buffer_ptr - an individual burst buffer record pointer
 * IN one_liner - print as a single line if not zero
 * IN verbose - higher values to log additional details
 * RET out - char * containing formatted output (must be freed after call)
 *	   NULL is returned on failure.
 */
extern void slurm_print_burst_buffer_record(FILE *out,
		burst_buffer_info_t *burst_buffer_ptr, int one_liner,
		int verbose)
{
	char tmp_line[512];
	char g_sz_buf[32],t_sz_buf[32], u_sz_buf[32];
	char *out_buf = NULL;
	burst_buffer_resv_t *bb_resv_ptr;
	burst_buffer_use_t  *bb_use_ptr;
	bool has_acl = false;
	int i;

	/****** Line ******/
	_get_size_str(g_sz_buf, sizeof(g_sz_buf),
		      burst_buffer_ptr->granularity);
	_get_size_str(t_sz_buf, sizeof(t_sz_buf),
		      burst_buffer_ptr->total_space);
	_get_size_str(u_sz_buf, sizeof(u_sz_buf),
		      burst_buffer_ptr->used_space);
	snprintf(tmp_line, sizeof(tmp_line),
		 "Name=%s DefaultPool=%s Granularity=%s TotalSpace=%s "
		 "UsedSpace=%s",
		 burst_buffer_ptr->name, burst_buffer_ptr->default_pool,
		 g_sz_buf, t_sz_buf, u_sz_buf);
	xstrcat(out_buf, tmp_line);
	if (!one_liner)
		xstrcat(out_buf, "\n");

	/****** Line (optional) ******/
	/* Alternate pool information */
	for (i = 0; i < burst_buffer_ptr->pool_cnt; i++) {
		_get_size_str(g_sz_buf, sizeof(g_sz_buf),
			      burst_buffer_ptr->pool_ptr[i].granularity);
		_get_size_str(t_sz_buf, sizeof(t_sz_buf),
			      burst_buffer_ptr->pool_ptr[i].total_space);
		_get_size_str(u_sz_buf, sizeof(u_sz_buf),
			      burst_buffer_ptr->pool_ptr[i].used_space);
		snprintf(tmp_line, sizeof(tmp_line),
			 "  AltPoolName[%d]=%s Granularity=%s TotalSpace=%s "
			 "UsedSpace=%s",
			 i, burst_buffer_ptr->pool_ptr[i].name,
			 g_sz_buf, t_sz_buf, u_sz_buf);
		xstrcat(out_buf, tmp_line);
		if (!one_liner)
			xstrcat(out_buf, "\n");
	}

	/****** Line ******/
	snprintf(tmp_line, sizeof(tmp_line),
		"  Flags=%s",
		slurm_bb_flags2str(burst_buffer_ptr->flags));
	xstrcat(out_buf, tmp_line);
	if (!one_liner)
		xstrcat(out_buf, "\n");

	/****** Line ******/
	snprintf(tmp_line, sizeof(tmp_line),
		"  StageInTimeout=%u StageOutTimeout=%u ValidateTimeout=%u "
		"OtherTimeout=%u",
		burst_buffer_ptr->stage_in_timeout,
		burst_buffer_ptr->stage_out_timeout,
		burst_buffer_ptr->validate_timeout,
		burst_buffer_ptr->other_timeout);
	xstrcat(out_buf, tmp_line);
	if (!one_liner)
		xstrcat(out_buf, "\n");

	/****** Line (optional) ******/
	if (burst_buffer_ptr->allow_users) {
		snprintf(tmp_line, sizeof(tmp_line),
			"  AllowUsers=%s", burst_buffer_ptr->allow_users);
		xstrcat(out_buf, tmp_line);
		has_acl = true;
	} else if (burst_buffer_ptr->deny_users) {
		snprintf(tmp_line, sizeof(tmp_line),
			"  DenyUsers=%s", burst_buffer_ptr->deny_users);
		xstrcat(out_buf, tmp_line);
		has_acl = true;
	}
	if (has_acl && !one_liner)
		xstrcat(out_buf, "\n");

	/****** Line (optional) ******/
	if (burst_buffer_ptr->create_buffer) {
		snprintf(tmp_line, sizeof(tmp_line),
			"  CreateBuffer=%s", burst_buffer_ptr->create_buffer);
		xstrcat(out_buf, tmp_line);
		if (!one_liner)
			xstrcat(out_buf, "\n");
	}

	/****** Line (optional) ******/
	if (burst_buffer_ptr->destroy_buffer) {
		snprintf(tmp_line, sizeof(tmp_line),
			"  DestroyBuffer=%s", burst_buffer_ptr->destroy_buffer);
		xstrcat(out_buf, tmp_line);
		if (!one_liner)
			xstrcat(out_buf, "\n");
	}

	/****** Line ******/
	snprintf(tmp_line, sizeof(tmp_line),
		"  GetSysState=%s", burst_buffer_ptr->get_sys_state);
	xstrcat(out_buf, tmp_line);
	if (!one_liner)
		xstrcat(out_buf, "\n");

	/****** Line (optional) ******/
	if (burst_buffer_ptr->start_stage_in) {
		snprintf(tmp_line, sizeof(tmp_line),
			"  StartStageIn=%s", burst_buffer_ptr->start_stage_in);
		xstrcat(out_buf, tmp_line);
		if (!one_liner)
			xstrcat(out_buf, "\n");
	}

	/****** Line ******/
	if (burst_buffer_ptr->start_stage_out) {
		snprintf(tmp_line, sizeof(tmp_line),
			"  StartStageIn=%s", burst_buffer_ptr->start_stage_out);
		xstrcat(out_buf, tmp_line);
		if (!one_liner)
			xstrcat(out_buf, "\n");
	}

	/****** Line (optional) ******/
	if (burst_buffer_ptr->stop_stage_in) {
		snprintf(tmp_line, sizeof(tmp_line),
			"  StopStageIn=%s", burst_buffer_ptr->stop_stage_in);
		xstrcat(out_buf, tmp_line);
		if (!one_liner)
			xstrcat(out_buf, "\n");
	}

	/****** Line (optional) ******/
	if (burst_buffer_ptr->stop_stage_out) {
		snprintf(tmp_line, sizeof(tmp_line),
			"  StopStageIn=%s", burst_buffer_ptr->stop_stage_out);
		xstrcat(out_buf, tmp_line);
		if (!one_liner)
			xstrcat(out_buf, "\n");
	}

	if (one_liner)
		xstrcat(out_buf, "\n");
	fprintf(out, "%s", out_buf);
	xfree(out_buf);

	/****** Lines (optional) ******/
	if (burst_buffer_ptr->buffer_count)
		fprintf(out, "  Allocated Buffers:\n");
	for (i = 0, bb_resv_ptr = burst_buffer_ptr->burst_buffer_resv_ptr;
	     i < burst_buffer_ptr->buffer_count; i++, bb_resv_ptr++) {
		 _print_burst_buffer_resv(out, bb_resv_ptr, one_liner, verbose);
	}

	/****** Lines (optional) ******/
	if (burst_buffer_ptr->use_count)
		fprintf(out, "  Per User Buffer Use:\n");
	for (i = 0, bb_use_ptr = burst_buffer_ptr->burst_buffer_use_ptr;
	     i < burst_buffer_ptr->use_count; i++, bb_use_ptr++) {
		 _print_burst_buffer_use(out, bb_use_ptr, one_liner);
	}
}
Beispiel #9
0
int get_xover(char *grpname, int startnr, int endnr, List **art)
{
    char	    cmd[81], *ptr, *ptr2, *resp, *p;
    int		    retval, dupe, done = FALSE;
    int		    nr;
    unsigned int    crc;
    POverview	    pov;

    snprintf(cmd, 81, "XOVER %d-%d\r\n", startnr, endnr);
    if ((retval = nntp_cmd(cmd, 224))) {
        switch (retval) {
        case 412:
            WriteError("No newsgroup selected");
            return RETVAL_NOXOVER;
        case 502:
            WriteError("Permission denied");
            return RETVAL_NOXOVER;
        case 420:
            Syslog('m', "No articles in group %s", grpname);
            return RETVAL_OK;
        }
    }

    while (done == FALSE) {
        resp = nntp_receive();
        if ((strlen(resp) == 1) && (strcmp(resp, ".") == 0)) {
            done = TRUE;
        } else {
            Marker();
            Nopper();
            pov = xoverview;
            ptr = resp;
            ptr2 = ptr;

            /*
             * First item is the message number.
             */
            while (*ptr2 != '\0' && *ptr2 != '\t')
                ptr2++;
            if (*ptr2 != '\0')
                *(ptr2) = '\0';
            nr = atol(ptr);
            ptr = ptr2;
            ptr++;

            /*
             * Search the message-id
             */
            while (*ptr != '\0' && pov != NULL && strcmp(pov->header, "Message-ID:") != 0) {
                /*
                 * goto the next field, past the tab.
                 */
                pov = pov->next;

                while (*ptr != '\t' && *ptr != '\0')
                    ptr++;
                if (*ptr != '\0')
                    ptr++;
            }
            if (*ptr != '\0' && pov != NULL) {
                /*
                 * Found it, now find start of msgid
                 */
                while (*ptr != '\0' && *ptr != '<')
                    ptr++;
                if(ptr != '\0') {
                    ptr2 = ptr;
                    while(*ptr2 != '\0' && *ptr2 != '>')
                        ptr2++;
                    if (*ptr2 != '\0') {
                        *(ptr2+1) = '\0';
                        p = xstrcpy(ptr);
                        p = xstrcat(p, grpname);
                        crc = str_crc32(p);
                        dupe = CheckDupe(crc, D_NEWS, CFG.nntpdupes);
                        fill_artlist(art, ptr, nr, dupe);
                        free(p);
                        if (CFG.slow_util && do_quiet)
                            msleep(1);
                    }
                }
            }
        }
    }

    return RETVAL_OK;
}
/*
 * get_jobs - get information on specific job(s) changed since some time
 * cmd_ptr IN   - CMD=GETJOBS ARG=[<UPDATETIME>:<JOBID>[:<JOBID>]...]
 *                              [<UPDATETIME>:ALL]
 * err_code OUT - 0 or an error code
 * err_msg OUT  - response message
 * NOTE: xfree() err_msg if err_code is zero
 * RET 0 on success, -1 on failure
 *
 * Response format
 * ARG=<cnt>#<JOBID>;
 *	STATE=<state>;			Moab equivalent job state
 *	[EXITCODE=<number>;]		Job exit code, if completed
 *	[RFEATURES=<features>;]		required features, if any,
 *					NOTE: OR operator not supported
 *	[HOSTLIST=<node1:node2>;]	list of required nodes, if any
 *	[EXCLUDE_HOSTLIST=<node1:node2>;list of excluded nodes, if any
 *	[STARTDATE=<uts>;]		earliest start time, if any
 *	[MAXNODES=<nodes>;]		maximum number of nodes, 0 if no limit
 *	[TASKLIST=<node1:node2>;]	nodes in use, if running or completing
 *	[REJMESSAGE=<str>;]		reason job is not running, if any
 *	[IWD=<directory>;]		Initial Working Directory
 *	[FLAGS=INTERACTIVE;]		set if interactive (not batch) job
 *	[GRES=<name>[:<count>[*cpus]],...;] generic resources required by the
 *					job on a per node basis
 *	[WCKEY=<key>;]			workload characterization key for job
 *	UPDATETIME=<uts>;		time last active
 *	WCLIMIT=<secs>;			wall clock time limit, seconds
 *	TASKS=<cpus>;			CPUs required
 *	NODES=<nodes>;			count of nodes required or allocated
 *	DPROCS=<cpus_per_task>;		count of CPUs required per task
 *	QUEUETIME=<uts>;		submission time
 *	STARTTIME=<uts>;		time execution started
 *	RCLASS=<partition>;		SLURM partition name
 *	RMEM=<MB>;			MB of memory required
 *	RDISK=<MB>;			MB of disk space required
 *	[COMMENT=<whatever>;]		job dependency or account number
 *	[COMPLETETIME=<uts>;]		termination time
 *	[SUSPENDTIME=<secs>;]		seconds that job has been suspended
 *	UNAME=<user_name>;		user name
 *	GNAME=<group_name>;		group name
 *	NAME=<job_name>;		job name
 * [#<JOBID>;...];			additional jobs, if any
 *
 */
extern int	get_jobs(char *cmd_ptr, int *err_code, char **err_msg)
{
	char *arg_ptr = NULL, *tmp_char = NULL, *tmp_buf = NULL, *buf = NULL;
	time_t update_time;
	/* Locks: read job, partition */
	slurmctld_lock_t job_read_lock = {
		NO_LOCK, READ_LOCK, NO_LOCK, READ_LOCK, NO_LOCK };
	int job_rec_cnt = 0, buf_size = 0;

	if (cr_test == 0) {
		select_g_get_info_from_plugin(SELECT_CR_PLUGIN, NULL,
					      &cr_enabled);
		cr_test = 1;
	}

	arg_ptr = strstr(cmd_ptr, "ARG=");
	if (arg_ptr == NULL) {
		*err_code = -300;
		*err_msg = "GETJOBS lacks ARG";
		error("wiki: GETJOBS lacks ARG");
		return -1;
	}
	update_time = (time_t) strtoul(arg_ptr+4, &tmp_char, 10);
	if (tmp_char[0] != ':') {
		*err_code = -300;
		*err_msg = "Invalid ARG value";
		error("wiki: GETJOBS has invalid ARG value");
		return -1;
	}
	if (job_list == NULL) {
		*err_code = -140;
		*err_msg = "Still performing initialization";
		error("wiki: job_list not yet initilized");
		return -1;
	}
	tmp_char++;
	lock_slurmctld(job_read_lock);
	if (xstrncmp(tmp_char, "ALL", 3) == 0) {
		/* report all jobs */
		buf = _dump_all_jobs(&job_rec_cnt, update_time);
	} else {
		struct job_record *job_ptr = NULL;
		char *job_name = NULL, *tmp2_char = NULL;
		uint32_t job_id;

		job_name = strtok_r(tmp_char, ":", &tmp2_char);
		while (job_name) {
			job_id = (uint32_t) strtoul(job_name, NULL, 10);
			job_ptr = find_job_record(job_id);
			tmp_buf = _dump_job(job_ptr, update_time);
			if (job_rec_cnt > 0)
				xstrcat(buf, "#");
			xstrcat(buf, tmp_buf);
			xfree(tmp_buf);
			job_rec_cnt++;
			job_name = strtok_r(NULL, ":", &tmp2_char);
		}
	}
	unlock_slurmctld(job_read_lock);

	/* Prepend ("ARG=%d", job_rec_cnt) to reply message */
	if (buf)
		buf_size = strlen(buf);
	tmp_buf = xmalloc(buf_size + 32);
	if (job_rec_cnt)
		sprintf(tmp_buf, "SC=0 ARG=%d#%s", job_rec_cnt, buf);
	else
		sprintf(tmp_buf, "SC=0 ARG=0#");
	xfree(buf);
	*err_code = 0;
	*err_msg = tmp_buf;
	return 0;
}
static char *	_dump_job(struct job_record *job_ptr, time_t update_time)
{
	char *buf = NULL, tmp[16384];
	char *gname, *pname, *quote, *uname;
	uint32_t end_time, suspend_time;
	uint64_t min_mem;
	int i, rej_sent = 0;

	if (!job_ptr)
		return NULL;

	snprintf(tmp, sizeof(tmp), "%u:STATE=%s;",
		job_ptr->job_id, _get_job_state(job_ptr));
	xstrcat(buf, tmp);

	if (update_time > last_job_update)
		return buf;

	if (IS_JOB_PENDING(job_ptr)) {
		char *req_features = _get_job_features(job_ptr);
		if (req_features) {
			snprintf(tmp, sizeof(tmp),
				"RFEATURES=%s;", req_features);
			xstrcat(buf, tmp);
			xfree(req_features);
		}
		if ((job_ptr->details) &&
		    (job_ptr->details->req_nodes) &&
		    (job_ptr->details->req_nodes[0])) {
			char *hosts = bitmap2wiki_node_name(
				job_ptr->details->req_node_bitmap);
			snprintf(tmp, sizeof(tmp),
				"HOSTLIST=%s;", hosts);
			xstrcat(buf, tmp);
			xfree(hosts);
		}
		if ((job_ptr->details) &&
		    (job_ptr->details->exc_nodes) &&
		    (job_ptr->details->exc_nodes[0])) {
			char *hosts = bitmap2wiki_node_name(
				job_ptr->details->exc_node_bitmap);
			snprintf(tmp, sizeof(tmp),
				"EXCLUDE_HOSTLIST=%s;", hosts);
			xstrcat(buf, tmp);
			xfree(hosts);
		}
		if ((job_ptr->details) && (job_ptr->details->begin_time)) {
			snprintf(tmp, sizeof(tmp),
				"STARTDATE=%u;", (uint32_t)
				job_ptr->details->begin_time);
			xstrcat(buf, tmp);
		}
		if (job_ptr->details) {
			snprintf(tmp, sizeof(tmp),
				 "MAXNODES=%u;", _get_job_max_nodes(job_ptr));
			xstrcat(buf, tmp);
		}
	} else if (!IS_JOB_FINISHED(job_ptr)) {
		char *hosts;
		hosts = slurm_job2moab_task_list(job_ptr);
		xstrcat(buf, "TASKLIST=");
		xstrcat(buf, hosts);
		xstrcat(buf, ";");
		xfree(hosts);
	}

	if (reject_msg_cnt) {
		/* Possible job requeue/reject message */
		for (i=0; i<REJECT_MSG_MAX; i++) {
			if (reject_msgs[i].job_id != job_ptr->job_id)
				continue;
			snprintf(tmp, sizeof(tmp),
				"REJMESSAGE=\"%s\";",
				reject_msgs[i].reason);
			xstrcat(buf, tmp);
			reject_msgs[i].job_id = 0;
			reject_msg_cnt--;
			rej_sent = 1;
			break;
		}
	}
	if ((rej_sent == 0) && IS_JOB_FAILED(job_ptr)) {
		snprintf(tmp, sizeof(tmp),
			"REJMESSAGE=\"%s\";",
			job_reason_string(job_ptr->state_reason));
		xstrcat(buf, tmp);
	}

	if (!IS_JOB_FINISHED(job_ptr) && job_ptr->details &&
	    job_ptr->details->work_dir) {
		if ((quote = strchr(job_ptr->details->work_dir, (int) '\"'))) {
			/* Moab does not like strings containing a quote */
			*quote = '\0';
			snprintf(tmp, sizeof(tmp), "IWD=\"%s\";",
				 job_ptr->details->work_dir);
			*quote = '\"';
		} else {
			snprintf(tmp, sizeof(tmp), "IWD=\"%s\";",
				 job_ptr->details->work_dir);
		}
		xstrcat(buf, tmp);
	}

	if (job_ptr->batch_flag == 0)
		xstrcat(buf, "FLAGS=INTERACTIVE;");

	if (job_ptr->gres) {
		snprintf(tmp, sizeof(tmp),"GRES=\"%s\";", job_ptr->gres);
		xstrcat(buf, tmp);
	}

	if (job_ptr->resp_host) {
		snprintf(tmp, sizeof(tmp),"SUBMITHOST=\"%s\";", job_ptr->resp_host);
		xstrcat(buf, tmp);
	}

	if (job_ptr->wckey) {
		if ((quote = strchr(job_ptr->wckey, (int) '\"'))) {
			/* Moab does not like strings containing a quote */
			*quote = '\0';
			snprintf(tmp, sizeof(tmp),
				"WCKEY=\"%s\";", job_ptr->wckey);
			*quote = '\"';
			xstrcat(buf, tmp);
		} else {
			snprintf(tmp, sizeof(tmp),
				"WCKEY=\"%s\";", job_ptr->wckey);
		}
		xstrcat(buf, tmp);
	}

	snprintf(tmp, sizeof(tmp),
		"UPDATETIME=%u;WCLIMIT=%u;TASKS=%u;",
		(uint32_t) job_ptr->time_last_active,
		(uint32_t) _get_job_time_limit(job_ptr),
		_get_job_tasks(job_ptr));
	xstrcat(buf, tmp);

	if (!IS_JOB_FINISHED(job_ptr)) {
		snprintf(tmp, sizeof(tmp),
			"NODES=%u;",
			_get_pn_min_nodes(job_ptr));
		xstrcat(buf, tmp);
	}

	snprintf(tmp, sizeof(tmp),
		"DPROCS=%u;",
		_get_job_cpus_per_task(job_ptr));
	xstrcat(buf, tmp);

	if (job_ptr->part_ptr)
		pname = job_ptr->part_ptr->name;
	else
		pname = "UNKNOWN";	/* should never see this */
	snprintf(tmp, sizeof(tmp),
		"QUEUETIME=%u;STARTTIME=%u;RCLASS=\"%s\";",
		_get_job_submit_time(job_ptr),
		(uint32_t) job_ptr->start_time, pname);
	xstrcat(buf, tmp);

	min_mem = _get_pn_min_mem(job_ptr);
	if (min_mem & MEM_PER_CPU) {
		min_mem &= ~MEM_PER_CPU;
	}
	snprintf(tmp, sizeof(tmp),
		"RMEM=%"PRIu64";RDISK=%u;",
		 min_mem,
		_get_pn_min_disk(job_ptr));
	xstrcat(buf, tmp);

	_get_job_comment(job_ptr, tmp, sizeof(tmp));
	xstrcat(buf, tmp);

	end_time = _get_job_end_time(job_ptr);
	if (end_time) {
		snprintf(tmp, sizeof(tmp),
			"COMPLETETIME=%u;", end_time);
		xstrcat(buf, tmp);
	}

	suspend_time = _get_job_suspend_time(job_ptr);
	if (suspend_time) {
		snprintf(tmp, sizeof(tmp),
			"SUSPENDTIME=%u;", suspend_time);
		xstrcat(buf, tmp);
	}

	if (job_ptr->account) {
		snprintf(tmp, sizeof(tmp),
			"ACCOUNT=\"%s\";", job_ptr->account);
		xstrcat(buf, tmp);
	}

	if (job_ptr->name && (quote = strchr(job_ptr->name, (int) '\"'))) {
		/* Moab does not like job names containing a quote */
		*quote = '\0';
		snprintf(tmp, sizeof(tmp),
			"NAME=\"%s\";", job_ptr->name);
		*quote = '\"';
	} else {
		snprintf(tmp, sizeof(tmp),
			"NAME=\"%s\";", job_ptr->name);
	}
	xstrcat(buf, tmp);

	if (job_ptr->details &&
	    (update_time > job_ptr->details->submit_time))
		return buf;

	uname = uid_to_string((uid_t) job_ptr->user_id);
	gname = gid_to_string(job_ptr->group_id);
	snprintf(tmp, sizeof(tmp),
		"UNAME=%s;GNAME=%s;", uname, gname);
	xstrcat(buf, tmp);
	xfree(uname);
	xfree(gname);

	return buf;
}
Beispiel #12
0
/*
 * parse_format - Take the user's format specification and use it to build
 *	build the format specifications (internalize it to print.c data
 *	structures)
 * IN format - user's format specification
 * RET zero or error code
 */
extern int parse_format( char* format )
{
	int field_size;
	bool right_justify;
	char *prefix = NULL, *suffix = NULL, *token = NULL;
	char *tmp_char = NULL, *tmp_format = NULL;
	char field[1];

	if (format == NULL) {
		error ("Format option lacks specification.");
		exit( 1 );
	}

	params.format_list = list_create( NULL );
	if ((prefix = _get_prefix(format))) {
		if (params.step_flag)
			step_format_add_prefix( params.format_list, 0, 0,
						prefix);
		else
			job_format_add_prefix( params.format_list, 0, 0,
					       prefix);
	}

	field_size = strlen( format );
	tmp_format = xmalloc( field_size + 1 );
	strcpy( tmp_format, format );

	token = strtok_r( tmp_format, "%", &tmp_char);
	if (token && (format[0] != '%'))	/* toss header */
		token = strtok_r( NULL, "%", &tmp_char );
	while (token) {
		_parse_token( token, field, &field_size, &right_justify,
			      &suffix);
		if (params.step_flag) {
			if      (field[0] == 'A')
				step_format_add_num_tasks( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else if (field[0] == 'b')
				step_format_add_gres( params.format_list,
						      field_size,
						      right_justify, suffix );
			else if (field[0] == 'i')
				step_format_add_id( params.format_list,
						    field_size,
						    right_justify, suffix );
			else if (field[0] == 'j')
				step_format_add_name( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'l')
				step_format_add_time_limit( params.format_list,
							    field_size,
							    right_justify,
							    suffix );
			else if (field[0] == 'M')
				step_format_add_time_used( params.format_list,
							    field_size,
							    right_justify,
							    suffix );
			else if (field[0] == 'N')
				step_format_add_nodes( params.format_list,
						       field_size,
						       right_justify, suffix );
			else if (field[0] == 'P')
				step_format_add_partition( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else if (field[0] == 'S')
				step_format_add_time_start( params.format_list,
							    field_size,
							    right_justify,
							    suffix );
			else if (field[0] == 'U')
				step_format_add_user_id( params.format_list,
							 field_size,
							 right_justify,
							 suffix );
			else if (field[0] == 'u')
				step_format_add_user_name( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else {
				prefix = xstrdup("%");
				xstrcat(prefix, token);
				xfree(suffix);
				suffix = prefix;
				
				step_format_add_invalid( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
				error ( "Invalid job step format "
					"specification: %c",
					field[0] );
			}
		} else {
			if (field[0] == 'a')
				job_format_add_account( params.format_list,
							field_size,
							right_justify,
							suffix  );
			else if (field[0] == 'b')
				job_format_add_gres( params.format_list,
						     field_size, right_justify,
						     suffix );
			else if (field[0] == 'B')
				job_format_add_batch_host( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else if (field[0] == 'c')
				job_format_add_min_cpus( params.format_list,
							 field_size,
							 right_justify,
							 suffix  );
			else if (field[0] == 'C')
				job_format_add_num_cpus( params.format_list,
							 field_size,
							 right_justify,
							 suffix  );
			else if (field[0] == 'd')
				job_format_add_min_tmp_disk(
							  params.format_list,
							  field_size,
							  right_justify,
							  suffix  );
			else if (field[0] == 'D')
				job_format_add_num_nodes( params.format_list,
							  field_size,
							  right_justify,
							  suffix  );
			else if (field[0] == 'e')
				job_format_add_time_end( params.format_list,
							 field_size,
							 right_justify,
							 suffix );
			else if (field[0] == 'E')
				job_format_add_dependency( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'f')
				job_format_add_features( params.format_list,
							 field_size,
							 right_justify,
							 suffix );
			else if (field[0] == 'g')
				job_format_add_group_name( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else if (field[0] == 'G')
				job_format_add_group_id( params.format_list,
							 field_size,
							 right_justify,
							 suffix );
			else if (field[0] == 'h')
				job_format_add_shared( params.format_list,
						       field_size,
						       right_justify,
						       suffix );
			else if (field[0] == 'H')
				job_format_add_sockets( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'i')
				job_format_add_job_id( params.format_list,
						       field_size,
						       right_justify,
						       suffix );
			else if (field[0] == 'I')
				job_format_add_cores( params.format_list,
						      field_size,
						      right_justify, suffix );
			else if (field[0] == 'j')
				job_format_add_name( params.format_list,
						     field_size,
						     right_justify, suffix );
			else if (field[0] == 'J')
				job_format_add_threads( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'k')
				job_format_add_comment( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'l')
				job_format_add_time_limit( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else if (field[0] == 'L')
				job_format_add_time_left( params.format_list,
							  field_size,
							  right_justify,
							  suffix );
			else if (field[0] == 'm')
				job_format_add_min_memory( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else if (field[0] == 'M')
				job_format_add_time_used( params.format_list,
							  field_size,
							  right_justify,
							  suffix );
			else if (field[0] == 'n')
				job_format_add_req_nodes( params.format_list,
							  field_size,
							  right_justify,
							  suffix );
			else if (field[0] == 'N')
				job_format_add_nodes( params.format_list,
						      field_size,
						      right_justify, suffix );
			else if (field[0] == 'O')
				job_format_add_contiguous( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else if (field[0] == 'p')
				job_format_add_priority( params.format_list,
							 field_size,
							 right_justify,
							 suffix );
			else if (field[0] == 'P')
				job_format_add_partition( params.format_list,
							  field_size,
							  right_justify,
							  suffix );
			else if (field[0] == 'q')
				job_format_add_qos( params.format_list,
						    field_size,
						    right_justify,
						    suffix );
			else if (field[0] == 'Q')
				 job_format_add_priority_long(
							params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'r')
				job_format_add_reason( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'R')
				job_format_add_reason_list( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 's')
				job_format_add_select_jobinfo(
							 params.format_list,
							 field_size,
							 right_justify,
							 suffix );
			else if (field[0] == 'S')
				job_format_add_time_start( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else if (field[0] == 't')
				job_format_add_job_state_compact(
							params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'T')
				job_format_add_job_state( params.format_list,
							  field_size,
							  right_justify,
							  suffix );
			else if (field[0] == 'U')
				job_format_add_user_id( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'u')
				job_format_add_user_name( params.format_list,
							  field_size,
							  right_justify,
							  suffix );
			else if (field[0] == 'v')
				job_format_add_reservation( params.format_list,
							field_size,
							right_justify,
							suffix );
			else if (field[0] == 'w')
				job_format_add_wckey( params.format_list,
						      field_size,
						      right_justify,
						      suffix );
			else if (field[0] == 'W')
				job_format_add_licenses( params.format_list,
						     field_size,
						     right_justify, suffix );
			else if (field[0] == 'x')
				job_format_add_exc_nodes( params.format_list,
							  field_size,
							  right_justify,
							  suffix );
			else if (field[0] == 'z')
				job_format_add_num_sct( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
			else {
				prefix = xstrdup("%");
				xstrcat(prefix, token);
				xfree(suffix);
				suffix = prefix;
				
				job_format_add_invalid( params.format_list,
							   field_size,
							   right_justify,
							   suffix );
				error( "Invalid job format specification: %c",
				       field[0] );
			}
		}
		token = strtok_r( NULL, "%", &tmp_char);
	}

	xfree( tmp_format );
	return SLURM_SUCCESS;
}
Beispiel #13
0
/*
 * Return a string containing any scheduling plugin configuration information
 * that we want to expose via "scontrol show configuration".
 * NOTE: the caller must xfree the returned pointer
 */
extern char *	get_wiki_conf(void)
{
	int i, first;
	char buf[32], *conf = NULL;

	snprintf(buf, sizeof(buf), "HostFormat=%u", use_host_exp);
	xstrcat(conf, buf);

	snprintf(buf, sizeof(buf), ";JobAggregationTime=%u",
		 job_aggregation_time);
	xstrcat(conf, buf);

	first = 1;
	for (i=0; i<EXC_PART_CNT; i++) {
		if (!exclude_part_ptr[i])
			continue;
		if (first) {
			xstrcat(conf, ";ExcludePartitions=");
			first = 0;
		} else
			xstrcat(conf, ",");
		xstrcat(conf, exclude_part_ptr[i]->name);
	}

	first = 1;
	for (i=0; i<HIDE_PART_CNT; i++) {
		if (!hide_part_ptr[i])
			continue;
		if (first) {
			xstrcat(conf, ";HidePartitionJobs=");
			first = 0;
		} else
			xstrcat(conf, ",");
		xstrcat(conf, hide_part_ptr[i]->name);
	}

	first = 1;
	for (i=0; i<HIDE_PART_CNT; i++) {
		if (!hide_part_nodes_ptr[i])
			continue;
		if (first) {
			xstrcat(conf, ";HidePartitionNodes=");
			first = 0;
		} else
			xstrcat(conf, ",");
		xstrcat(conf, hide_part_nodes_ptr[i]->name);
	}

	return conf;
}
Beispiel #14
0
/*
 * Returns > 0 if error, 0 if ok.
 */
int LoadTic(char *inb, char *tfn, orphans **opl)
{
    FILE	    *tfp;
    char	    *Temp, *Temp2, *Buf, *Log = NULL, RealName[256];
    int		    i, j, rc, bufsize, DescCnt = FALSE;
    fa_list	    *sbl = NULL;

    if (CFG.slow_util && do_quiet)
	msleep(1);

    memset(&RealName, 0, sizeof(RealName));
    memset(&TIC, 0, sizeof(TIC));
    memset(&T_File, 0, sizeof(T_File));

    snprintf(TIC.Inbound, PATH_MAX, "%s", inb);
    strncpy(TIC.TicName, tfn, 12);

    chdir(inb);
    if ((tfp = fopen(tfn, "r")) == NULL) {
	WriteError("$Cannot open %s", tfn);
	return 1;
    }

    /*
     * Although a TIC line may only be 255 characters long,
     * nobody seems to care and lines are up to 1024 characters
     * long.
     */
    if (PATH_MAX > 1024)
	bufsize = PATH_MAX;
    else
	bufsize = 1024;
    Temp = calloc(bufsize+1, sizeof(char));
    Buf  = calloc(bufsize+1, sizeof(char));

    while ((fgets(Buf, bufsize, tfp)) != NULL) {

	if (strlen(Buf) == bufsize)
	    Syslog('!', "Detected a TIC file line of %d characters long", bufsize);

	/*
	 * Remove all garbage from this tic line.
	 */
	Temp[0] = '\0';
	j = 0;
	for (i = 0; i < strlen(Buf); i++) {
	    if (isprint(Buf[i] & 0x7f)) {
		Temp[j] = Buf[i] & 0x7f;
		j++;
	    }
	}
	Temp[j] = '\0';

	if (strncasecmp(Temp, "hatch", 5) == 0) {
	    TIC.TicIn.Hatch = TRUE;

	} else if (TIC.TicIn.Hatch && (strncasecmp(Temp, "pth ", 4) == 0)) {
	    strncpy(TIC.TicIn.Pth, Temp+4, PATH_MAX);

	} else if (strncasecmp(Temp, "area ", 5) == 0) {
	    strncpy(TIC.TicIn.Area, Temp+5, 20);
	    strncpy(T_File.Echo, Temp+5, 20);

	} else if (strncasecmp(Temp, "origin ", 7) == 0) {
	    strncpy(TIC.TicIn.Origin, Temp+7, 80);
	    strncpy(T_File.Origin, Temp+7, 23);

	} else if (strncasecmp(Temp, "from ", 5) == 0) {
	    strncpy(TIC.TicIn.From, Temp+5, 80);
	    strncpy(T_File.From, Temp+5, 23);

	} else if (strncasecmp(Temp, "file ", 5) == 0) {
	    strncpy(TIC.TicIn.File, Temp+5, 80);
	    for (i = 0; i < strlen(TIC.TicIn.File); i++)
		TIC.TicIn.File[i] = toupper(TIC.TicIn.File[i]);
	    
	} else if (strncasecmp(Temp, "fullname ", 9) == 0) {
	    strncpy(TIC.TicIn.FullName, Temp+9, 80);

	} else if (strncasecmp(Temp, "created ", 8) == 0) {
	    strncpy(TIC.TicIn.Created, Temp+8, 80);

	} else if (strncasecmp(Temp, "magic ", 6) == 0) {
	    strncpy(TIC.TicIn.Magic, Temp+6, 20);
	    strncpy(T_File.Magic, Temp+6, 20);

	} else if (strncasecmp(Temp, "crc ", 4) == 0) {
	    TIC.Crc_Int = strtoul(Temp+4, (char **)NULL, 16);
	    snprintf(TIC.TicIn.Crc, 9, "%08X", TIC.Crc_Int);
	    strncpy(T_File.Crc, TIC.TicIn.Crc, 8);

	} else if (strncasecmp(Temp, "pw ", 3) == 0) {
	    strncpy(TIC.TicIn.Pw, Temp+3, 20);

	} else if (strncasecmp(Temp, "replaces ", 9) == 0) {
	    strncpy(TIC.TicIn.Replace, Temp+9, 80);
	    strncpy(T_File.Replace, Temp+9, 80);

	} else if (strncasecmp(Temp, "desc ", 5) == 0) {
	    if (!DescCnt) {
		strncpy(TIC.TicIn.Desc, Temp+5, 1023);
		strncpy(T_File.Desc, TIC.TicIn.Desc, 255);
		DescCnt = TRUE;
	    } else {
		Syslog('!', "More than one \"Desc\" line");
	    }
	
	} else if (strncasecmp(Temp, "path ", 5) == 0) {
	    if (strchr(Temp+5, ':') && strchr(Temp+5, '/')) {
		strncpy(TIC.TicIn.Path[TIC.TicIn.TotPath], Temp+5, 80);
		TIC.TicIn.TotPath++;
		TIC.Aka.zone = atoi(strtok(Temp+5, ":"));
		TIC.Aka.net  = atoi(strtok(NULL, "/"));
		TIC.Aka.node = atoi(strtok(NULL, "\0"));
		for (i = 0; i < 40; i++)
		    if ((CFG.akavalid[i]) && (CFG.aka[i].zone  == TIC.Aka.zone) && (CFG.aka[i].net   == TIC.Aka.net) &&
			(CFG.aka[i].node  == TIC.Aka.node) && (!CFG.aka[i].point)) {
			TIC.TicIn.PathError = TRUE;
			Syslog('+', "Aka %d: %s in path", i + 1, aka2str(CFG.aka[i]));
		    }
	    } else {
		WriteError("No valid AKA in Path line: \"%s\"", printable(Temp, 0));
		WriteError("Report this to author of that program");
	    }
		
	} else if (strncasecmp(Temp, "seenby ", 7) == 0) {
	    if (strchr(Temp+7, ':') && strchr(Temp+7, '/')) {
		fill_list(&sbl, Temp+7, NULL);
	    } else {
		WriteError("No valid AKA in Seenby line: \"%s\"", printable(Temp, 0));
	    }

	} else if (strncasecmp(Temp, "areadesc ", 9) == 0) {
	    strncpy(TIC.TicIn.AreaDesc, Temp+9, 60);

	} else if (strncasecmp(Temp, "to ", 3) == 0) {
	    /*
	     * Drop this one
	     * FIXME: should check if this is for us.
	     */
	} else if (strncasecmp(Temp, "size ", 5) == 0) {
	    TIC.TicIn.Size = atoi(Temp+5);

	} else if (strncasecmp(Temp, "date ", 5) == 0) {
	    /*
	     * Drop this one (HTick writes these)
	     */
	} else if (strncasecmp(Temp, "cost ", 5) == 0) {
	    TIC.TicIn.Cost = atoi(Temp+5);

	} else if (strncasecmp(Temp, "ldesc ", 6) == 0) {
	    if (TIC.TicIn.TotLDesc < 25) {
		strncpy(TIC.TicIn.LDesc[TIC.TicIn.TotLDesc], Temp+6, 80);
		TIC.TicIn.TotLDesc++;
	    } else {
		Syslog('f', "Too many LDesc lines in TIC file");
	    }
	    
	} else if (strncasecmp(Temp, "destination ", 12) == 0) {
	    /*
	     * Drop this one
	     */
	} else {
	    /*
	     * If we didn't find a matching keyword it is a line we
	     * will just remember and forward if there are downlinks.
	     */
	    if (strlen(Temp) > 127) {
		Syslog('+', "Unknown too long TIC line dropped");
	    } else if (TIC.TicIn.Unknowns < 25) {
		strncpy(TIC.TicIn.Unknown[TIC.TicIn.Unknowns], Temp, 127);
		TIC.TicIn.Unknowns++;
	    }
	}
    }
    fclose(tfp);

    /*
     * Do some basic checks on the loaded ticfile.
     */
    if ( (strlen(TIC.TicIn.File) == 0) || (strlen(TIC.TicIn.Area) == 0) ||
	 (strlen(TIC.TicIn.From) == 0) || (strlen(TIC.TicIn.Origin) == 0)) {
	WriteError("TIC file %s misses important information", TIC.TicName);
	tidy_falist(&sbl);
	mover(TIC.TicName);
	tic_in++;
	tic_bad++;
	return 1;
    }

    if (TIC.TicIn.TotLDesc) {
	/*
	 * First check for a bug in Harald Harms Allfix program that
	 * lets Allfix forward dummy Ldesc lines with the contents:
	 * "Long description not available"
	 */
	if (strstr(TIC.TicIn.LDesc[0], "ion not avail") != NULL) {
	    Syslog('!', "Killing invalid Ldesc line(s)");
	    TIC.TicIn.TotLDesc = 0;
	}
    }
    if (TIC.TicIn.TotLDesc) {
	T_File.TotLdesc = TIC.TicIn.TotLDesc;
	for (i = 0; i < TIC.TicIn.TotLDesc; i++) {
	    strncpy(T_File.LDesc[i], TIC.TicIn.LDesc[i], 48);
	}
    }

    /*
     * Show on screen what we are doing
     */
    if (!do_quiet) {
	ftnd_colour(CYAN, BLACK);
	printf("\r");
	for (i = 0; i < 79; i++)
	    printf(" ");
	printf("\rTic: %12s  File: %-14s Area: %-12s ", TIC.TicName, TIC.TicIn.File, TIC.TicIn.Area);
	fflush(stdout);
    }

    /*
     * Show in logfile what we are doing
     */
    Syslog('+', "Processing %s, %s area %s from %s", TIC.TicName, TIC.TicIn.File, TIC.TicIn.Area, TIC.TicIn.From);
    Syslog('+', "+- %s", TIC.TicIn.Created);
    Log = NULL;

    if (strlen(TIC.TicIn.Replace)) {
	Log = xstrcpy((char *)"Replace ");
	Log = xstrcat(Log, TIC.TicIn.Replace);
    }
    if (strlen(TIC.TicIn.Magic)) {
	if (Log != NULL)
	    Log = xstrcat(Log, (char *)", Magic ");
	else
	    Log = xstrcpy((char *)"Magic ");
	Log = xstrcat(Log, TIC.TicIn.Magic);
    }
    if (Log != NULL) {
	Syslog('+', "%s", Log);
	free(Log);
	Log = NULL;
    }

    strcpy(Temp, TIC.TicIn.From);
    TIC.Aka.zone = atoi(strtok(Temp, ":"));
    TIC.Aka.net  = atoi(strtok(NULL, "/"));
    TIC.Aka.node = atoi(strtok(NULL, "@\0"));
    if (SearchFidonet(TIC.Aka.zone))
	strcpy(TIC.Aka.domain, fidonet.domain);
    strcpy(Temp, TIC.TicIn.Origin);
    TIC.OrgAka.zone = atoi(strtok(Temp, ":"));
    TIC.OrgAka.net  = atoi(strtok(NULL, "/"));
    TIC.OrgAka.node = atoi(strtok(NULL, "@\0"));
    if (SearchFidonet(TIC.OrgAka.zone))
	strcpy(TIC.OrgAka.domain, fidonet.domain);

    Temp2 = calloc(PATH_MAX, sizeof(char));

    if (TIC.TicIn.Hatch) {
	/*
	 * Try to move the hatched file to the inbound
	 */
	snprintf(Temp, bufsize, "%s/%s", TIC.TicIn.Pth, TIC.TicIn.FullName);
	if (file_exist(Temp, R_OK) == 0) {
	    strcpy(RealName, TIC.TicIn.FullName);
	} else {
	    WriteError("Can't find %s", Temp);
	    tidy_falist(&sbl);
	    return 2;
	}
	snprintf(Temp2, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.FullName);
	if ((rc = file_mv(Temp, Temp2))) {
	    WriteError("Can't move %s to inbound: %s", Temp, strerror(rc));
	    tidy_falist(&sbl);
	    return 1;
	}
	if (!strlen(TIC.TicIn.File)) {
	    strcpy(Temp, TIC.TicIn.FullName);
	    name_mangle(Temp);
	    strncpy(TIC.TicIn.File, Temp, 12);
	    Syslog('f', "Local hatch created 8.3 name %s", Temp);
	}
    } else {
	/*
	 * Find out what the real name of the file is,
	 * most likely this is a 8.3 filename.
	 */
	strncpy(RealName, TIC.TicIn.File, 255);
	Syslog('f', "getfilecase(%s, %s)", TIC.Inbound, RealName);
	if (! getfilecase(TIC.Inbound, RealName)) {
	    strncpy(RealName, TIC.TicIn.FullName, 255);
	    Syslog('f', "getfilecase(%s, %s)", TIC.Inbound, RealName);
	    if (! getfilecase(TIC.Inbound, RealName)) {
		memset(&RealName, 0, sizeof(RealName));
	    }
	}
    }

    if (strlen(RealName) == 0) {
	/*
	 * We leave RealName empty, the ProcessTic function
	 * will handle this orphaned tic file.
	 */
	TIC.Orphaned = TRUE;
	Syslog('+', "Can't find file in inbound, will check later");
    } else {
	/*
	 * If no LFN received in the ticfile and the file in the inbound is the same as the 8.3 name
	 * but only the case is different, then treat the real filename as LFN.
	 */
	if ((strlen(TIC.TicIn.FullName) == 0) && strcmp(TIC.TicIn.File, RealName) && (strcasecmp(TIC.TicIn.File, RealName) == 0)) {
	    Syslog('f', "Real filename possible LFN, faking it");
	    strcpy(TIC.TicIn.FullName, RealName);
	}
	Syslog('f', "Real filename in inbound is \"%s\"", RealName);
	if ((strlen(TIC.TicIn.FullName)) == 0) {
	    Syslog('f', "LFN is empty, create lowercase one");
	    strncpy(TIC.TicIn.FullName, RealName, 255);
	    for (i = 0; i < strlen(TIC.TicIn.FullName); i++)
		TIC.TicIn.FullName[i] = tolower(TIC.TicIn.FullName[i]);
	}

	Syslog('+', "8.3 name \"%s\", LFN \"%s\"", TIC.TicIn.File, TIC.TicIn.FullName);
	if (strcmp(RealName, TIC.TicIn.File)) {
	    /*
	     * File in inbound has not the same name as the name on disk.
	     * It may be a LFN but also a case difference. The whole tic
	     * processing is based on 8.3 filenames.
	     */
	    snprintf(Temp, bufsize, "%s/%s", TIC.Inbound, RealName);
	    snprintf(Temp2, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);
	    if (rename(Temp, Temp2))
		WriteError("$Can't rename %s to %s", Temp, Temp2);
	    else
		Syslog('f', "Renamed %s to %s", Temp, Temp2);
	}
    }
    strncpy(TIC.NewFile, TIC.TicIn.File, 80);
    strncpy(TIC.NewFullName, TIC.TicIn.FullName, 255);

    free(Temp2);
    free(Temp);
    free(Buf);

    tic_in++;
    rc = ProcessTic(&sbl, opl);
    tidy_falist(&sbl);

    return rc;
}
Beispiel #15
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_assoc_rec);
	List wckey_list = list_create(slurmdb_destroy_wckey_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(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_assoc_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 (!xstrcmp(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 (!xstrcmp(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 ((rc = as_mysql_add_assocs(mysql_conn, uid, assoc_list))
		     != SLURM_SUCCESS)
			error("Problem adding user associations");
	}
	FREE_NULL_LIST(assoc_list);

	if (rc == SLURM_SUCCESS && list_count(wckey_list)) {
		if ((rc = as_mysql_add_wckeys(mysql_conn, uid, wckey_list))
		    != SLURM_SUCCESS)
			error("Problem adding user wckeys");
	}
	FREE_NULL_LIST(wckey_list);
	return rc;
}
Beispiel #16
0
static char *	_dump_all_nodes(int *node_cnt, time_t update_time)
{
	int i, cnt = 0, rc;
	struct node_record *node_ptr = node_record_table_ptr;
	char *tmp_buf = NULL, *buf = NULL;
	struct node_record *uniq_node_ptr = NULL;
	hostlist_t hl = NULL;

	for (i=0; i<node_record_count; i++, node_ptr++) {
		if (node_ptr->name == NULL)
			continue;
		if (IS_NODE_FUTURE(node_ptr))
			continue;
		if (_hidden_node(node_ptr))
			continue;
		if (use_host_exp == 2) {
			rc = _same_info(uniq_node_ptr, node_ptr, update_time);
			if (rc == 0) {
				uniq_node_ptr = node_ptr;
				if (hl) {
					hostlist_push_host(hl, node_ptr->name);
				} else {
					hl = hostlist_create(node_ptr->name);
					if (!hl) {
						fatal("Invalid node_name: %s",
						      node_ptr->name);
					}
				}
				continue;
			} else {
				tmp_buf = _dump_node(uniq_node_ptr, hl,
						     update_time);
				hostlist_destroy(hl);
				hl = hostlist_create(node_ptr->name);
				if (!hl) {
					fatal("Invalid node_name: %s",
					      node_ptr->name);
				}
				uniq_node_ptr = node_ptr;
			}
		} else {
			tmp_buf = _dump_node(node_ptr, hl, update_time);
		}
		if (cnt > 0)
			xstrcat(buf, "#");
		xstrcat(buf, tmp_buf);
		xfree(tmp_buf);
		cnt++;
	}

	if (hl) {
		tmp_buf = _dump_node(uniq_node_ptr, hl, update_time);
		hostlist_destroy(hl);
		if (cnt > 0)
			xstrcat(buf, "#");
		xstrcat(buf, tmp_buf);
		xfree(tmp_buf);
		cnt++;
	}

	*node_cnt = cnt;
	return buf;
}
Beispiel #17
0
extern List as_mysql_modify_users(mysql_conn_t *mysql_conn, uint32_t uid,
				  slurmdb_user_cond_t *user_cond,
				  slurmdb_user_rec_t *user)
{
	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;

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

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

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

	if (user_cond->admin_level != SLURMDB_ADMIN_NOTSET)
		xstrfmtcat(extra, " && admin_level=%u",
			   user_cond->admin_level);

	ret_list = _get_other_user_names_to_mod(mysql_conn, uid, user_cond);

	if (user->name)
		xstrfmtcat(vals, ", name='%s'", user->name);

	if (user->admin_level != SLURMDB_ADMIN_NOTSET)
		xstrfmtcat(vals, ", admin_level=%u", user->admin_level);

	if ((!extra && !ret_list)
	    || (!vals && !user->default_acct && !user->default_wckey)) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("Nothing to change");
		return NULL;
	}

	if (!extra) {
		/* means we got a ret_list and don't need to look at
		   the user_table. */
		goto no_user_table;
	}

	query = xstrdup_printf(
		"select distinct name from %s where deleted=0 %s;",
		user_table, extra);
	xfree(extra);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		FREE_NULL_LIST(ret_list);
		return NULL;
	}

	if (!ret_list)
		ret_list = list_create(slurm_destroy_char);
	while ((row = mysql_fetch_row(result))) {
		slurmdb_user_rec_t *user_rec = NULL;

		object = row[0];
		slurm_addto_char_list(ret_list, object);
		if (!name_char)
			xstrfmtcat(name_char, "(name='%s'", object);
		else
			xstrfmtcat(name_char, " || name='%s'", object);

		user_rec = xmalloc(sizeof(slurmdb_user_rec_t));

		if (!user->name)
			user_rec->name = xstrdup(object);
		else {
			user_rec->name = xstrdup(user->name);
			user_rec->old_name = xstrdup(object);
			if (_change_user_name(mysql_conn, user_rec)
			    != SLURM_SUCCESS)
				break;
		}

		user_rec->admin_level = user->admin_level;
		if (addto_update_list(mysql_conn->update_list,
				      SLURMDB_MODIFY_USER, user_rec)
		    != SLURM_SUCCESS)
			slurmdb_destroy_user_rec(user_rec);
	}
	mysql_free_result(result);

no_user_table:
	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(vals);
		xfree(query);
		return ret_list;
	} else if (user->name && (list_count(ret_list) != 1)) {
		errno = ESLURM_ONE_CHANGE;
		xfree(vals);
		xfree(query);
		FREE_NULL_LIST(ret_list);
		return NULL;
	}

	xfree(query);

	if (name_char && vals) {
		xstrcat(name_char, ")");
		user_name = uid_to_string((uid_t) uid);
		rc = modify_common(mysql_conn, DBD_MODIFY_USERS, now,
				   user_name, user_table, name_char,
				   vals, NULL);
		xfree(user_name);
	}

	xfree(name_char);
	xfree(vals);
	if (rc == SLURM_ERROR) {
		error("Couldn't modify users");
		FREE_NULL_LIST(ret_list);
	}

	if (user->default_acct) {
		slurmdb_assoc_cond_t assoc_cond;
		slurmdb_assoc_rec_t assoc;
		List tmp_list = NULL;

		memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
		slurmdb_init_assoc_rec(&assoc, 0);
		assoc.is_def = 1;
		assoc_cond.acct_list = list_create(NULL);
		list_append(assoc_cond.acct_list, user->default_acct);
		assoc_cond.user_list = ret_list;
		if (user_cond->assoc_cond
		    && user_cond->assoc_cond->cluster_list)
			assoc_cond.cluster_list =
				user_cond->assoc_cond->cluster_list;
		tmp_list = as_mysql_modify_assocs(mysql_conn, uid,
						  &assoc_cond, &assoc);
		FREE_NULL_LIST(assoc_cond.acct_list);

		if (!tmp_list) {
			FREE_NULL_LIST(ret_list);
			goto end_it;
		}
		/* char *names = NULL; */
		/* ListIterator itr = list_iterator_create(tmp_list); */
		/* while ((names = list_next(itr))) { */
		/* 	info("%s", names); */
		/* } */
		/* list_iterator_destroy(itr); */
		FREE_NULL_LIST(tmp_list);
	}

	if (user->default_wckey) {
		slurmdb_wckey_cond_t wckey_cond;
		slurmdb_wckey_rec_t wckey;
		List tmp_list = NULL;

		memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t));
		slurmdb_init_wckey_rec(&wckey, 0);
		wckey.is_def = 1;
		wckey_cond.name_list = list_create(NULL);
		list_append(wckey_cond.name_list, user->default_wckey);
		wckey_cond.user_list = ret_list;
		if (user_cond->assoc_cond
		    && user_cond->assoc_cond->cluster_list)
			wckey_cond.cluster_list =
				user_cond->assoc_cond->cluster_list;
		tmp_list = as_mysql_modify_wckeys(mysql_conn, uid,
						  &wckey_cond, &wckey);
		FREE_NULL_LIST(wckey_cond.name_list);

		if (!tmp_list) {
			FREE_NULL_LIST(ret_list);
			goto end_it;
		}
		/* char *names = NULL; */
		/* ListIterator itr = list_iterator_create(tmp_list); */
		/* while ((names = list_next(itr))) { */
		/* 	info("%s", names); */
		/* } */
		/* list_iterator_destroy(itr); */
		FREE_NULL_LIST(tmp_list);
	}
end_it:
	return ret_list;
}
Beispiel #18
0
static char *	_dump_node(struct node_record *node_ptr, hostlist_t hl,
			   time_t update_time)
{
	char tmp[16*1024], *buf = NULL;
	int i;
	uint32_t cpu_cnt;

	if (!node_ptr)
		return NULL;

	if (hl) {
		char *node_list;
		hostlist_sort(hl);
		hostlist_uniq(hl);
		node_list = hostlist_ranged_string_xmalloc(hl);
		xstrcat(buf, node_list);
		xfree(node_list);
	} else {
		snprintf(tmp, sizeof(tmp), "%s", node_ptr->name);
		xstrcat(buf, tmp);
	}

	snprintf(tmp, sizeof(tmp), ":STATE=%s;", _get_node_state(node_ptr));
	xstrcat(buf, tmp);

	if (node_ptr->cpu_load != NO_VAL) {
		snprintf(tmp, sizeof(tmp), "CPULOAD=%f;",
			 (node_ptr->cpu_load / 100.0));
		xstrcat(buf, tmp);
	}

	if (node_ptr->reason) {
		/* Strip out any quotes, they confuse Moab */
		char *reason, *bad_char;
		reason = xstrdup(node_ptr->reason);
		while ((bad_char = strchr(reason, '\'')))
			bad_char[0] = ' ';
		while ((bad_char = strchr(reason, '\"')))
			bad_char[0] = ' ';
		snprintf(tmp, sizeof(tmp), "CAT=\"%s\";", reason);
		xstrcat(buf, tmp);
		xfree(reason);
	}

	if (update_time > last_node_update)
		return buf;

	if (slurmctld_conf.fast_schedule) {
		/* config from slurm.conf */
		cpu_cnt = node_ptr->config_ptr->cpus;
	} else {
		/* config as reported by slurmd */
		cpu_cnt = node_ptr->cpus;
	}
	for (i=0; i<node_ptr->part_cnt; i++) {
		if (i == 0)
			xstrcat(buf, "CCLASS=");
		snprintf(tmp, sizeof(tmp), "[%s:%u]",
			node_ptr->part_pptr[i]->name,
			cpu_cnt);
		xstrcat(buf, tmp);
	}
	if (i > 0)
		xstrcat(buf, ";");

	if (node_ptr->arch) {
		snprintf(tmp, sizeof(tmp), "ARCH=%s;", node_ptr->arch);
		xstrcat(buf, tmp);
	}

	if (node_ptr->os) {
		snprintf(tmp, sizeof(tmp), "OS=%s;", node_ptr->os);
		xstrcat(buf, tmp);
	}

	if (node_ptr->config_ptr && node_ptr->config_ptr->feature) {
		snprintf(tmp, sizeof(tmp), "FEATURE=%s;",
			node_ptr->config_ptr->feature);
		/* comma separator to colon */
		for (i=0; (tmp[i] != '\0'); i++) {
			if (tmp[i] == ',')
				tmp[i] = ':';
		}
		xstrcat(buf, tmp);
	}

	if (node_ptr->config_ptr && node_ptr->config_ptr->gres) {
		snprintf(tmp, sizeof(tmp), "GRES=%s;",
			node_ptr->config_ptr->gres);
		xstrcat(buf, tmp);
	}

	if (update_time > 0)
		return buf;

	if (slurmctld_conf.fast_schedule && node_ptr->config_ptr) {
		/* config from slurm.conf */
		snprintf(tmp, sizeof(tmp),
			"CMEMORY=%u;CDISK=%u;CPROC=%u;",
			node_ptr->config_ptr->real_memory,
			node_ptr->config_ptr->tmp_disk,
			node_ptr->config_ptr->cpus);
	} else {
		/* config as reported by slurmd */
		snprintf(tmp, sizeof(tmp),
			"CMEMORY=%u;CDISK=%u;CPROC=%u;",
			node_ptr->real_memory,
			node_ptr->tmp_disk,
			node_ptr->cpus);
	}
	xstrcat(buf, tmp);

	return buf;
}
Beispiel #19
0
extern List as_mysql_remove_coord(mysql_conn_t *mysql_conn, uint32_t uid,
				  List acct_list,
				  slurmdb_user_cond_t *user_cond)
{
	char *query = NULL, *object = NULL, *extra = NULL, *last_user = NULL;
	char *user_name = NULL;
	time_t now = time(NULL);
	int set = 0, is_admin=0, rc = SLURM_SUCCESS;
	ListIterator itr = NULL;
	slurmdb_user_rec_t *user_rec = NULL;
	List ret_list = NULL;
	List user_list = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	slurmdb_user_rec_t user;

	if (!user_cond && !acct_list) {
		error("we need something to remove");
		return NULL;
	} else if (user_cond && user_cond->assoc_cond)
		user_list = user_cond->assoc_cond->user_list;

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

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

	if (!(is_admin = is_user_min_admin_level(
		      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
		if (!is_user_any_coord(mysql_conn, &user)) {
			error("Only admins/coordinators can "
			      "remove coordinators");
			errno = ESLURM_ACCESS_DENIED;
			return NULL;
		}
	}

	/* Leave it this way since we are using extra below */

	if (user_list && list_count(user_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, "(");

		itr = list_iterator_create(user_list);
		while ((object = list_next(itr))) {
			if (!object[0])
				continue;
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "user='******'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (acct_list && list_count(acct_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, "(");

		itr = list_iterator_create(acct_list);
		while ((object = list_next(itr))) {
			if (!object[0])
				continue;
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "acct='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (!extra) {
		errno = SLURM_ERROR;
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "No conditions given");
		return NULL;
	}

	query = xstrdup_printf(
		"select user, acct from %s where deleted=0 && %s order by user",
		acct_coord_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(extra);
		errno = SLURM_ERROR;
		return NULL;
	}
	xfree(query);
	ret_list = list_create(slurm_destroy_char);
	user_list = list_create(slurm_destroy_char);
	while ((row = mysql_fetch_row(result))) {
		if (!is_admin) {
			slurmdb_coord_rec_t *coord = NULL;
			if (!user.coord_accts) { // This should never
				// happen
				error("We are here with no coord accts");
				errno = ESLURM_ACCESS_DENIED;
				FREE_NULL_LIST(ret_list);
				FREE_NULL_LIST(user_list);
				xfree(extra);
				mysql_free_result(result);
				return NULL;
			}
			itr = list_iterator_create(user.coord_accts);
			while ((coord = list_next(itr))) {
				if (!xstrcasecmp(coord->name, row[1]))
					break;
			}
			list_iterator_destroy(itr);

			if (!coord) {
				error("User %s(%d) does not have the "
				      "ability to change this account (%s)",
				      user.name, user.uid, row[1]);
				errno = ESLURM_ACCESS_DENIED;
				FREE_NULL_LIST(ret_list);
				FREE_NULL_LIST(user_list);
				xfree(extra);
				mysql_free_result(result);
				return NULL;
			}
		}
		if (!last_user || xstrcasecmp(last_user, row[0])) {
			list_append(user_list, xstrdup(row[0]));
			last_user = row[0];
		}
		list_append(ret_list, xstrdup_printf("U = %-9s A = %-10s",
						     row[0], row[1]));
	}
	mysql_free_result(result);

	user_name = uid_to_string((uid_t) uid);
	rc = remove_common(mysql_conn, DBD_REMOVE_ACCOUNT_COORDS,
			   now, user_name, acct_coord_table,
			   extra, NULL, NULL, NULL, NULL);
	xfree(user_name);
	xfree(extra);
	if (rc == SLURM_ERROR) {
		FREE_NULL_LIST(ret_list);
		FREE_NULL_LIST(user_list);
		errno = SLURM_ERROR;
		return NULL;
	}

	/* get the update list set */
	itr = list_iterator_create(user_list);
	while ((last_user = list_next(itr))) {
		user_rec = xmalloc(sizeof(slurmdb_user_rec_t));
		user_rec->name = xstrdup(last_user);
		_get_user_coords(mysql_conn, user_rec);
		if (addto_update_list(mysql_conn->update_list,
				      SLURMDB_REMOVE_COORD, user_rec)
		    != SLURM_SUCCESS)
			slurmdb_destroy_user_rec(user_rec);
	}
	list_iterator_destroy(itr);
	FREE_NULL_LIST(user_list);

	return ret_list;
}
Beispiel #20
0
/* Create an IO filename from job parameters and the filename format
 * sent from client
 */
char *
fname_create(stepd_step_rec_t *job, const char *format, int taskid)
{
	unsigned int wid   = 0;
	char *name = NULL;
	char *orig = xstrdup(format);
	char *uname;
	char *p, *q;
	int id;

	if (((id = fname_single_task_io (format)) >= 0) && (taskid != id))
			return (xstrdup ("/dev/null"));

	/* If format doesn't specify an absolute pathname,
	 * use cwd
	 */
	if (orig[0] != '/') {
		xstrcat(name, job->cwd);
		if (name[strlen(name)-1] != '/')
			xstrcatchar(name, '/');
	}

	q = p = orig;
	while (*p != '\0') {
		if (*p == '%') {
			if (isdigit(*(++p))) {
				unsigned long in_width = 0;
				xmemcat(name, q, p - 1);
				if ((in_width = strtoul(p, &p, 10)) > MAX_WIDTH)
					wid = MAX_WIDTH;
				else
					wid = (unsigned int)in_width;
				q = p - 1;
				if (*p == '\0')
					break;
			}

			switch (*p) {
			case 'a':  /* '%a' => array task id   */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid,
					   job->array_task_id);
				q = ++p;
				break;
			case 'A':  /* '%A' => array master job id */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid,
					   job->array_job_id);
				q = ++p;
				break;
			case 's':  /* '%s' => step id        */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid, job->stepid);
				q = ++p;
				break;
			case 't':  /* '%t' => taskid         */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid, taskid);
				q = ++p;
				break;
			case 'n':  /* '%n' => nodeid         */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid, job->nodeid);
				q = ++p;
				break;
			case 'N':  /* '%N' => node name      */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%s", conf->hostname);
				q = ++p;
				break;
			case 'u':  /* '%u' => user name      */
				uname = uid_to_string(job->uid);
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%s", uname);
				xfree(uname);
				q = ++p;
				break;
			case 'J':  /* '%J' => jobid.stepid */
			case 'j':  /* '%j' => jobid        */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid, job->jobid);

				if ((*p == 'J') && (job->stepid != NO_VAL))
					xstrfmtcat(name, ".%d", job->stepid);
				q = ++p;
				break;

			default:
				break;
			}
			wid = 0;

		} else
			p++;
	}

	if (q != p)
		xmemcat(name, q, p);

	xfree(orig);
	return name;
}
Beispiel #21
0
extern List as_mysql_modify_accts(mysql_conn_t *mysql_conn, uint32_t uid,
				  slurmdb_account_cond_t *acct_cond,
				  slurmdb_account_rec_t *acct)
{
	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;

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

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

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

	if (acct_cond->description_list
	    && list_count(acct_cond->description_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_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 (acct_cond->organization_list
	    && list_count(acct_cond->organization_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->organization_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "organization='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (acct->description)
		xstrfmtcat(vals, ", description='%s'", acct->description);
	if (acct->organization)
		xstrfmtcat(vals, ", organization='%s'", acct->organization);

	if (!extra || !vals) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("Nothing to change");
		return NULL;
	}

	query = xstrdup_printf("select name from %s %s;", acct_table, extra);
	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);
		xfree(vals);
		return NULL;
	}

	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;
		debug3("didn't effect anything\n%s", query);
		xfree(query);
		xfree(vals);
		return ret_list;
	}
	xfree(query);
	xstrcat(name_char, ")");

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

	xfree(name_char);
	xfree(vals);

	return ret_list;
}
Beispiel #22
0
static int
_exec_srun_multiple(spawn_req_t *req, char **env)
{
	int argc, ntasks, i, j, spawn_cnt, fd;
	char **argv = NULL, *buf = NULL;
	spawn_subcmd_t *subcmd = NULL;
	char fbuf[128];

	debug3("mpi/pmi2: in _exec_srun_multiple");
	/* create a tmp multi_prog file */
	/* TODO: how to delete the file? */
	sprintf(fbuf, "/tmp/%d.XXXXXX", getpid());
	fd = mkstemp(fbuf);
	if (fd < 0) {
		error("mpi/pmi2: failed to open multi-prog file %s: %m", fbuf);
		return SLURM_ERROR;
	}
	ntasks = 0;
	for (spawn_cnt = 0; spawn_cnt < req->subcmd_cnt; spawn_cnt ++) {
		subcmd = req->subcmds[spawn_cnt];
		/* TODO: write a wrapper program to handle the info */
		if (subcmd->info_cnt > 0) {
			error("mpi/pmi2: spawn info ignored");
		}
		if (subcmd->max_procs == 1) {
			xstrfmtcat(buf, "%d  %s", ntasks, subcmd->cmd);
		} else {
			xstrfmtcat(buf, "%d-%d  %s", ntasks,
				   ntasks + subcmd->max_procs - 1, subcmd->cmd);
		}
		for (i = 0; i < subcmd->argc; i ++) {
			xstrfmtcat(buf, " %s", subcmd->argv[i]);
		}
		xstrcat(buf, "\n");
		ntasks += subcmd->max_procs;
	}
	if (buf) {
		safe_write(fd, buf, strlen(buf));
		xfree(buf);
	}
	close(fd);

	argc = 7;
	xrealloc(argv, argc * sizeof(char *));

	j = 0;
	argv[j ++] = "srun";
	argv[j ++] = "--mpi=pmi2";
	xstrfmtcat(argv[j ++], "--ntasks=%d", ntasks);
	if (job_info.srun_opt && job_info.srun_opt->no_alloc) {
		argv[j ++] = "--no-alloc";
		xstrfmtcat(argv[j ++], "--nodelist=%s",
			   job_info.srun_opt->nodelist);
	}
	argv[j ++] = "--multi-prog";
	argv[j ++] = fbuf;
	argv[j ++] = NULL;

	debug3("mpi/mpi2: to execve");

	execve(SLURM_PREFIX"/bin/srun", argv, env);
	error("mpi/pmi2: failed to exec srun: %m");
	return SLURM_ERROR;
rwfail:
	error("mpi/pmi2: failed to generate multi-prog file");
	return SLURM_ERROR;
}
Beispiel #23
0
/* Fill in all the users that are coordinator for this account.  This
 * will fill in if there are coordinators from a parent account also.
 */
static int _get_account_coords(mysql_conn_t *mysql_conn,
			       slurmdb_account_rec_t *acct)
{
	char *query = NULL, *cluster_name = NULL;
	slurmdb_coord_rec_t *coord = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	ListIterator itr;

	if (!acct) {
		error("We need a account to fill in.");
		return SLURM_ERROR;
	}

	if (!acct->coordinators)
		acct->coordinators = list_create(slurmdb_destroy_coord_rec);

	query = xstrdup_printf(
		"select user from %s where acct='%s' && deleted=0",
		acct_coord_table, acct->name);

	if (!(result =
	      mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);
	while ((row = mysql_fetch_row(result))) {
		coord = xmalloc(sizeof(slurmdb_coord_rec_t));
		list_append(acct->coordinators, coord);
		coord->name = xstrdup(row[0]);
		coord->direct = 1;
	}
	mysql_free_result(result);

	slurm_mutex_lock(&as_mysql_cluster_list_lock);
	itr = list_iterator_create(as_mysql_cluster_list);
	while ((cluster_name = list_next(itr))) {
		if (query)
			xstrcat(query, " union ");
		xstrfmtcat(query,
			   "select distinct t0.user from %s as t0, "
			   "\"%s_%s\" as t1, \"%s_%s\" as t2 "
			   "where t0.acct=t1.acct && "
			   "t1.lft<t2.lft && t1.rgt>t2.lft && "
			   "t1.user='' && t2.acct='%s' "
			   "&& t1.acct!='%s' && !t0.deleted",
			   acct_coord_table, cluster_name, assoc_table,
			   cluster_name, assoc_table,
			   acct->name, acct->name);
	}
	list_iterator_destroy(itr);
	slurm_mutex_unlock(&as_mysql_cluster_list_lock);

	if (!query) {
		error("No clusters defined?  How could there be accts?");
		return SLURM_SUCCESS;
	}
	xstrcat(query, ";");

	if (!(result =  mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);
	while ((row = mysql_fetch_row(result))) {
		coord = xmalloc(sizeof(slurmdb_coord_rec_t));
		list_append(acct->coordinators, coord);
		coord->name = xstrdup(row[0]);
		coord->direct = 0;
	}
	mysql_free_result(result);
	return SLURM_SUCCESS;
}
Beispiel #24
0
/*
 * get_nodes - get information on specific node(s) changed since some time
 * cmd_ptr IN - CMD=GETNODES ARG=[<UPDATETIME>:<NODEID>[:<NODEID>]...]
 *                               [<UPDATETIME>:ALL]
 * RET 0 on success, -1 on failure
 *
 * Response format
 * Response format
 * ARG=<cnt>#<NODEID>:
 *	STATE=<state>;		 Moab equivalent node state
 *	[ARCH=<architecture>;]	 Computer architecture
 *	[OS=<operating_system>;] Operating system
 *	CMEMORY=<MB>;		 MB of memory on node
 *	CDISK=<MB>;		 MB of disk space on node
 *	CPROC=<cpus>;		 CPU count on node
 *	[FEATURE=<feature>;]	 Features associated with node, if any
 *  [#<NODEID>:...];
 */
extern int	get_nodes(char *cmd_ptr, int *err_code, char **err_msg)
{
	char *arg_ptr, *tmp_char, *tmp_buf, *buf = NULL;
	time_t update_time;
	/* Locks: read node, read partition */
	slurmctld_lock_t node_read_lock = {
		NO_LOCK, NO_LOCK, READ_LOCK, READ_LOCK };
	int node_rec_cnt = 0, buf_size = 0;

#ifdef HAVE_CRAY
	/* Locks: write node */
	slurmctld_lock_t node_write_lock = {
		NO_LOCK, NO_LOCK, WRITE_LOCK, NO_LOCK };

	/*
	 * Run a Basil Inventory immediately before scheduling, to avoid
	 * race conditions caused by ALPS node state change (caused e.g.
	 * by the node health checker).
	 * This relies on the above write lock for the node state.
	 */
	lock_slurmctld(node_write_lock);
	if (select_g_reconfigure()) {
		unlock_slurmctld(node_write_lock);
		*err_code = -720;
		*err_msg = "Unable to run ALPS inventory";
		error("wiki: Unable to run ALPS inventory");
		return -1;
	}
	unlock_slurmctld(node_write_lock);
#endif

	arg_ptr = strstr(cmd_ptr, "ARG=");
	if (arg_ptr == NULL) {
		*err_code = -300;
		*err_msg = "GETNODES lacks ARG";
		error("wiki: GETNODES lacks ARG");
		return -1;
	}
	update_time = (time_t) strtoul(arg_ptr+4, &tmp_char, 10);
	if (tmp_char[0] != ':') {
		*err_code = -300;
		*err_msg = "Invalid ARG value";
		error("wiki: GETNODES has invalid ARG value");
		return -1;
	}
	tmp_char++;
	lock_slurmctld(node_read_lock);
	if (strncmp(tmp_char, "ALL", 3) == 0) {
		/* report all nodes */
		buf = _dump_all_nodes(&node_rec_cnt, update_time);
	} else {
		struct node_record *node_ptr = NULL;
		char *node_name = NULL, *tmp2_char = NULL;

		node_name = strtok_r(tmp_char, ":", &tmp2_char);
		while (node_name) {
			node_ptr = find_node_record(node_name);
			if (node_ptr == NULL) {
				error("sched/wiki2: bad hostname %s",
				      node_name);
				continue;
			}
			if (_hidden_node(node_ptr))
				continue;
			tmp_buf = _dump_node(node_ptr, update_time);
			if (node_rec_cnt > 0)
				xstrcat(buf, "#");
			xstrcat(buf, tmp_buf);
			xfree(tmp_buf);
			node_rec_cnt++;
			node_name = strtok_r(NULL, ":", &tmp2_char);
		}
	}
	unlock_slurmctld(node_read_lock);

	/* Prepend ("ARG=%d", node_rec_cnt) to reply message */
	if (buf)
		buf_size = strlen(buf);
	tmp_buf = xmalloc(buf_size + 32);
	if (node_rec_cnt)
		sprintf(tmp_buf, "SC=0 ARG=%d#%s", node_rec_cnt, buf);
	else
		sprintf(tmp_buf, "SC=0 ARG=0#");
	xfree(buf);
	*err_code = 0;
	*err_msg = tmp_buf;
	return 0;
}
Beispiel #25
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;
}
Beispiel #26
0
extern List as_mysql_get_users(mysql_conn_t *mysql_conn, uid_t uid,
			       slurmdb_user_cond_t *user_cond)
{
	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	List user_list = NULL;
	ListIterator itr = NULL;
	char *object = NULL;
	int set = 0;
	int i=0, is_admin=1;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	uint16_t private_data = 0;
	slurmdb_user_rec_t user;

	/* if this changes you will need to edit the corresponding enum */
	char *user_req_inx[] = {
		"name",
		"admin_level"
	};
	enum {
		USER_REQ_NAME,
		USER_REQ_AL,
		USER_REQ_COUNT
	};

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

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

	private_data = slurm_get_private_data();
	if (private_data & PRIVATE_DATA_USERS) {
		if (!(is_admin = is_user_min_admin_level(
			      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
			assoc_mgr_fill_in_user(
				mysql_conn, &user, 1, NULL);
		}
		if (!is_admin && !user.name) {
			debug("User %u has no assocations, and is not admin, "
			      "so not returning any users.", user.uid);
			return NULL;
		}
	}

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

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


	user_list = _get_other_user_names_to_mod(mysql_conn, uid, user_cond);
	if (user_list) {
		if (!user_cond->assoc_cond)
			user_cond->assoc_cond =
				xmalloc(sizeof(slurmdb_assoc_rec_t));

		if (!user_cond->assoc_cond->user_list)
			user_cond->assoc_cond->user_list = user_list;
		else {
			list_transfer(user_cond->assoc_cond->user_list,
				      user_list);
			FREE_NULL_LIST(user_list);
		}
		user_list = NULL;
	} else if ((user_cond->def_acct_list
		    && list_count(user_cond->def_acct_list))
		   || (user_cond->def_wckey_list
		       && list_count(user_cond->def_wckey_list)))
		return NULL;

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

	if (user_cond->admin_level != SLURMDB_ADMIN_NOTSET) {
		xstrfmtcat(extra, " && admin_level=%u",
			   user_cond->admin_level);
	}

empty:
	/* This is here to make sure we are looking at only this user
	 * if this flag is set.
	 */
	if (!is_admin && (private_data & PRIVATE_DATA_USERS)) {
		xstrfmtcat(extra, " && name='%s'", user.name);
	}

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

	query = xstrdup_printf("select %s from %s %s", tmp, user_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);

	user_list = list_create(slurmdb_destroy_user_rec);

	while ((row = mysql_fetch_row(result))) {
		slurmdb_user_rec_t *user = xmalloc(sizeof(slurmdb_user_rec_t));

		list_append(user_list, user);

		user->name =  xstrdup(row[USER_REQ_NAME]);
		user->admin_level = slurm_atoul(row[USER_REQ_AL]);

		if (user_cond && user_cond->with_coords)
			_get_user_coords(mysql_conn, user);
	}
	mysql_free_result(result);

	if (user_cond && (user_cond->with_assocs
			  || (user_cond->assoc_cond
			      && user_cond->assoc_cond->only_defs))) {
		ListIterator assoc_itr = NULL;
		slurmdb_user_rec_t *user = NULL;
		slurmdb_assoc_rec_t *assoc = NULL;
		List assoc_list = NULL;

		/* Make sure we don't get any non-user associations
		 * this is done by at least having a user_list
		 * defined */
		if (!user_cond->assoc_cond)
			user_cond->assoc_cond =
				xmalloc(sizeof(slurmdb_assoc_cond_t));

		if (!user_cond->assoc_cond->user_list)
			user_cond->assoc_cond->user_list = list_create(NULL);

		user_cond->assoc_cond->with_deleted = user_cond->with_deleted;

		assoc_list = as_mysql_get_assocs(
			mysql_conn, uid, user_cond->assoc_cond);

		if (!assoc_list) {
			error("no associations");
			goto get_wckeys;
		}

		itr = list_iterator_create(user_list);
		assoc_itr = list_iterator_create(assoc_list);
		while ((user = list_next(itr))) {
			while ((assoc = list_next(assoc_itr))) {
				if (xstrcmp(assoc->user, user->name))
					continue;
				/* Set up the default.  This is needed
				 * for older versions primarily that
				 * don't have the notion of default
				 * account per cluster. */
				if (!user->default_acct && (assoc->is_def == 1))
					user->default_acct =
						xstrdup(assoc->acct);

				if (!user_cond->with_assocs) {
					/* We just got the default so no
					   reason to hang around if we aren't
					   getting the associations.
					*/
					if (user->default_acct)
						break;
					else
						continue;
				}

				if (!user->assoc_list)
					user->assoc_list = list_create(
						slurmdb_destroy_assoc_rec);
				list_append(user->assoc_list, assoc);
				list_remove(assoc_itr);
			}
			list_iterator_reset(assoc_itr);
		}
		list_iterator_destroy(itr);
		list_iterator_destroy(assoc_itr);
		FREE_NULL_LIST(assoc_list);
	}

get_wckeys:
	if (user_cond && (user_cond->with_wckeys
			  || (user_cond->assoc_cond
			      && user_cond->assoc_cond->only_defs))) {
		ListIterator wckey_itr = NULL;
		slurmdb_user_rec_t *user = NULL;
		slurmdb_wckey_rec_t *wckey = NULL;
		List wckey_list = NULL;
		slurmdb_wckey_cond_t wckey_cond;

		memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t));
		if (user_cond->assoc_cond) {
			wckey_cond.user_list =
				user_cond->assoc_cond->user_list;
			wckey_cond.cluster_list =
				user_cond->assoc_cond->cluster_list;
			wckey_cond.only_defs =
				user_cond->assoc_cond->only_defs;
		}
		wckey_list = as_mysql_get_wckeys(mysql_conn, uid, &wckey_cond);

		if (!wckey_list)
			return user_list;

		itr = list_iterator_create(user_list);
		wckey_itr = list_iterator_create(wckey_list);
		while ((user = list_next(itr))) {
			while ((wckey = list_next(wckey_itr))) {
				if (xstrcmp(wckey->user, user->name))
					continue;

				/* Set up the default.  This is needed
				 * for older versions primarily that
				 * don't have the notion of default
				 * wckey per cluster. */
				if (!user->default_wckey
				    && (wckey->is_def == 1))
					user->default_wckey =
						xstrdup(wckey->name);

				/* We just got the default so no
				   reason to hang around if we aren't
				   getting the wckeys.
				*/
				if (!user_cond->with_wckeys) {
					/* We just got the default so no
					   reason to hang around if we aren't
					   getting the wckeys.
					*/
					if (user->default_wckey)
						break;
					else
						continue;
				}

				if (!user->wckey_list)
					user->wckey_list = list_create(
						slurmdb_destroy_wckey_rec);
				list_append(user->wckey_list, wckey);
				list_remove(wckey_itr);
			}
			list_iterator_reset(wckey_itr);
			/* If a user doesn't have a default wckey (they
			   might not of had track_wckeys on), set it now.
			*/
			if (!user->default_wckey)
				user->default_wckey = xstrdup("");
		}
		list_iterator_destroy(itr);
		list_iterator_destroy(wckey_itr);

		FREE_NULL_LIST(wckey_list);
	}

	return user_list;
}
extern int task_cgroup_cpuset_create(stepd_step_rec_t *job)
{
	int rc;
	int fstatus = SLURM_ERROR;

	xcgroup_t cpuset_cg;

	uint32_t jobid = job->jobid;
	uint32_t stepid = job->stepid;
	uid_t uid = job->uid;
	uid_t gid = job->gid;
	char* user_alloc_cores = NULL;
	char* job_alloc_cores = NULL;
	char* step_alloc_cores = NULL;
	char cpuset_meta[PATH_MAX];

	char* cpus = NULL;
	size_t cpus_size;

	char* slurm_cgpath;
	xcgroup_t slurm_cg;

#ifdef HAVE_NATIVE_CRAY
	char expected_usage[32];
#endif

	/* create slurm root cg in this cg namespace */
	slurm_cgpath = task_cgroup_create_slurm_cg(&cpuset_ns);
	if ( slurm_cgpath == NULL ) {
		return SLURM_ERROR;
	}

	/* check that this cgroup has cpus allowed or initialize them */
	if (xcgroup_load(&cpuset_ns,&slurm_cg,slurm_cgpath)
	    != XCGROUP_SUCCESS) {
		error("task/cgroup: unable to load slurm cpuset xcgroup");
		xfree(slurm_cgpath);
		return SLURM_ERROR;
	}
again:
	snprintf(cpuset_meta, sizeof(cpuset_meta), "%scpus", cpuset_prefix);
	rc = xcgroup_get_param(&slurm_cg, cpuset_meta, &cpus,&cpus_size);
	if (rc != XCGROUP_SUCCESS || cpus_size == 1) {
		if (!cpuset_prefix_set && (rc != XCGROUP_SUCCESS)) {
			cpuset_prefix_set = 1;
			cpuset_prefix = "cpuset.";
			goto again;
		}

		/* initialize the cpusets as it was inexistant */
		if (_xcgroup_cpuset_init(&slurm_cg) !=
		    XCGROUP_SUCCESS) {
			xfree(slurm_cgpath);
			xcgroup_destroy(&slurm_cg);
			return SLURM_ERROR;
		}
	}
	xfree(cpus);

	/* build user cgroup relative path if not set (should not be) */
	if (*user_cgroup_path == '\0') {
		if (snprintf(user_cgroup_path, PATH_MAX,
			     "%s/uid_%u", slurm_cgpath, uid) >= PATH_MAX) {
			error("task/cgroup: unable to build uid %u cgroup "
			      "relative path : %m", uid);
			xfree(slurm_cgpath);
			return SLURM_ERROR;
		}
	}
	xfree(slurm_cgpath);

	/* build job cgroup relative path if no set (should not be) */
	if (*job_cgroup_path == '\0') {
		if (snprintf(job_cgroup_path,PATH_MAX,"%s/job_%u",
			     user_cgroup_path,jobid) >= PATH_MAX) {
			error("task/cgroup: unable to build job %u cpuset "
			      "cg relative path : %m",jobid);
			return SLURM_ERROR;
		}
	}

	/* build job step cgroup relative path (should not be) */
	if (*jobstep_cgroup_path == '\0') {
		if (stepid == NO_VAL) {
			if (snprintf(jobstep_cgroup_path, PATH_MAX,
				     "%s/step_batch", job_cgroup_path)
			    >= PATH_MAX) {
				error("task/cgroup: unable to build job step"
				      " %u.batch cpuset cg relative path: %m",
				      jobid);
				return SLURM_ERROR;
			}
		} else {
			if (snprintf(jobstep_cgroup_path,
				     PATH_MAX, "%s/step_%u",
				     job_cgroup_path, stepid) >= PATH_MAX) {
				error("task/cgroup: unable to build job step"
				      " %u.%u cpuset cg relative path: %m",
				      jobid, stepid);
				return SLURM_ERROR;
			}
		}
	}

	/*
	 * create cpuset root cg and lock it
	 *
	 * we will keep the lock until the end to avoid the effect of a release
	 * agent that would remove an existing cgroup hierarchy while we are
	 * setting it up. As soon as the step cgroup is created, we can release
	 * the lock.
	 * Indeed, consecutive slurm steps could result in cg being removed
	 * between the next EEXIST instanciation and the first addition of
	 * a task. The release_agent will have to lock the root cpuset cgroup
	 * to avoid this scenario.
	 */
	if (xcgroup_create(&cpuset_ns,&cpuset_cg,"",0,0) != XCGROUP_SUCCESS) {
		error("task/cgroup: unable to create root cpuset xcgroup");
		return SLURM_ERROR;
	}
	if (xcgroup_lock(&cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&cpuset_cg);
		error("task/cgroup: unable to lock root cpuset cg");
		return SLURM_ERROR;
	}

	/*
	 * build job and job steps allocated cores lists
	 */
	debug("task/cgroup: job abstract cores are '%s'",
	      job->job_alloc_cores);
	debug("task/cgroup: step abstract cores are '%s'",
	      job->step_alloc_cores);
	if (xcpuinfo_abs_to_mac(job->job_alloc_cores,
			&job_alloc_cores) != SLURM_SUCCESS) {
		error("task/cgroup: unable to build job physical cores");
		goto error;
	}
	if (xcpuinfo_abs_to_mac(job->step_alloc_cores,
			&step_alloc_cores) != SLURM_SUCCESS) {
		error("task/cgroup: unable to build step physical cores");
		goto error;
	}
	debug("task/cgroup: job physical cores are '%s'",
	      job_alloc_cores);
	debug("task/cgroup: step physical cores are '%s'",
	      step_alloc_cores);

	/*
	 * create user cgroup in the cpuset ns (it could already exist)
	 */
	if (xcgroup_create(&cpuset_ns,&user_cpuset_cg,
			   user_cgroup_path,
			   getuid(),getgid()) != XCGROUP_SUCCESS) {
		goto error;
	}
	if (xcgroup_instanciate(&user_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		goto error;
	}

	/*
	 * check that user's cpuset cgroup is consistant and add the job cores
	 */
	rc = xcgroup_get_param(&user_cpuset_cg, cpuset_meta, &cpus,&cpus_size);
	if (rc != XCGROUP_SUCCESS || cpus_size == 1) {
		/* initialize the cpusets as it was inexistant */
		if (_xcgroup_cpuset_init(&user_cpuset_cg) !=
		    XCGROUP_SUCCESS) {
			xcgroup_delete(&user_cpuset_cg);
			xcgroup_destroy(&user_cpuset_cg);
			goto error;
		}
	}
	user_alloc_cores = xstrdup(job_alloc_cores);
	if (cpus != NULL && cpus_size > 1) {
		cpus[cpus_size-1]='\0';
		xstrcat(user_alloc_cores,",");
		xstrcat(user_alloc_cores,cpus);
	}
	xcgroup_set_param(&user_cpuset_cg, cpuset_meta, user_alloc_cores);
	xfree(cpus);

	/*
	 * create job cgroup in the cpuset ns (it could already exist)
	 */
	if (xcgroup_create(&cpuset_ns,&job_cpuset_cg,
			   job_cgroup_path,
			   getuid(),getgid()) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		goto error;
	}
	if (xcgroup_instanciate(&job_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		goto error;
	}
	if (_xcgroup_cpuset_init(&job_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		goto error;
	}
	xcgroup_set_param(&job_cpuset_cg, cpuset_meta, job_alloc_cores);

	/*
	 * create step cgroup in the cpuset ns (it should not exists)
	 * use job's user uid/gid to enable tasks cgroups creation by
	 * the user inside the step cgroup owned by root
	 */
	if (xcgroup_create(&cpuset_ns,&step_cpuset_cg,
			   jobstep_cgroup_path,
			   uid,gid) != XCGROUP_SUCCESS) {
		/* do not delete user/job cgroup as */
		/* they can exist for other steps */
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		goto error;
	}
	if (xcgroup_instanciate(&step_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		xcgroup_destroy(&step_cpuset_cg);
		goto error;
	}
	if (_xcgroup_cpuset_init(&step_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		xcgroup_delete(&step_cpuset_cg);
		xcgroup_destroy(&step_cpuset_cg);
		goto error;
	}
	xcgroup_set_param(&step_cpuset_cg, cpuset_meta, step_alloc_cores);

	/*
	 * on Cray systems, set the expected usage in bytes.
	 * This is used by the Cray OOM killer
	 */
#ifdef HAVE_NATIVE_CRAY
	snprintf(expected_usage, sizeof(expected_usage), "%"PRIu64,
		 (uint64_t)job->step_mem * 1024 * 1024);
	xcgroup_set_param(&step_cpuset_cg, "expected_usage_in_bytes",
			  expected_usage);
#endif

	/* attach the slurmstepd to the step cpuset cgroup */
	pid_t pid = getpid();
	rc = xcgroup_add_pids(&step_cpuset_cg,&pid,1);
	if (rc != XCGROUP_SUCCESS) {
		error("task/cgroup: unable to add slurmstepd to cpuset cg '%s'",
		      step_cpuset_cg.path);
		fstatus = SLURM_ERROR;
	} else
		fstatus = SLURM_SUCCESS;

	/* validate the requested cpu frequency and set it */
	cpu_freq_cgroup_validate(job, step_alloc_cores);

error:
	xcgroup_unlock(&cpuset_cg);
	xcgroup_destroy(&cpuset_cg);

	xfree(user_alloc_cores);
	xfree(job_alloc_cores);
	xfree(step_alloc_cores);

	return fstatus;
}
Beispiel #28
0
/* Fill in all the accounts this user is coordinator over.  This
 * will fill in all the sub accounts they are coordinator over also.
 */
static int _get_user_coords(mysql_conn_t *mysql_conn, slurmdb_user_rec_t *user)
{
	char *query = NULL;
	slurmdb_coord_rec_t *coord = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	ListIterator itr = NULL, itr2 = NULL;
	char *cluster_name = NULL;

	if (!user) {
		error("We need a user to fill in.");
		return SLURM_ERROR;
	}

	if (!user->coord_accts)
		user->coord_accts = list_create(slurmdb_destroy_coord_rec);

	query = xstrdup_printf(
		"select acct from %s where user='******' && deleted=0",
		acct_coord_table, user->name);

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

	while ((row = mysql_fetch_row(result))) {
		coord = xmalloc(sizeof(slurmdb_coord_rec_t));
		list_append(user->coord_accts, coord);
		coord->name = xstrdup(row[0]);
		coord->direct = 1;
	}
	mysql_free_result(result);

	if (!list_count(user->coord_accts))
		return SLURM_SUCCESS;

	slurm_mutex_lock(&as_mysql_cluster_list_lock);
	itr2 = list_iterator_create(as_mysql_cluster_list);
	itr = list_iterator_create(user->coord_accts);
	while ((cluster_name = list_next(itr2))) {
		int set = 0;
		if (query)
			xstrcat(query, " union ");

		while ((coord = list_next(itr))) {
			if (set)
				xstrcat(query, " || ");
			else
				xstrfmtcat(query,
					   "select distinct t1.acct from "
					   "\"%s_%s\" as t1, \"%s_%s\" "
					   "as t2 where t1.deleted=0 && (",
					   cluster_name, assoc_table,
					   cluster_name, assoc_table);
			/* Make sure we don't get the same
			 * account back since we want to keep
			 * track of the sub-accounts.
			 */
			xstrfmtcat(query, "(t2.acct='%s' "
				   "&& t1.lft between t2.lft "
				   "and t2.rgt && t1.user='' "
				   "&& t1.acct!='%s')",
				   coord->name, coord->name);
			set = 1;
		}
		list_iterator_reset(itr);
		if (set)
			xstrcat(query, ")");

	}
	list_iterator_destroy(itr2);
	slurm_mutex_unlock(&as_mysql_cluster_list_lock);

	if (query) {
		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);

		while ((row = mysql_fetch_row(result))) {
			list_iterator_reset(itr);
			while ((coord = list_next(itr))) {
				if (!xstrcmp(coord->name, row[0]))
					break;
			}

			if (coord)
				continue;

			coord = xmalloc(sizeof(slurmdb_coord_rec_t));
			list_append(user->coord_accts, coord);
			coord->name = xstrdup(row[0]);
			coord->direct = 0;
		}
		mysql_free_result(result);
	}
	list_iterator_destroy(itr);

	return SLURM_SUCCESS;
}
Beispiel #29
0
static int _setup_cluster_cond_limits(slurmdb_cluster_cond_t *cluster_cond,
				      char **extra)
{
	int set = 0;
	ListIterator itr = NULL;
	char *object = NULL;

	if (!cluster_cond)
		return 0;

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

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

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

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

	if (cluster_cond->classification) {
		xstrfmtcat(*extra, " && (classification & %u)",
			   cluster_cond->classification);
	}

	if (cluster_cond->flags != NO_VAL) {
		xstrfmtcat(*extra, " && (flags & %u)",
			   cluster_cond->flags);
	}

	return set;
}
Beispiel #30
0
ftnmsg *mkftnhdr(rfcmsg *msg, int newsmode, faddr *recipient)
{
    char	    *freename = NULL, *rfcfrom = NULL, *p, *q, *l, *r;
    char	    *fbuf = NULL, *ftnfrom=NULL;
    static ftnmsg   *tmsg;
    int		    needreplyaddr = 1;
    faddr	    *tmp, *tmp2;

    tmsg=(ftnmsg *)malloc(sizeof(ftnmsg));
    memset(tmsg, 0, sizeof(ftnmsg));

    if (newsmode) {
	p = xstrcpy(hdr((char *)"Comment-To",msg));
	if (p == NULL) 
	    p = xstrcpy(hdr((char *)"X-Comment-To",msg));
	if (p == NULL) 
	    p = xstrcpy(hdr((char *)"X-FTN-To",msg));
	if (p == NULL) 
	    p = xstrcpy(hdr((char *)"X-Fidonet-Comment-To",msg));
	if (p == NULL) 
	    p = xstrcpy(hdr((char *)"X-Apparently-To",msg));
	if (p == NULL)
	    p = xstrcpy(hdr((char *)"To", msg));  /* 14-Aug-2001 MB */
	if (p) {
	    Syslog('m', "Getting `to' address from \"%s\"", MBSE_SS(p));

	    if ((tmsg->to = parsefaddr(p)) == NULL)
		tmsg->to = parsefaddr((char *)"[email protected]");
	    if ((l = strrchr(p,'<')) && (r = strchr(p,'>')) && (l < r)) {
		r = l;
		*r-- = '\0';
		if ((l = strchr(p,'"')) && (r = strrchr(p,'"')) && (l < r)) {
		    l++;
		    *r-- = '\0';
		}
		while (isspace(*r)) 
		    *r-- = '\0';
		if (!l) 
		    l = p;
		while (isspace(*l)) 
		    l++;
	    } else if ((l = strrchr(p,'(')) && (r = strchr(p,')')) && (l < r)) {
		*r-- = '\0';
		while (isspace(*r)) 
		    *r-- = '\0';
		l++;
		while (isspace(*l)) 
		    l++;
	    } else {
		l = p;
		while (isspace(*l)) 
		    l++;
		r = p + strlen(p) -1;
		if (*r == '\n') 
		    *r-- = '\0';
		while (isspace(*r)) 
		    *r-- = '\0';
	    }

	    if (*l) {
		if (strlen(l) > MAXNAME)
		    l[MAXNAME]='\0';
		free(tmsg->to->name);
		tmsg->to->name=xstrcpy(l);
	    }
	    free(p);
	    /*
	     *  It will become echomail, the destination FTN address must
	     *  be our address.  14-Aug-2001 MB.
	     */
	    tmsg->to->zone   = msgs.Aka.zone;
	    tmsg->to->net    = msgs.Aka.net;
	    tmsg->to->node   = msgs.Aka.node;
	    tmsg->to->point  = msgs.Aka.point;
	    tmsg->to->domain = xstrcpy(msgs.Aka.domain);
	} else {
	    /*
	     *  Filling a default To: address.
	     */
	    tmsg->to = (faddr*)malloc(sizeof(faddr));
	    tmsg->to->name   = xstrcpy((char *)"All");
	    tmsg->to->zone   = msgs.Aka.zone;
	    tmsg->to->net    = msgs.Aka.net;
	    tmsg->to->node   = msgs.Aka.node;
	    tmsg->to->point  = msgs.Aka.point;
	    tmsg->to->domain = xstrcpy(msgs.Aka.domain);
	}
    } else {
	if (recipient) {
	    /*
	     *  In mbmail mode the recipient is valid and must be used 
	     *  as the destination address. The To: field is probably
	     *  an RFC address an cannot be used to route the message.
	     */
	    tmsg->to = (faddr *)malloc(sizeof(faddr));
	    tmsg->to->point = recipient->point;
	    tmsg->to->node  = recipient->node;
	    tmsg->to->net   = recipient->net;
	    tmsg->to->zone  = recipient->zone;
	    tmsg->to->name  = xstrcpy(recipient->name);
	    if (tmsg->to->name && (strlen(tmsg->to->name) > MAXNAME))
		tmsg->to->name[MAXNAME]='\0';
	    tmsg->to->domain = xstrcpy(recipient->domain);
	    Syslog('m', "Recipient TO: %s", ascfnode(tmsg->to,0xff));
	} else {
	    p = xstrcpy(hdr((char *)"To",msg));
	    if (p == NULL)
		p = xstrcpy(hdr((char *)"X-Apparently-To",msg));
	    if (p) {
		if ((tmsg->to = parsefaddr(p)) == NULL)
		    WriteError("Unparsable destination address");
		else
		    Syslog('m', "RFC parsed TO: %s",ascfnode(tmsg->to,0xff));
	    }
	}
    } /* else (newsmode) */

    p = fbuf = xstrcpy(hdr((char *)"Reply-To", msg));
    if (fbuf == NULL) 
	p = fbuf = xstrcpy(hdr((char *)"From", msg));
    if (fbuf == NULL) 
	p = fbuf = xstrcpy(hdr((char *)"X-UUCP-From", msg));
    if (p) {
	q = p;
	while (isspace(*q)) 
	    q++;
	fbuf = parserfcaddr(q).remainder;
	if (parserfcaddr(q).target) {
	    fbuf = xstrcat(fbuf, (char *)"@");
	    fbuf = xstrcat(fbuf, parserfcaddr(q).target);
	}	
	rfcfrom = fbuf;
    }
    if (p)
	free(p);
    p = NULL;
    if (!rfcfrom) 
	rfcfrom = xstrcpy((char *)"postmaster");
    p = fbuf = xstrcpy(hdr((char *)"From", msg));
    if (fbuf == NULL) 
	p = fbuf = xstrcpy(hdr((char *)"X-UUCP-From", msg));
    if (p) {
	q = p;
	while (isspace(*q)) 
	    q++;
        if ((q) && (*q !=  '\0'))
            freename = parserfcaddr(q).comment;
        else 
	    freename = NULL;
    } else 
	freename = xstrcpy((char *)"Unidentified User");
    if (freename) {
	while (isspace(*freename)) 
	    freename++;
    }

    if (rfcfrom) {
	while (isspace(*rfcfrom)) 
	    rfcfrom++;
	p = rfcfrom + strlen(rfcfrom) -1;
	while ((isspace(*p)) || (*p == '\n')) 
	    *(p--)='\0';
    }

    if ((freename) && (*freename != '\0')) {
	while (isspace(*freename)) 
	    freename++;
	p = freename + strlen(freename) -1;
	while ((isspace(*p)) || (*p == '\n')) 
	    *(p--)='\0';
	if ((*freename == '\"') && (*(p=freename+strlen(freename)-1) == '\"')) {
	    freename++;
	    *p='\0';
	}
    }
    // if (*freename == '\0') freename=rfcfrom;
    if ((!freename) || ((freename) && (*freename == '\0')) || (strcmp(freename,".")==0)) 
	freename=rfcfrom;

    if (! newsmode)
	Syslog('+', "from: %s <%s>",freename,rfcfrom);

    needreplyaddr = 1;
    if ((tmsg->from=parsefaddr(rfcfrom)) == NULL) {
	if (freename && rfcfrom)
	    if (!strchr(freename,'@') && !strchr(freename,'%') && 
			    strncasecmp(freename,rfcfrom,MAXNAME) &&
			    strncasecmp(freename,"uucp",4) &&
			    strncasecmp(freename,"usenet",6) &&
			    strncasecmp(freename,"news",4) &&
			    strncasecmp(freename,"super",5) &&
			    strncasecmp(freename,"admin",5) &&
			    strncasecmp(freename,"postmaster",10) &&
			    strncasecmp(freename,"sys",3)) 
		needreplyaddr=registrate(freename,rfcfrom);
    } else {
	tmsg->ftnorigin = 1;
	tmsg->from->name = xstrcpy(freename);
	if (strlen(tmsg->from->name) > MAXNAME)
	    tmsg->from->name[MAXNAME]='\0';
    }
    if (replyaddr) {
	free(replyaddr);
	replyaddr=NULL;
    }
    if (needreplyaddr && (tmsg->from == NULL)) {
	replyaddr=xstrcpy(rfcfrom);
    }

    if (tmsg->from)
	Syslog('m', "From address was%s distinguished as ftn", tmsg->from ? "" : " not");

    if (newsmode) {
	tmp2 = fido2faddr(msgs.Aka);
	bestaka = bestaka_s(tmp2);
	tidy_faddr(tmp2);
    } else
	bestaka = bestaka_s(tmsg->to);

    if ((tmsg->from == NULL) && (bestaka)) {
	if (CFG.dontregate) {
	    p = xstrcpy(hdr((char *)"X-FTN-Sender",msg));
	    if (p == NULL) {
		if ((p = hdr((char *)"X-FTN-From",msg))) {
		    tmp = parsefnode(p);
		    p = xstrcpy(ascinode(tmp, 0xff));
		    tidy_faddr(tmp);
		}
	    }
	    if (p) {
	        q = p;
		while (isspace(*q)) 
		    q++;
		ftnfrom = parserfcaddr(q).remainder;
		if (parserfcaddr(q).target) {
		    ftnfrom = xstrcat(ftnfrom,(char *)"@");
		    ftnfrom = xstrcat(ftnfrom,parserfcaddr(q).target);
		}	
		Syslog('m', "Ftn gateway: \"%s\"", ftnfrom);
		Syslog('+', "Ftn sender: %s",ftnfrom);
		if (ftnfrom) 
		    tmsg->from = parsefaddr(ftnfrom);
		if ((tmsg->from) && (!tmsg->from->name))
		    tmsg->from->name = xstrcpy(rfcfrom);
	    }
	    if (p)
		free(p);
	    p = NULL;
	    if (tmsg->from == NULL) {
		tmsg->from=(faddr *)malloc(sizeof(faddr));
		tmsg->from->name=xstrcpy(freename);
		if (tmsg->from->name && (strlen(tmsg->from->name) > MAXNAME))
		    tmsg->from->name[MAXNAME]='\0';
		tmsg->from->point=bestaka->point;
		tmsg->from->node=bestaka->node;
		tmsg->from->net=bestaka->net;
		tmsg->from->zone=bestaka->zone;
		tmsg->from->domain=xstrcpy(bestaka->domain);
	    }
	} else {
	    tmsg->from=(faddr *)xmalloc(sizeof(faddr));
	    tmsg->from->name=xstrcpy(freename);
	    if (tmsg->from->name && (strlen(tmsg->from->name) > MAXNAME))
		tmsg->from->name[MAXNAME]='\0';
	    tmsg->from->point=bestaka->point;
	    tmsg->from->node=bestaka->node;
	    tmsg->from->net=bestaka->net;
	    tmsg->from->zone=bestaka->zone;
	    tmsg->from->domain=xstrcpy(bestaka->domain);
	}
    }
    if (fbuf) 
	free(fbuf); 
    fbuf = NULL;

    p = hdr((char *)"Subject", msg);
    if (p) {
	while (isspace(*p)) 
	    p++;
	tmsg->subj = xstrcpy(p);
	if (*(p=tmsg->subj+strlen(tmsg->subj)-1) == '\n') 
	    *p='\0';
	if (strlen(tmsg->subj) > MAXSUBJ) 
	    tmsg->subj[MAXSUBJ]='\0';
    } else {
	tmsg->subj = xstrcpy((char *)" ");
    }

    if ((p = hdr((char *)"X-FTN-FLAGS",msg))) 
	tmsg->flags |= flagset(p);
    if (hdr((char *)"Return-Receipt-To",msg)) 
	tmsg->flags |= M_RRQ;
    if (hdr((char *)"Notice-Requested-Upon-Delivery-To",msg)) 
	tmsg->flags |= M_RRQ;
    if (!newsmode) {
	tmsg->flags |= M_PVT;
	tmsg->flags |= M_KILLSENT;
    }

    if ((p = hdr((char *)"X-Origin-Date",msg))) 
	tmsg->date = parsedate(p, NULL) - (gmt_offset((time_t)0) * 60);
    else if ((p = hdr((char *)"Date",msg))) 
	tmsg->date = parsedate(p, NULL) - (gmt_offset((time_t)0) * 60);
    else 
	tmsg->date = time((time_t *)NULL);

    /*
     * SunMail 1.0 creates invalid date formats like: Wed, 19 Jun 2002 18:21:07 GMT-08:00
     *                                                                                ^---- not allowed.
     */
    if (tmsg->date == -1) {
	Syslog('!', "Parsing date \"%s\" failed, using current date", p);
	tmsg->date = time((time_t *)NULL);
    }
	
    if ((p = hdr((char *)"X-FTN-MSGID", msg))) {
	tmsg->ftnorigin &= 1;
	while (isspace(*p)) 
	    p++;
	tmsg->msgid_s = xstrcpy(p);
	if (*(p = tmsg->msgid_s + strlen(tmsg->msgid_s) -1) == '\n') 
	    *p='\0';
    } else if ((p = hdr((char *)".MSGID",msg))) {
	tmsg->ftnorigin &= 1;
	while (isspace(*p)) 
	    p++;
	tmsg->msgid_s = xstrcpy(p);
	if (*(p = tmsg->msgid_s + strlen(tmsg->msgid_s) -1) == '\n') 
	    *p='\0';
    } else if ((p = hdr((char *)"Message-ID",msg))) {
	tmsg->ftnorigin &= ftnmsgid(p,&(tmsg->msgid_a),&(tmsg->msgid_n),tmsg->area);
    } else
	tmsg->msgid_a = NULL;

    if ((p = hdr((char *)"X-FTN-REPLY",msg))) {
	while (isspace(*p)) 
	    p++;
	tmsg->reply_s = xstrcpy(p);
	if (*(p=tmsg->reply_s + strlen(tmsg->reply_s) -1) == '\n') 
	    *p='\0';
    } else {
	if (newsmode) {
	    p = hdr((char *)"References",msg);
	    if (p) {       
		l = xstrcpy(p);
		r = strtok(l," \t\n");
		while ((l=strtok(NULL," \t\n")) != NULL) 
		    r = l;
		p = r;
		free(l);
	    }
	} else
	    p = hdr((char *)"In-Reply-To",msg);
    }
    if (p)
	(void)ftnmsgid(p,&(tmsg->reply_a),&(tmsg->reply_n),NULL);
    else
	tmsg->reply_a=NULL;

    p = hdr((char *)"Organization",msg);
    if (p == NULL)
	p = hdr((char *)"Organisation",msg);
    if (p) {
	while (isspace(*p)) 
	    p++;
	tmsg->origin = xstrcpy(p);
	if (tmsg->origin)
	    if (*(p = tmsg->origin + strlen(tmsg->origin)-1) == '\n') 
		*p='\0';
    } else {
	/*
	 *  No Organization header, insert the default BBS origin.
	 */
	tmsg->origin = xstrcpy(CFG.origin);
    }

    return tmsg;
}