Example #1
0
/*
 * _build_user_list- build a list of UIDs
 * IN str - comma separated list of user names
 * RET List of UIDs (uint32_t)
 */
static List
_build_user_list( char* str )
{
	List my_list;
	char *user = NULL;
	char *tmp_char = NULL, *my_user_list = NULL;
	uid_t uid = (uid_t) 0;

	if ( str == NULL)
		return NULL;

	my_list = list_create( NULL );
	my_user_list = xstrdup( str );
	user = strtok_r( my_user_list, ",", &tmp_char );
	while (user) {
		if (uid_from_string (user, &uid) < 0) {
			error( "Invalid user: %s\n", user);
		} else {
			uint32_t *u_tmp = xmalloc( sizeof( uint32_t ));
			*u_tmp = (uint32_t) uid;
			list_append( my_list, u_tmp );
		}
		user = strtok_r (NULL, ",", &tmp_char);
	}
	return my_list;
}
Example #2
0
/*
 * opt_verify : perform some post option processing verification
 *
 */
static bool
_opt_verify(void)
{
	bool verified = true;

	if (opt.user_name) {	/* translate to user_id */
		if ( uid_from_string( opt.user_name, &opt.user_id ) != 0 ) {
			error("Invalid user name: %s", opt.user_name);
			return false;
		}
	}

	if ((opt.account == 0) &&
	    (opt.job_cnt == 0) &&
	    (opt.job_name == NULL) &&
	    (opt.nodelist == NULL) &&
	    (opt.partition == NULL) &&
	    (opt.qos == NULL) &&
	    (opt.reservation == NULL) &&
	    (opt.state == JOB_END) &&
	    (opt.user_name == NULL) &&
	    (opt.wckey == NULL)) {
		error("No job identification provided");
		verified = false;	/* no job specification */
	}

	return verified;
}
Example #3
0
static uid_t *_xlate_users(char *user_str, int *user_cnt)
{
	char *tok, *tmp_str, *save_ptr = NULL;
	uid_t uid, *uid_ptr = NULL;

	*user_cnt = 0;
	if ((user_str == NULL) || (user_str[0] == '\0'))
		return uid_ptr;

	tmp_str = xstrdup(user_str);
	tok = strtok_r(tmp_str, ",", &save_ptr);
	while (tok) {
		int rc = 0;
		if (!strcasecmp(tok, "ALL"))
			uid = NO_VAL;
		else
			rc = uid_from_string(tok, &uid);
		if (rc < 0) {
			error("nonstop.conf: Invalid user: %s", tok);
		} else {
			xrealloc(uid_ptr, (sizeof(uid_t) * (*user_cnt + 1)));
			uid_ptr[*user_cnt] = uid;
			(*user_cnt)++;
		}
		tok = strtok_r(NULL, ",", &save_ptr);
	}
	xfree(tmp_str);
	return uid_ptr;
}
Example #4
0
/* Translate colon delimitted list of users into a UID array,
 * Return value must be xfreed */
static uid_t *_parse_users(char *buf)
{
	char *delim, *tmp, *tok, *save_ptr = NULL;
	int inx = 0, array_size;
	uid_t *user_array = NULL;

	if (!buf)
		return user_array;
	tmp = xstrdup(buf);
	delim = strchr(tmp, ',');
	if (delim)
		delim[0] = '\0';
	array_size = 1;
	user_array = xmalloc(sizeof(uid_t) * array_size);
	tok = strtok_r(tmp, ":", &save_ptr);
	while (tok) {
		if ((uid_from_string(tok, user_array + inx) == -1) ||
		    (user_array[inx] == 0)) {
			error("%s: ignoring invalid user: %s", __func__, tok);
		} else {
			if (++inx >= array_size) {
				array_size *= 2;
				user_array = xrealloc(user_array,
						      sizeof(uid_t)*array_size);
			}
		}
		tok = strtok_r(NULL, ":", &save_ptr);
	}
	xfree(tmp);
	return user_array;
}
Example #5
0
/* All changes to the bg_list target_name must
   be done before this function is called.
   also slurm_conf_lock() must be called before calling this
   function along with slurm_conf_unlock() afterwards.
*/
extern int update_block_user(bg_record_t *bg_record, int set)
{
	int rc=0;

	if (!bg_record->target_name) {
		error("Must set target_name to run update_block_user.");
		return -1;
	}
	if (!bg_record->user_name) {
		error("No user_name");
		bg_record->user_name = xstrdup(bg_conf->slurm_user_name);
	}

	if (set) {
		if ((rc = bridge_block_remove_all_users(
			     bg_record, bg_record->target_name))
		    == REMOVE_USER_ERR) {
			error("1 Something happened removing "
			      "users from block %s",
			      bg_record->bg_block_id);
			return -1;
		} else if (rc == REMOVE_USER_NONE) {
			if (strcmp(bg_record->target_name,
				   bg_conf->slurm_user_name)) {
				info("Adding user %s to Block %s",
				     bg_record->target_name,
				     bg_record->bg_block_id);

				if ((rc = bridge_block_add_user(
					     bg_record,
					     bg_record->target_name))
				    != SLURM_SUCCESS) {
					error("bridge_add_block_user"
					      "(%s,%s): %s",
					      bg_record->bg_block_id,
					      bg_record->target_name,
					      bg_err_str(rc));
					return -1;
				}
			}
		}
	}

	if (strcmp(bg_record->target_name, bg_record->user_name)) {
		uid_t pw_uid;
		xfree(bg_record->user_name);
		bg_record->user_name = xstrdup(bg_record->target_name);
		if (uid_from_string (bg_record->user_name, &pw_uid) < 0) {
			error("No such user: %s", bg_record->user_name);
			return -1;
		} else {
			bg_record->user_uid = pw_uid;
		}
		return 1;
	}

	return 0;
}
Example #6
0
static char *_string_to_uid( char *name )
{
	uid_t uid;
	if ( uid_from_string( name, &uid ) != 0 ) {
		fprintf(stderr, "Invalid user id: %s\n", name);
		exit(1);
	}
	xfree(name);
	return xstrdup_printf( "%d", (int) uid );
}
Example #7
0
static char *_convert_to_id(char *name, bool gid)
{
	if (gid) {
		gid_t gid;
		if ( gid_from_string( name, &gid ) != 0 ) {
			fprintf(stderr, "Invalid group id: %s\n", name);
			exit(1);
		}
		xfree(name);
		name = xstrdup_printf( "%d", (int) gid );
	} else {
		uid_t uid;
		if ( uid_from_string( name, &uid ) != 0 ) {
			fprintf(stderr, "Invalid user id: %s\n", name);
			exit(1);
		}
		xfree(name);
		name = xstrdup_printf( "%d", (int) uid );
	}
	return name;
}
Example #8
0
/* Translate comma delimited string of UIDs/user names into a zero terminated
 * array of UIDs */
uid_t *_xlate_users(char *user_str, char *key)
{
	char *tmp_str, *token, *save_ptr = NULL;
	uid_t *uids_array = NULL;
	int array_size = 0;
	uid_t uid;

	if (!user_str || !user_str[0])
		return uids_array;

	tmp_str = xstrdup(user_str);
	token = strtok_r(tmp_str, ",", &save_ptr);
	while (token) {
		if (uid_from_string(token, &uid) || (uid == (uid_t) 0)) {
			error("Invalid %s value (%s), ignored", key, token);
		} else {
			xrealloc(uids_array, sizeof(uid_t) * (array_size+2));
			uids_array[array_size++] = uid;
		}
		token = strtok_r(NULL, ",", &save_ptr);
	}
	xfree(tmp_str);
	return uids_array;
}
Example #9
0
File: groups.c Project: VURM/slurm
/*
 * get_group_members - identify the users in a given group name
 * IN group_name - a single group name
 * RET a zero terminated list of its UIDs or NULL on error
 * NOTE: User root has implicitly access to every group
 * NOTE: The caller must xfree non-NULL return values
 */
extern uid_t *get_group_members(char *group_name)
{
	char grp_buffer[PW_BUF_SIZE];
  	struct group grp,  *grp_result = NULL;
	struct passwd *pwd_result = NULL;
	uid_t *group_uids = NULL, my_uid;
	gid_t my_gid;
	int i, j, uid_cnt;
#ifdef HAVE_AIX
	FILE *fp = NULL;
#elif defined (__APPLE__) || defined (__CYGWIN__)
#else
	char pw_buffer[PW_BUF_SIZE];
	struct passwd pw;
#endif

	group_uids = _get_group_cache(group_name);
	if (group_uids)	{	/* We found in cache */
		_log_group_members(group_name, group_uids);
		return group_uids;
	}

	/* We need to check for !grp_result, since it appears some
	 * versions of this function do not return an error on failure.
	 */
	if (getgrnam_r(group_name, &grp, grp_buffer, PW_BUF_SIZE,
		       &grp_result) || (grp_result == NULL)) {
		error("Could not find configured group %s", group_name);
		return NULL;
	}
	my_gid = grp_result->gr_gid;

	j = 0;
	uid_cnt = 0;
#ifdef HAVE_AIX
	setgrent_r(&fp);
	while (!getgrent_r(&grp, grp_buffer, PW_BUF_SIZE, &fp)) {
		grp_result = &grp;
#elif defined (__APPLE__) || defined (__CYGWIN__)
	setgrent();
	while ((grp_result = getgrent()) != NULL) {
#else
	setgrent();
	while (getgrent_r(&grp, grp_buffer, PW_BUF_SIZE,
			  &grp_result) == 0 && grp_result != NULL) {
#endif
	        if (grp_result->gr_gid == my_gid) {
			if (strcmp(grp_result->gr_name, group_name)) {
				debug("including members of group '%s' as it "
				      "corresponds to the same gid as group"
				      " '%s'",grp_result->gr_name,group_name);
			}

		        for (i=0; grp_result->gr_mem[i]; i++) {
				if (uid_from_string(grp_result->gr_mem[i],
						    &my_uid) < 0) {
					/* Group member without valid login */
					continue;
				}
				if (my_uid == 0)
					continue;
				if (j >= uid_cnt) {
					uid_cnt += 100;
					xrealloc(group_uids, 
						 (sizeof(uid_t) * uid_cnt));
				}
				group_uids[j++] = my_uid;
			}
		}
	}
#ifdef HAVE_AIX
	endgrent_r(&fp);
	setpwent_r(&fp);
	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &fp)) {
		pwd_result = &pw;
#else
	endgrent();
	setpwent();
#if defined (__sun)
	while ((pwd_result = getpwent_r(&pw, pw_buffer, PW_BUF_SIZE)) != NULL) {
#elif defined (__APPLE__) || defined (__CYGWIN__)
	while ((pwd_result = getpwent()) != NULL) {
#else
	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &pwd_result)) {
#endif
#endif
 		if (pwd_result->pw_gid != my_gid)
			continue;
		if (j >= uid_cnt) {
			uid_cnt += 100;
			xrealloc(group_uids, (sizeof(uid_t) * uid_cnt));
		}
		group_uids[j++] = pwd_result->pw_uid;
	}
#ifdef HAVE_AIX
	endpwent_r(&fp);
#else
	endpwent();
#endif

	_put_group_cache(group_name, group_uids, uid_cnt);
	_log_group_members(group_name, group_uids);
	return group_uids;
}

/* Delete our group/uid cache */
extern void clear_group_cache(void)
{
	pthread_mutex_lock(&group_cache_mutex);
	if (group_cache_list) {
		list_destroy(group_cache_list);
		group_cache_list = NULL;
	}
	pthread_mutex_unlock(&group_cache_mutex);
}

/* Get a record from our group/uid cache. 
 * Return NULL if not found. */
static uid_t *_get_group_cache(char *group_name)
{
	ListIterator iter;
	struct group_cache_rec *cache_rec;
	uid_t *group_uids = NULL;
	int sz;

	pthread_mutex_lock(&group_cache_mutex);
	if (!group_cache_list) {
		pthread_mutex_unlock(&group_cache_mutex);
		return NULL;
	}

	iter = list_iterator_create(group_cache_list);
	if (!iter)
		fatal("list_iterator_create: malloc failure");
	while ((cache_rec = (struct group_cache_rec *) list_next(iter))) {
		if (strcmp(group_name, cache_rec->group_name))
			continue;
		sz = sizeof(uid_t) * (cache_rec->uid_cnt + 1);
		group_uids = (uid_t *) xmalloc(sz);
		memcpy(group_uids, cache_rec->group_uids, sz);
		break;
	}
	list_iterator_destroy(iter);
	pthread_mutex_unlock(&group_cache_mutex);
	return group_uids;
}

/* Delete a record from the group/uid cache, used by list functions */
static void _cache_del_func(void *x)
{
	struct group_cache_rec *cache_rec;

	cache_rec = (struct group_cache_rec *) x;
	xfree(cache_rec->group_name);
	xfree(cache_rec->group_uids);
	xfree(cache_rec);
}

/* Put a record on our group/uid cache */
static void _put_group_cache(char *group_name, void *group_uids, int uid_cnt)
{
	struct group_cache_rec *cache_rec;
	int sz;

	pthread_mutex_lock(&group_cache_mutex);
	if (!group_cache_list) {
		group_cache_list = list_create(_cache_del_func);
		if (!group_cache_list)
			fatal("list_create: malloc failure:");
	}

	sz = sizeof(uid_t) * (uid_cnt + 1);
	cache_rec = xmalloc(sizeof(struct group_cache_rec));
	cache_rec->group_name = xstrdup(group_name);
	cache_rec->uid_cnt    = uid_cnt;
	cache_rec->group_uids = (uid_t *) xmalloc(sz);
	if (uid_cnt > 0)
		memcpy(cache_rec->group_uids, group_uids, sz);
	list_append(group_cache_list, cache_rec);
	pthread_mutex_unlock(&group_cache_mutex);
}

static void _log_group_members(char *group_name, uid_t *group_uids)
{
#if _DEBUG
	int i;

	if ((group_uids == NULL) || (group_uids[0] == 0)) {
		info("Group %s has no users", group_name);
		return;
	}

	info("Group %s contains uids:", group_name);
	for (i=0; group_uids && group_uids[i]; i++)
		info("  %u", group_uids[i]);
#endif
}
Example #10
0
/* block_state_mutex must be locked before calling this. */
extern int add_bg_record(List records, List *used_nodes,
			 select_ba_request_t *blockreq,
			 bool no_check, bitoff_t io_start)
{
	bg_record_t *bg_record = NULL;
	ba_mp_t *ba_mp = NULL;
	ListIterator itr;
	uid_t pw_uid;
	int i, len;
	int small_count = 0;

	xassert(bg_conf->slurm_user_name);

	if (!records) {
		fatal("add_bg_record: no records list given");
	}
	bg_record = (bg_record_t*) xmalloc(sizeof(bg_record_t));

	bg_record->magic = BLOCK_MAGIC;

	bg_record->user_name = xstrdup(bg_conf->slurm_user_name);
	bg_record->target_name = xstrdup(bg_conf->slurm_user_name);

	if (uid_from_string (bg_record->user_name, &pw_uid) < 0)
		error("add_bg_record: No such user: %s", bg_record->user_name);
	else
		bg_record->user_uid = pw_uid;

	if (used_nodes && *used_nodes) {
#ifdef HAVE_BGQ
		bg_record->ba_mp_list = *used_nodes;
		*used_nodes = NULL;
#else
		bg_record->ba_mp_list = list_create(destroy_ba_mp);
		if (copy_node_path(*used_nodes, &bg_record->ba_mp_list)
		    == SLURM_ERROR)
			error("add_bg_record: "
			      "couldn't copy the path for the allocation");
#endif
	} else
		bg_record->ba_mp_list = list_create(destroy_ba_mp);

	/* bg_record->boot_state = 0; 	Implicit */
	bg_record->state = BG_BLOCK_FREE;

#ifdef HAVE_BGL
	if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK)
		info("add_bg_record: asking for %s %d %d %s",
		     blockreq->save_name, blockreq->small32, blockreq->small128,
		     conn_type_string(blockreq->conn_type[0]));
#else
	if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK)
		info("add_bg_record: asking for %s %d %d %d %d %d %s",
		     blockreq->save_name, blockreq->small256,
		     blockreq->small128, blockreq->small64,
		     blockreq->small32, blockreq->small16,
		     conn_type_string(blockreq->conn_type[0]));
