Merge pull request #2713 from JuhaSointusalo/client-gpu-detection

client: fixes for launching GPU detection
This commit is contained in:
David Anderson 2018-09-26 00:41:51 -07:00 committed by GitHub
commit 388dcea7fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 39 deletions

View File

@ -58,6 +58,7 @@
#ifdef _WIN32
#include "boinc_win.h"
#include "win_util.h"
#ifdef _MSC_VER
#define snprintf _snprintf
#define chdir _chdir
@ -66,6 +67,8 @@
#include "config.h"
#include <setjmp.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#endif
#include "coproc.h"
@ -595,6 +598,7 @@ int COPROCS::launch_child_process_to_detect_gpus() {
#else
int prog;
#endif
char quoted_client_path[MAXPATHLEN];
char quoted_data_dir[MAXPATHLEN+2];
char data_dir[MAXPATHLEN];
int retval = 0;
@ -612,25 +616,38 @@ int COPROCS::launch_child_process_to_detect_gpus() {
}
}
// use full path to exe if possible, otherwise keep using argv[0]
char execpath[MAXPATHLEN];
if (!get_real_executable_path(execpath, sizeof(execpath))) {
client_path = execpath;
}
boinc_getcwd(data_dir);
#ifdef _WIN32
strlcpy(quoted_client_path, "\"", sizeof(quoted_client_path));
strlcat(quoted_client_path, client_path, sizeof(quoted_client_path));
strlcat(quoted_client_path, "\"", sizeof(quoted_client_path));
strlcpy(quoted_data_dir, "\"", sizeof(quoted_data_dir));
strlcat(quoted_data_dir, data_dir, sizeof(quoted_data_dir));
strlcat(quoted_data_dir, "\"", sizeof(quoted_data_dir));
#else
strlcpy(quoted_client_path, client_path, sizeof(quoted_client_path));
strlcpy(quoted_data_dir, data_dir, sizeof(quoted_data_dir));
#endif
if (log_flags.coproc_debug) {
msg_printf(0, MSG_INFO,
"[coproc] launching child process at %s",
client_path
);
msg_printf(0, MSG_INFO,
"[coproc] relative to directory %s",
client_dir
quoted_client_path
);
if (!is_path_absolute(client_path)) {
msg_printf(0, MSG_INFO,
"[coproc] relative to directory %s",
client_dir
);
}
msg_printf(0, MSG_INFO,
"[coproc] with data directory %s",
quoted_data_dir
@ -639,15 +656,13 @@ int COPROCS::launch_child_process_to_detect_gpus() {
int argc = 4;
char* const argv[5] = {
const_cast<char *>(CLIENT_EXEC_FILENAME),
const_cast<char *>(quoted_client_path),
const_cast<char *>("--detect_gpus"),
const_cast<char *>("--dir"),
const_cast<char *>(quoted_data_dir),
NULL
};
chdir(client_dir);
retval = run_program(
client_dir,
client_path,
@ -657,8 +672,6 @@ int COPROCS::launch_child_process_to_detect_gpus() {
prog
);
chdir(data_dir);
if (retval) {
if (log_flags.coproc_debug) {
msg_printf(0, MSG_INFO,
@ -671,9 +684,25 @@ int COPROCS::launch_child_process_to_detect_gpus() {
retval = get_exit_status(prog);
if (retval) {
char buf[200];
#ifdef _WIN32
char buf2[200];
windows_format_error_string(retval, buf2, sizeof(buf2));
snprintf(buf, sizeof(buf), "process exited with status 0x%x: %s", retval, buf2);
#else
if (WIFEXITED(retval)) {
int code = WEXITSTATUS(retval);
snprintf(buf, sizeof(buf), "process exited with status %d: %s", code, strerror(code));
} else if (WIFSIGNALED(retval)) {
int sig = WTERMSIG(retval);
snprintf(buf, sizeof(buf), "process was terminated by signal %d", sig);
} else {
snprintf(buf, sizeof(buf), "unknown status %d", retval);
}
#endif
msg_printf(0, MSG_INFO,
"GPU detection failed. error code %d",
retval
"GPU detection failed: %s",
buf
);
}

View File

@ -463,12 +463,17 @@ int main(int argc, char** argv) {
) {
int i, len=1024;
char commandLine[1024];
char execpath[MAXPATHLEN];
STARTUPINFO si;
PROCESS_INFORMATION pi;
if (get_real_executable_path(execpath, sizeof(execpath))) {
strlcpy(execpath, argv[0], sizeof(execpath));
}
argv[index] = "-detach_phase_two";
sprintf(commandLine, "\"%s\"", CLIENT_EXEC_FILENAME);
snprintf(commandLine, sizeof(commandLine), "\"%s\"", execpath);
for (i = 1; i < argc; i++) {
strlcat(commandLine, " ", len);
strlcat(commandLine, argv[i], len);

View File

@ -993,11 +993,6 @@ if test -e "/proc/self/stat"; then
AC_DEFINE(HAVE__PROC_SELF_STAT, 1, [Define to 1 if /proc/self/stat exists])
fi
dnl Check for /proc/self/exe (Linux)
if test -e "/proc/self/exe"; then
AC_DEFINE(HAVE__PROC_SELF_EXE, 1, [Define to 1 if /proc/self/exe exists])
fi
dnl Check for /proc/meminfo (Linux)
if test -e "/proc/meminfo"; then
AC_DEFINE(HAVE__PROC_MEMINFO, 1, [Define to 1 if /proc/meminfo exists])

View File

@ -977,3 +977,20 @@ int get_filesystem_info(double &total_space, double &free_space, char* path) {
#endif
return 0;
}
bool is_path_absolute(const std::string path) {
#ifdef _WIN32
if (path.length() >= 3 && isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) {
// c:\file
return true;
}
if (path.length() >= 2 && (path[0] == '\\' || path[0] == '/') && (path[1] == '\\' || path[1] == '/')) {
// \\server\file
// \\?\c:\file
return true;
}
return false;
#else
return path.length() >= 1 && path[0] == '/';
#endif
}

View File

@ -93,6 +93,7 @@ extern int file_size(const char*, double&);
extern int clean_out_dir(const char*);
extern int dir_size(const char* dirpath, double&, bool recurse=true);
extern int get_filesystem_info(double& total, double& free, char* path=const_cast<char *>("."));
extern bool is_path_absolute(const std::string path);
// TODO TODO TODO
// remove this code - the DirScanner class does the same thing.

View File

@ -41,9 +41,15 @@
#ifndef _WIN32
#include "config.h"
#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
@ -408,7 +414,7 @@ int read_file_string(
#ifdef _WIN32
int run_program(
const char* dir, const char* file, int argc, char *const argv[], double nsecs, HANDLE& id
const char* dir, const char* /*file*/, int argc, char *const argv[], double nsecs, HANDLE& id
) {
int retval;
PROCESS_INFORMATION process_info;
@ -430,7 +436,7 @@ int run_program(
}
retval = CreateProcessA(
file,
NULL,
cmdline,
NULL,
NULL,
@ -473,11 +479,11 @@ int run_program(
retval = chdir(dir);
if (retval) return retval;
}
execv(file, argv);
execvp(file, argv);
#ifdef _USING_FCGI_
FCGI::perror("execv");
FCGI::perror("execvp");
#else
perror("execv");
perror("execvp");
#endif
exit(errno);
}
@ -629,23 +635,50 @@ double rand_normal() {
// determines the real path and filename of the current process
// not the current working directory
//
#ifdef HAVE__PROC_SELF_EXE
int get_real_executable_path(char* path, size_t max_len) {
int ret = readlink("/proc/self/exe", path, max_len - 1);
if ( ret >= 0) {
path[ret] = '\0'; // readlink does not null terminate
return 0;
} else {
#ifdef _USING_FCGI_
FCGI::perror("readlink");
#else
perror("readlink");
#endif
return ERR_PROC_PARSE;
#if defined(__APPLE__)
uint32_t size = (uint32_t)max_len;
if (_NSGetExecutablePath(path, &size)) {
return ERR_BUFFER_OVERFLOW;
}
}
return BOINC_SUCCESS;
#elif (defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_PROC_PATHNAME)
#if defined(__DragonFly__) || defined(__FreeBSD__)
int name[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
#else
int get_real_executable_path(char* , size_t ) {
return ERR_NOT_IMPLEMENTED;
}
int name[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME };
#endif
if (sysctl(name, 4, path, &max_len, NULL, 0)) {
return errno == ENOMEM ? ERR_BUFFER_OVERFLOW : ERR_PROC_PARSE;
}
return BOINC_SUCCESS;
#elif defined(_WIN32)
DWORD length = GetModuleFileNameA(NULL, path, (DWORD)max_len);
if (!length) {
return ERR_PROC_PARSE;
} else if (length == (DWORD)max_len) {
return ERR_BUFFER_OVERFLOW;
}
return BOINC_SUCCESS;
#else
const char* links[] = { "/proc/self/exe", "/proc/curproc/exe", "/proc/self/path/a.out", "/proc/curproc/file" };
for (unsigned int i = 0; i < sizeof(links) / sizeof(links[0]); ++i) {
ssize_t ret = readlink(links[i], path, max_len - 1);
if (ret < 0) {
if (errno != ENOENT) {
#ifdef _USING_FCGI_
FCGI::perror("readlink");
#else
perror("readlink");
#endif
}
continue;
} else if ((size_t)ret == max_len - 1) {
return ERR_BUFFER_OVERFLOW;
}
path[ret] = '\0'; // readlink does not null terminate
return BOINC_SUCCESS;
}
return ERR_NOT_IMPLEMENTED;
#endif
}