Ejemplo n.º 1
0
/**
 * @brief
 *	-migrate users info on the current server to a destination server.
 *
 * @param[in] c - socket descriptor
 * @param[in] tohost - the destination host to migrate users cred to
 *
 * @return      int
 * @retval      0		success
 * @retval      error code      error
 *
 */
int
PBSD_user_migrate(int c, char *tohost)
{
	int			rc;
	struct batch_reply	*reply = NULL;
	int			sock;

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return pbs_errno;

	/* lock pthread mutex here for this connection */
	/* blocking call, waits for mutex release */
	if (pbs_client_thread_lock_connection(c) != 0)
		return pbs_errno;

	sock = connection[c].ch_socket;
	DIS_tcp_setup(sock);

	if ((rc =encode_DIS_ReqHdr(sock, PBS_BATCH_UserMigrate,
		pbs_current_user)) ||
		(rc = encode_DIS_UserMigrate(sock, tohost)) ||
		(rc = encode_DIS_ReqExtend(sock, NULL))) {
		connection[c].ch_errtxt = strdup(dis_emsg[rc]);
		if (connection[c].ch_errtxt == NULL) {
			pbs_errno = PBSE_SYSTEM;
		} else {
			pbs_errno = PBSE_PROTOCOL;
		}
		(void)pbs_client_thread_unlock_connection(c);
		return pbs_errno;
	}
	if (DIS_tcp_wflush(sock)) {
		pbs_errno = PBSE_PROTOCOL;
		(void)pbs_client_thread_unlock_connection(c);
		return pbs_errno;
	}

	reply = PBSD_rdrpy(c);

	PBSD_FreeReply(reply);

	rc = connection[c].ch_errno;

	/* unlock the thread lock and update the thread context data */
	if (pbs_client_thread_unlock_connection(c) != 0)
		return pbs_errno;

	return rc;
}
Ejemplo n.º 2
0
int
totpool(int con, int update)
{
	struct pbs_client_thread_context *ptr;
	struct node_pool *np;

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return -1;

	ptr = (struct pbs_client_thread_context *)
		pbs_client_thread_get_context_data();
	if (!ptr) {
		pbs_errno = PBSE_INTERNAL;
		return -1;
	}

	if (!ptr->th_node_pool) {
		np = (struct node_pool *) malloc(sizeof(struct node_pool));
		if (!np) {
			pbs_errno = PBSE_INTERNAL;
			return -1;
		}
		ptr->th_node_pool = (void *) np;
		if ((np->resc_nodes = strdup("nodes")) == NULL) {
			free(np);
			np = NULL;
			pbs_errno = PBSE_SYSTEM;
			return -1;
		}
	} else
		np = (struct node_pool *) ptr->th_node_pool;


	if (update) {
		if (pbs_rescquery(con, &np->resc_nodes, 1,
			&np->nodes_avail,
			&np->nodes_alloc,
			&np->nodes_resrv,
			&np->nodes_down) != 0) {
			return (-1);
		}
	}
	return (np->nodes_avail +
		np->nodes_alloc +
		np->nodes_resrv +
		np->nodes_down);
}
Ejemplo n.º 3
0
/**
 * @brief
 *	-send manager request and read reply.
 *
 * @param[in] c - communication handle
 * @param[in] function - req type
 * @param[in] command - command
 * @param[in] objtype - object type
 * @param[in] objname - object name
 * @param[in] aoplp - attribute list
 * @param[in] extend - extend string for req
 *
 * @return	int
 * @retval	0	success
 * @retval	!0	error
 *
 */ 
int
PBSD_manager(int c, int function, int command, int objtype, char *objname, struct attropl *aoplp, char *extend)
{
	int i;
	struct batch_reply *reply;
	int rc;

	/* initialize the thread context data, if not initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return pbs_errno;

	/* verify the object name if creating a new one */
	if (command == MGR_CMD_CREATE)
		if (pbs_verify_object_name(objtype, objname) != 0)
			return pbs_errno;

	/* now verify the attributes, if verification is enabled */
	if ((pbs_verify_attributes(c, function, objtype,
		command, aoplp)) != 0)
		return pbs_errno;

	/* lock pthread mutex here for this connection */
	/* blocking call, waits for mutex release */
	if (pbs_client_thread_lock_connection(c) != 0)
		return pbs_errno;

	/* send the manage request */
	i = PBSD_mgr_put(c, function, command, objtype, objname, aoplp, extend, 0, NULL);
	if (i) {
		(void)pbs_client_thread_unlock_connection(c);
		return i;
	}

	/* read reply from stream into presentation element */

	reply = PBSD_rdrpy(c);

	PBSD_FreeReply(reply);

	rc = connection[c].ch_errno;

	/* unlock the thread lock and update the thread context data */
	if (pbs_client_thread_unlock_connection(c) != 0)
		return pbs_errno;

	return rc;
}
Ejemplo n.º 4
0
/**
 * @brief
 *	Return the status of a hook.
 *
 * @param[in] c - communication handle
 * @param[in] id - object name
 * @param[in] attrib - pointer to attrl structure(list)
 * @param[in] extend - extend string for req
 *
 * @return	structure handle
 * @retval	pointer to attr list	success
 * @retval	NULL			error
 *
 */
struct batch_status *
__pbs_stathook(int c, char *id, struct attrl *attrib, char *extend)
{
	struct batch_status *ret = NULL;
	int                  rc;
	int		    hook_obj;

	if (extend != NULL) {
		if (strcmp(extend, PBS_HOOK) == 0) {
			hook_obj = MGR_OBJ_PBS_HOOK;
		} else if (strcmp(extend, SITE_HOOK) == 0) {
			hook_obj = MGR_OBJ_SITE_HOOK;
		} else {
			return NULL;	/* bad extend value */
		}
	} else {
		hook_obj = MGR_OBJ_SITE_HOOK;
	}

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return NULL;

	/* first verify the attributes, if verification is enabled */
	rc = pbs_verify_attributes(c, PBS_BATCH_StatusHook,
		hook_obj, MGR_CMD_NONE, (struct attropl *) attrib);
	if (rc)
		return NULL;

	if (pbs_client_thread_lock_connection(c) != 0)
		return NULL;

	ret = PBSD_status(c, PBS_BATCH_StatusHook, id, attrib, extend);

	/* unlock the thread lock and update the thread context data */
	if (pbs_client_thread_unlock_connection(c) != 0)
		return NULL;

	return ret;
}
Ejemplo n.º 5
0
/**
 * @brief
 *	Passes submit reservation request to PBSD_submit_resv( )
 *
 * @param[in]   c - socket on which connected
 * @param[in]   attrib - the list of attributes for batch request
 * @parma[in]   extend - extension of batch request
 *
 * @return char*
 * @retval SUCCESS returns the reservation ID
 * @retval ERROR NULL
 */
char *
__pbs_submit_resv(int c, struct attropl *attrib, char *extend)
{
	struct attropl *pal;
	int rc;
	char *ret;

	for (pal = attrib; pal; pal = pal->next)
		pal->op = SET;		/* force operator to SET */

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return (char *)NULL;

	/* first verify the attributes, if verification is enabled */
	rc = pbs_verify_attributes(c, PBS_BATCH_SubmitResv,
		MGR_OBJ_RESV, MGR_CMD_NONE, attrib);
	if (rc)
		return (char *)NULL;

	/* lock pthread mutex here for this connection */
	/* blocking call, waits for mutex release */
	if (pbs_client_thread_lock_connection(c) != 0)
		return (char *)NULL;

	/* initiate the queueing of the reservation  */

	/* Queue job with null string for job id */
	ret = PBSD_submit_resv(c, "", attrib, extend);

	/* unlock the thread lock and update the thread context data */
	if (pbs_client_thread_unlock_connection(c) != 0)
		return (char *) NULL;

	return ret;
}
Ejemplo n.º 6
0
/**
 * @brief
 *	pbs_loadconf - Populate the pbs_conf structure
 *
 * @par
 *	Load the pbs_conf structure.  The variables can be filled in
 *	from either the environment or the pbs.conf file.  The
 *	environment gets priority over the file.  If any of the
 *	primary variables are not filled in, the function fails.
 *	Primary vars: pbs_home_path, pbs_exec_path, pbs_server_name
 *
 * @note
 *	Clients can now be multithreaded. So dont call pbs_loadconf with
 *	reload = TRUE. Currently, the code flow ensures that the configuration
 *	is loaded only once (never used with reload true). Thus in the rest of
 *	the code a direct read of the pbs_conf.variables is fine. There is no
 *	race of access of pbs_conf vars against the loading of pbs_conf vars.
 *	However, if pbs_loadconf is called with reload = TRUE, this assumption
 *	will be void. In that case, access to every pbs_conf.variable has to be
 *	synchronized against the reload of those variables.
 *
 * @param[in] reload		Whether to attempt a reload
 *
 * @return int
 * @retval 1 Success
 * @retval 0 Failure
 */