#endif
	/* Set the bitmap blank here if it is a full node we don't
	   want anything set we also don't want the bg_record->ionode_str set.
	*/
	bg_record->ionode_bitmap = bit_alloc(bg_conf->ionodes_per_mp);
	bg_record->mp_used_bitmap = bit_alloc(node_record_count);

	len = strlen(blockreq->save_name);
	i=0;
	while (i<len
	       && blockreq->save_name[i] != '['
	       && (blockreq->save_name[i] < '0' || blockreq->save_name[i] > 'Z'
		   || (blockreq->save_name[i] > '9'
		       && blockreq->save_name[i] < 'A')))
		i++;

	if (i<len) {
		len -= i;

		len += strlen(bg_conf->slurm_node_prefix)+1;
		bg_record->mp_str = xmalloc(len);
		snprintf(bg_record->mp_str, len, "%s%s",
			 bg_conf->slurm_node_prefix, blockreq->save_name+i);
	} else
		fatal("add_bg_record: MPs=%s is in a weird format",
		      blockreq->save_name);

	process_nodes(bg_record, false);

#ifdef HAVE_BGL
	bg_record->node_use = SELECT_COPROCESSOR_MODE;
#endif
	memcpy(bg_record->conn_type, blockreq->conn_type,
	       sizeof(bg_record->conn_type));

	bg_record->cpu_cnt = bg_conf->cpus_per_mp * bg_record->mp_count;
	bg_record->cnode_cnt = bg_conf->mp_cnode_cnt * bg_record->mp_count;
	bg_record->job_running = NO_JOB_RUNNING;

#ifdef HAVE_BGL
	if (blockreq->blrtsimage)
		bg_record->blrtsimage = xstrdup(blockreq->blrtsimage);
	else
		bg_record->blrtsimage = xstrdup(bg_conf->default_blrtsimage);
#endif

#ifdef HAVE_BG_L_P
	if (blockreq->linuximage)
		bg_record->linuximage = xstrdup(blockreq->linuximage);
	else
		bg_record->linuximage = xstrdup(bg_conf->default_linuximage);
	if (blockreq->ramdiskimage)
		bg_record->ramdiskimage = xstrdup(blockreq->ramdiskimage);
	else
		bg_record->ramdiskimage =
			xstrdup(bg_conf->default_ramdiskimage);
#endif
	if (blockreq->mloaderimage)
		bg_record->mloaderimage = xstrdup(blockreq->mloaderimage);
	else
		bg_record->mloaderimage =
			xstrdup(bg_conf->default_mloaderimage);

	if (bg_record->conn_type[0] < SELECT_SMALL) {
		/* this needs to be an append so we keep things in the
		   order we got them, they will be sorted later */
		list_append(records, bg_record);
		/* this isn't a correct list so we need to set it later for
		   now we just used it to be the mp number */
		if (!used_nodes) {
			debug4("add_bg_record: "
			       "we didn't get a request list so we are "
			       "destroying this mp list");
			list_destroy(bg_record->ba_mp_list);
			bg_record->ba_mp_list = NULL;
		}
	} else {
		List ba_mp_list = NULL;

		if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK)
			info("add_bg_record: adding a small block");
		if (no_check)
			goto no_check;
		/* if the ionode cnt for small32 is 0 then don't
		   allow a sub quarter allocation
		*/
		if (bg_conf->nodecard_ionode_cnt < 2) {
			if (!bg_conf->nodecard_ionode_cnt && blockreq->small32)
				fatal("add_bg_record: "
				      "There is an error in your "
				      "bluegene.conf file.\n"
				      "Can't create a 32 node block with "
				      "IonodesPerMP=%u. (Try setting it "
				      "to at least 16)",
				      bg_conf->ionodes_per_mp);
#ifndef HAVE_BGL
			if (blockreq->small16)
				fatal("add_bg_record: "
				      "There is an error in your "
				      "bluegene.conf file.\n"
				      "Can't create a 16 node block with "
				      "IonodesPerMP=%u. (Try setting it to "
				      "at least 32)",
				      bg_conf->ionodes_per_mp);
			if ((bg_conf->io_ratio < 0.5) && blockreq->small64)
				fatal("add_bg_record: "
				      "There is an error in your "
				      "bluegene.conf file.\n"
				      "Can't create a 64 node block with "
				      "IonodesPerMP=%u. (Try setting it "
				      "to at least 8)",
				      bg_conf->ionodes_per_mp);
#endif
		}

#ifdef HAVE_BGL
		if (blockreq->small32==0 && blockreq->small128==0) {
			info("add_bg_record: "
			     "No specs given for this small block, "
			     "I am spliting this block into 4 128CnBlocks");
			blockreq->small128=4;
		}

		i = (blockreq->small32*bg_conf->nodecard_cnode_cnt) +
			(blockreq->small128*bg_conf->quarter_cnode_cnt);
		if (i != bg_conf->mp_cnode_cnt)
			fatal("add_bg_record: "
			      "There is an error in your bluegene.conf file.\n"
			      "I am unable to request %d nodes consisting of "
			      "%u 32CnBlocks and\n%u 128CnBlocks in one "
			      "base partition with %u nodes.",
			      i, blockreq->small32, blockreq->small128,
			      bg_conf->mp_cnode_cnt);
		small_count = blockreq->small32+blockreq->small128;
#else
		if (!blockreq->small16 && !blockreq->small32
		    && !blockreq->small64 && !blockreq->small128
		    && !blockreq->small256) {
			info("add_bg_record: "
			     "No specs given for this small block, "
			     "I am spliting this block into 2 256CnBlocks");
			blockreq->small256=2;
		}

		i = (blockreq->small16*16)
			+ (blockreq->small32*32)
			+ (blockreq->small64*64)
			+ (blockreq->small128*128)
			+ (blockreq->small256*256);
		if (i != bg_conf->mp_cnode_cnt)
			fatal("add_bg_record: "
			      "There is an error in your bluegene.conf file.\n"
			      "I am unable to request %d nodes consisting of "
			      "%u 16CNBlocks, %u 32CNBlocks,\n"
			      "%u 64CNBlocks, %u 128CNBlocks, "
			      "and %u 256CNBlocks\n"
			      "in one base partition with %u nodes.",
			      i, blockreq->small16, blockreq->small32,
			      blockreq->small64, blockreq->small128,
			      blockreq->small256, bg_conf->mp_cnode_cnt);
		small_count = blockreq->small16
			+ blockreq->small32
			+ blockreq->small64
			+ blockreq->small128
			+ blockreq->small256;
#endif
	no_check:
		/* Automatically create 2-way split if
		 * conn_type == SELECT_SMALL in bluegene.conf
		 * Here we go through each node listed and do the same thing
		 * for each node.
		 */
		ba_mp_list = bg_record->ba_mp_list;
		bg_record->ba_mp_list = list_create(NULL);
		itr = list_iterator_create(ba_mp_list);
		while ((ba_mp = list_next(itr)) != NULL) {
			xfree(bg_record->mp_str);
			bg_record->mp_str = xstrdup_printf(
				"%s%s",
				bg_conf->slurm_node_prefix,
				ba_mp->coord_str);
			list_append(bg_record->ba_mp_list, ba_mp);
			handle_small_record_request(records, blockreq,
						    bg_record, io_start);
			list_flush(bg_record->ba_mp_list);
		}
		list_iterator_destroy(itr);
		destroy_bg_record(bg_record);
		list_destroy(ba_mp_list);
	}

	return SLURM_SUCCESS;
}
Example #11
0
static void _admin_front_end(GtkTreeModel *model, GtkTreeIter *iter, char *type,
			     char *node_list)
{
	uint16_t state = (uint16_t) NO_VAL;
	update_front_end_msg_t front_end_update_msg;
	char *new_type = NULL, *reason = NULL;
	char tmp_char[100];
	char *lower;
	int rc;
	GtkWidget *label = NULL;
	GtkWidget *entry = NULL;
	GtkWidget *popup = NULL;

	if (cluster_flags & CLUSTER_FLAG_FED) {
		display_fed_disabled_popup(type);
		global_entry_changed = 0;
		return;
	}

	popup = gtk_dialog_new_with_buttons(
		type,
		GTK_WINDOW(main_window),
		GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
		NULL);

	gtk_window_set_transient_for(GTK_WINDOW(popup), NULL);

	label = gtk_dialog_add_button(GTK_DIALOG(popup),
				      GTK_STOCK_YES, GTK_RESPONSE_OK);
	gtk_window_set_default(GTK_WINDOW(popup), label);
	gtk_dialog_add_button(GTK_DIALOG(popup),
			      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);

	if (!strncasecmp("Drain", type, 5)) {
		new_type = "DRAIN";
		reason = "\n\nPlease enter reason.";
		state = NODE_STATE_DRAIN;
		entry = create_entry();
	} else if (!strncasecmp("Resume", type, 6)) {
		new_type = "RESUME";
		reason = "";
		state = NODE_RESUME;
	}
	snprintf(tmp_char, sizeof(tmp_char),
		 "Are you sure you want to set state of front end node %s "
		 "to %s?%s", node_list, new_type, reason);
	label = gtk_label_new(tmp_char);

	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
			   label, false, false, 0);
	if (entry)
		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
				   entry, true, true, 0);
	gtk_widget_show_all(popup);
	rc = gtk_dialog_run (GTK_DIALOG(popup));

	slurm_init_update_front_end_msg(&front_end_update_msg);

	if (rc == GTK_RESPONSE_OK) {
		front_end_update_msg.name = node_list;
		front_end_update_msg.node_state = state;
		if (entry) {
			front_end_update_msg.reason = xstrdup(
				gtk_entry_get_text(GTK_ENTRY(entry)));
			if (!front_end_update_msg.reason ||
			    !strlen(front_end_update_msg.reason)) {
				lower = g_strdup_printf(
					"You need a reason to do that.");
				display_edit_note(lower);
				g_free(lower);
				goto end_it;
			}
			rc = uid_from_string(getlogin(),
					     &front_end_update_msg.reason_uid);
			if (rc < 0)
				front_end_update_msg.reason_uid = getuid();
		}

		rc = slurm_update_front_end(&front_end_update_msg);
		if (rc == SLURM_SUCCESS) {
			lower = g_strdup_printf(
				"Nodes %s updated successfully.",
				node_list);
			display_edit_note(lower);
			g_free(lower);
		} else {
			lower = g_strdup_printf(
				"Problem updating nodes %s: %s",
				node_list, slurm_strerror(rc));
			display_edit_note(lower);
			g_free(lower);
		}
	}

