/** * @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; }
/* * @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; }