int
pbs_loadconf(int reload)
{
	FILE *fp;
	char buf[256];
	char *conf_name; 		/* the name of the conf parameter */
	char *conf_value;		/* the value from the conf file or env*/
	char *gvalue;			/* used with getenv() */
	unsigned int uvalue;		/* used with sscanf() */
#ifndef WIN32
	struct servent *servent;	/* for use with getservent */
	char **servalias;		/* service alias list */
	unsigned int *pui;		/* for use with identify_service_entry */
#endif

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return 0;

	/* this section of the code modified the procecss-wide
	 * tcp array. Since multiple threads can get into this
	 * simultaneously, we need to serialize it
	 */
	if (pbs_client_thread_lock_conf() != 0)
		return 0;

	if (pbs_conf.loaded && !reload) {
		(void)pbs_client_thread_unlock_conf();
		return 1;
	}
	else if (pbs_conf.load_failed && !reload) {
		(void)pbs_client_thread_unlock_conf();
		return 0;
	}

	/*
	 * If there are service port definitions available, use them
	 * as the defaults. They may be overridden later by the config
	 * file or environment variables. If not available, retain
	 * whatever we were using before.
	 */
#ifdef WIN32
	/* Windows does not have the getservent() call. */
	pbs_conf.batch_service_port = get_svrport(
		PBS_BATCH_SERVICE_NAME, "tcp",
		pbs_conf.batch_service_port);
	pbs_conf.batch_service_port_dis = get_svrport(
		PBS_BATCH_SERVICE_NAME_DIS, "tcp",
		pbs_conf.batch_service_port_dis);
	pbs_conf.mom_service_port = get_svrport(
		PBS_MOM_SERVICE_NAME, "tcp",
		pbs_conf.mom_service_port);
	pbs_conf.manager_service_port = get_svrport(
		PBS_MANAGER_SERVICE_NAME, "tcp",
		pbs_conf.manager_service_port);
	pbs_conf.scheduler_service_port = get_svrport(
		PBS_SCHEDULER_SERVICE_NAME, "tcp",
		pbs_conf.scheduler_service_port);
	pbs_conf.pbs_data_service_port = get_svrport(
		PBS_DATA_SERVICE_NAME, "tcp",
		pbs_conf.pbs_data_service_port);
#else
	/* Non-Windows uses getservent() for better performance. */
	while ((servent = getservent()) != NULL) {
		if (strcmp(servent->s_proto, "tcp") != 0)
			continue;
		/* First, check the official service name. */
		pui = identify_service_entry(servent->s_name);
		if (pui != NULL) {
			*pui = (unsigned int)ntohs(servent->s_port);
			continue;
		}
		/* Next, check any aliases that may be defined. */
		for (servalias = servent->s_aliases; (servalias != NULL) && (*servalias != NULL); servalias++) {
			pui = identify_service_entry(*servalias);
			if (pui != NULL) {
				*pui = (unsigned int)ntohs(servent->s_port);
				break;
			}
		}
	}
	endservent();
#endif

	/*
	 * Once we determine the location of the pbs.conf file, it never changes.
	 * The fact that it is saved to the pbs_conf global structure means that
	 * we can always see its location when debugging.
	 */
	if (pbs_conf.pbs_conf_file == NULL)
		pbs_conf.pbs_conf_file = pbs_get_conf_file();

	/*
	 * Parse through the configuration file and set variables based
	 * on the contents of the file.
	 */
	if ((fp = fopen(pbs_conf.pbs_conf_file, "r")) != NULL) {
		while (parse_config_line(fp, &conf_name, &conf_value) != NULL) {
			if ((conf_name == NULL) || (*conf_name == '\0'))
				continue;

			if (!strcmp(conf_name, PBS_CONF_START_SERVER)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.start_server = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_START_MOM)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.start_mom = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_START_SCHED)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.start_sched = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_START_COMM)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.start_comm = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_LOCALLOG)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.locallog = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_SYSLOG)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.syslogfac = ((uvalue <= (23<<3)) ? uvalue : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_SYSLOGSEVR)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.syslogsvr = ((uvalue <= 7) ? uvalue : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_BATCH_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.batch_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_BATCH_SERVICE_PORT_DIS)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.batch_service_port_dis =
						((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port_dis);
			}
			else if (!strcmp(conf_name, PBS_CONF_MOM_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.mom_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.mom_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_MANAGER_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.manager_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.manager_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_SCHEDULER_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.scheduler_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.scheduler_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_DATA_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_data_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.pbs_data_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_DATA_SERVICE_HOST)) {
				free(pbs_conf.pbs_data_service_host);
				pbs_conf.pbs_data_service_host = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_USE_TCP)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_use_tcp = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_USE_COMPRESSION)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_use_compression = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_USE_MCAST)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_use_mcast = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_FORCE_FT_COMM)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_use_ft = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_LEAF_NAME)) {
				if (pbs_conf.pbs_leaf_name)
					free(pbs_conf.pbs_leaf_name);
				pbs_conf.pbs_leaf_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_LEAF_ROUTERS)) {
				if (pbs_conf.pbs_leaf_routers)
					free(pbs_conf.pbs_leaf_routers);
				pbs_conf.pbs_leaf_routers = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_COMM_NAME)) {
				if (pbs_conf.pbs_comm_name)
					free(pbs_conf.pbs_comm_name);
				pbs_conf.pbs_comm_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_COMM_ROUTERS)) {
				if (pbs_conf.pbs_comm_routers)
					free(pbs_conf.pbs_comm_routers);
				pbs_conf.pbs_comm_routers = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_COMM_THREADS)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_comm_threads = uvalue;
			}
			else if (!strcmp(conf_name, PBS_CONF_COMM_LOG_EVENTS)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_comm_log_events = uvalue;
			}
			else if (!strcmp(conf_name, PBS_CONF_HOME)) {
				free(pbs_conf.pbs_home_path);
				pbs_conf.pbs_home_path = shorten_and_cleanup_path(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_EXEC)) {
				free(pbs_conf.pbs_exec_path);
				pbs_conf.pbs_exec_path = shorten_and_cleanup_path(conf_value);
			}
			/* Check for PBS_DEFAULT for backward compatibility */
			else if (!strcmp(conf_name, PBS_CONF_DEFAULT_NAME)) {
				free(pbs_conf.pbs_server_name);
				pbs_conf.pbs_server_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SERVER_NAME)) {
				free(pbs_conf.pbs_server_name);
				pbs_conf.pbs_server_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_RCP)) {
				free(pbs_conf.rcp_path);
				pbs_conf.rcp_path = shorten_and_cleanup_path(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SCP)) {
				free(pbs_conf.scp_path);
				pbs_conf.scp_path = shorten_and_cleanup_path(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_K5DCELOGIN)) {
				free(pbs_conf.k5dcelogin_path);
				pbs_conf.k5dcelogin_path = shorten_and_cleanup_path(conf_value);
			}
			/* rcp_path can be inferred from pbs_conf.pbs_exec_path - see below */
			/* pbs_demux_path is inferred from pbs_conf.pbs_exec_path - see below */
			else if (!strcmp(conf_name, PBS_CONF_ENVIRONMENT)) {
				free(pbs_conf.pbs_environment);
				pbs_conf.pbs_environment = shorten_and_cleanup_path(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_PRIMARY)) {
				free(pbs_conf.pbs_primary);
				pbs_conf.pbs_primary = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SECONDARY)) {
				free(pbs_conf.pbs_secondary);
				pbs_conf.pbs_secondary = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_MOM_HOME)) {
				free(pbs_conf.pbs_mom_home);
				pbs_conf.pbs_mom_home = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_CORE_LIMIT)) {
				free(pbs_conf.pbs_core_limit);
				pbs_conf.pbs_core_limit = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_LICENSE_STRING)) {
				free(pbs_conf.pbs_license_file_location);
				pbs_conf.pbs_license_file_location = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SERVER_HOST_NAME)) {
				free(pbs_conf.pbs_server_host_name);
				pbs_conf.pbs_server_host_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_PUBLIC_HOST_NAME)) {
				free(pbs_conf.pbs_public_host_name);
				pbs_conf.pbs_public_host_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_MAIL_HOST_NAME)) {
				free(pbs_conf.pbs_mail_host_name);
				pbs_conf.pbs_mail_host_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SMTP_SERVER_NAME)) {
				free(pbs_conf.pbs_smtp_server_name);
				pbs_conf.pbs_smtp_server_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_OUTPUT_HOST_NAME)) {
				free(pbs_conf.pbs_output_host_name);
				pbs_conf.pbs_output_host_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SCHEDULER_MODIFY_EVENT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.sched_modify_event = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_MOM_NODE_NAME)) {
				free(pbs_conf.pbs_mom_node_name);
				pbs_conf.pbs_mom_node_name = strdup(conf_value);
			}
#ifdef WIN32
			else if (!strcmp(conf_name, PBS_CONF_REMOTE_VIEWER)) {
				free(pbs_conf.pbs_conf_remote_viewer);
				pbs_conf.pbs_conf_remote_viewer = strdup(conf_value);
			}
#endif
#ifndef WIN32
			else if (!strcmp(conf_name, PBS_CONF_AUTH)) {
				if (!strcasecmp(conf_value, "MUNGE")) {
				   pbs_conf.auth_method = AUTH_MUNGE;
				} else {
					fprintf(stderr, "pbsconf error: illegal value for %s\n",PBS_CONF_AUTH);
					goto err;
				}
			}