end_it:
	global_entry_changed = 0;
	xfree(front_end_update_msg.reason);
	gtk_widget_destroy(popup);
	if (got_edit_signal) {
		type = got_edit_signal;
		got_edit_signal = NULL;
		_admin_front_end(model, iter, type, node_list);
		xfree(type);
	}
	return;
}
Example #12
0
/*
 * scontrol_update_front_end - update the slurm front_end node configuration
 *	per the supplied arguments
 * IN argc - count of arguments
 * IN argv - list of arguments
 * RET 0 if no slurm error, errno otherwise. parsing error prints
 *			error message and returns 0
 */
extern int
scontrol_update_front_end (int argc, char **argv)
{
	int i, rc = 0, update_cnt = 0;
	update_front_end_msg_t front_end_msg;
	char *reason_str = NULL;
	char *tag, *val;
	int tag_len, val_len;

	slurm_init_update_front_end_msg(&front_end_msg);
	for (i=0; i<argc; i++) {
		tag = argv[i];
		val = strchr(argv[i], '=');
		if (val) {
			tag_len = val - argv[i];
			val++;
			val_len = strlen(val);
		} else {
			exit_code = 1;
			error("Invalid input: %s  Request aborted", argv[i]);
			return -1;
		}
		if (xstrncasecmp(tag, "FrontendName", MAX(tag_len, 1)) == 0)
			front_end_msg.name = val;
		else if (xstrncasecmp(tag, "Reason", MAX(tag_len, 1)) == 0) {
			int len = strlen(val);
			reason_str = xmalloc(len+1);
			if (*val == '"')
				strcpy(reason_str, val+1);
			else
				strcpy(reason_str, val);

			len = strlen(reason_str) - 1;
			if ((len >= 0) && (reason_str[len] == '"'))
				reason_str[len] = '\0';

			front_end_msg.reason = reason_str;
			if ((getlogin() == NULL) ||
			    (uid_from_string(getlogin(),
					     &front_end_msg.reason_uid) < 0)) {
				front_end_msg.reason_uid = getuid();
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "State", MAX(tag_len, 1)) == 0) {
			if (xstrncasecmp(val, "DRAIN", MAX(val_len, 3)) == 0) {
				front_end_msg.node_state = NODE_STATE_DRAIN;
				update_cnt++;
			} else if (xstrncasecmp(val, "DOWN",
						MAX(val_len, 3)) == 0) {
				front_end_msg.node_state = NODE_STATE_DOWN;
				update_cnt++;
			} else if (xstrncasecmp(val, "RESUME",
						MAX(val_len, 3)) == 0) {
				front_end_msg.node_state = NODE_RESUME;
				update_cnt++;
			} else {
				exit_code = 1;
				fprintf(stderr,
					 "Invalid input: %s\n"
					 "Request aborted\n"
					 "Valid states are: DRAIN RESUME\n",
					 argv[i]);
				goto done;
			}
		} else {
			exit_code = 1;
			fprintf(stderr, "Update of this parameter is not "
				"supported: %s\n", argv[i]);
			fprintf(stderr, "Request aborted\n");
			goto done;
		}
	}

	if ((front_end_msg.node_state == NODE_STATE_DOWN) &&
	    ((front_end_msg.reason == NULL) ||
	     (strlen(front_end_msg.reason) == 0))) {
		fprintf (stderr, "You must specify a reason when DOWNING a "
			"frontend node\nRequest aborted\n");
		goto done;
	}
	if ((front_end_msg.node_state == NODE_STATE_DRAIN) &&
	    ((front_end_msg.reason == NULL) ||
	     (strlen(front_end_msg.reason) == 0))) {
		fprintf (stderr, "You must specify a reason when DRAINING a "
			"frontend node\nRequest aborted\n");
		goto done;
	}

	if (update_cnt == 0) {
		exit_code = 1;
		fprintf(stderr, "No changes specified\n");
		return 0;
	}

	rc = slurm_update_front_end(&front_end_msg);

done:	xfree(reason_str);
	if (rc) {
		exit_code = 1;
		return slurm_get_errno ();
	} else
		return 0;
}
Example #13
0
extern int as_mysql_user_no_assocs_or_no_uid(
	mysql_conn_t *mysql_conn,
	slurmdb_assoc_cond_t *assoc_cond,
	List ret_list)
{
	int rc = SLURM_SUCCESS;
	char *query = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	List use_cluster_list = as_mysql_cluster_list;
	ListIterator itr = NULL;
	char *cluster_name = NULL;

	xassert(ret_list);

	query = xstrdup_printf("select name from %s where deleted=0",
			       user_table);
	if (assoc_cond &&
	    assoc_cond->user_list && list_count(assoc_cond->user_list)) {
		int set = 0;
		char *object = NULL;
		xstrcat(query, " && (");
		itr = list_iterator_create(assoc_cond->user_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(query, " || ");
			xstrfmtcat(query, "name='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(query, ")");
	}

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

	if (assoc_cond &&
	    assoc_cond->cluster_list && list_count(assoc_cond->cluster_list))
		use_cluster_list = assoc_cond->cluster_list;
	else
		slurm_mutex_lock(&as_mysql_cluster_list_lock);

	itr = list_iterator_create(use_cluster_list);
	while ((row = mysql_fetch_row(result))) {
		MYSQL_RES *result2 = NULL;
		int cnt = 0;
		slurmdb_assoc_rec_t *assoc = NULL;
		uid_t pw_uid;

		if (uid_from_string (row[0], &pw_uid) < 0) {
			assoc =	xmalloc(sizeof(slurmdb_assoc_rec_t));
			list_append(ret_list, assoc);

			assoc->id = SLURMDB_PROBLEM_USER_NO_UID;
			assoc->user = xstrdup(row[0]);

			continue;
		}

		/* See if we have at least 1 association in the system */
		while ((cluster_name = list_next(itr))) {
			if (query)
				xstrcat(query, " union ");
			xstrfmtcat(query,
				   "select distinct id_assoc from \"%s_%s\" "
				   "where deleted=0 && "
				   "user='******'",
				   cluster_name, assoc_table, row[0]);
		}
		list_iterator_reset(itr);

		if (query)
			xstrcat(query, " limit 1");

		if (!(result2 = mysql_db_query_ret(
			      mysql_conn, query, 0))) {
			xfree(query);
			rc = SLURM_ERROR;
			break;
		}
		xfree(query);

		cnt = mysql_num_rows(result2);
		mysql_free_result(result2);

		if (cnt)
			continue;

		assoc =	xmalloc(sizeof(slurmdb_assoc_rec_t));
		list_append(ret_list, assoc);

		assoc->id = SLURMDB_PROBLEM_USER_NO_ASSOC;
		assoc->user = xstrdup(row[0]);
	}
	mysql_free_result(result);

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

	return rc;
}
Example #14
0
/*
 * scontrol_update_job - update the slurm job configuration per the supplied
 *	arguments
 * IN argc - count of arguments
 * IN argv - list of arguments
 * RET 0 if no slurm error, errno otherwise. parsing error prints
 *			error message and returns 0
 */
extern int scontrol_update_job(int argc, char **argv)
{
	bool update_size = false;
	int i, update_cnt = 0, rc = SLURM_SUCCESS, rc2;
	char *tag, *val;
	int taglen, vallen;
	job_desc_msg_t job_msg;
	job_array_resp_msg_t *resp = NULL;
	uint32_t job_uid = NO_VAL;

	slurm_init_job_desc_msg (&job_msg);
	for (i = 0; i < argc; i++) {
		char *add_info = NULL;
		tag = argv[i];
		val = strchr(argv[i], '=');
		if (val) {
			taglen = val - argv[i];
			if ((taglen > 0) && ((val[-1] == '+') ||
					     (val[-1] == '-'))) {
				add_info = val - 1;
				taglen--;
			}
			val++;
			vallen = strlen(val);
		} else if (xstrncasecmp(tag, "Nice", MAX(strlen(tag), 2)) == 0){
			/* "Nice" is the only tag that might not have an
			   equal sign, so it is handled specially. */
			job_msg.nice = NICE_OFFSET + 100;
			update_cnt++;
			continue;
		} else if (!val && argv[i + 1]) {
			tag = argv[i];
			taglen = strlen(tag);
			val = argv[++i];
			vallen = strlen(val);
		} else {
			exit_code = 1;
			fprintf (stderr, "Invalid input: %s\n", argv[i]);
			fprintf (stderr, "Request aborted\n");
			return -1;
		}

		if (xstrncasecmp(tag, "JobId", MAX(taglen, 3)) == 0) {
			job_msg.job_id_str = val;
		}
		else if (xstrncasecmp(tag, "AdminComment",
				      MAX(taglen, 3)) == 0) {
			if (add_info) {
				if (add_info[0] == '-') {
					error("Invalid syntax, AdminComment can not be subtracted from.");
					exit_code = 1;
					return 0;
				}
				job_msg.admin_comment = add_info;
				/*
				 * Mark as unset so we know we handled this
				 * correctly as there is a check later to make
				 * sure we know we got a +-.
				 */
				add_info = NULL;
			} else
				job_msg.admin_comment = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "ArrayTaskThrottle",
				      MAX(taglen, 10)) == 0) {
			int throttle;
			throttle = strtoll(val, (char **) NULL, 10);
			if (throttle < 0) {
				error("Invalid ArrayTaskThrottle value");
				exit_code = 1;
				return 0;
			}
			job_msg.array_inx = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Comment", MAX(taglen, 3)) == 0) {
			job_msg.comment = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Clusters", MAX(taglen, 8)) == 0) {
			job_msg.clusters = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "ClusterFeatures",
				      MAX(taglen, 8)) == 0) {
			job_msg.cluster_features = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "DelayBoot", MAX(taglen, 5)) == 0) {
			int time_sec = time_str2secs(val);
			if (time_sec == NO_VAL) {
				error("Invalid DelayBoot value");
				exit_code = 1;
				return 0;
			}
			job_msg.delay_boot = time_sec;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "TimeLimit", MAX(taglen, 5)) == 0) {
			uint32_t job_current_time, time_limit;

			if (val && ((val[0] == '+') || (val[0] == '-'))) {
				if (add_info) {
					error("Invalid syntax, variations of +=- are not accepted.");
					exit_code = 1;
					return 0;
				}
				add_info = val;
				val++;
			}

			time_limit = time_str2mins(val);
			if (time_limit == NO_VAL) {
				error("Invalid TimeLimit value");
				exit_code = 1;
				return 0;
			}
			if (add_info) {
				if (!job_msg.job_id_str) {
					error("JobId must precede TimeLimit "
					      "increment or decrement");
					exit_code = 1;
					return 0;
				}

				job_current_time = _get_job_time(job_msg.
								 job_id_str);
				if (job_current_time == NO_VAL) {
					exit_code = 1;
					return 0;
				}
				if (add_info[0] == '+') {
					time_limit += job_current_time;
				} else if (time_limit > job_current_time) {
					error("TimeLimit decrement larger than"
					      " current time limit (%u > %u)",
					      time_limit, job_current_time);
					exit_code = 1;
					return 0;
				} else {
					time_limit = job_current_time -
						     time_limit;
				}
				/*
				 * Mark as unset so we know we handled this
				 * correctly as there is a check later to make
				 * sure we know we got a +-.
				 */
				add_info = NULL;
			}
			job_msg.time_limit = time_limit;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "TimeMin", MAX(taglen, 5)) == 0) {
			int time_min = time_str2mins(val);
			if ((time_min < 0) && (time_min != INFINITE)) {
				error("Invalid TimeMin value");
				exit_code = 1;
				return 0;
			}
			job_msg.time_min = time_min;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Priority", MAX(taglen, 2)) == 0) {
			if (parse_uint32(val, &job_msg.priority)) {
				error ("Invalid Priority value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Nice", MAX(taglen, 2)) == 0) {
			long long tmp_nice;
			tmp_nice = strtoll(val, (char **)NULL, 10);
			if (llabs(tmp_nice) > (NICE_OFFSET - 3)) {
				error("Nice value out of range (+/- %u). Value "
				      "ignored", NICE_OFFSET - 3);
				exit_code = 1;
				return 0;
			}
			job_msg.nice = NICE_OFFSET + tmp_nice;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "CPUsPerTask", MAX(taglen, 9))) {
			if (parse_uint16(val, &job_msg.cpus_per_task)) {
				error("Invalid CPUsPerTask value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "CpusPerTres", MAX(taglen, 9))) {
			job_msg.cpus_per_tres = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "NumCPUs", MAX(taglen, 6)) == 0) {
			int min_cpus, max_cpus=0;
			if (!get_resource_arg_range(val, "NumCPUs", &min_cpus,
						   &max_cpus, false) ||
			    (min_cpus <= 0) ||
			    (max_cpus && (max_cpus < min_cpus))) {
				error ("Invalid NumCPUs value: %s", val);
				exit_code = 1;
				return 0;
			}
			job_msg.min_cpus = min_cpus;
			if (max_cpus)
				job_msg.max_cpus = max_cpus;
			update_cnt++;
		}
		/* ReqProcs was removed in Slurm version 2.1 */
		else if ((xstrncasecmp(tag, "NumTasks", MAX(taglen, 8)) == 0) ||
			 (xstrncasecmp(tag, "ReqProcs", MAX(taglen, 8)) == 0)) {
			if (parse_uint32(val, &job_msg.num_tasks)) {
				error ("Invalid NumTasks value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Requeue", MAX(taglen, 4)) == 0) {
			if (parse_uint16(val, &job_msg.requeue)) {
				error ("Invalid Requeue value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		/* ReqNodes was replaced by NumNodes in Slurm version 2.1 */
		else if ((xstrncasecmp(tag, "ReqNodes", MAX(taglen, 8)) == 0) ||
		         (xstrncasecmp(tag, "NumNodes", MAX(taglen, 8)) == 0)) {
			int min_nodes, max_nodes, rc;
			if (xstrcmp(val, "0") == 0) {
				job_msg.min_nodes = 0;
			} else if (xstrcasecmp(val, "ALL") == 0) {
				job_msg.min_nodes = INFINITE;
			} else {
				min_nodes = (int) job_msg.min_nodes;
				max_nodes = (int) job_msg.max_nodes;
				rc = get_resource_arg_range(
						val, "requested node count",
						&min_nodes, &max_nodes, false);
				if (!rc)
					return rc;
				job_msg.min_nodes = (uint32_t) min_nodes;
				job_msg.max_nodes = (uint32_t) max_nodes;
			}
			update_size = true;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "ReqSockets", MAX(taglen, 4)) == 0) {
			if (parse_uint16(val, &job_msg.sockets_per_node)) {
				error ("Invalid ReqSockets value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "ReqCores", MAX(taglen, 4)) == 0) {
			if (parse_uint16(val, &job_msg.cores_per_socket)) {
				error ("Invalid ReqCores value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
                else if (xstrncasecmp(tag, "TasksPerNode", MAX(taglen, 2))==0) {
			if (parse_uint16(val, &job_msg.ntasks_per_node)) {
				error ("Invalid TasksPerNode value: %s", val);
				exit_code = 1;
				return 0;
			}
                        update_cnt++;
                }
		else if (xstrncasecmp(tag, "ReqThreads", MAX(taglen, 4)) == 0) {
			if (parse_uint16(val, &job_msg.threads_per_core)) {
				error ("Invalid ReqThreads value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "MinCPUsNode", MAX(taglen, 4)) == 0) {
			if (parse_uint16(val, &job_msg.pn_min_cpus)) {
				error ("Invalid MinCPUsNode value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "MinMemoryNode",
				     MAX(taglen, 10)) == 0) {
			if (parse_uint64(val, &job_msg.pn_min_memory)) {
				error ("Invalid MinMemoryNode value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "MinMemoryCPU",
				     MAX(taglen, 10)) == 0) {
			if (parse_uint64(val, &job_msg.pn_min_memory)) {
				error ("Invalid MinMemoryCPU value: %s", val);
				exit_code = 1;
				return 0;
			}
			job_msg.pn_min_memory |= MEM_PER_CPU;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "MinTmpDiskNode",
				     MAX(taglen, 5)) == 0) {
			if (parse_uint32(val, &job_msg.pn_min_tmp_disk)) {
				error ("Invalid MinTmpDiskNode value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Partition", MAX(taglen, 2)) == 0) {
			job_msg.partition = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "QOS", MAX(taglen, 2)) == 0) {
			job_msg.qos = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "ReservationName",
				     MAX(taglen, 3)) == 0) {
			job_msg.reservation = val;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "Name", MAX(taglen, 2)) ||
			 !xstrncasecmp(tag, "JobName", MAX(taglen, 4))) {
			job_msg.name = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "WCKey", MAX(taglen, 1)) == 0) {
			job_msg.wckey = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "StdOut", MAX(taglen, 6)) == 0) {
			job_msg.std_out = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Switches", MAX(taglen, 5)) == 0) {
			char *sep_char;
			job_msg.req_switch =
				(uint32_t) strtol(val, &sep_char, 10);
			update_cnt++;
			if (sep_char && sep_char[0] == '@') {
				job_msg.wait4switch = time_str2mins(sep_char+1)
						      * 60;
			}
		}
		else if (xstrncasecmp(tag, "wait-for-switch", MAX(taglen, 5))
			 == 0) {
			if (parse_uint32(val, &job_msg.wait4switch)) {
				error ("Invalid wait-for-switch value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "OverSubscribe", MAX(taglen, 2)) ||
			 !xstrncasecmp(tag, "Shared", MAX(taglen, 2))) {
			if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				job_msg.shared = 1;
			else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				job_msg.shared = 0;
			else if (parse_uint16(val, &job_msg.shared)) {
				error("Invalid OverSubscribe value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Contiguous", MAX(taglen, 3)) == 0) {
			if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				job_msg.contiguous = 1;
			else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				job_msg.contiguous = 0;
			else if (parse_uint16(val, &job_msg.contiguous)) {
				error ("Invalid Contiguous value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "CoreSpec", MAX(taglen, 4)) == 0) {
			if (!xstrcmp(val, "-1") || !xstrcmp(val, "*"))
				job_msg.core_spec = INFINITE16;
			else if (parse_uint16(val, &job_msg.core_spec)) {
				error ("Invalid CoreSpec value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "MemPerTres", MAX(taglen, 5))) {
			job_msg.mem_per_tres = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "ThreadSpec", MAX(taglen, 4)) == 0) {
			if (!xstrcmp(val, "-1") || !xstrcmp(val, "*"))
				job_msg.core_spec = INFINITE16;
			else if (parse_uint16(val, &job_msg.core_spec)) {
				error ("Invalid ThreadSpec value: %s", val);
				exit_code = 1;
				return 0;
			} else
				job_msg.core_spec |= CORE_SPEC_THREAD;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "TresBind", MAX(taglen, 5))) {
			job_msg.tres_bind = val;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "TresFreq", MAX(taglen, 5))) {
			job_msg.tres_freq = val;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "TresPerJob", MAX(taglen, 8))) {
			job_msg.tres_per_job = val;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "TresPerNode", MAX(taglen, 8))) {
			/* "gres" replaced by "tres_per_node" in v18.08 */
			if (job_msg.tres_per_node)
				xstrfmtcat(job_msg.tres_per_node, ",%s", val);
			else
				job_msg.tres_per_node = xstrdup(val);
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "TresPerSocket", MAX(taglen, 8))) {
			job_msg.tres_per_socket = val;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "TresPerTask", MAX(taglen, 8))) {
			job_msg.tres_per_task = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "ExcNodeList", MAX(taglen, 3)) == 0){
			job_msg.exc_nodes = val;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "NodeList",    MAX(taglen, 8)) ||
			 !xstrncasecmp(tag, "ReqNodeList", MAX(taglen, 8))) {
			job_msg.req_nodes = val;
			update_size = true;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Features", MAX(taglen, 1)) == 0) {
			job_msg.features = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Gres", MAX(taglen, 2)) == 0) {
			/* "gres" replaced by "tres_per_node" in v18.08 */
			if (!xstrcasecmp(val, "help") ||
			    !xstrcasecmp(val, "list")) {
				print_gres_help();
			} else if (job_msg.tres_per_node) {
				xstrfmtcat(job_msg.tres_per_node, ",%s", val);
			} else {
				job_msg.tres_per_node = xstrdup(val);
				update_cnt++;
			}
		}
		else if (xstrncasecmp(tag, "Account", MAX(taglen, 1)) == 0) {
			job_msg.account = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "BurstBuffer", MAX(taglen, 1)) == 0) {
			job_msg.burst_buffer = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Dependency", MAX(taglen, 1)) == 0) {
			job_msg.dependency = val;
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "Licenses", MAX(taglen, 1)) == 0) {
			job_msg.licenses = val;
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "EligibleTime", MAX(taglen, 2)) ||
			 !xstrncasecmp(tag, "StartTime",    MAX(taglen, 2))) {
			if ((job_msg.begin_time = parse_time(val, 0))) {
				if (job_msg.begin_time < time(NULL))
					job_msg.begin_time = time(NULL);
				update_cnt++;
			}
		}
		else if (!xstrncasecmp(tag, "EndTime", MAX(taglen, 2))) {
			job_msg.end_time = parse_time(val, 0);
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "Reboot", MAX(taglen, 3))) {
			if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				job_msg.reboot = 1;
			else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				job_msg.reboot = 0;
			else if (parse_uint16(val, &job_msg.reboot)) {
				error ("Invalid reboot value: %s", val);
				exit_code = 1;
				return 0;
			}
			update_cnt++;
		}
		else if (!xstrncasecmp(tag, "UserID", MAX(taglen, 3))) {
			uid_t user_id = 0;
			if (uid_from_string(val, &user_id) < 0) {
				exit_code = 1;
				fprintf (stderr, "Invalid UserID: %s\n", val);
				fprintf (stderr, "Request aborted\n");
				return 0;
			}
			job_uid = (uint32_t) user_id;
		}
		else if (!xstrncasecmp(tag, "Deadline", MAX(taglen, 3))) {
			if ((job_msg.deadline = parse_time(val, 0))) {
				update_cnt++;
			}
		}
		else {
			exit_code = 1;
			fprintf (stderr, "Update of this parameter is not "
				 "supported: %s\n", argv[i]);
			fprintf (stderr, "Request aborted\n");
			return 0;
		}

		if (add_info) {
			error("Option %s does not accept [+|-]= syntax", tag);
			exit_code = 1;
			return 0;
		}
	}

	if (update_cnt == 0) {
		exit_code = 1;
		fprintf (stderr, "No changes specified\n");
		return 0;
	}

	/* If specified, override uid with effective uid provided by
	 * -u <uid> or --uid=<uid> */
	if (euid != NO_VAL)
		job_msg.user_id = euid;

	if (!job_msg.job_id_str && job_msg.name) {
		/* Translate name to job ID string */
		job_msg.job_id_str = _job_name2id(job_msg.name, job_uid);
		if (!job_msg.job_id_str) {
			exit_code = 1;
			return 0;
		}
	}

	if (!job_msg.job_id_str) {
		error("No job ID specified");
		exit_code = 1;
		return 0;
	}

	if (update_size && !_is_single_job(job_msg.job_id_str)) {
		exit_code = 1;
		return 0;
	}

	if (_is_job_id(job_msg.job_id_str)) {
		job_msg.job_id_str = _next_job_id();
		while (job_msg.job_id_str) {
			rc2 = slurm_update_job2(&job_msg, &resp);
			if (update_size && (rc2 == SLURM_SUCCESS)) {
				/* See check above for one job ID */
				job_msg.job_id = slurm_atoul(job_msg.job_id_str);
				_update_job_size(job_msg.job_id);
			}
			if (rc2 != SLURM_SUCCESS) {
				rc2 = slurm_get_errno();
				rc = MAX(rc, rc2);
				exit_code = 1;
				if (quiet_flag != 1) {
					fprintf(stderr, "%s for job %s\n",
						slurm_strerror(slurm_get_errno()),
						job_msg.job_id_str);
				}
			} else if (resp) {
				for (i = 0; i < resp->job_array_count; i++) {
					if ((resp->error_code[i] == SLURM_SUCCESS)
					    && (resp->job_array_count == 1))
						continue;
					exit_code = 1;
					if (quiet_flag == 1)
						continue;
					fprintf(stderr, "%s: %s\n",
						resp->job_array_id[i],
						slurm_strerror(resp->
							       error_code[i]));
				}
				slurm_free_job_array_resp(resp);
				resp = NULL;
			}
			job_msg.job_id_str = _next_job_id();
		}
	} else if (job_msg.job_id_str) {
		exit_code = 1;
		rc = ESLURM_INVALID_JOB_ID;
		slurm_seterrno(rc);
		if (quiet_flag != 1) {
			fprintf(stderr, "%s for job %s\n",
				slurm_strerror(rc), job_msg.job_id_str);
		}
	}

	return rc;
}
Example #15
0
extern List as_mysql_modify_wckeys(mysql_conn_t *mysql_conn,
                                   uint32_t uid,
                                   slurmdb_wckey_cond_t *wckey_cond,
                                   slurmdb_wckey_rec_t *wckey)
{
    List ret_list = NULL;
    int rc = SLURM_SUCCESS;
    char *extra = NULL, *object = NULL, *vals = NULL;
    char *user_name = NULL;
    List use_cluster_list = as_mysql_cluster_list;
    ListIterator itr;

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

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

    if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) {
        if (wckey_cond->user_list
                && (list_count(wckey_cond->user_list) == 1)) {
            uid_t pw_uid;
            char *name;
            name = list_peek(wckey_cond->user_list);
            if ((uid_from_string (name, &pw_uid) >= 0)
                    && (pw_uid == uid)) {
                /* Make sure they aren't trying to
                   change something else and then set
                   this association as a default.
                */
                slurmdb_init_wckey_rec(wckey, 1);
                wckey->is_def = 1;
                goto is_same_user;
            }
        }

        error("Only admins can modify wckeys");
        errno = ESLURM_ACCESS_DENIED;
        return NULL;
    }
