Example #1
0
/**
 * @brief
 * 		This is the Windows counterpart of the monitoring
 *		code.
 * @par
 *		This function does the following:
 *		a) Creates/opens a file $PBS_HOME/datastore/pbs_dblock.
 *		b) If mode is "check", attempts to lock the file. If locking
 *		succeeds, unlocks the file and returns success.
 *		c) If mode is "monitor", launches itself with a "monitorchild"
 *		parameter, which calls function "win_db_monitor_child".
 *		d) It launches a child process using win_popen() and reads its stdout.
 *		e) If the child was able to successfully lock the file, it prints "0"
 *	   to its stdout. Otherwise it prints the reason for why it could
 *	   not acquire the lockfile.
 *
 * @param[in]	mode	-	"check"	: to just check if lockfile can be locked
 *		     				"monitor"	:  to launch a monitoring process that holds
 *				 			onto the file lock
 *
 * @retval	1	: Function failed to acquire lock
 * @retval	0	: Function succeded in the requested operation
 *
 * @par MT-safe:	Yes
 */
int
win_db_monitor(char *mode)
{
	int rc;
	BOOL fSuccess = FALSE;
	HANDLE hFile;
	char lockfile[MAXPATHLEN + 1];
	char cmd_line[2*MAXPATHLEN + 1];
	char result[RES_BUF_SIZE];
	int is_lock_local = 0;
	pio_handles pio;
	proc_ctrl proc_info;
	HANDLE hOut, hErr;

	result[0] = '\0';
	snprintf(lockfile, MAXPATHLEN, "%s\\datastore\\pbs_dblock", pbs_conf.pbs_home_path);

	/*
	 * If mode is check, just attempt to lock the file.
	 * Return success if able to lock, else return failure.
	 */
	if (strcmp(mode, "check") == 0) {
		hFile = acquire_lock(lockfile, result, sizeof(result), &is_lock_local);
		if (hFile == INVALID_HANDLE_VALUE) {
			if (is_lock_local)
				return 0; /* Since lock is already held by this host, return success */
			fprintf(stderr, "Failed to acquire lock on %s. %s\n", lockfile, result);
			return 1;
		}

		lock_out(hFile, F_UNLCK);
		CloseHandle(hFile);
		unlink(lockfile);
		return 0;
	}

	/* monitor part */
	proc_info.flags = CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW;
	proc_info.bInheritHandle = TRUE;
	proc_info.bnowait = TRUE;
	proc_info.need_ptree_termination = FALSE;
	proc_info.buse_cmd = FALSE;

	sprintf(cmd_line, "\"%s\" monitorchild", pbs_ds_monitor_exe);

	/* set the current processes stdout/stderr not be inherited */
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	SetHandleInformation(hOut, HANDLE_FLAG_INHERIT, 0);

	hErr = GetStdHandle(STD_ERROR_HANDLE);
	SetHandleInformation(hErr, HANDLE_FLAG_INHERIT, 0);

	/* start child process to lock db lockfile and monitor db process */
	if (win_popen(cmd_line, "r", &pio, &proc_info) == 0) {
		win_pclose(&pio);
		fprintf(stderr, "Unable to create process, errno = %d\n", errno);
		return 1;
	}

	/* wait and read the info from child whether it was able to acquire lock */
	rc = win_pread(&pio, result, sizeof(result) - 1);

	win_pclose2(&pio); /* close handles but keep process running */

	if (rc > 0) {
		if (result[0] == '0') { /* indicates success */
			return 0;
		}
		result[rc - 1] = '\0';
	}

	/* failure */
	fprintf(stderr, "Failed to acquire lock on %s. %s\n", lockfile, result);
	return 1;
}
Example #2
0
/*
 * @brief
 *      PBS_authenticate - call pbs_iff(1) to authenticate use to the PBS server.
 *
 * @note
 * This function now accepts a argument sock_port and invoke pbs_iff
 * passing this port as a command line argument (both on unix and windows)
 * This change is done because getsockname() fails sometimes on Windows.
 *
 * Also, this would create an environment variable PBS_IFF_CLIENT_ADDR set to
 * the client's connecting address, which is made known to the pbs_iff process.
 *
 * If unable to authenticate, an attempt is made to run the old method
 * 'pbs_iff -i <pbs_client_addr>' also.
 *
 *
 * @param[in]  psock           Socket descriptor used by PBS client to connect PBS server.
 * @param[in]  server_name     Connecting PBS server host name.
 * @param[in]  server_port     Connecting PBS server port number.
 * @param[in]  paddr           Connecting PBS client sockaddr.
 *
 * @return int
 * @retval  0 on success.
 * @retval -1 on failure.
 */
static int
PBSD_authenticate(int psock, char * server_name, int server_port,
	struct sockaddr_in *paddr)
{
	char   cmd[2][PBS_MAXSERVERNAME + 80];
	int    cred_type;
	int    i, k;
	char*  pbs_client_addr = NULL;
	u_short psock_port = 0;
	int	rc;
#ifdef WIN32
	struct	pio_handles	pio;
#else
	FILE	*piff;
#endif
	if (paddr == NULL) {
		return (-1);
	}
	pbs_client_addr = inet_ntoa(paddr->sin_addr);
	if (pbs_client_addr == NULL) {
		return (-1);
	}
	psock_port = paddr->sin_port;

	/* for compatibility with 12.0 pbs_iff */
	(void)snprintf(cmd[1], sizeof(cmd[1])-1, "%s -i %s %s %u %d %u",
		pbs_conf.iff_path, pbs_client_addr,
		server_name, server_port, psock, psock_port);
#ifdef WIN32

	(void)snprintf(cmd[0], sizeof(cmd[0])-1, "%s %s %u %d %u", pbs_conf.iff_path,
		server_name, server_port, psock, psock_port);
	for (k=0; k < 2; k++) {
		rc = 0;
		SetEnvironmentVariable(PBS_IFF_CLIENT_ADDR, pbs_client_addr);
		if (!win_popen(cmd[k], "r", &pio, NULL)) {
			printf("failed to execute %s\n", cmd[k]);
			SetEnvironmentVariable(PBS_IFF_CLIENT_ADDR, NULL);
			rc = -1;
			break;
		}
		i=win_pread(&pio, (char *)&cred_type, (int)sizeof(int));
		win_pclose(&pio);
		SetEnvironmentVariable(PBS_IFF_CLIENT_ADDR, NULL);

		if ((i != sizeof(int)) ||
			(cred_type != PBS_credentialtype_none)) {
			rc = -1;
		} else {
			break;
		}
	}

#else	/* UNIX code here */
	/* Use pbs_iff to authenticate me */
	(void)snprintf(cmd[0], sizeof(cmd[0])-1, "%s=%s %s %s %u %d %u", PBS_IFF_CLIENT_ADDR,
		pbs_client_addr, pbs_conf.iff_path,
		server_name, server_port, psock, psock_port);

	for (k=0; k < 2; k++) {
		rc = 0;

		piff = (FILE *)popen(cmd[k], "r");
		if (piff == NULL) {
			rc = -1;
			break;
		}

		while ((i = read(fileno(piff), &cred_type, sizeof(int))) == -1) {
			if (errno != EINTR)
				break;
		}

		(void)pclose(piff);
		if ((i != sizeof(int)) ||
			(cred_type != PBS_credentialtype_none)) {
			rc = -1;
		} else {
			break;
		}
	}
#endif	/* end of UNIX code */

	return rc;
}