#endif
			/* iff_path is inferred from pbs_conf.pbs_exec_path - see below */
		}
		fclose(fp);
		free(pbs_loadconf_buf);
		pbs_loadconf_buf = NULL;
		pbs_loadconf_len = 0;
	}

	/*
	 * Next, check the environment variables and set values accordingly
	 * overriding those that were set in the configuration file.
	 */

	if ((gvalue = getenv(PBS_CONF_START_SERVER)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.start_server = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_START_MOM)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.start_mom = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_START_SCHED)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.start_sched = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_START_COMM)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.start_comm = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_LOCALLOG)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.locallog = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_SYSLOG)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.syslogfac = ((uvalue <= (23<<3)) ? uvalue : 0);
	}
	if ((gvalue = getenv(PBS_CONF_SYSLOGSEVR)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.syslogsvr = ((uvalue <= 7) ? uvalue : 0);
	}
	if ((gvalue = getenv(PBS_CONF_BATCH_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.batch_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_BATCH_SERVICE_PORT_DIS)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.batch_service_port_dis =
				((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port_dis);
	}
	if ((gvalue = getenv(PBS_CONF_MOM_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.mom_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.mom_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_MANAGER_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.manager_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.manager_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_SCHEDULER_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.scheduler_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.scheduler_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_HOME)) != NULL) {
		free(pbs_conf.pbs_home_path);
		pbs_conf.pbs_home_path = shorten_and_cleanup_path(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_EXEC)) != NULL) {
		free(pbs_conf.pbs_exec_path);
		pbs_conf.pbs_exec_path = shorten_and_cleanup_path(gvalue);
	}
	/* Check for PBS_DEFAULT for backward compatibility */
	if ((gvalue = getenv(PBS_CONF_DEFAULT_NAME)) != NULL) {
		free(pbs_conf.pbs_server_name);
		if ((pbs_conf.pbs_server_name = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_SERVER_NAME)) != NULL) {
		free(pbs_conf.pbs_server_name);
		if ((pbs_conf.pbs_server_name = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_RCP)) != NULL) {
		free(pbs_conf.rcp_path);
		pbs_conf.rcp_path = shorten_and_cleanup_path(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_SCP)) != NULL) {
		free(pbs_conf.scp_path);
		pbs_conf.scp_path = shorten_and_cleanup_path(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_K5DCELOGIN)) != NULL) {
		free(pbs_conf.k5dcelogin_path);
		pbs_conf.k5dcelogin_path = shorten_and_cleanup_path(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_PRIMARY)) != NULL) {
		free(pbs_conf.pbs_primary);
		if ((pbs_conf.pbs_primary = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_SECONDARY)) != NULL) {
		free(pbs_conf.pbs_secondary);
		if ((pbs_conf.pbs_secondary = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_MOM_HOME)) != NULL) {
		free(pbs_conf.pbs_mom_home);
		if ((pbs_conf.pbs_mom_home = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_CORE_LIMIT)) != NULL) {
		free(pbs_conf.pbs_core_limit);
		if ((pbs_conf.pbs_core_limit = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_DATA_SERVICE_HOST)) != NULL) {
		free(pbs_conf.pbs_data_service_host);
		if ((pbs_conf.pbs_data_service_host = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_USE_TCP)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_use_tcp = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_USE_COMPRESSION)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_use_compression = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_USE_MCAST)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_use_mcast = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_FORCE_FT_COMM)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_use_ft = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_LEAF_NAME)) != NULL) {
		if (pbs_conf.pbs_leaf_name)
			free(pbs_conf.pbs_leaf_name);
		pbs_conf.pbs_leaf_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_LEAF_ROUTERS)) != NULL) {
		if (pbs_conf.pbs_leaf_routers)
			free(pbs_conf.pbs_leaf_routers);
		pbs_conf.pbs_leaf_routers = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_COMM_NAME)) != NULL) {
		if (pbs_conf.pbs_comm_name)
			free(pbs_conf.pbs_comm_name);
		pbs_conf.pbs_comm_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_COMM_ROUTERS)) != NULL) {
		if (pbs_conf.pbs_comm_routers)
			free(pbs_conf.pbs_comm_routers);
		pbs_conf.pbs_comm_routers = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_COMM_THREADS)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_comm_threads = uvalue;
	}
	if ((gvalue = getenv(PBS_CONF_COMM_LOG_EVENTS)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_comm_log_events = uvalue;
	}
	if ((gvalue = getenv(PBS_CONF_DATA_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_data_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.pbs_data_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_SERVER_HOST_NAME)) != NULL) {
		free(pbs_conf.pbs_server_host_name);
		pbs_conf.pbs_server_host_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_PUBLIC_HOST_NAME)) != NULL) {
		free(pbs_conf.pbs_public_host_name);
		pbs_conf.pbs_public_host_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_MAIL_HOST_NAME)) != NULL) {
		free(pbs_conf.pbs_mail_host_name);
		pbs_conf.pbs_mail_host_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_SMTP_SERVER_NAME)) != NULL) {
		free(pbs_conf.pbs_smtp_server_name);
		pbs_conf.pbs_smtp_server_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_OUTPUT_HOST_NAME)) != NULL) {
		free(pbs_conf.pbs_output_host_name);
		pbs_conf.pbs_output_host_name = strdup(gvalue);
	}

	/* support PBS_MOM_NODE_NAME to tell MOM natural node name on server */
	if ((gvalue = getenv(PBS_CONF_MOM_NODE_NAME)) != NULL) {
		free(pbs_conf.pbs_mom_node_name);
		pbs_conf.pbs_mom_node_name = strdup(gvalue);
	}

	/* rcp_path is inferred from pbs_conf.pbs_exec_path - see below */
	/* pbs_demux_path is inferred from pbs_conf.pbs_exec_path - see below */
	if ((gvalue = getenv(PBS_CONF_ENVIRONMENT)) != NULL) {
		free(pbs_conf.pbs_environment);
		pbs_conf.pbs_environment = shorten_and_cleanup_path(gvalue);
	}

#ifdef WIN32
	if ((gvalue = getenv(PBS_CONF_REMOTE_VIEWER)) != NULL) {
		free(pbs_conf.pbs_conf_remote_viewer);
		pbs_conf.pbs_conf_remote_viewer = strdup(gvalue);
	}
	
#endif

	/* iff_path is inferred from pbs_conf.pbs_exec_path - see below */

	/*
	 * Now that we have parsed through the configuration file and the
	 * environment variables, check to make sure that all the critical
	 * items are set.
	 */

	buf[0] = '\0';
	if (pbs_conf.pbs_home_path == NULL)
		sprintf(buf, "%s %s", buf, PBS_CONF_HOME);
	if (pbs_conf.pbs_exec_path == NULL)
		sprintf(buf, "%s %s", buf, PBS_CONF_EXEC);
	if (pbs_conf.pbs_server_name == NULL)
		sprintf(buf, "%s %s", buf, PBS_CONF_SERVER_NAME);
	if (buf[0] != '\0') {
		fprintf(stderr, "pbsconf error: pbs conf variables not found: %s\n", buf);
		goto err;
	}

	/*
	 * Perform sanity checks on PBS_*_HOST_NAME values and PBS_CONF_SMTP_SERVER_NAME.
	 * See IDD for SPID 4534.
	 */
	buf[0] = '\0';
	if ((pbs_conf.pbs_server_host_name != NULL) &&
			(strchr(pbs_conf.pbs_server_host_name, ':') != NULL))
		strcpy(buf, PBS_CONF_SERVER_HOST_NAME);
	else if ((pbs_conf.pbs_public_host_name != NULL) &&
			(strchr(pbs_conf.pbs_public_host_name, ':') != NULL))
		strcpy(buf, PBS_CONF_PUBLIC_HOST_NAME);
	else if ((pbs_conf.pbs_mail_host_name != NULL) &&
			(strchr(pbs_conf.pbs_mail_host_name, ':') != NULL))
		strcpy(buf, PBS_CONF_MAIL_HOST_NAME);
	else if ((pbs_conf.pbs_smtp_server_name != NULL) &&
			(strchr(pbs_conf.pbs_smtp_server_name, ':') != NULL))
		strcpy(buf, PBS_CONF_SMTP_SERVER_NAME);
	else if ((pbs_conf.pbs_output_host_name != NULL) &&
			(strchr(pbs_conf.pbs_output_host_name, ':') != NULL))
		strcpy(buf, PBS_CONF_OUTPUT_HOST_NAME);
	else if ((pbs_conf.pbs_mom_node_name != NULL) &&
			(strchr(pbs_conf.pbs_mom_node_name, ':') != NULL))
		strcpy(buf, PBS_CONF_MOM_NODE_NAME);

	if (buf[0] != '\0') {
		fprintf(stderr, "pbsconf error: illegal value for: %s\n", buf);
		goto err;
	}

	/*
	 * Finally, fill in the blanks for variables with inferred values.
	 */

	if (pbs_conf.pbs_environment == NULL) {
		/* a reasonable default for the pbs_environment file is in pbs_home */
		/* strlen("/pbs_environment") + '\0' == 16 + 1 == 17 */
		if ((pbs_conf.pbs_environment =
			malloc(strlen(pbs_conf.pbs_home_path) + 17)) != NULL) {
			sprintf(pbs_conf.pbs_environment, "%s/pbs_environment",
				pbs_conf.pbs_home_path);
#ifdef WIN32
			back2forward_slash(pbs_conf.pbs_environment);
#endif
		} else {
			goto err;
		}
	}

	free(pbs_conf.iff_path);
	/* strlen("/sbin/pbs_iff") + '\0' == 13 + 1 == 14 */
	if ((pbs_conf.iff_path =
		malloc(strlen(pbs_conf.pbs_exec_path) + 14)) != NULL) {
		sprintf(pbs_conf.iff_path, "%s/sbin/pbs_iff", pbs_conf.pbs_exec_path);
#ifdef WIN32
		back2forward_slash(pbs_conf.iff_path);
#endif
	} else {
		goto err;
	}

	if (pbs_conf.rcp_path == NULL) {
		if ((pbs_conf.rcp_path =
			malloc(strlen(pbs_conf.pbs_exec_path) + 14)) != NULL) {
			sprintf(pbs_conf.rcp_path, "%s/sbin/pbs_rcp", pbs_conf.pbs_exec_path);
#ifdef WIN32
			back2forward_slash(pbs_conf.rcp_path);
#endif
		} else {
			goto err;
		}
	}

	free(pbs_conf.pbs_demux_path);
	/* strlen("/sbin/pbs_demux") + '\0' == 15 + 1 == 16 */
	if ((pbs_conf.pbs_demux_path =
		malloc(strlen(pbs_conf.pbs_exec_path) + 16)) != NULL) {
		sprintf(pbs_conf.pbs_demux_path, "%s/sbin/pbs_demux",
			pbs_conf.pbs_exec_path);
#ifdef WIN32
		back2forward_slash(pbs_conf.pbs_demux_path);
#endif
	} else {
		goto err;
	}

	if ((gvalue = getenv(PBS_CONF_LICENSE_STRING)) != NULL) {
		free(pbs_conf.pbs_license_file_location);
		if ((pbs_conf.pbs_license_file_location = strdup(gvalue)) == NULL) {
			goto err;
		}
	}

#ifndef WIN32
	if ((gvalue = getenv(PBS_CONF_AUTH)) != NULL) {
		if (!strcasecmp(gvalue, "MUNGE")) {
			pbs_conf.auth_method = AUTH_MUNGE;
		} else {
			fprintf(stderr, "pbsconf error: illegal value for %s\n",PBS_CONF_AUTH);
			goto err;
		}
	}
#endif

	pbs_conf.pbs_tmpdir = pbs_get_tmpdir();

	/* if routers has null value populate with server name as the default */
	if (pbs_conf.pbs_leaf_routers == NULL) {
		if (pbs_conf.pbs_primary && pbs_conf.pbs_secondary) {
			pbs_conf.pbs_leaf_routers = malloc(strlen(pbs_conf.pbs_primary) + strlen(pbs_conf.pbs_secondary) + 2);
			if (pbs_conf.pbs_leaf_routers == NULL) {
				fprintf(stderr, "Out of memory\n");
				goto err;
			}
			sprintf(pbs_conf.pbs_leaf_routers, "%s,%s", pbs_conf.pbs_primary, pbs_conf.pbs_secondary);
		} else {
			if (pbs_conf.pbs_server_host_name) {
				pbs_conf.pbs_leaf_routers = strdup(pbs_conf.pbs_server_host_name);
			} else if (pbs_conf.pbs_server_name) {
				pbs_conf.pbs_leaf_routers = strdup(pbs_conf.pbs_server_name);
			} else {
				fprintf(stderr, "PBS server undefined\n");
				goto err;
			}
			if (pbs_conf.pbs_leaf_routers == NULL) {
				fprintf(stderr, "Out of memory\n");
				goto err;
			}
		}
	}

	if (pbs_conf.pbs_use_tcp == 0) {
		pbs_conf.pbs_use_compression = 0;
		pbs_conf.pbs_use_mcast = 0;
		pbs_conf.pbs_use_ft = 0;
	}
	pbs_conf.loaded = 1;

	if (pbs_client_thread_unlock_conf() != 0)
		return 0;

	return 1;		/* success */

err:
	if (pbs_conf.pbs_conf_file) {
		free(pbs_conf.pbs_conf_file);
		pbs_conf.pbs_conf_file = NULL;
	}
	if (pbs_conf.pbs_data_service_host) {
		free(pbs_conf.pbs_data_service_host);
		pbs_conf.pbs_data_service_host = NULL;
	}
	if (pbs_conf.pbs_home_path) {
		free(pbs_conf.pbs_home_path);
		pbs_conf.pbs_home_path = NULL;
	}
	if (pbs_conf.pbs_exec_path) {
		free(pbs_conf.pbs_exec_path);
		pbs_conf.pbs_exec_path = NULL;
	}
	if (pbs_conf.pbs_server_name) {
		free(pbs_conf.pbs_server_name);
		pbs_conf.pbs_server_name = NULL;
	}
	if (pbs_conf.rcp_path) {
		free(pbs_conf.rcp_path);
		pbs_conf.rcp_path = NULL;
	}
	if (pbs_conf.scp_path) {
		free(pbs_conf.scp_path);
		pbs_conf.scp_path = NULL;
	}
	if (pbs_conf.k5dcelogin_path) {
		free(pbs_conf.k5dcelogin_path);
		pbs_conf.k5dcelogin_path = NULL;
	}
	if (pbs_conf.pbs_environment) {
		free(pbs_conf.pbs_environment);
		pbs_conf.pbs_environment = NULL;
	}
	if (pbs_conf.pbs_primary) {
		free(pbs_conf.pbs_primary);
		pbs_conf.pbs_primary = NULL;
	}
	if (pbs_conf.pbs_secondary) {
		free(pbs_conf.pbs_secondary);
		pbs_conf.pbs_secondary = NULL;
	}
	if (pbs_conf.pbs_mom_home) {
		free(pbs_conf.pbs_mom_home);
		pbs_conf.pbs_mom_home = NULL;
	}
	if (pbs_conf.pbs_core_limit) {
		free(pbs_conf.pbs_core_limit);
		pbs_conf.pbs_core_limit = NULL;
	}
	if (pbs_conf.pbs_license_file_location) {
		free(pbs_conf.pbs_license_file_location);
		pbs_conf.pbs_license_file_location = NULL;
	}

	pbs_conf.load_failed = 1;
	(void)pbs_client_thread_unlock_conf();
	return 0;
}
Ejemplo n.º 7
0
/**
 * @brief
 * 	main - the initialization and main loop of pbs_daemon
 */
int
main(int argc, char *argv[])
{

	char		buf[4096];
	char		*param_name, *param_val;
	int		rc;

	execution_mode(argc, argv);

	if(set_msgdaemonname("PBS_send_hooks")) {
		fprintf(stderr, "Out of memory\n");
		return 1;
	}


	pbs_loadconf(0);

	/* If we are not run with real and effective uid of 0, forget it */
	if (!isAdminPrivilege(getlogin())) {
		fprintf(stderr, "%s: Must be run by root\n", argv[0]);
		exit(-1);
	}

	pbs_client_thread_set_single_threaded_mode();
	/* disable attribute verification */
	set_no_attribute_verification();

	/* initialize the thread context */
	if (pbs_client_thread_init_thread_context() != 0) {
		fprintf(stderr, "%s: Unable to initialize thread context\n",
			argv[0]);
		exit(-1);
	}

	winsock_init();

	connection_init();

	while (fgets(buf, sizeof(buf), stdin) != NULL) {
		buf[strlen(buf)-1] = '\0';	/* gets rid of newline */

		param_name = buf;
		param_val = strchr(buf, '=');
		if (param_val) {
			*param_val = '\0';
			param_val++;
		} else {	/* bad param_val -- skipping */
			break;
		}

		if (strcmp(param_name, "path_log") == 0) {

			path_log[0] = '\0';
			strncpy(path_log, param_val, MAXPATHLEN);
		} else if (strcmp(param_name, "path_hooks") == 0) {

			path_hooks = strdup(param_val);
			if (path_hooks == NULL)
				exit(-1);
		} else if (strcmp(param_name, "log_file") == 0) {
			log_file = strdup(param_val);
			if (log_file == NULL)
				exit(-1);
		} else if (strcmp(param_name, "path_hooks_tracking") == 0) {
			path_hooks_tracking = strdup(param_val);
			if (path_hooks_tracking == NULL)
				exit(-1);
		} else if (strcmp(param_name, "hook_action_tid") == 0) {
#ifdef WIN32
			hook_action_tid_set(_atoi64(param_val));
#else
			hook_action_tid_set(atoll(param_val));
#endif
		} else if (strcmp(param_name, "pbs_server_port_dis") == 0) {
			pbs_server_port_dis = atoi(param_val);
		} else if (strcmp(param_name, "pbs_server_addr") == 0) {
			pbs_server_addr = atol(param_val);
		} else
			break;
	}

	(void)log_open_main(log_file, path_log, 1); /* silent open */


	hook_track_recov();

	rc = sync_mom_hookfiles(NULL);


	log_close(0);	/* silent close */
	net_close(-1);
	if (log_file != NULL)
		free(log_file);
	if (path_hooks != NULL)
		free(path_hooks);
	if (path_hooks_tracking != NULL)
		free(path_hooks_tracking);
	exit(rc);


}
Ejemplo n.º 8
0
/**
 * @brief
 * 	main - the initialization and main loop of pbs_daemon
 */
