mirror of https://github.com/BOINC/boinc.git
Merge pull request #2713 from JuhaSointusalo/client-gpu-detection
client: fixes for launching GPU detection
This commit is contained in:
commit
388dcea7fe
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
75
lib/util.cpp
75
lib/util.cpp
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue