mirror of https://github.com/BOINC/boinc.git
- client (Unix): use symbolic links instead of XML link files.
This will allow applications to access shared libraries by their logical names, which simplifies things when you have multiple platforms, and the apps (or libraries) refer to shared libraries by names that don't include the platform. This shouldn't impact the API - boinc_resolve_filename() will open the file, see that it's not an XML link file, and the symbolic link will be used directly. At some point we can change boinc_resolve_filename() on Unix to be a no-op if the client is 6.2+ - client (Unix): Append the slot dir to LD_LIBRARY_PATH. svn path=/trunk/boinc/; revision=14944
This commit is contained in:
parent
0592fa868b
commit
6ba8928537
|
@ -2504,3 +2504,29 @@ Charlie Mar 19 2008
|
|||
mac_installer/
|
||||
release_boinc.sh
|
||||
release_GridRepublic.sh
|
||||
|
||||
David Mar 19 2008
|
||||
- client (Unix): use symbolic links instead of XML link files.
|
||||
This will allow applications to access shared libraries
|
||||
by their logical names,
|
||||
which simplifies things when you have multiple platforms,
|
||||
and the apps (or libraries) refer to shared libraries
|
||||
by names that don't include the platform.
|
||||
This shouldn't impact the API - boinc_resolve_filename()
|
||||
will open the file, see that it's not an XML link file,
|
||||
and the symbolic link will be used directly.
|
||||
At some point we can change boinc_resolve_filename() on Unix
|
||||
to be a no-op if the client is 6.2+
|
||||
- client (Unix):
|
||||
Append the slot dir to LD_LIBRARY_PATH.
|
||||
|
||||
client/
|
||||
app_start.C
|
||||
client_types.C,h
|
||||
lib/
|
||||
boinc_cmd.C
|
||||
error_numbers.h
|
||||
py/Boinc/
|
||||
tools.py
|
||||
tools/
|
||||
update_versions
|
||||
|
|
|
@ -81,10 +81,8 @@ using std::vector;
|
|||
//
|
||||
#ifndef _WIN32
|
||||
static void debug_print_argv(char** argv) {
|
||||
int i;
|
||||
|
||||
msg_printf(0, MSG_INFO, "[task_debug] Arguments:");
|
||||
for (i=0; argv[i]; i++) {
|
||||
for (int i=0; argv[i]; i++) {
|
||||
msg_printf(0, MSG_INFO,
|
||||
"[task_debug] argv[%d]: %s\n", i, argv[i]
|
||||
);
|
||||
|
@ -92,43 +90,6 @@ static void debug_print_argv(char** argv) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// create a file (new_link) which contains an XML
|
||||
// reference to existing file.
|
||||
//
|
||||
static int make_link(const char *existing, const char *new_link) {
|
||||
FILE *fp;
|
||||
|
||||
fp = boinc_fopen(new_link, "w");
|
||||
if (!fp) return ERR_FOPEN;
|
||||
fprintf(fp, "<soft_link>%s</soft_link>\n", existing);
|
||||
fclose(fp);
|
||||
#ifdef SANDBOX
|
||||
return set_to_project_group(new_link);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ACTIVE_TASK::link_user_files() {
|
||||
PROJECT* project = wup->project;
|
||||
unsigned int i;
|
||||
FILE_REF fref;
|
||||
FILE_INFO* fip;
|
||||
char link_path[1024], buf[256], file_path[1024];
|
||||
int retval;
|
||||
|
||||
for (i=0; i<project->user_files.size(); i++) {
|
||||
fref = project->user_files[i];
|
||||
fip = fref.file_info;
|
||||
if (fip->status != FILE_PRESENT) continue;
|
||||
get_pathname(fip, file_path, sizeof(file_path));
|
||||
sprintf(link_path, "%s/%s", slot_dir, strlen(fref.open_name)?fref.open_name:fip->name);
|
||||
sprintf(buf, "../../%s", file_path);
|
||||
retval = make_link(buf, link_path);
|
||||
if (retval) return retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make a unique key for core/app shared memory segment
|
||||
//
|
||||
int ACTIVE_TASK::get_shmem_seg_name() {
|
||||
|
@ -250,11 +211,14 @@ int ACTIVE_TASK::write_app_init_file() {
|
|||
return retval;
|
||||
}
|
||||
|
||||
// set up a 'symbolic link' in the slot dir to the given file
|
||||
// (or copy the file to slot dir)
|
||||
// set up a file reference, given a slot dir and project dir.
|
||||
// This means:
|
||||
// 1) copy the file to slot dir, if reference is by copy
|
||||
// 2) (Unix) make a symbolic link
|
||||
// 3) (Windows) make a
|
||||
//
|
||||
static int setup_file(
|
||||
WORKUNIT* wup, FILE_INFO* fip, FILE_REF& fref,
|
||||
PROJECT* project, FILE_INFO* fip, FILE_REF& fref,
|
||||
char* file_path, char* slot_dir, bool input
|
||||
) {
|
||||
char link_path[256], buf[256];
|
||||
|
@ -266,11 +230,18 @@ static int setup_file(
|
|||
);
|
||||
sprintf(buf, "../../%s", file_path );
|
||||
|
||||
// if anonymous platform, this is called even if not first time,
|
||||
// so link may already be there
|
||||
//
|
||||
if (input && project->anonymous_platform && boinc_file_exists(link_path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fref.copy_file) {
|
||||
if (input) {
|
||||
retval = boinc_copy(file_path, link_path);
|
||||
if (retval) {
|
||||
msg_printf(wup->project, MSG_INTERNAL_ERROR,
|
||||
msg_printf(project, MSG_INTERNAL_ERROR,
|
||||
"Can't copy %s to %s", file_path, link_path
|
||||
);
|
||||
return retval;
|
||||
|
@ -279,18 +250,46 @@ static int setup_file(
|
|||
return 0;
|
||||
}
|
||||
|
||||
// if anonymous platform, link may already be there
|
||||
//
|
||||
if (input && wup->project->anonymous_platform && boinc_file_exists(link_path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = make_link(buf, link_path);
|
||||
if (retval) {
|
||||
msg_printf(wup->project, MSG_INTERNAL_ERROR,
|
||||
"Can't link %s to %s", file_path, link_path
|
||||
#ifdef _WIN32
|
||||
FILE *fp = boinc_fopen(link_path, "w");
|
||||
if (!fp) {
|
||||
msg_printf(project, MSG_INTERNAL_ERROR,
|
||||
"Can't open link file %s", link_path
|
||||
);
|
||||
return retval;
|
||||
return ERR_FOPEN;
|
||||
}
|
||||
fprintf(fp, "<soft_link>%s</soft_link>\n", file_path);
|
||||
fclose(fp);
|
||||
#else
|
||||
retval = symlink(file_path, link_path);
|
||||
if (retval) {
|
||||
msg_printf(project, MSG_INTERNAL_ERROR,
|
||||
"Can't symlink %s to %s", file_path, link_path
|
||||
);
|
||||
return ERR_SYMLINK;
|
||||
}
|
||||
#endif
|
||||
#ifdef SANDBOX
|
||||
return set_to_project_group(link_path);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ACTIVE_TASK::link_user_files() {
|
||||
PROJECT* project = wup->project;
|
||||
unsigned int i;
|
||||
FILE_REF fref;
|
||||
FILE_INFO* fip;
|
||||
char file_path[1024];
|
||||
int retval;
|
||||
|
||||
for (i=0; i<project->user_files.size(); i++) {
|
||||
fref = project->user_files[i];
|
||||
fip = fref.file_info;
|
||||
if (fip->status != FILE_PRESENT) continue;
|
||||
get_pathname(fip, file_path, sizeof(file_path));
|
||||
setup_file(project, fip, fref, file_path, slot_dir, true);
|
||||
if (retval) return retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -415,10 +414,10 @@ int ACTIVE_TASK::start(bool first_time) {
|
|||
safe_strcpy(exec_path, file_path);
|
||||
}
|
||||
// anonymous platform may use different files than
|
||||
// when the result was started
|
||||
// when the result was started, so link files even if not first time
|
||||
//
|
||||
if (first_time || wup->project->anonymous_platform) {
|
||||
retval = setup_file(wup, fip, fref, file_path, slot_dir, true);
|
||||
retval = setup_file(result->project, fip, fref, file_path, slot_dir, true);
|
||||
if (retval) {
|
||||
strcpy(buf, "Can't link input file");
|
||||
goto error;
|
||||
|
@ -438,7 +437,7 @@ int ACTIVE_TASK::start(bool first_time) {
|
|||
fref = wup->input_files[i];
|
||||
fip = fref.file_info;
|
||||
get_pathname(fref.file_info, file_path, sizeof(file_path));
|
||||
retval = setup_file(wup, fip, fref, file_path, slot_dir, true);
|
||||
retval = setup_file(result->project, fip, fref, file_path, slot_dir, true);
|
||||
if (retval) {
|
||||
strcpy(buf, "Can't link input file");
|
||||
goto error;
|
||||
|
@ -449,7 +448,7 @@ int ACTIVE_TASK::start(bool first_time) {
|
|||
if (fref.copy_file) continue;
|
||||
fip = fref.file_info;
|
||||
get_pathname(fref.file_info, file_path, sizeof(file_path));
|
||||
retval = setup_file(wup, fip, fref, file_path, slot_dir, false);
|
||||
retval = setup_file(result->project, fip, fref, file_path, slot_dir, false);
|
||||
if (retval) {
|
||||
strcpy(buf, "Can't link output file");
|
||||
goto error;
|
||||
|
@ -710,7 +709,7 @@ int ACTIVE_TASK::start(bool first_time) {
|
|||
//
|
||||
char libpath[8192];
|
||||
get_project_dir(wup->project, buf, sizeof(buf));
|
||||
sprintf(libpath, "%s:%s", getenv("LD_LIBRARY_PATH"), buf);
|
||||
sprintf(libpath, "%s:%s:%s", getenv("LD_LIBRARY_PATH"), buf, slot_dir);
|
||||
setenv("LD_LIBRARY_PATH", libpath, 1);
|
||||
|
||||
retval = chdir(slot_dir);
|
||||
|
|
|
@ -1177,7 +1177,6 @@ int FILE_REF::parse(MIOFILE& in) {
|
|||
|
||||
strcpy(file_name, "");
|
||||
strcpy(open_name, "");
|
||||
fd = -1;
|
||||
main_program = false;
|
||||
copy_file = false;
|
||||
optional = false;
|
||||
|
@ -1185,7 +1184,6 @@ int FILE_REF::parse(MIOFILE& in) {
|
|||
if (match_tag(buf, "</file_ref>")) return 0;
|
||||
if (parse_str(buf, "<file_name>", file_name, sizeof(file_name))) continue;
|
||||
if (parse_str(buf, "<open_name>", open_name, sizeof(open_name))) continue;
|
||||
if (parse_int(buf, "<fd>", fd)) continue;
|
||||
if (parse_bool(buf, "main_program", main_program)) continue;
|
||||
if (parse_bool(buf, "copy_file", copy_file)) continue;
|
||||
if (parse_bool(buf, "optional", optional)) continue;
|
||||
|
@ -1208,9 +1206,6 @@ int FILE_REF::write(MIOFILE& out) {
|
|||
if (strlen(open_name)) {
|
||||
out.printf(" <open_name>%s</open_name>\n", open_name);
|
||||
}
|
||||
if (fd >= 0) {
|
||||
out.printf(" <fd>%d</fd>\n", fd);
|
||||
}
|
||||
if (main_program) {
|
||||
out.printf(" <main_program/>\n");
|
||||
}
|
||||
|
|
|
@ -122,9 +122,8 @@ public:
|
|||
// or the app will be connected by the given fd (in which case fd is nonzero)
|
||||
//
|
||||
struct FILE_REF {
|
||||
char file_name[256];
|
||||
char open_name[256];
|
||||
int fd;
|
||||
char file_name[256]; // physical name
|
||||
char open_name[256]; // logical name
|
||||
bool main_program;
|
||||
FILE_INFO* file_info;
|
||||
bool copy_file;
|
||||
|
|
|
@ -59,7 +59,6 @@ Commands:\n\
|
|||
--project_attach URL auth attach to project\n\
|
||||
--join_acct_mgr URL name passwd attach account manager\n\
|
||||
--quit_acct_mgr quit current account manager\n\
|
||||
\n\
|
||||
--get_state show entire state\n\
|
||||
--get_results show results\n\
|
||||
--get_simple_gui_info show status of projects and active results\n\
|
||||
|
@ -70,7 +69,6 @@ Commands:\n\
|
|||
--get_messages seqno show messages > seqno\n\
|
||||
--get_host_info\n\
|
||||
--version, -V show core client version\n\
|
||||
\n\
|
||||
--result url result_name op job operation\n\
|
||||
op = suspend | resume | abort | graphics_window | graphics_fullscreen\n\
|
||||
--project URL op project operation\n\
|
||||
|
|
|
@ -185,6 +185,7 @@
|
|||
#define ERR_TOO_MANY_EXITS -226
|
||||
#define ERR_RMDIR -227
|
||||
#define ERR_CHILD_FAILED -228
|
||||
#define ERR_SYMLINK -229
|
||||
|
||||
// PLEASE: add a text description of your error to
|
||||
// the text description function boincerror() in str_util.C.
|
||||
|
|
|
@ -132,6 +132,7 @@ def process_app_version(
|
|||
signature_files={},
|
||||
file_ref_infos={},
|
||||
api_version='',
|
||||
extra_xml='',
|
||||
quiet=False
|
||||
):
|
||||
"""Return xml for application version
|
||||
|
@ -157,10 +158,11 @@ def process_app_version(
|
|||
file_ref_infos is a dictionary mapping exec_file -> extra XML strings to
|
||||
include in <file_info>, e.g. '<copy_file/>'
|
||||
|
||||
exec_files[1:] and non_exec_files should be named like 'open_name=url_filename'.
|
||||
(url_filename is the basename of file as copied to
|
||||
download/) If there is no '=', then the entire filename is
|
||||
used as both the open_name and the filename.
|
||||
exec_files[1:] and non_exec_files should be named like
|
||||
'open_name=url_filename'.
|
||||
(url_filename is the basename of file as copied to download/)
|
||||
If there is no '=', then the entire filename is used as
|
||||
both the open_name and the filename.
|
||||
|
||||
"""
|
||||
assert(exec_files)
|
||||
|
@ -191,7 +193,9 @@ def process_app_version(
|
|||
app.name, version_num)
|
||||
|
||||
if (len(api_version)):
|
||||
xml_doc += ' <api_version>'+api_version+'</api_version>\n';
|
||||
xml_doc += ' <api_version>'+api_version+'</api_version>\n'
|
||||
if (len(extra_xml)):
|
||||
xml_doc += extra_xml
|
||||
|
||||
first = True
|
||||
for exec_file in exec_files + non_exec_files:
|
||||
|
|
|
@ -59,7 +59,8 @@ def add_files(
|
|||
exec_files, # executable files; entry 0 is the main program
|
||||
non_exec_files=[], # non-executable files
|
||||
signature_files={},
|
||||
file_ref_infos = {}
|
||||
file_ref_infos = {},
|
||||
extra_xml = ''
|
||||
):
|
||||
''' add files to app.
|
||||
'''
|
||||
|
@ -98,7 +99,8 @@ def add_files(
|
|||
non_exec_files = non_exec_files,
|
||||
signature_files = signature_files,
|
||||
file_ref_infos = file_ref_infos,
|
||||
api_version = api_version
|
||||
api_version = api_version,
|
||||
extra_xml = extra_xml
|
||||
)
|
||||
|
||||
object = database.AppVersion(
|
||||
|
@ -120,12 +122,8 @@ def re_match_exec_filename(filepath):
|
|||
|
||||
def find_versions(app, dir):
|
||||
"""Find application versions in DIR.
|
||||
|
||||
If directory contains sub-directories, those are scanned (non-recursively)
|
||||
for files. If an executable is found, the first one found
|
||||
(alphabetically) is the main program and other files bundled as
|
||||
non-executables.
|
||||
|
||||
If directory contains sub-directories,
|
||||
those are scanned (non-recursively) for files.
|
||||
"""
|
||||
|
||||
for filepath in xlistdir(dir):
|
||||
|
@ -184,6 +182,7 @@ def find_versions__process_bundle(app, match, dir):
|
|||
non_exec_files = []
|
||||
signature_files = {}
|
||||
file_ref_infos = {}
|
||||
extra_xml = ''
|
||||
dirname = os.path.basename(dir)
|
||||
found_main = False
|
||||
for filepath in xlistdir(dir):
|
||||
|
@ -200,6 +199,9 @@ def find_versions__process_bundle(app, match, dir):
|
|||
s = filepath[:-4]
|
||||
signature_files[s] = filepath
|
||||
continue
|
||||
if os.path.basename(filepath) == 'extra_xml':
|
||||
extra_xml = open(filepath).read()
|
||||
continue
|
||||
if filepath.endswith('.file_ref_info'):
|
||||
s = filepath[:-len('.file_ref_info')]
|
||||
file_ref_infos[s] = open(filepath).read()
|
||||
|
@ -228,6 +230,7 @@ def find_versions__process_bundle(app, match, dir):
|
|||
non_exec_files = non_exec_files,
|
||||
signature_files = signature_files,
|
||||
file_ref_infos = file_ref_infos,
|
||||
extra_xml = extra_xml,
|
||||
)
|
||||
|
||||
####################
|
||||
|
|
Loading…
Reference in New Issue