int
main(int argc, char *argv[])
{
	char		jobfile[MAXPATHLEN+1];
	char		jobfile_full[MAXPATHLEN+1];
	pbs_net_t	hostaddr = 0;
	int			port = -1;
	int			move_type = -1;
	pbs_list_head	attrl;
	enum conn_type  cntype = ToServerDIS;
	int		con = -1;
	char		*destin;
	int			encode_type;
	int			i;
	job			*jobp;
	char		 job_id[PBS_MAXSVRJOBID+1];
	attribute	*pattr;
	struct attropl  *pqjatr;      /* list (single) of attropl for quejob */
	char		 script_name[MAXPATHLEN+1];
	int			in_server = -1;
	char		*param_name, *param_val;
	char		buf[4096];
	struct  hostent *hp;
	struct in_addr  addr;
	char            *credbuf = NULL;
	size_t		credlen = 0;
	int 		prot = PROT_TCP;
	/*the real deal or output version and exit?*/

	execution_mode(argc, argv);

	/* If we are not run with real and effective uid of 0, forget it */

	pbs_loadconf(0);

	if (!isAdminPrivilege(getlogin())) {
		fprintf(stderr, "%s: Must be run by root\n", argv[0]);
		exit(SEND_JOB_FATAL);
	}

	/* initialize the pointers in the resource_def array */
	for (i = 0; i < (svr_resc_size - 1); ++i)
		svr_resc_def[i].rs_next = &svr_resc_def[i+1];
	/* last entry is left with null pointer */
	/* set single threaded mode */
	pbs_client_thread_set_single_threaded_mode();
	/* disable attribute verification */
	set_no_attribute_verification();

	/* initialize the thread context */
	if (pbs_client_thread_init_thread_context() != 0) {
		fprintf(stderr, "%s: Unable to initialize thread context\n",
			argv[0]);
		exit(SEND_JOB_FATAL);
	}

	if(set_msgdaemonname("PBS_send_job")) {
		fprintf(stderr, "Out of memory\n");
		return 1;
	}

	winsock_init();

	connection_init();

	while (fgets(buf, sizeof(buf), stdin) != NULL) {
		buf[strlen(buf)-1] = '\0';	/* gets rid of newline */

		param_name = buf;
		param_val = strchr(buf, '=');
		if (param_val) {
			*param_val = '\0';
			param_val++;
		} else {	/* bad param_val -- skipping */
			break;
		}

		if (strcmp(param_name, "jobfile") == 0) {
			jobfile[0] = '\0';
			strncpy(jobfile, param_val, MAXPATHLEN);
		} else if (strcmp(param_name, "destaddr") == 0) {
			hostaddr = atol(param_val);
		} else if (strcmp(param_name, "destport") == 0) {
			port = atoi(param_val);
		} else if (strcmp(param_name, "move_type") == 0) {
			move_type = atoi(param_val);
		} else if (strcmp(param_name, "in_server") == 0) {
			in_server = atoi(param_val);
		} else if (strcmp(param_name, "server_name") == 0) {
			server_name[0] = '\0';
			strncpy(server_name, param_val, PBS_MAXSERVERNAME);
		} else if (strcmp(param_name, "server_host") == 0) {
			server_host[0] = '\0';
			strncpy(server_host, param_val, (sizeof(server_host) - 1));
		} else if (strcmp(param_name, "server_addr") == 0) {
			pbs_server_addr = atol(param_val);
		} else if (strcmp(param_name, "server_port") == 0) {
			pbs_server_port_dis = atoi(param_val);
		} else if (strcmp(param_name, "log_file") == 0) {
			log_file = strdup(param_val);
		} else if (strcmp(param_name, "path_log") == 0) {
			path_log[0] = '\0';
			strncpy(path_log, param_val, MAXPATHLEN);
		} else if (strcmp(param_name, "path_jobs") == 0) {
			path_jobs = strdup(param_val);
		} else if (strcmp(param_name, "path_spool") == 0) {
			path_spool = strdup(param_val);
		} else if (strcmp(param_name, "path_rescdef") == 0) {
			path_rescdef = strdup(param_val);
		} else if (strcmp(param_name, "path_users") == 0) {
			path_users = strdup(param_val);
		} else if (strcmp(param_name, "path_hooks_workdir") == 0) {
			path_hooks_workdir = strdup(param_val);
			if (path_hooks_workdir == NULL)
				exit(SEND_JOB_FATAL);
		} else if (strcmp(param_name, "svr_history_enable") == 0) {
			svr_history_enable = atol(param_val);
		} else if (strcmp(param_name, "svr_history_duration") == 0) {
			svr_history_duration = atol(param_val);
		} else if (strcmp(param_name, "single_signon_password_enable") == 0) {
			if (decode_b(&server.sv_attr[(int)SRV_ATR_ssignon_enable],
				NULL, NULL, param_val) != 0) {
				fprintf(stderr, "%s: failed to set ssignon_password_enable\n", argv[0]);
				exit(SEND_JOB_FATAL);
			}
		} else if (strcmp(param_name, "script_name") == 0) {
			strncpy(script_name, param_val, MAXPATHLEN + 1);
		} else
			break;
	}

	time(&time_now);

	(void)log_open_main(log_file, path_log, 1); /* silent open */

	if (setup_resc(1) == -1) {
		/* log_buffer set in setup_resc */
		log_err(-1, "pbsd_send_job(setup_resc)", log_buffer);
		return (-1);
	}

	if( strlen(jobfile) == 0 || hostaddr == 0 || port == 0 ||  move_type == -1 || \
			in_server == -1 || strlen(server_name) == 0 || strlen(server_host) == 0 || \
			pbs_server_addr == 0 || pbs_server_port_dis == 0 || \
			strlen(path_log) == 0 || path_jobs == NULL || \
			path_spool == NULL || path_users == NULL ) {
		log_err(-1, "pbs_send_job", "error on one of the parameters");
		log_close(0);	/* silent close */
		exit(SEND_JOB_FATAL);
	}

	CLEAR_HEAD(task_list_immed);
	CLEAR_HEAD(task_list_timed);
	CLEAR_HEAD(task_list_event);
	CLEAR_HEAD(svr_queues);
	CLEAR_HEAD(svr_alljobs);
	CLEAR_HEAD(svr_newjobs);
	CLEAR_HEAD(svr_allresvs);
	CLEAR_HEAD(svr_newresvs);
	CLEAR_HEAD(svr_deferred_req);
	CLEAR_HEAD(svr_unlicensedjobs);

	strcpy(jobfile_full, path_jobs);
	strcat(jobfile_full, jobfile);

	if (chk_save_file(jobfile_full) != 0) {
		sprintf(log_buffer, "Error opening jobfile=%s", jobfile);
		log_err(-1, __func__, log_buffer);
		goto fatal_exit;
	}

	if ((jobp=job_recov_fs(jobfile, RECOV_SUBJOB)) == NULL) {
		sprintf(log_buffer, "Failed to recreate job in jobfile=%s", jobfile);
		log_err(-1, __func__, log_buffer);
		goto fatal_exit;
	}

	/* now delete the temp job file that was created by job_save_fs in server code
	 * jobs are in database now, no need to keep in filesystem
	 */
	unlink(jobfile_full);

	if (in_server)
		append_link(&svr_alljobs, &jobp->ji_alljobs, jobp);


	/* select attributes/resources to send based on move type */

	if (move_type == MOVE_TYPE_Exec) {
		resc_access_perm = ATR_DFLAG_MOM;
		encode_type = ATR_ENCODE_MOM;
		cntype = ToServerDIS;
	} else {
		resc_access_perm = ATR_DFLAG_USWR | ATR_DFLAG_OPWR |
			ATR_DFLAG_MGWR | ATR_DFLAG_SvRD;
		encode_type = ATR_ENCODE_SVR;
		svr_dequejob(jobp);
	}

	CLEAR_HEAD(attrl);
	pattr = jobp->ji_wattr;
	for (i=0; i < (int)JOB_ATR_LAST; i++) {
		if ((job_attr_def+i)->at_flags & resc_access_perm) {
			(void)(job_attr_def+i)->at_encode(pattr+i, &attrl,
				(job_attr_def+i)->at_name, NULL,
				encode_type, NULL);
		}
	}
	attrl_fixlink(&attrl);

	/* script name is passed from parent */

	/* get host name */
	pbs_loadconf(0);
	addr.s_addr = htonl(hostaddr);
	hp = gethostbyaddr((void *)&addr, sizeof(struct in_addr), AF_INET);
	if (hp == NULL) {
		sprintf(log_buffer, "%s: h_errno=%d",
			inet_ntoa(addr), h_errno);
		log_err(-1, __func__, log_buffer);
	}
	else {
		/* read any credential file */
		(void)get_credential(hp->h_name, jobp,  PBS_GC_BATREQ,
			&credbuf, &credlen);
	}
	/* save the job id for when after we purge the job */

	(void)strcpy(job_id, jobp->ji_qs.ji_jobid);

	con = -1;

	DIS_tcparray_init();

	for (i=0; i<RETRY; i++) {

		pbs_errno = 0;
		/* connect to receiving server with retries */

		if (i > 0) {	/* recycle after an error */
			if (con >= 0)
				svr_disconnect(con);
			if (should_retry_route(pbs_errno) == -1) {
				goto fatal_exit;	/* fatal error, don't retry */
			}
			sleep(1<<i);
		}
		if ((con = svr_connect(hostaddr, port, 0, cntype, prot)) ==
			PBS_NET_RC_FATAL) {
			(void)sprintf(log_buffer, "send_job failed to %lx port %d",
				hostaddr, port);
			log_err(pbs_errno, __func__, log_buffer);
			goto fatal_exit;
		} else if (con == PBS_NET_RC_RETRY) {
			pbs_errno = WSAECONNREFUSED;	/* should retry */
			continue;
		}
		/*
		 * if the job is substate JOB_SUBSTATE_TRNOUTCM which means
		 * we are recovering after being down or a late failure, we
		 * just want to send the "read-to-commit/commit"
		 */


		if (jobp->ji_qs.ji_substate != JOB_SUBSTATE_TRNOUTCM) {

			if (jobp->ji_qs.ji_substate != JOB_SUBSTATE_TRNOUT) {
				jobp->ji_qs.ji_substate = JOB_SUBSTATE_TRNOUT;
			}

			pqjatr = &((svrattrl *)GET_NEXT(attrl))->al_atopl;
			destin = jobp->ji_qs.ji_destin;

			if (PBSD_queuejob(con, jobp->ji_qs.ji_jobid, destin, pqjatr, NULL, prot, NULL)== 0) {
				if (pbs_errno == PBSE_JOBEXIST && move_type == MOVE_TYPE_Exec) {
					/* already running, mark it so */
					log_event(PBSEVENT_ERROR,
						PBS_EVENTCLASS_JOB, LOG_INFO,
						jobp->ji_qs.ji_jobid, "Mom reports job already running");
					goto ok_exit;

				} else if ((pbs_errno == PBSE_HOOKERROR) ||
					(pbs_errno == PBSE_HOOK_REJECT)  ||
					(pbs_errno == PBSE_HOOK_REJECT_RERUNJOB)  ||
					(pbs_errno == PBSE_HOOK_REJECT_DELETEJOB)) {
					char		name_buf[MAXPATHLEN+1];
					int		rfd;
					int		len;
					char		*reject_msg;
					int		err;

					err = pbs_errno;

					reject_msg = pbs_geterrmsg(con);
					(void)snprintf(log_buffer, sizeof(log_buffer),
						"send of job to %s failed error = %d reject_msg=%s",
						destin, err,
						reject_msg?reject_msg:"");
					log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB,
						LOG_INFO, jobp->ji_qs.ji_jobid,
						log_buffer);

					(void)strcpy(name_buf, path_hooks_workdir);
					(void)strcat(name_buf, jobp->ji_qs.ji_jobid);
					(void)strcat(name_buf, HOOK_REJECT_SUFFIX);

					if ((reject_msg != NULL) &&
						(reject_msg[0] != '\0')) {

						if ((rfd = open(name_buf,
							O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) {
							snprintf(log_buffer,
								sizeof(log_buffer),
								"open of reject file %s failed: errno %d",
								name_buf, errno);
							log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer);
						} else {
							secure_file(name_buf, "Administrators",
								READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED);
							setmode(rfd, O_BINARY);
							len = strlen(reject_msg)+1;
							/* write also trailing null char */
							if (write(rfd, reject_msg, len) != len) {
								snprintf(log_buffer,
									sizeof(log_buffer),
									"write to file %s incomplete: errno %d", name_buf, errno);
								log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer);
							}
							close(rfd);
						}
					}

					if (err == PBSE_HOOKERROR)
						exit(SEND_JOB_HOOKERR);
					if (err == PBSE_HOOK_REJECT)
						exit(SEND_JOB_HOOK_REJECT);
					if (err == PBSE_HOOK_REJECT_RERUNJOB)
						exit(SEND_JOB_HOOK_REJECT_RERUNJOB);
					if (err == PBSE_HOOK_REJECT_DELETEJOB)
						exit(SEND_JOB_HOOK_REJECT_DELETEJOB);
				} else {
					(void)sprintf(log_buffer, "send of job to %s failed error = %d", destin, pbs_errno);
					log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer);
					continue;
				}
			}

			if (jobp->ji_qs.ji_svrflags & JOB_SVFLG_SCRIPT) {
				if (PBSD_jscript(con, script_name, prot, NULL) != 0)
					continue;
			}

			if (credlen > 0) {
				int     ret;

				ret = PBSD_jcred(con,
					jobp->ji_extended.ji_ext.ji_credtype,
					credbuf, credlen, prot, NULL);
				if ((ret == 0) || (i == (RETRY - 1)))
					free(credbuf);	/* free credbuf if credbuf is sent successfully OR */
				/* at the end of all retry attempts */
				if (ret != 0)
					continue;
			}

			if ((move_type == MOVE_TYPE_Exec) &&
				(jobp->ji_qs.ji_svrflags & JOB_SVFLG_HASRUN) &&
				(hostaddr !=  pbs_server_addr)) {
				/* send files created on prior run */
				if ((move_job_file(con, jobp, StdOut, prot) != 0) ||
					(move_job_file(con, jobp, StdErr, prot) != 0) ||
					(move_job_file(con, jobp, Chkpt, prot) != 0))
					continue;
			}

			jobp->ji_qs.ji_substate = JOB_SUBSTATE_TRNOUTCM;
		}

		if (PBSD_rdytocmt(con, job_id, prot, NULL) != 0)
			continue;

		if (PBSD_commit(con, job_id, prot, NULL) != 0)
			goto fatal_exit;
		goto ok_exit;	/* This child process is all done */
	}
	if (con >= 0)
		svr_disconnect(con);
	/*
	 * If connection is actively refused by the execution node(or mother superior) OR
	 * the execution node(or mother superior) is rejecting request with error
	 * PBSE_BADHOST(failing to authorize server host), the node should be marked down.
	 */
	if ((move_type == MOVE_TYPE_Exec) && (pbs_errno == WSAECONNREFUSED || pbs_errno == PBSE_BADHOST)) {
		i = SEND_JOB_NODEDW;
	} else if (should_retry_route(pbs_errno) == -1) {
		i = SEND_JOB_FATAL;
	} else {
		i = SEND_JOB_RETRY;
	}
	(void)sprintf(log_buffer, "send_job failed with error %d", pbs_errno);
	log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_NOTICE,
		jobp->ji_qs.ji_jobid, log_buffer);
	log_close(0);
	net_close(-1);
	unlink(script_name);
	exit(i);

fatal_exit:
	if (con >= 0)
		svr_disconnect(con);
	log_close(0);
	net_close(-1);
	unlink(script_name);
	exit(SEND_JOB_FATAL);