is_same_user:

    (void) _setup_wckey_cond_limits(wckey_cond, &extra);

    if (wckey->is_def == 1)
        xstrcat(vals, ", is_def=1");

    if (!extra || !vals) {
        error("Nothing to modify '%s' '%s'", extra, vals);
        return NULL;
    }

    if (wckey_cond->cluster_list && list_count(wckey_cond->cluster_list))
        use_cluster_list = wckey_cond->cluster_list;

    user_name = uid_to_string((uid_t) uid);

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

    ret_list = list_create(slurm_destroy_char);
    itr = list_iterator_create(use_cluster_list);
    while ((object = list_next(itr))) {
        if ((rc = _cluster_modify_wckeys(
                      mysql_conn, wckey, object,
                      extra, vals, user_name, ret_list))
                != SLURM_SUCCESS)
            break;
    }
    list_iterator_destroy(itr);
    xfree(extra);
    xfree(user_name);

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

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

    return ret_list;
}
Example #16
0
/* block_state_mutex must be unlocked before calling this. */
extern int put_block_in_error_state(bg_record_t *bg_record, char *reason)
{
	uid_t pw_uid;

	xassert(bg_record);

	/* Only check this if the blocks are created, meaning this
	   isn't at startup.
	*/
	if (blocks_are_created) {
		/* Since we are putting this block in an error state we need
		   to wait for the job to be removed.  We don't really
		   need to free the block though since we may just
		   want it to be in an error state for some reason. */
		while (bg_record->job_running > NO_JOB_RUNNING) {
			if (bg_record->magic != BLOCK_MAGIC) {
				error("While putting block %s in a error "
				      "state it was destroyed",
				      bg_record->bg_block_id);
				return SLURM_ERROR;
			}
			debug2("block %s is still running job %d",
			       bg_record->bg_block_id, bg_record->job_running);
			sleep(1);
		}
	}

	slurm_mutex_lock(&block_state_mutex);
	if (!block_ptr_exist_in_list(bg_lists->main, bg_record)) {
		slurm_mutex_unlock(&block_state_mutex);
		error("while trying to put block in "
		      "error state it disappeared");
		return SLURM_ERROR;
	}

	info("Setting Block %s to ERROR state. (reason: '%s')",
	     bg_record->bg_block_id, reason);
	/* we add the block to these lists so we don't try to schedule
	   on them. */
	if (!block_ptr_exist_in_list(bg_lists->job_running, bg_record)) {
		list_push(bg_lists->job_running, bg_record);
		num_unused_cpus -= bg_record->cpu_cnt;
	}
	if (!block_ptr_exist_in_list(bg_lists->booted, bg_record))
		list_push(bg_lists->booted, bg_record);

	bg_record->job_running = BLOCK_ERROR_STATE;
	bg_record->state |= BG_BLOCK_ERROR_FLAG;

	xfree(bg_record->user_name);
	xfree(bg_record->target_name);
	bg_record->user_name = xstrdup(bg_conf->slurm_user_name);
	bg_record->target_name = xstrdup(bg_conf->slurm_user_name);
	bg_record->reason = xstrdup(reason);

	if (uid_from_string (bg_record->user_name, &pw_uid) < 0)
		error("No such user: %s", bg_record->user_name);
	else
		bg_record->user_uid = pw_uid;

	/* Only send if reason is set.  If it isn't set then
	   accounting should already know about this error state */
	if (reason)
		_set_block_nodes_accounting(bg_record, reason);
	slurm_mutex_unlock(&block_state_mutex);

	trigger_block_error();
	return SLURM_SUCCESS;
}
Example #17
0
/*
 * read_slurmdbd_conf - load the SlurmDBD configuration from the slurmdbd.conf
 *	file. Store result into global variable slurmdbd_conf.
 *	This function can be called more than once.
 * RET SLURM_SUCCESS if no error, otherwise an error code
 */
