diff --git a/checkin_notes b/checkin_notes index 3059b81b14..3738152edc 100644 --- a/checkin_notes +++ b/checkin_notes @@ -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 diff --git a/client/app_start.C b/client/app_start.C index d45046ed77..a6c84dafbe 100644 --- a/client/app_start.C +++ b/client/app_start.C @@ -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, "%s\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; iuser_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, "%s\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; iuser_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); diff --git a/client/client_types.C b/client/client_types.C index 3e9517cb07..36738801d3 100644 --- a/client/client_types.C +++ b/client/client_types.C @@ -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, "")) return 0; if (parse_str(buf, "", file_name, sizeof(file_name))) continue; if (parse_str(buf, "", open_name, sizeof(open_name))) continue; - if (parse_int(buf, "", 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(" %s\n", open_name); } - if (fd >= 0) { - out.printf(" %d\n", fd); - } if (main_program) { out.printf(" \n"); } diff --git a/client/client_types.h b/client/client_types.h index 81d9d16e36..1ece334e55 100644 --- a/client/client_types.h +++ b/client/client_types.h @@ -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; diff --git a/lib/boinc_cmd.C b/lib/boinc_cmd.C index 4435f53a86..9f48faa978 100644 --- a/lib/boinc_cmd.C +++ b/lib/boinc_cmd.C @@ -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\ diff --git a/lib/error_numbers.h b/lib/error_numbers.h index b9cec8bd32..93503f3421 100644 --- a/lib/error_numbers.h +++ b/lib/error_numbers.h @@ -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. diff --git a/py/Boinc/tools.py b/py/Boinc/tools.py index 95e6254c1a..bb1b96d6e5 100644 --- a/py/Boinc/tools.py +++ b/py/Boinc/tools.py @@ -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 , e.g. '' - 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+'\n'; + xml_doc += ' '+api_version+'\n' + if (len(extra_xml)): + xml_doc += extra_xml first = True for exec_file in exec_files + non_exec_files: diff --git a/tools/update_versions b/tools/update_versions index eeb8678db6..070fb9cdd1 100755 --- a/tools/update_versions +++ b/tools/update_versions @@ -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, ) ####################