ok_exit:
	if (con >= 0)
		svr_disconnect(con);
	log_close(0);
	net_close(-1);
	unlink(script_name);
	exit(SEND_JOB_OK);
}
Ejemplo n.º 9
0
int
__pbs_rerunjob(int c, char *jobid, char *extend)
{
	int	rc;
	struct batch_reply *reply;
	int	sock;
	time_t  old_tcp_timeout;

	if ((jobid == NULL) || (*jobid == '\0'))
		return (pbs_errno = PBSE_IVALREQ);

	sock = connection[c].ch_socket;

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return pbs_errno;

	/* lock pthread mutex here for this connection */
	/* blocking call, waits for mutex release */
	if (pbs_client_thread_lock_connection(c) != 0)
		return pbs_errno;

	/* setup DIS support routines for following DIS calls */

	DIS_tcp_setup(sock);

	if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_Rerun, pbs_current_user)) ||
		(rc = encode_DIS_JobId(sock, jobid)) ||
		(rc = encode_DIS_ReqExtend(sock, extend))) {
		connection[c].ch_errtxt = strdup(dis_emsg[rc]);
		if (connection[c].ch_errtxt == NULL) {
			pbs_errno = PBSE_SYSTEM;
		} else {
			pbs_errno = PBSE_PROTOCOL;
		}
		(void)pbs_client_thread_unlock_connection(c);
		return pbs_errno;
	}

	/* write data */

	if (DIS_tcp_wflush(sock)) {
		pbs_errno = PBSE_PROTOCOL;
		(void)pbs_client_thread_unlock_connection(c);
		return pbs_errno;
	}

	/* Set timeout value to very long value as rerun request */
	/* goes from Server to Mom and may take a long time      */
	old_tcp_timeout = pbs_tcp_timeout;
	pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG;

	/* read reply from stream into presentation element */

	reply = PBSD_rdrpy(c);

	/* reset timeout */
	pbs_tcp_timeout = old_tcp_timeout;


	PBSD_FreeReply(reply);

	rc = connection[c].ch_errno;

	/* unlock the thread lock and update the thread context data */
	if (pbs_client_thread_unlock_connection(c) != 0)
		return pbs_errno;

	return rc;
}
Ejemplo n.º 10
0
/**
 * @brief
 *	-send async run job batch request.
 *
 * @param[in] c - connection handle
 * @param[in] jobid- job identifier
 * @param[in] location - string of vnodes/resources to be allocated to the job 
 * @param[in] extend - extend string for encoding req
 *
 * @return      int
 * @retval      0       success
 * @retval      !0      error
 *
 */
int
pbs_asyrunjob(int c, char *jobid, char *location, char *extend)
{
	int	rc;
	struct batch_reply   *reply;
	unsigned long resch = 0;
	int	sock;

	if ((jobid == (char *)0) || (*jobid == '\0'))
		return (pbs_errno = PBSE_IVALREQ);
	if (location == (char *)0)
		location = "";

	sock = connection[c].ch_socket;

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return pbs_errno;

	/* lock pthread mutex here for this connection */
	/* blocking call, waits for mutex release */
	if (pbs_client_thread_lock_connection(c) != 0)
		return pbs_errno;

	/* setup DIS support routines for following DIS calls */

	DIS_tcp_setup(sock);

	/* send run request */

	if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_AsyrunJob,
		pbs_current_user)) ||
		(rc = encode_DIS_Run(sock, jobid, location, resch)) ||
		(rc = encode_DIS_ReqExtend(sock, extend))) {
		connection[c].ch_errtxt = strdup(dis_emsg[rc]);
		if (connection[c].ch_errtxt == NULL) {
			pbs_errno = PBSE_SYSTEM;
		} else {
			pbs_errno = PBSE_PROTOCOL;
		}
		(void)pbs_client_thread_unlock_connection(c);
		return pbs_errno;
	}

	if (DIS_tcp_wflush(sock)) {
		pbs_errno = PBSE_PROTOCOL;
		(void)pbs_client_thread_unlock_connection(c);
		return pbs_errno;
	}

	/* get reply */

	reply = PBSD_rdrpy(c);
	rc = connection[c].ch_errno;

	PBSD_FreeReply(reply);

	/* unlock the thread lock and update the thread context data */
	if (pbs_client_thread_unlock_connection(c) != 0)
		return pbs_errno;

	return rc;
}
Ejemplo n.º 11
0
/**
 * @brief
 *	establishes connection to host
 * 
 * @param[in] momhost - The name of the MOM host to connect to.
 *
 * @return	int
 * @retval	connection slot		success
 * @retval	-1			error
 *
 */
static int
pbs_connect2mom(char *momhost)
{
	int conn, sd;
#if defined(__hpux)
	struct sockaddr_in mom_addr;
	struct hostent *hp;
#else
	struct addrinfo *aip, *pai;
	struct addrinfo hints;
	struct sockaddr_in *inp;
#endif

#if 0
	struct passwd *pw;
#endif

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return -1;

	if (pbs_loadconf(0) == 0)
		return -1;

	if (pbs_client_thread_lock_conntable() != 0)
		return -1;

	/*
	 * Find an available connection slot.
	 */
	for (conn=1; conn<NCONNECTS; conn++) {
		if (connection[conn].ch_inuse)
			continue;
		break;
	}
	if (conn >= NCONNECTS) {
		pbs_errno = PBSE_NOCONNECTS;
		goto err;
	}

	/*
	 * Ensure we have something valid to connect to.
	 */
	if (!momhost)
		momhost = "localhost";
	if (strlen(momhost) <= 0)
		momhost = "localhost";

#if defined(__hpux)
	hp = gethostbyname(momhost);
	if (!hp) {
		pbs_errno = PBSE_BADHOST;
		goto err;
	}
#else
	memset(&hints, 0, sizeof(struct addrinfo));
	/*
	 *	Why do we use AF_UNSPEC rather than AF_INET?  Some
	 *	implementations of getaddrinfo() will take an IPv6
	 *	address and map it to an IPv4 one if we ask for AF_INET
	 *	only.  We don't want that - we want only the addresses
	 *	that are genuinely, natively, IPv4 so we start with
	 *	AF_UNSPEC and filter ai_family below.
	 */
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	if (getaddrinfo(momhost, NULL, &hints, &pai) != 0) {
		pbs_errno = PBSE_BADHOST;
		goto err;
	}
	for (aip = pai; aip != NULL; aip = aip->ai_next) {
		/* skip non-IPv4 addresses */
		if (aip->ai_family == AF_INET) {
			inp = (struct sockaddr_in *) aip->ai_addr;
			break;
		}
	}
	if (aip == NULL) {
		pbs_errno = PBSE_BADHOST;
		goto err;
	} else
		inp->sin_port = htons(pbs_conf.mom_service_port);
#endif

#if 0
	/*
	 * Prepare for authentication before we make the connection.
	 */
	pbs_current_uid = getuid();
	if ((pw = getpwuid(pbs_current_uid)) == NULL) {
		pbs_errno = PBSE_SYSTEM;
		goto err;
	}
	strcpy(pbs_current_user, pw->pw_name);
#endif

	/*
	 * Establish a connection.
	 */
	sd = socket(AF_INET, SOCK_STREAM, 0);
	if (sd < 0) {
		pbs_errno = PBSE_PROTOCOL;
		goto err;
	}

#if defined(__hpux)
	mom_addr.sin_family = AF_INET;
	mom_addr.sin_port = htons(pbs_conf.mom_service_port);
	memcpy((char *)&mom_addr.sin_addr, hp->h_addr_list[0], hp->h_length);
	if (connect(sd, (struct sockaddr *)&mom_addr, sizeof(mom_addr)) < 0) {
		close(sd);
		pbs_errno = errno;
		goto err;
	}
#else
	if (connect(sd, aip->ai_addr, aip->ai_addrlen) < 0) {
		close(sd);
		pbs_errno = errno;
		freeaddrinfo(pai);
		goto err;
	}
	freeaddrinfo(pai);
#endif

#if 0
	/*
	 * Have pbs_iff authenticate the connection.
	 */
	if (PBSD_authenticate(sd)) {
		close(sd);
		pbs_errno = PBSE_PERM;
		return -1;
	}
#endif

	/*
	 * Setup DIS support routines.
	 */
	DIS_tcp_setup(sd);
	pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG;

	/*
	 * Register the connection slot as in use.
	 */
	connection[conn].ch_inuse = 1;
	connection[conn].ch_errno = 0;
	connection[conn].ch_socket= sd;
	connection[conn].ch_errtxt = (char *)NULL;

	/* setup connection level thread context */
	if (pbs_client_thread_init_connect_context(conn) != 0) {
		close(connection[conn].ch_socket);
		connection[conn].ch_inuse = 0;
		/* pbs_errno would be set by the pbs_connect_init_context routine */
		goto err;
	}

	if (pbs_client_thread_unlock_conntable() != 0)
		return -1;
	return conn;

err:
	(void)pbs_client_thread_unlock_conntable();
	return -1;
}
Ejemplo n.º 12
0
/**
 * @brief
 *	-submit job request
 *
 * @param[in] c - communication handle
 * @param[in] attrib - ponter to attr list
 * @param[in] script - job script
 * @param[in] destination - host where job submitted
 * @param[in] extend - buffer to hold cred info
 *
 * @return      string
 * @retval      jobid   success
 * @retval      NULL    error
 *
 */