extern int read_slurmdbd_conf(void)
{
	s_p_options_t options[] = {
		{"ArchiveDir", S_P_STRING},
		{"ArchiveEvents", S_P_BOOLEAN},
		{"ArchiveJobs", S_P_BOOLEAN},
		{"ArchiveResvs", S_P_BOOLEAN},
		{"ArchiveScript", S_P_STRING},
		{"ArchiveSteps", S_P_BOOLEAN},
		{"ArchiveSuspend", S_P_BOOLEAN},
		{"ArchiveTXN", S_P_BOOLEAN},
		{"ArchiveUsage", S_P_BOOLEAN},
		{"AuthInfo", S_P_STRING},
		{"AuthType", S_P_STRING},
		{"CommitDelay", S_P_UINT16},
		{"DbdAddr", S_P_STRING},
		{"DbdBackupHost", S_P_STRING},
		{"DbdHost", S_P_STRING},
		{"DbdPort", S_P_UINT16},
		{"DebugFlags", S_P_STRING},
		{"DebugLevel", S_P_STRING},
		{"DebugLevelSyslog", S_P_STRING},
		{"DefaultQOS", S_P_STRING},
		{"JobPurge", S_P_UINT32},
		{"LogFile", S_P_STRING},
		{"LogTimeFormat", S_P_STRING},
		{"MaxQueryTimeRange", S_P_STRING},
		{"MessageTimeout", S_P_UINT16},
		{"PidFile", S_P_STRING},
		{"PluginDir", S_P_STRING},
		{"PrivateData", S_P_STRING},
		{"PurgeEventAfter", S_P_STRING},
		{"PurgeJobAfter", S_P_STRING},
		{"PurgeResvAfter", S_P_STRING},
		{"PurgeStepAfter", S_P_STRING},
		{"PurgeSuspendAfter", S_P_STRING},
		{"PurgeTXNAfter", S_P_STRING},
		{"PurgeUsageAfter", S_P_STRING},
		{"PurgeEventMonths", S_P_UINT32},
		{"PurgeJobMonths", S_P_UINT32},
		{"PurgeStepMonths", S_P_UINT32},
		{"PurgeSuspendMonths", S_P_UINT32},
		{"PurgeTXNMonths", S_P_UINT32},
		{"PurgeUsageMonths", S_P_UINT32},
		{"SlurmUser", S_P_STRING},
		{"StepPurge", S_P_UINT32},
		{"StorageBackupHost", S_P_STRING},
		{"StorageHost", S_P_STRING},
		{"StorageLoc", S_P_STRING},
		{"StoragePass", S_P_STRING},
		{"StoragePort", S_P_UINT16},
		{"StorageType", S_P_STRING},
		{"StorageUser", S_P_STRING},
		{"TCPTimeout", S_P_UINT16},
		{"TrackWCKey", S_P_BOOLEAN},
		{"TrackSlurmctldDown", S_P_BOOLEAN},
		{NULL} };
	s_p_hashtbl_t *tbl = NULL;
	char *conf_path = NULL;
	char *temp_str = NULL;
	struct stat buf;

	/* Set initial values */
	slurm_mutex_lock(&conf_mutex);
	if (slurmdbd_conf == NULL) {
		slurmdbd_conf = xmalloc(sizeof(slurm_dbd_conf_t));
		boot_time = time(NULL);
	}
	slurmdbd_conf->debug_level = LOG_LEVEL_INFO;
	_clear_slurmdbd_conf();

	/* Get the slurmdbd.conf path and validate the file */
	conf_path = get_extra_conf_path("slurmdbd.conf");
	if ((conf_path == NULL) || (stat(conf_path, &buf) == -1)) {
		info("No slurmdbd.conf file (%s)", conf_path);
	} else {
		bool a_events = false, a_jobs = false, a_resv = false;
		bool a_steps = false, a_suspend = false, a_txn = false;
		bool a_usage = false;
		debug("Reading slurmdbd.conf file %s", conf_path);

		tbl = s_p_hashtbl_create(options);
		if (s_p_parse_file(tbl, NULL, conf_path, false)
		    == SLURM_ERROR) {
			fatal("Could not open/read/parse slurmdbd.conf file %s",
			      conf_path);
		}

		if (!s_p_get_string(&slurmdbd_conf->archive_dir, "ArchiveDir",
				    tbl))
			slurmdbd_conf->archive_dir =
				xstrdup(DEFAULT_SLURMDBD_ARCHIVE_DIR);
		s_p_get_boolean(&a_events, "ArchiveEvents", tbl);
		s_p_get_boolean(&a_jobs, "ArchiveJobs", tbl);
		s_p_get_boolean(&a_resv, "ArchiveResvs", tbl);
		s_p_get_string(&slurmdbd_conf->archive_script, "ArchiveScript",
			       tbl);
		s_p_get_boolean(&a_steps, "ArchiveSteps", tbl);
		s_p_get_boolean(&a_suspend, "ArchiveSuspend", tbl);
		s_p_get_boolean(&a_txn, "ArchiveTXN", tbl);
		s_p_get_boolean(&a_usage, "ArchiveUsage", tbl);
		s_p_get_string(&slurmdbd_conf->auth_info, "AuthInfo", tbl);
		s_p_get_string(&slurmdbd_conf->auth_type, "AuthType", tbl);
		s_p_get_uint16(&slurmdbd_conf->commit_delay,
			       "CommitDelay", tbl);
		s_p_get_string(&slurmdbd_conf->dbd_backup,
			       "DbdBackupHost", tbl);
		s_p_get_string(&slurmdbd_conf->dbd_host, "DbdHost", tbl);
		s_p_get_string(&slurmdbd_conf->dbd_addr, "DbdAddr", tbl);
		s_p_get_uint16(&slurmdbd_conf->dbd_port, "DbdPort", tbl);

		if (s_p_get_string(&temp_str, "DebugFlags", tbl)) {
			if (debug_str2flags(temp_str,
					    &slurmdbd_conf->debug_flags)
			    != SLURM_SUCCESS)
				fatal("DebugFlags invalid: %s", temp_str);
			xfree(temp_str);
		} else	/* Default: no DebugFlags */
			slurmdbd_conf->debug_flags = 0;

		if (s_p_get_string(&temp_str, "DebugLevel", tbl)) {
			slurmdbd_conf->debug_level = log_string2num(temp_str);
			if (slurmdbd_conf->debug_level == NO_VAL16)
				fatal("Invalid DebugLevel %s", temp_str);
			xfree(temp_str);
		}

		s_p_get_string(&slurmdbd_conf->default_qos, "DefaultQOS", tbl);
		if (s_p_get_uint32(&slurmdbd_conf->purge_job,
				   "JobPurge", tbl)) {
			if (!slurmdbd_conf->purge_job)
				slurmdbd_conf->purge_job = NO_VAL;
			else
				slurmdbd_conf->purge_job |=
					SLURMDB_PURGE_MONTHS;
		}

		s_p_get_string(&slurmdbd_conf->log_file, "LogFile", tbl);

		if (s_p_get_string(&temp_str, "DebugLevelSyslog", tbl)) {
			slurmdbd_conf->syslog_debug = log_string2num(temp_str);
			if (slurmdbd_conf->syslog_debug == NO_VAL16)
				fatal("Invalid DebugLevelSyslog %s", temp_str);
			xfree(temp_str);
		}

		if (s_p_get_string(&temp_str, "LogTimeFormat", tbl)) {
			if (xstrcasestr(temp_str, "iso8601_ms"))
				slurmdbd_conf->log_fmt = LOG_FMT_ISO8601_MS;
			else if (xstrcasestr(temp_str, "iso8601"))
				slurmdbd_conf->log_fmt = LOG_FMT_ISO8601;
			else if (xstrcasestr(temp_str, "rfc5424_ms"))
				slurmdbd_conf->log_fmt = LOG_FMT_RFC5424_MS;
			else if (xstrcasestr(temp_str, "rfc5424"))
				slurmdbd_conf->log_fmt = LOG_FMT_RFC5424;
			else if (xstrcasestr(temp_str, "clock"))
				slurmdbd_conf->log_fmt = LOG_FMT_CLOCK;
			else if (xstrcasestr(temp_str, "short"))
				slurmdbd_conf->log_fmt = LOG_FMT_SHORT;
			else if (xstrcasestr(temp_str, "thread_id"))
				slurmdbd_conf->log_fmt = LOG_FMT_THREAD_ID;
			xfree(temp_str);
		} else
			slurmdbd_conf->log_fmt = LOG_FMT_ISO8601_MS;

		if (s_p_get_string(&temp_str, "MaxQueryTimeRange", tbl)) {
			slurmdbd_conf->max_time_range = time_str2secs(temp_str);
			xfree(temp_str);
		} else {
			slurmdbd_conf->max_time_range = INFINITE;
		}

		if (!s_p_get_uint16(&slurmdbd_conf->msg_timeout,
				    "MessageTimeout", tbl))
			slurmdbd_conf->msg_timeout = DEFAULT_MSG_TIMEOUT;
		else if (slurmdbd_conf->msg_timeout > 100) {
			info("WARNING: MessageTimeout is too high for "
			     "effective fault-tolerance");
		}
		s_p_get_string(&slurmdbd_conf->pid_file, "PidFile", tbl);
		s_p_get_string(&slurmdbd_conf->plugindir, "PluginDir", tbl);

		slurmdbd_conf->private_data = 0; /* default visible to all */
		if (s_p_get_string(&temp_str, "PrivateData", tbl)) {
			if (xstrcasestr(temp_str, "account"))
				slurmdbd_conf->private_data
					|= PRIVATE_DATA_ACCOUNTS;
			if (xstrcasestr(temp_str, "job"))
				slurmdbd_conf->private_data
					|= PRIVATE_DATA_JOBS;
			if (xstrcasestr(temp_str, "event"))
				slurmdbd_conf->private_data
					|= PRIVATE_DATA_EVENTS;
			if (xstrcasestr(temp_str, "node"))
				slurmdbd_conf->private_data
					|= PRIVATE_DATA_NODES;
			if (xstrcasestr(temp_str, "partition"))
				slurmdbd_conf->private_data
					|= PRIVATE_DATA_PARTITIONS;
			if (xstrcasestr(temp_str, "reservation"))
				slurmdbd_conf->private_data
					|= PRIVATE_DATA_RESERVATIONS;
			if (xstrcasestr(temp_str, "usage"))
				slurmdbd_conf->private_data
					|= PRIVATE_DATA_USAGE;
			if (xstrcasestr(temp_str, "user"))
				slurmdbd_conf->private_data
					|= PRIVATE_DATA_USERS;
			if (xstrcasestr(temp_str, "all"))
				slurmdbd_conf->private_data = 0xffff;
			xfree(temp_str);
		}
		if (s_p_get_string(&temp_str, "PurgeEventAfter", tbl)) {
			/* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */
			if ((slurmdbd_conf->purge_event =
			     slurmdb_parse_purge(temp_str)) == NO_VAL) {
				fatal("Bad value \"%s\" for PurgeEventAfter",
				      temp_str);
			}
			xfree(temp_str);
		}
		if (s_p_get_string(&temp_str, "PurgeJobAfter", tbl)) {
			/* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */
  			if ((slurmdbd_conf->purge_job =
			     slurmdb_parse_purge(temp_str)) == NO_VAL) {
				fatal("Bad value \"%s\" for PurgeJobAfter",
				      temp_str);
			}
			xfree(temp_str);
		}
		if (s_p_get_string(&temp_str, "PurgeResvAfter", tbl)) {
			/* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */
			if ((slurmdbd_conf->purge_resv =
			     slurmdb_parse_purge(temp_str)) == NO_VAL) {
				fatal("Bad value \"%s\" for PurgeResvAfter",
				      temp_str);
			}
			xfree(temp_str);
		}
		if (s_p_get_string(&temp_str, "PurgeStepAfter", tbl)) {
			/* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */
  			if ((slurmdbd_conf->purge_step =
			     slurmdb_parse_purge(temp_str)) == NO_VAL) {
				fatal("Bad value \"%s\" for PurgeStepAfter",
				      temp_str);
			}
			xfree(temp_str);
		}
		if (s_p_get_string(&temp_str, "PurgeSuspendAfter", tbl)) {
			/* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */
 			if ((slurmdbd_conf->purge_suspend =
			     slurmdb_parse_purge(temp_str)) == NO_VAL) {
				fatal("Bad value \"%s\" for PurgeSuspendAfter",
				      temp_str);
			}
			xfree(temp_str);
		}
		if (s_p_get_string(&temp_str, "PurgeTXNAfter", tbl)) {
			/* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */
 			if ((slurmdbd_conf->purge_txn =
			     slurmdb_parse_purge(temp_str)) == NO_VAL) {
				fatal("Bad value \"%s\" for PurgeTXNAfter",
				      temp_str);
			}
			xfree(temp_str);
		}
		if (s_p_get_string(&temp_str, "PurgeUsageAfter", tbl)) {
			/* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */
			if ((slurmdbd_conf->purge_usage =
			     slurmdb_parse_purge(temp_str)) == NO_VAL) {
				fatal("Bad value \"%s\" for PurgeUsageAfter",
				      temp_str);
			}
			xfree(temp_str);
		}
		if (s_p_get_uint32(&slurmdbd_conf->purge_event,
				   "PurgeEventMonths", tbl)) {
			if (!slurmdbd_conf->purge_event)
				slurmdbd_conf->purge_event = NO_VAL;
			else
				slurmdbd_conf->purge_event |=
					SLURMDB_PURGE_MONTHS;
		}

		if (s_p_get_uint32(&slurmdbd_conf->purge_job,
				   "PurgeJobMonths", tbl)) {
			if (!slurmdbd_conf->purge_job)
				slurmdbd_conf->purge_job = NO_VAL;
			else
				slurmdbd_conf->purge_job |=
					SLURMDB_PURGE_MONTHS;
		}

		if (s_p_get_uint32(&slurmdbd_conf->purge_step,
				   "PurgeStepMonths", tbl)) {
			if (!slurmdbd_conf->purge_step)
				slurmdbd_conf->purge_step = NO_VAL;
			else
				slurmdbd_conf->purge_step |=
					SLURMDB_PURGE_MONTHS;
		}

		if (s_p_get_uint32(&slurmdbd_conf->purge_suspend,
				   "PurgeSuspendMonths", tbl)) {
			if (!slurmdbd_conf->purge_suspend)
				slurmdbd_conf->purge_suspend = NO_VAL;
			else
				slurmdbd_conf->purge_suspend
					|= SLURMDB_PURGE_MONTHS;
		}

		if (s_p_get_uint32(&slurmdbd_conf->purge_txn,
				   "PurgeTXNMonths", tbl)) {
			if (!slurmdbd_conf->purge_txn)
				slurmdbd_conf->purge_txn = NO_VAL;
			else
				slurmdbd_conf->purge_txn
					|= SLURMDB_PURGE_MONTHS;
		}

		if (s_p_get_uint32(&slurmdbd_conf->purge_usage,
				   "PurgeUsageMonths", tbl)) {
			if (!slurmdbd_conf->purge_usage)
				slurmdbd_conf->purge_usage = NO_VAL;
			else
				slurmdbd_conf->purge_usage
					|= SLURMDB_PURGE_MONTHS;
		}

		s_p_get_string(&slurmdbd_conf->slurm_user_name,
			       "SlurmUser", tbl);

		if (s_p_get_uint32(&slurmdbd_conf->purge_step,
				   "StepPurge", tbl)) {
			if (!slurmdbd_conf->purge_step)
				slurmdbd_conf->purge_step = NO_VAL;
			else
				slurmdbd_conf->purge_step |=
					SLURMDB_PURGE_MONTHS;
		}

		s_p_get_string(&slurmdbd_conf->storage_backup_host,
			       "StorageBackupHost", tbl);
		s_p_get_string(&slurmdbd_conf->storage_host,
			       "StorageHost", tbl);
		s_p_get_string(&slurmdbd_conf->storage_loc,
			       "StorageLoc", tbl);
		s_p_get_string(&slurmdbd_conf->storage_pass,
			       "StoragePass", tbl);
		s_p_get_uint16(&slurmdbd_conf->storage_port,
			       "StoragePort", tbl);
		s_p_get_string(&slurmdbd_conf->storage_type,
			       "StorageType", tbl);
		s_p_get_string(&slurmdbd_conf->storage_user,
			       "StorageUser", tbl);

		if (!s_p_get_uint16(&slurmdbd_conf->tcp_timeout,
				    "TCPTimeout", tbl))
			slurmdbd_conf->tcp_timeout = DEFAULT_TCP_TIMEOUT;

		if (!s_p_get_boolean((bool *)&slurmdbd_conf->track_wckey,
				     "TrackWCKey", tbl))
			slurmdbd_conf->track_wckey = false;

		if (!s_p_get_boolean((bool *)&slurmdbd_conf->track_ctld,
				     "TrackSlurmctldDown", tbl))
			slurmdbd_conf->track_ctld = false;

		if (a_events && slurmdbd_conf->purge_event)
			slurmdbd_conf->purge_event |= SLURMDB_PURGE_ARCHIVE;
		if (a_jobs && slurmdbd_conf->purge_job)
			slurmdbd_conf->purge_job |= SLURMDB_PURGE_ARCHIVE;
		if (a_resv && slurmdbd_conf->purge_resv)
			slurmdbd_conf->purge_resv |= SLURMDB_PURGE_ARCHIVE;
		if (a_steps && slurmdbd_conf->purge_step)
			slurmdbd_conf->purge_step |= SLURMDB_PURGE_ARCHIVE;
		if (a_suspend && slurmdbd_conf->purge_suspend)
			slurmdbd_conf->purge_suspend |= SLURMDB_PURGE_ARCHIVE;
		if (a_txn && slurmdbd_conf->purge_txn)
			slurmdbd_conf->purge_txn |= SLURMDB_PURGE_ARCHIVE;
		if (a_usage && slurmdbd_conf->purge_usage)
			slurmdbd_conf->purge_usage |= SLURMDB_PURGE_ARCHIVE;

		s_p_hashtbl_destroy(tbl);
	}

	xfree(conf_path);
	if (slurmdbd_conf->auth_type == NULL)
		slurmdbd_conf->auth_type = xstrdup(DEFAULT_SLURMDBD_AUTHTYPE);
	if (slurmdbd_conf->dbd_host == NULL) {
		error("slurmdbd.conf lacks DbdHost parameter, "
		      "using 'localhost'");
		slurmdbd_conf->dbd_host = xstrdup("localhost");
	}
	if (slurmdbd_conf->dbd_addr == NULL)
		slurmdbd_conf->dbd_addr = xstrdup(slurmdbd_conf->dbd_host);
	if (slurmdbd_conf->pid_file == NULL)
		slurmdbd_conf->pid_file = xstrdup(DEFAULT_SLURMDBD_PIDFILE);
	if (slurmdbd_conf->dbd_port == 0)
		slurmdbd_conf->dbd_port = SLURMDBD_PORT;
	if (slurmdbd_conf->plugindir == NULL)
		slurmdbd_conf->plugindir = xstrdup(default_plugin_path);
	if (slurmdbd_conf->slurm_user_name) {
		uid_t pw_uid;
		if (uid_from_string (slurmdbd_conf->slurm_user_name,
				     &pw_uid) < 0)
			fatal("Invalid user for SlurmUser %s, ignored",
			      slurmdbd_conf->slurm_user_name);
		else
			slurmdbd_conf->slurm_user_id = pw_uid;
	} else {
		slurmdbd_conf->slurm_user_name = xstrdup("root");
		slurmdbd_conf->slurm_user_id = 0;
	}

	if (slurmdbd_conf->storage_type == NULL)
		fatal("StorageType must be specified");
	if (!xstrcmp(slurmdbd_conf->storage_type,
		     "accounting_storage/slurmdbd")) {
		fatal("StorageType=%s is invalid in slurmdbd.conf",
		      slurmdbd_conf->storage_type);
	}

	if (!slurmdbd_conf->storage_host)
		slurmdbd_conf->storage_host = xstrdup(DEFAULT_STORAGE_HOST);

	if (!slurmdbd_conf->storage_user)
		slurmdbd_conf->storage_user = xstrdup(getlogin());

	if (!xstrcmp(slurmdbd_conf->storage_type,
		     "accounting_storage/mysql")) {
		if (!slurmdbd_conf->storage_port)
			slurmdbd_conf->storage_port = DEFAULT_MYSQL_PORT;
		if (!slurmdbd_conf->storage_loc)
			slurmdbd_conf->storage_loc =
				xstrdup(DEFAULT_ACCOUNTING_DB);
	} else {
		if (!slurmdbd_conf->storage_port)
			slurmdbd_conf->storage_port = DEFAULT_STORAGE_PORT;
		if (!slurmdbd_conf->storage_loc)
			slurmdbd_conf->storage_loc =
				xstrdup(DEFAULT_STORAGE_LOC);
	}

	if (slurmdbd_conf->archive_dir) {
		if (stat(slurmdbd_conf->archive_dir, &buf) < 0)
			fatal("Failed to stat the archive directory %s: %m",
			      slurmdbd_conf->archive_dir);
		if (!(buf.st_mode & S_IFDIR))
			fatal("archive directory %s isn't a directory",
			      slurmdbd_conf->archive_dir);

		if (access(slurmdbd_conf->archive_dir, W_OK) < 0)
			fatal("archive directory %s is not writable",
			      slurmdbd_conf->archive_dir);
	}

	if (slurmdbd_conf->archive_script) {
		if (stat(slurmdbd_conf->archive_script, &buf) < 0)
			fatal("Failed to stat the archive script %s: %m",
			      slurmdbd_conf->archive_dir);

		if (!(buf.st_mode & S_IFREG))
			fatal("archive script %s isn't a regular file",
			      slurmdbd_conf->archive_script);

		if (access(slurmdbd_conf->archive_script, X_OK) < 0)
			fatal("archive script %s is not executable",
			      slurmdbd_conf->archive_script);
	}

	if (!slurmdbd_conf->purge_event)
		slurmdbd_conf->purge_event = NO_VAL;
	if (!slurmdbd_conf->purge_job)
		slurmdbd_conf->purge_job = NO_VAL;
	if (!slurmdbd_conf->purge_resv)
		slurmdbd_conf->purge_resv = NO_VAL;
	if (!slurmdbd_conf->purge_step)
		slurmdbd_conf->purge_step = NO_VAL;
	if (!slurmdbd_conf->purge_suspend)
		slurmdbd_conf->purge_suspend = NO_VAL;
	if (!slurmdbd_conf->purge_txn)
		slurmdbd_conf->purge_txn = NO_VAL;
	if (!slurmdbd_conf->purge_usage)
		slurmdbd_conf->purge_usage = NO_VAL;

	slurm_mutex_unlock(&conf_mutex);
	return SLURM_SUCCESS;
}
Example #18
0
static void _set_options(const int argc, char **argv)
{
	int option_index = 0, c;
	log_options_t logopt = LOG_OPTS_STDERR_ONLY;
	char *next_str = NULL;
	uid_t uid = -1;

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

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

	_init_opts();

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

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

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

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

	params.user = uid_to_string(uid);

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

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

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

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

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

	}

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

}
Example #19
0
/*
 * scontrol_update_node - update the slurm node configuration per the supplied
 *	arguments
 * IN argc - count of arguments
 * IN argv - list of arguments
 * RET 0 if no slurm error, errno otherwise. parsing error prints
 *			error message and returns 0
 */