char *
__pbs_submit(int c, struct attropl  *attrib, char *script, char *destination, char *extend)
{
	struct attropl		*pal;
	char			*return_jobid = NULL;
	int			rc;
	struct pbs_client_thread_context *ptr;
	struct cred_info	*cred_info = NULL;

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return return_jobid;

	ptr = (struct pbs_client_thread_context *)
		pbs_client_thread_get_context_data();
	if (!ptr) {
		pbs_errno = PBSE_INTERNAL;
		return return_jobid;
	}

	/* first verify the attributes, if verification is enabled */
	rc = pbs_verify_attributes(c, PBS_BATCH_QueueJob,
		MGR_OBJ_JOB, MGR_CMD_NONE, attrib);
	if (rc)
		return return_jobid;

	/* lock pthread mutex here for this connection */
	/* blocking call, waits for mutex release */
	if (pbs_client_thread_lock_connection(c) != 0)
		return return_jobid;

	/* first be sure that the script is readable if specified ... */

	if ((script != NULL) && (*script != '\0')) {
		if (access(script, R_OK) != 0) {
			pbs_errno = PBSE_BADSCRIPT;
			if ((connection[c].ch_errtxt = strdup("cannot access script file")) == NULL)
				pbs_errno = PBSE_SYSTEM;
			goto error;
		}
	}

	/* initiate the queueing of the job */

	for (pal = attrib; pal; pal = pal->next)
		pal->op = SET;		/* force operator to SET */

	/* Queue job with null string for job id */
	return_jobid = PBSD_queuejob(c, "", destination, attrib, extend, 0, NULL);
	if (return_jobid == NULL)
		goto error;

	/* send script across */

	if ((script != NULL) && (*script != '\0')) {
		if ((rc = PBSD_jscript(c, script, 0, NULL)) != 0) {
			if (rc == PBSE_JOBSCRIPTMAXSIZE)
				pbs_errno = rc;
			else
				pbs_errno = PBSE_BADSCRIPT;
			goto error;
		}
	}

	/* OK, the script got across, apparently, so we are */
	/* ready to commit 				    */

	cred_info = (struct cred_info *) ptr->th_cred_info;

	/* opaque information */
	if (cred_info && cred_info->cred_len > 0) {
		if (PBSD_jcred(c, cred_info->cred_type,
			cred_info->cred_buf,
			cred_info->cred_len, 0, NULL) != 0) {
			pbs_errno = PBSE_BADCRED;
			goto error;
		}
	}

	if (PBSD_commit(c, return_jobid, 0, NULL) != 0)
		goto error;

	/* unlock the thread lock and update the thread context data */
	if (pbs_client_thread_unlock_connection(c) != 0)
		return NULL;

	return return_jobid;
error:
	(void)pbs_client_thread_unlock_connection(c);
	return NULL;
}
Ejemplo n.º 13
0
int
pbs_rescquery(int c, char **resclist, int num_resc,
	int *available, int *allocated, int *reserved, int *down)
{
	int i;
	struct batch_reply *reply;
	int rc = 0;

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return pbs_errno;

	/* lock pthread mutex here for this connection */
	/* blocking call, waits for mutex release */
	if (pbs_client_thread_lock_connection(c) != 0)
		return pbs_errno;

	if (resclist == 0) {
		pbs_errno = connection[c].ch_errno = PBSE_RMNOPARAM;
		(void)pbs_client_thread_unlock_connection(c);
		return pbs_errno;
	}

	/* send request */

	if ((rc = PBS_resc(c, PBS_BATCH_Rescq, resclist,
		num_resc, (pbs_resource_t)0)) != 0) {
		(void)pbs_client_thread_unlock_connection(c);
		return rc;
	}

	/* read in reply */

	reply = PBSD_rdrpy(c);
	if ((rc = connection[c].ch_errno) == PBSE_NONE &&
		reply->brp_choice == BATCH_REPLY_CHOICE_RescQuery) {
		struct	brp_rescq	*resq = &reply->brp_un.brp_rescq;

		if (resq == NULL || num_resc != resq->brq_number) {
			rc = pbs_errno = connection[c].ch_errno =
				PBSE_IRESVE;
			goto done;
		}

		/* copy in available and allocated numbers */

		for (i=0; i<num_resc; i++) {
			available[i] = resq->brq_avail[i];
			allocated[i] = resq->brq_alloc[i];
			reserved[i]  = resq->brq_resvd[i];
			down[i]	     = resq->brq_down[i];
		}
	}

done:
	PBSD_FreeReply(reply);

	/* unlock the thread lock and update the thread context data */
	if (pbs_client_thread_unlock_connection(c) != 0)
		return pbs_errno;

	return (rc);
}
Ejemplo n.º 14
0
/**
 * @brief
 *	Open a connection with a pbs server.
 *	Do not allow TCP to block us if Server host is down
 *	At this point, this does not attempt to find a fail_over Server
 *
 * @param[in]   server - specifies the server to which to connect
 * @param[in]   tout - timeout value for select
 *
 * @return int
 * @retval >= 0	index to the internal connection table representing the
 *		connection made.
 * @retval -1	error encountered in getting index
 */
int
pbs_connect_noblk(char *server, int tout)
{
	int out;
	int i;
	pbs_socklen_t l;
	int n;
	struct timeval tv;
	fd_set fdset;
	struct batch_reply *reply;
	char server_name[PBS_MAXSERVERNAME+1];
	unsigned int server_port;
	struct addrinfo *aip, *pai;
	struct addrinfo hints;
	struct sockaddr_in *inp;
	short int connect_err = 0;

	struct sockaddr_in sockname;
	pbs_socklen_t	 socknamelen;

#ifdef WIN32
	int     non_block = 1;
	struct sockaddr_in to_sock;
	struct sockaddr_in from_sock;
#endif

#ifndef WIN32
	int nflg;
	int oflg;
#endif

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return -1;

	if (pbs_loadconf(0) == 0)
		return -1;

	/* get server host and port	*/

	server = PBS_get_server(server, server_name, &server_port);
	if (server == NULL) {
		pbs_errno = PBSE_NOSERVER;
		return -1;
	}

	/* Reserve a connection state record */
	if (pbs_client_thread_lock_conntable() != 0)
		return -1;

	out = -1;
	for (i=1;i<NCONNECTS;i++) {
		if (connection[i].ch_inuse) continue;
		out = i;
		connection[out].ch_inuse = 1;
		connection[out].ch_errno = 0;
		connection[out].ch_socket= -1;
		connection[out].ch_errtxt = NULL;
		break;
	}

	if (pbs_client_thread_unlock_conntable() != 0)
		return -1; /* pbs_errno set by the function */

	if (out < 0) {
		pbs_errno = PBSE_NOCONNECTS;
		return -1;
	}


	/* get socket	*/

#ifdef WIN32
	/* the following lousy hack is needed since the socket call needs */
	/* SYSTEMROOT env variable properly set! */
	if (getenv("SYSTEMROOT") == NULL) {
		setenv("SYSTEMROOT", "C:\\WINNT", 1);
		setenv("SystemRoot", "C:\\WINNT", 1);
	}
	connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (connection[out].ch_socket < 0) {
		setenv("SYSTEMROOT", "C:\\WINDOWS", 1);
		setenv("SystemRoot", "C:\\WINDOWS", 1);
		connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
	}
#else
	connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
#endif
	if (connection[out].ch_socket < 0) {
		connection[out].ch_inuse = 0;
		pbs_errno = ERRORNO;
		return -1;
	}

	/* set socket non-blocking */

#ifdef WIN32
	if (ioctlsocket(connection[out].ch_socket, FIONBIO, &non_block) == SOCKET_ERROR)
#else
	oflg = fcntl(connection[out].ch_socket, F_GETFL) & ~O_ACCMODE;
	nflg = oflg | O_NONBLOCK;
	if (fcntl(connection[out].ch_socket, F_SETFL, nflg) == -1)
#endif
		goto err;

	/* and connect... */

	strcpy(pbs_server, server);    /* set for error messages from commands */
	memset(&hints, 0, sizeof(struct addrinfo));
	/*
	 *      Why do we use AF_UNSPEC rather than AF_INET?  Some
	 *      implementations of getaddrinfo() will take an IPv6
	 *      address and map it to an IPv4 one if we ask for AF_INET
	 *      only.  We don't want that - we want only the addresses
	 *      that are genuinely, natively, IPv4 so we start with
	 *      AF_UNSPEC and filter ai_family below.
	 */
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	if (getaddrinfo(server, NULL, &hints, &pai) != 0) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_BADHOST;
		return -1;
	}
	for (aip = pai; aip != NULL; aip = aip->ai_next) {
		/* skip non-IPv4 addresses */
		if (aip->ai_family == AF_INET) {
			inp = (struct sockaddr_in *) aip->ai_addr;
			break;
		}
	}
	if (aip == NULL) {
		/* treat no IPv4 addresses as getaddrinfo() failure */
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_BADHOST;
		freeaddrinfo(pai);
		return -1;
	} else
		inp->sin_port = htons(server_port);
	if (connect(connection[out].ch_socket,
		aip->ai_addr,
		aip->ai_addrlen) < 0) {
		connect_err = 1;
	}
	if (connect_err == 1)
	{
		/* connect attempt failed */
		pbs_errno = ERRORNO;
		switch (pbs_errno) {
#ifdef WIN32
			case WSAEWOULDBLOCK:
#else
			case EINPROGRESS:
			case EWOULDBLOCK:
#endif
				while (1) {
					FD_ZERO(&fdset);
					FD_SET(connection[out].ch_socket, &fdset);
					tv.tv_sec = tout;
					tv.tv_usec = 0;
					n = select(connection[out].ch_socket+1, NULL, &fdset, NULL, &tv);
					if (n > 0) {
						pbs_errno = 0;
						l = sizeof(pbs_errno);
						(void)getsockopt(connection[out].ch_socket,
							SOL_SOCKET, SO_ERROR,
							&pbs_errno, &l);
						if (pbs_errno == 0)
							break;
						else
							goto err;
					} if ((n < 0) &&
#ifdef WIN32
						(ERRORNO == WSAEINTR)
#else
						(ERRORNO == EINTR)
#endif
						) {
						continue;
					} else {
						goto err;
					}
				}
				break;

			default:
err:
				CLOSESOCKET(connection[out].ch_socket);
				connection[out].ch_inuse = 0;
				freeaddrinfo(pai);
				return -1;	/* cannot connect */

		}
	}
	freeaddrinfo(pai);

	/* reset socket blocking */
#ifdef WIN32
	non_block = 0;
	if (ioctlsocket(connection[out].ch_socket, FIONBIO, &non_block) == SOCKET_ERROR)
#else
	if (fcntl(connection[out].ch_socket, F_SETFL, oflg) < 0)
#endif
		goto err;

	/*
	 * multiple threads cant get the same connection id above,
	 * so no need to lock this piece of code
	 */
	/* setup connection level thread context */
	if (pbs_client_thread_init_connect_context(out) != 0) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		/* pbs_errno set by the pbs_connect_init_context routine */
		return -1;
	}
	/*
	 * even though the following is communication with server on
	 * a connection handle, it does not need to be lock since
	 * this connection handle has not be returned back yet to the client
	 * so others threads cannot use it
	 */

	/* send "dummy" connect message */
	DIS_tcp_setup(connection[out].ch_socket);
	if ((i = encode_DIS_ReqHdr(connection[out].ch_socket,
		PBS_BATCH_Connect, pbs_current_user)) ||
		(i = encode_DIS_ReqExtend(connection[out].ch_socket,
		NULL))) {
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}
	if (DIS_tcp_wflush(connection[out].ch_socket)) {
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}
	reply = PBSD_rdrpy(out);
	PBSD_FreeReply(reply);

	/*do configured authentication (kerberos, pbs_iff, whatever)*/

	/*Get the socket port for engage_authentication()*/
	socknamelen = sizeof(sockname);
	if (getsockname(connection[out].ch_socket, (struct sockaddr *)&sockname, &socknamelen))
		return -1;
	if (engage_authentication(connection[out].ch_socket,
		server,
		server_port,
		&sockname) == -1) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_PERM;
		return -1;
	}

	/* setup DIS support routines for following pbs_* calls */
	DIS_tcp_setup(connection[out].ch_socket);
	pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG;	/* set for 3 hours */

	return out;
}
Ejemplo n.º 15
0
/**
 * @brief
 *	-send close connection batch request
 *
 * @param[in] connect - socket descriptor
 *
 * @return	int
 * @retval	0	success
 * @retval	-1	error
 *
 */
int
__pbs_disconnect(int connect)
{
	int  sock;
	char x;

	if (connect < 0 || NCONNECTS <= connect)
		return 0;

	if (!connection[connect].ch_inuse)
		return 0;

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return -1;

	/*
	 * Use only connection handle level lock since this is
	 * just communication with server
	 */
	if (pbs_client_thread_lock_connection(connect) != 0)
		return -1;

	/*
	 * check again to ensure that another racing thread
	 * had not already closed the connection
	 */
	if (!connection[connect].ch_inuse) {
		(void)pbs_client_thread_unlock_connection(connect);
		return 0;
	}

	/* send close-connection message */

	sock = connection[connect].ch_socket;

	DIS_tcp_setup(sock);
	if ((encode_DIS_ReqHdr(sock, PBS_BATCH_Disconnect,
		pbs_current_user) == 0) &&
		(DIS_tcp_wflush(sock) == 0)) {
		for (;;) {	/* wait for server to close connection */
#ifdef WIN32
			if (recv(sock, &x, 1, 0) < 1)
#else
			if (read(sock, &x, 1) < 1)
#endif
				break;
		}
	}

	CS_close_socket(sock);
	CLOSESOCKET(sock);

	if (connection[connect].ch_errtxt != NULL) {
		free(connection[connect].ch_errtxt);
		connection[connect].ch_errtxt = NULL;
	}
	connection[connect].ch_errno = 0;
	connection[connect].ch_inuse = 0;

	/* unlock the connection level lock */
	if (pbs_client_thread_unlock_connection(connect) != 0)
		return -1;

	/*
	 * this is only a per thread work, so outside lock and unlock
	 * connection needs the thread level connect context so this should be
	 * called after unlocking
	 */
	if (pbs_client_thread_destroy_connect_context(connect) != 0)
		return -1;

	return 0;
}
Ejemplo n.º 16
0
/**
 * @brief
 *	Makes a PBS_BATCH_Connect request to 'server'.
 *
 * @param[in]   server - the hostname of the pbs server to connect to.
 * @param[in]   extend_data - a string to send as "extend" data.
 *
 * @return int
 * @retval >= 0	index to the internal connection table representing the
 *		connection made.
 * @retval -1	error encountered setting up the connection.
 */
int
__pbs_connect_extend(char *server, char *extend_data)
{
	struct sockaddr_in server_addr;
	struct sockaddr_in my_sockaddr;
	int out;
	int i;
	int f;
	char  *altservers[2];
	int    have_alt = 0;
	struct batch_reply	*reply;
	char server_name[PBS_MAXSERVERNAME+1];
	unsigned int server_port;
	struct sockaddr_in sockname;
	pbs_socklen_t	 socknamelen;
#ifdef WIN32
	struct sockaddr_in to_sock;
	struct sockaddr_in from_sock;
#endif

#ifndef WIN32
	char   pbsrc[_POSIX_PATH_MAX];
	struct stat sb;
	int    using_secondary = 0;
#endif  /* not WIN32 */

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return -1;

	if (pbs_loadconf(0) == 0)
		return -1;

	/* get server host and port	*/

	server = PBS_get_server(server, server_name, &server_port);
	if (server == NULL) {
		pbs_errno = PBSE_NOSERVER;
		return -1;
	}

	if (pbs_conf.pbs_primary && pbs_conf.pbs_secondary) {
		/* failover configuered ...   */
		if (hostnmcmp(server, pbs_conf.pbs_primary) == 0) {
			have_alt = 1;
			/* We want to try the one last seen as "up" first to not   */
			/* have connection delays.   If the primary was up, there  */
			/* is no .pbsrc.NAME file.  If the last command connected  */
			/* to the Secondary, then it created the .pbsrc.USER file. */

			/* see if already seen Primary down */
#ifdef WIN32
			/* due to windows quirks, all try both in same order */
			altservers[0] = pbs_conf.pbs_primary;
			altservers[1] = pbs_conf.pbs_secondary;
#else
			(void)snprintf(pbsrc, _POSIX_PATH_MAX, "%s/.pbsrc.%s", pbs_conf.pbs_tmpdir, pbs_current_user);
			if (stat(pbsrc, &sb) == -1) {
				/* try primary first */
				altservers[0] = pbs_conf.pbs_primary;
				altservers[1] = pbs_conf.pbs_secondary;
				using_secondary = 0;
			} else {
				/* try secondary first */
				altservers[0] = pbs_conf.pbs_secondary;
				altservers[1] = pbs_conf.pbs_primary;
				using_secondary = 1;
			}
#endif
		}
	}

	/* if specific host name declared for the host on which */
	/* this client is running,  get its address */
	if (pbs_conf.pbs_public_host_name) {
		if (get_hostsockaddr(pbs_conf.pbs_public_host_name, &my_sockaddr) != 0)
			return -1; /* pbs_errno was set */
	}

	/* Reserve a connection state record */
	if (pbs_client_thread_lock_conntable() != 0)
		return -1;

	out = -1;
	for (i=1;i<NCONNECTS;i++) {
		if (connection[i].ch_inuse) continue;
		out = i;
		connection[out].ch_errno = 0;
		connection[out].ch_socket= -1;
		connection[out].ch_errtxt = NULL;
		connection[out].ch_inuse = 1; /* reserve the socket */
		break;
	}

	if (pbs_client_thread_unlock_conntable() != 0)
		return -1; /* pbs_errno set by the function */

	if (out < 0) {
		pbs_errno = PBSE_NOCONNECTS;
		return -1;
	}

	/*
	 * connect to server ...
	 * If attempt to connect fails and if Failover configured and
	 *   if attempting to connect to Primary,  try the Secondary
	 *   if attempting to connect to Secondary, try the Primary
	 */
	for (i=0; i<(have_alt+1); ++i) {

		/* get socket	*/

#ifdef WIN32
		/* the following lousy hack is needed since the socket call needs */
		/* SYSTEMROOT env variable properly set! */
		if (getenv("SYSTEMROOT") == NULL) {
			setenv("SYSTEMROOT", "C:\\WINNT", 1);
			setenv("SystemRoot", "C:\\WINNT", 1);
		}
		connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
		if (connection[out].ch_socket < 0) {
			setenv("SYSTEMROOT", "C:\\WINDOWS", 1);
			setenv("SystemRoot", "C:\\WINDOWS", 1);
			connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);

		}
#else
		connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
#endif
		if (connection[out].ch_socket < 0) {
			connection[out].ch_inuse = 0;
			pbs_errno = errno;
			return -1;
		}

		/* and connect... */

		if (have_alt) {
			server = altservers[i];
		}
		strcpy(pbs_server, server); /* set for error messages from commands */

		/* If a specific host name is defined which the client should use */

		if (pbs_conf.pbs_public_host_name) {
			/* my address will be in my_sockaddr,  bind the socket to it */
			my_sockaddr.sin_port = 0;
			if (bind(connection[out].ch_socket, (struct sockaddr *)&my_sockaddr, sizeof(my_sockaddr)) != 0) {
				return -1;
			}
		}

		if (get_hostsockaddr(server, &server_addr) != 0)
			return -1;

		server_addr.sin_port = htons(server_port);
		if (connect(connection[out].ch_socket,
			(struct sockaddr *)&server_addr,
			sizeof(struct sockaddr)) == 0) {

				break;
		} else {
			/* connect attempt failed */
			CLOSESOCKET(connection[out].ch_socket);
			pbs_errno = errno;
		}
	}
	if (i >= (have_alt+1)) {
		connection[out].ch_inuse = 0;
		return -1; 		/* cannot connect */
	}

#ifndef WIN32
	if (have_alt && (i == 1)) {
		/* had to use the second listed server ... */
		if (using_secondary == 1) {
			/* remove file that causes trying the Secondary first */
			unlink(pbsrc);
		} else {
			/* create file that causes trying the Primary first   */
			f = open(pbsrc, O_WRONLY|O_CREAT, 0200);
			if (f != -1)
				(void)close(f);
		}
	}
#endif

	/* setup connection level thread context */
	if (pbs_client_thread_init_connect_context(out) != 0) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		/* pbs_errno set by the pbs_connect_init_context routine */
		return -1;
	}

	/*
	 * No need for global lock now on, since rest of the code
	 * is only communication on a connection handle.
	 * But we dont need to lock the connection handle, since this
	 * connection handle is not yet been returned to the client
	 */

	/* The following code was originally  put in for HPUX systems to deal
	 * with the issue where returning from the connect() call doesn't
	 * mean the connection is complete.  However, this has also been
	 * experienced in some Linux ppc64 systems like js-2. Decision was
	 * made to enable this harmless code for all architectures.
	 * FIX: Need to use the socket to send
	 * a message to complete the process.  For IFF authentication there is
	 * no leading authentication message needing to be sent on the client
	 * socket, so will send a "dummy" message and discard the replyback.
	 */

#if !defined(PBS_SECURITY ) || (PBS_SECURITY == STD )

	DIS_tcp_setup(connection[out].ch_socket);
	if ((i = encode_DIS_ReqHdr(connection[out].ch_socket,
		PBS_BATCH_Connect, pbs_current_user)) ||
		(i = encode_DIS_ReqExtend(connection[out].ch_socket,
		extend_data))) {
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}
	if (DIS_tcp_wflush(connection[out].ch_socket)) {
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}

	reply = PBSD_rdrpy(out);
	PBSD_FreeReply(reply);

#endif	/* PBS_SECURITY ... */

	/*do configured authentication (kerberos, pbs_iff, whatever)*/

	/*Get the socket port for engage_authentication() */
	socknamelen = sizeof(sockname);
	if (getsockname(connection[out].ch_socket, (struct sockaddr *)&sockname, &socknamelen))
		return -1;

	if (engage_authentication(connection[out].ch_socket,
		server,
		server_port,
		&sockname) == -1) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_PERM;
		return -1;
	}

	/* setup DIS support routines for following pbs_* calls */

	DIS_tcp_setup(connection[out].ch_socket);
	pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG;	/* set for 3 hours */

	/*
	 * Disable Nagle's algorithm on the TCP connection to server.
	 * Nagle's algorithm is hurting cmd-server communication.
	 */
	if (pbs_connection_set_nodelay(out) == -1) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}

	return out;
}