extern int
scontrol_update_node (int argc, char **argv)
{
	int i, j, rc = 0, update_cnt = 0;
	uint16_t state_val;
	update_node_msg_t node_msg;
	char *reason_str = NULL;
	char *tag, *val;
	int tag_len, val_len;

	slurm_init_update_node_msg(&node_msg);
	for (i = 0; i < argc; i++) {
		tag = argv[i];
		val = strchr(argv[i], '=');
		if (val) {
			tag_len = val - argv[i];
			val++;
			val_len = strlen(val);
		} else {
			exit_code = 1;
			error("Invalid input: %s  Request aborted", argv[i]);
			return -1;
		}

		if (xstrncasecmp(tag, "NodeAddr", MAX(tag_len, 5)) == 0) {
			node_msg.node_addr = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "NodeHostName", MAX(tag_len, 5))
			   == 0) {
			node_msg.node_hostname = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "NodeName", MAX(tag_len, 1)) == 0) {
			node_msg.node_names = val;
		} else if (!xstrncasecmp(tag, "ActiveFeatures",
					 MAX(tag_len,3))) {
			node_msg.features_act = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "CpuBind", MAX(tag_len, 7)) == 0) {
			if (xlate_cpu_bind_str(val, &node_msg.cpu_bind) !=
			    SLURM_SUCCESS) {
				exit_code = 1;
				error("Invalid input %s", argv[i]);
				return -1;
			}
			update_cnt++;


		} else if (!xstrncasecmp(tag, "Features", MAX(tag_len, 1)) ||
			   !xstrncasecmp(tag, "AvailableFeatures",
					 MAX(tag_len,3))) {
			node_msg.features = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "Gres", MAX(tag_len, 1)) == 0) {
			node_msg.gres = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "Weight", MAX(tag_len,1)) == 0) {
			/* Logic borrowed from function _handle_uint32 */
			char *endptr;
			unsigned long num;
			errno = 0;
			num = strtoul(val, &endptr, 0);
			if ((endptr[0] == 'k') || (endptr[0] == 'K')) {
				num *= 1024;
				endptr++;
			}
			if ((num == 0 && errno == EINVAL)
        		            || (*endptr != '\0')) {
				if ((xstrcasecmp(val, "UNLIMITED") == 0) ||
				    (xstrcasecmp(val, "INFINITE")  == 0)) {
					num = INFINITE;
				} else {
					error("Weight value (%s) is not a "
					      "valid number", val);
					break;
				}
			} else if (errno == ERANGE) {
				error("Weight value (%s) is out of range",
				      val);
				break;
			} else if (val[0] == '-') {
				error("Weight value (%s) is less than zero",
				      val);
				break;
			} else if (num > 0xfffffff0) {
				error("Weight value (%s) is greater than %u",
					val, 0xfffffff0);
				break;
			}
			node_msg.weight = num;
			update_cnt++;
		} else if (xstrncasecmp(tag, "Reason", MAX(tag_len, 1)) == 0) {
			int len = strlen(val);
			reason_str = xmalloc(len+1);
			if (*val == '"')
				strcpy(reason_str, val+1);
			else
				strcpy(reason_str, val);

			len = strlen(reason_str) - 1;
			if ((len >= 0) && (reason_str[len] == '"'))
				reason_str[len] = '\0';

			node_msg.reason = reason_str;
			if ((getlogin() == NULL) ||
			    (uid_from_string(getlogin(),
					     &node_msg.reason_uid) < 0)) {
				node_msg.reason_uid = getuid();
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "State", MAX(tag_len, 1)) == 0) {
			if (cluster_flags & CLUSTER_FLAG_CRAY_A) {
				fprintf (stderr, "%s can not be changed through"
					 " SLURM. Use native Cray tools such as"
					 " xtprocadmin(8)\n", argv[i]);
				fprintf (stderr, "Request aborted\n");
				exit_code = 1;
				goto done;
			}
			if (xstrncasecmp(val, "NoResp",
				        MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_NO_RESPOND;
				update_cnt++;
			} else if (xstrncasecmp(val, "DRAIN",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_DRAIN;
				update_cnt++;
			} else if (xstrncasecmp(val, "FAIL",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_FAIL;
				update_cnt++;
			} else if (xstrncasecmp(val, "FUTURE",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_FUTURE;
				update_cnt++;
			} else if (xstrncasecmp(val, "RESUME",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_RESUME;
				update_cnt++;
			} else if (xstrncasecmp(val, "POWER_DOWN",
				   MAX(val_len, 7)) == 0) {
				node_msg.node_state = NODE_STATE_POWER_SAVE;
				update_cnt++;
			} else if (xstrncasecmp(val, "POWER_UP",
				   MAX(val_len, 7)) == 0) {
				node_msg.node_state = NODE_STATE_POWER_UP;
				update_cnt++;
			} else if (xstrncasecmp(val, "UNDRAIN",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_UNDRAIN;
				update_cnt++;
			} else {
				state_val = NO_VAL16;
				for (j = 0; j < NODE_STATE_END; j++) {
					if (xstrncasecmp(node_state_string(j),
							 val,
							 MAX(val_len, 3)) == 0){
						state_val = (uint16_t) j;
						break;
					}
				}
				if (j == NODE_STATE_END) {
					exit_code = 1;
					fprintf(stderr, "Invalid input: %s\n",
						argv[i]);
					fprintf (stderr, "Request aborted\n");
					fprintf (stderr, "Valid states are: ");
					fprintf (stderr,
						 "NoResp DRAIN FAIL FUTURE RESUME "
						 "POWER_DOWN POWER_UP UNDRAIN");
					fprintf (stderr, "\n");
					fprintf (stderr,
						 "Not all states are valid "
						 "given a node's prior "
						 "state\n");
					goto done;
				}
				node_msg.node_state = state_val;
				update_cnt++;
			}
		} else {
			exit_code = 1;
			fprintf (stderr, "Update of this parameter is not "
				 "supported: %s\n", argv[i]);
			fprintf (stderr, "Request aborted\n");
			goto done;
		}
	}

	if (((node_msg.node_state == NODE_STATE_DOWN)  ||
	     (node_msg.node_state == NODE_STATE_DRAIN) ||
	     (node_msg.node_state == NODE_STATE_FAIL)) &&
	    ((node_msg.reason == NULL) || (strlen(node_msg.reason) == 0))) {
		fprintf(stderr, "You must specify a reason when DOWNING or "
			"DRAINING a node. Request denied\n");
		goto done;
	}

	if (update_cnt == 0) {
		exit_code = 1;
		fprintf (stderr, "No changes specified\n");
		return 0;
	}

	rc = slurm_update_node(&node_msg);

done:	xfree(reason_str);
	if (rc) {
		exit_code = 1;
		return slurm_get_errno ();
	} else
		return 0;
}
Example #20
0
/*
 * parse_command_line, fill in params data structure with data
 */
extern void parse_command_line(int argc, char *argv[])
{
	int first = 1;
	int opt_char;
	int option_index;
	uid_t some_uid;
	long tmp_l;
	static struct option long_options[] = {
		{"primary_slurmctld_failure",           no_argument, 0, 'a'},
		{"primary_slurmctld_resumed_operation", no_argument, 0, 'A'},
		{"primary_slurmctld_resumed_control",   no_argument, 0, 'b'},
		{"backup_slurmctld_failure",            no_argument, 0, 'B'},
		{"backup_slurmctld_resumed_operation",  no_argument, 0, 'c'},
		{"backup_slurmctld_assumed_control",    no_argument, 0, 'C'},
		{"down",                                no_argument, 0, 'd'},
		{"drained",                             no_argument, 0, 'D'},
		{"primary_slurmctld_acct_buffer_full",  no_argument, 0, 'e'},
		{"fini",                                no_argument, 0, 'f'},
		{"fail",                                no_argument, 0, 'F'},
		{"primary_slurmdbd_failure",            no_argument, 0, 'g'},
		{"primary_slurmdbd_resumed_operation",  no_argument, 0, 'G'},
		{"primary_database_failure",            no_argument, 0, 'h'},
		{"primary_database_resumed_operation",  no_argument, 0, 'H'},
		{"id",                            required_argument, 0, 'i'},
		{"idle",                                no_argument, 0, 'I'},
		{"jobid",                         required_argument, 0, 'j'},
		{"cluster",                       required_argument, 0, 'M'},
		{"clusters",                      required_argument, 0, 'M'},
		{"node",                          optional_argument, 0, 'n'},
		{"offset",                        required_argument, 0, 'o'},
		{"program",                       required_argument, 0, 'p'},
		{"quiet",                               no_argument, 0, 'Q'},
		{"reconfig",                            no_argument, 0, 'r'},
		{"time",                                no_argument, 0, 't'},
		{"up",                                  no_argument, 0, 'u'},
		{"verbose",                             no_argument, 0, 'v'},
		{"version",                             no_argument, 0, 'V'},
		{"block_err", no_argument,       0, OPT_LONG_BLOCK_ERR},
		{"clear",     no_argument,       0, OPT_LONG_CLEAR},
		{"flags",     required_argument, 0, OPT_LONG_FLAGS},
		{"front_end", no_argument,       0, OPT_LONG_FRONT_END},
		{"get",       no_argument,       0, OPT_LONG_GET},
		{"help",      no_argument,       0, OPT_LONG_HELP},
		{"set",       no_argument,       0, OPT_LONG_SET},
		{"usage",     no_argument,       0, OPT_LONG_USAGE},
		{"user",      required_argument, 0, OPT_LONG_USER},
		{NULL,        0,                 0, 0}
	};

	_init_options();

	optind = 0;
	while ((opt_char = getopt_long(argc, argv,
				       "aAbBcCdDeFfgGhHi:Ij:M:n::o:p:QrtuvV",
				       long_options, &option_index)) != -1) {
		switch (opt_char) {
		case (int)'?':
			if (first) {
				first = 0;
				fprintf(stderr, "Try \"strigger --help\" for "
					"more information\n");
			}
			exit(1);
			break;
		case (int)'a':
			params.pri_ctld_fail = true;
			break;
		case (int)'A':
			params.pri_ctld_res_op = true;
			break;
		case (int)'b':
			params.pri_ctld_res_ctrl = true;
			break;
		case (int)'B':
			params.bu_ctld_fail = true;
			break;
		case (int)'c':
			params.bu_ctld_res_op = true;
			break;
		case (int)'C':
			params.bu_ctld_as_ctrl = true;
			break;
		case (int)'d':
			params.node_down = true;
			break;
		case (int)'D':
			params.node_drained = true;
			break;
		case (int)'e':
			params.pri_ctld_acct_buffer_full = true;
			break;
		case (int)'f':
			params.job_fini = true;
			break;
		case (int)'F':
			params.node_fail = true;
			break;
		case (int)'g':
			params.pri_dbd_fail = true;
			break;
		case (int)'G':
			params.pri_dbd_res_op = true;
			break;
		case (int)'h':
			params.pri_db_fail = true;
			break;
		case (int)'H':
			params.pri_db_res_op = true;
			break;
		case (int)'i':
			params.trigger_id = atoi(optarg);
			break;
		case (int)'I':
			params.node_idle = true;
			break;
		case (int)'j':
			tmp_l = atol(optarg);
			if (tmp_l <= 0) {
				error("Invalid jobid %s", optarg);
				exit(1);
			}
			params.job_id = tmp_l;
			break;
		case (int) 'M':
			if (params.clusters)
				list_destroy(params.clusters);
			if (!(params.clusters =
			      slurmdb_get_info_cluster(optarg))) {
				error("'%s' can't be reached now, "
				      "or it is an invalid entry for "
				      "--cluster.  Use 'sacctmgr --list "
				      "cluster' to see available clusters.",
				      optarg);
				exit(1);
			}
			working_cluster_rec = list_peek(params.clusters);
			break;
		case (int)'n':
			xfree(params.node_id);
			if (optarg)
				params.node_id = xstrdup(optarg);
			else
				params.node_id = xstrdup("*");
			break;
		case (int)'o':
			params.offset = atoi(optarg);
			break;
		case (int)'p':
			xfree(params.program);
			params.program = xstrdup(optarg);
			break;
		case (int)'Q':
			params.quiet = true;
			break;
		case (int)'r':
			params.reconfig = true;
			break;
		case (int)'t':
			params.time_limit = true;
			break;
		case (int)'u':
			params.node_up = true;
			break;
		case (int) 'v':
			params.verbose++;
			break;
		case (int) 'V':
			print_slurm_version();
			exit(0);
		case (int) OPT_LONG_BLOCK_ERR:
			params.block_err = true;
			break;
		case (int) OPT_LONG_HELP:
			_help();
			exit(0);
		case (int) OPT_LONG_USAGE:
			_usage();
			exit(0);
		case (int) OPT_LONG_CLEAR:
			params.mode_clear = true;
			break;
		case (int) OPT_LONG_FLAGS:
			if (!strncasecmp(optarg, "perm", 4))
				params.flags = TRIGGER_FLAG_PERM;
			else {
				error("Invalid flags %s", optarg);
				exit(1);
			}
			break;
		case (int) OPT_LONG_FRONT_END:
			params.front_end = true;
			break;
		case (int) OPT_LONG_GET:
			params.mode_get = true;
			break;
		case (int) OPT_LONG_SET:
			params.mode_set = true;
			break;
		case (int) OPT_LONG_USER:
			if ( uid_from_string( optarg, &some_uid ) != 0 ) {
				error("Invalid user %s", optarg);
				exit(1);
			}
			params.user_id = (uint32_t) some_uid;
			break;
		}
	}

	if (params.verbose)
		_print_options();
	_validate_options();
}
Example #21
0
/*
 * get_group_members - identify the users in a given group name
 * IN group_name - a single group name
 * RET a zero terminated list of its UIDs or NULL on error
 * NOTE: User root has implicitly access to every group
 * NOTE: The caller must xfree non-NULL return values
 */
extern uid_t *get_group_members(char *group_name)
{
	char *grp_buffer = NULL;
  	struct group grp,  *grp_result = NULL;
	struct passwd *pwd_result = NULL;
	uid_t *group_uids = NULL, my_uid;
	gid_t my_gid;
	int buflen = PW_BUF_SIZE, i, j, res, uid_cnt;
#ifdef HAVE_AIX
	FILE *fp = NULL;
#elif defined (__APPLE__) || defined (__CYGWIN__)
#else
	char pw_buffer[PW_BUF_SIZE];
	struct passwd pw;
#endif

	group_uids = _get_group_cache(group_name);
	if (group_uids)	{	/* We found in cache */
		_log_group_members(group_name, group_uids);
		return group_uids;
	}

#if defined(_SC_GETGR_R_SIZE_MAX)
	i = sysconf(_SC_GETGR_R_SIZE_MAX);
	buflen = MAX(buflen, i);
#endif
	grp_buffer = xmalloc(buflen);
	while (1) {
		slurm_seterrno(0);
		res = getgrnam_r(group_name, &grp, grp_buffer, buflen,
				 &grp_result);

		/* We need to check for !grp_result, since it appears some
		 * versions of this function do not return an error on
		 * failure.
		 */
		if (res != 0 || !grp_result) {
			if (errno == ERANGE) {
				buflen *= 2;
				xrealloc(grp_buffer, buflen);
				continue;
			}
			error("%s: Could not find configured group %s",
			      __func__, group_name);
			xfree(grp_buffer);
			return NULL;
		}
		break;
	}
	my_gid = grp_result->gr_gid;

	j = 0;
	uid_cnt = 0;

	/* Get the members from the getgrnam_r() call.
	 */
	for (i = 0; grp_result->gr_mem[i]; i++) {

		if (uid_from_string(grp_result->gr_mem[i],
				    &my_uid) < 0) {
			continue;
		}
		if (my_uid == 0)
			continue;
		if (j + 1 >= uid_cnt) {
			uid_cnt += 100;
			xrealloc(group_uids,
				 (sizeof(uid_t) * uid_cnt));
		}

		group_uids[j++] = my_uid;
	}

#ifdef HAVE_AIX
	setgrent_r(&fp);
	while (1) {
		slurm_seterrno(0);
		res = getgrent_r(&grp, grp_buffer, buflen, &fp);
		if (res != 0) {
			if (errno == ERANGE) {
				buflen *= 2;
				xrealloc(grp_buffer, buflen);
				continue;
			}
			break;
		}
		grp_result = &grp;
#elif defined (__APPLE__) || defined (__CYGWIN__)
	setgrent();
	while (1) {
		if ((grp_result = getgrent()) == NULL)
			break;
#else
	setgrent();
	while (1) {
		/* MH-CEA workaround to handle different group entries with
		 * the same gid
		 */
		slurm_seterrno(0);
		res = getgrent_r(&grp, grp_buffer, buflen, &grp_result);
		if (res != 0 || grp_result == NULL) {
			/* FreeBSD returns 0 and sets the grp_result to NULL
			 * unlike linux which returns ENOENT.
			 */
			if (errno == ERANGE) {
				buflen *= 2;
				xrealloc(grp_buffer, buflen);
				continue;
			}
			break;
		}
#endif
	        if (grp_result->gr_gid == my_gid) {
			if (strcmp(grp_result->gr_name, group_name)) {
				debug("including members of group '%s' as it "
				      "corresponds to the same gid as group"
				      " '%s'",grp_result->gr_name,group_name);
			}

		        for (i=0; grp_result->gr_mem[i]; i++) {
				if (uid_from_string(grp_result->gr_mem[i],
						    &my_uid) < 0) {
					/* Group member without valid login */
					continue;
				}
				if (my_uid == 0)
					continue;
				if (j+1 >= uid_cnt) {
					uid_cnt += 100;
					xrealloc(group_uids,
						 (sizeof(uid_t) * uid_cnt));
				}
				group_uids[j++] = my_uid;
			}
		}
	}
#ifdef HAVE_AIX
	endgrent_r(&fp);
	setpwent_r(&fp);
	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &fp)) {
		pwd_result = &pw;
#else
	endgrent();
	setpwent();
#if defined (__sun)
	while ((pwd_result = getpwent_r(&pw, pw_buffer, PW_BUF_SIZE)) != NULL) {
#elif defined (__APPLE__) || defined (__CYGWIN__)
	while ((pwd_result = getpwent()) != NULL) {
#else
	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &pwd_result)) {
#endif
#endif
		/* At eof FreeBSD returns 0 unlike Linux
		 * which returns ENOENT.
		 */
		if (pwd_result == NULL)
			break;
 		if (pwd_result->pw_gid != my_gid)
			continue;
		if (j+1 >= uid_cnt) {
			uid_cnt += 100;
			xrealloc(group_uids, (sizeof(uid_t) * uid_cnt));
		}
		group_uids[j++] = pwd_result->pw_uid;
	}
#ifdef HAVE_AIX
	endpwent_r(&fp);
#else
	endpwent();
#endif
	xfree(grp_buffer);
	_put_group_cache(group_name, group_uids, j);
	_log_group_members(group_name, group_uids);
	return group_uids;
}

/* Delete our group/uid cache */
extern void clear_group_cache(void)
{
	slurm_mutex_lock(&group_cache_mutex);
	FREE_NULL_LIST(group_cache_list);
	slurm_mutex_unlock(&group_cache_mutex);
}

/* Get a record from our group/uid cache.
 * Return NULL if not found. */
static uid_t *_get_group_cache(char *group_name)
{
	ListIterator iter;
	struct group_cache_rec *cache_rec;
	uid_t *group_uids = NULL;
	int sz;

	slurm_mutex_lock(&group_cache_mutex);
	if (!group_cache_list) {
		slurm_mutex_unlock(&group_cache_mutex);
		return NULL;
	}

	iter = list_iterator_create(group_cache_list);
	while ((cache_rec = (struct group_cache_rec *) list_next(iter))) {
		if (strcmp(group_name, cache_rec->group_name))
			continue;
		sz = sizeof(uid_t) * (cache_rec->uid_cnt + 1);
		group_uids = (uid_t *) xmalloc(sz);
		memcpy(group_uids, cache_rec->group_uids, sz);
		break;
	}
	list_iterator_destroy(iter);
	slurm_mutex_unlock(&group_cache_mutex);
	return group_uids;
}

/* Delete a record from the group/uid cache, used by list functions */
static void _cache_del_func(void *x)
{
	struct group_cache_rec *cache_rec;

	cache_rec = (struct group_cache_rec *) x;
	xfree(cache_rec->group_name);
	xfree(cache_rec->group_uids);
	xfree(cache_rec);
}

/* Put a record on our group/uid cache */
static void _put_group_cache(char *group_name, void *group_uids, int uid_cnt)
{
	struct group_cache_rec *cache_rec;
	int sz;

	slurm_mutex_lock(&group_cache_mutex);
	if (!group_cache_list) {
		group_cache_list = list_create(_cache_del_func);
	}

	sz = sizeof(uid_t) * (uid_cnt);
	cache_rec = xmalloc(sizeof(struct group_cache_rec));
	cache_rec->group_name = xstrdup(group_name);
	cache_rec->uid_cnt    = uid_cnt;
	cache_rec->group_uids = (uid_t *) xmalloc(sizeof(uid_t) + sz);
	if (uid_cnt > 0)
		memcpy(cache_rec->group_uids, group_uids, sz);
	list_append(group_cache_list, cache_rec);
	slurm_mutex_unlock(&group_cache_mutex);
}

static void _log_group_members(char *group_name, uid_t *group_uids)
{
#if _DEBUG
	int i;

	if ((group_uids == NULL) || (group_uids[0] == 0)) {
		info("Group %s has no users", group_name);
		return;
	}

	info("Group %s contains uids:", group_name);
	for (i=0; group_uids && group_uids[i]; i++)
		info("  %u", group_uids[i]);
#endif
}