From 4811c240b37ffcd030c2b5a75185f459bc20a424 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 13 Jun 2006 20:27:35 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=10329 --- checkin_notes | 13 ++++ client/app_control.C | 9 ++- doc/app.php | 26 +------ doc/client_app.php | 9 --- doc/files.php | 130 -------------------------------- doc/sandbox.php | 143 ++++++++++++++++++++++++------------ doc/xml.php | 171 +++++++++++++++++++++++++++++++++++++++++++ doc/yeti.jpg | Bin 31756 -> 0 bytes lib/parse.C | 19 ++++- sched/sched_config.C | 8 -- 10 files changed, 304 insertions(+), 224 deletions(-) create mode 100644 doc/xml.php delete mode 100644 doc/yeti.jpg diff --git a/checkin_notes b/checkin_notes index cacf2bb3fd..d416ed2334 100755 --- a/checkin_notes +++ b/checkin_notes @@ -5896,3 +5896,16 @@ Charlie 13 June 2006 mac_build/ boinc.xcodeproj/ project.pbxproj + +David 13 June 2006 + - core client: don't check app disk usage more often than + every 5 min (used to be 5*disk interval) + - scheduler XML parsing code: handle XML comments + (you can now have comments in config.xml) + + client/ + app_control.C + lib/ + parse.C + sched/ + sched_config.C diff --git a/client/app_control.C b/client/app_control.C index d31fe28da4..cb23b69710 100644 --- a/client/app_control.C +++ b/client/app_control.C @@ -520,11 +520,12 @@ bool ACTIVE_TASK_SET::check_rsc_limits_exceeded() { bool do_disk_check = false; bool did_anything = false; - // disk_interval is typically 60 sec, - // and some slot dirs have lots of files. - // So only check every 5*disk_interval + // Some slot dirs have lots of files, + // so only check every min(disk_interval, 300) secs // - if (gstate.now > last_disk_check_time + 5*gstate.global_prefs.disk_interval) { + double min_interval = gstate.global_prefs.disk_interval; + if (min_interval < 300) min_interval = 300; + if (gstate.now > last_disk_check_time + min_interval) { do_disk_check = true; } for (j=0;j -An application represents a collection of related computation. -It consists of a program (perhaps with versions for different platforms) +An application +consists of a program (perhaps with versions for different platforms) and a set of workunits and results. A project can operate many applications. Applications are maintained in the application table in the BOINC DB, @@ -31,28 +31,10 @@ it is also sent the latest application version for its platform. It is sent work only if this version is the minimum or greater.

-Application versions are maintained in the app_version table -in the BOINC DB. -Each entry includes an XML document describing the -files that make up the application version: -".html_text(" - - ... - -[ ... ] - - foobar - 4 - - program_1 - - - - library_12 - -")." Application versions can be created using update_versions. +Descriptions of application versions are stored in the app_version +table in the BOINC DB. "; page_tail(); ?> diff --git a/doc/client_app.php b/doc/client_app.php index b59c294eea..5c485e2c96 100644 --- a/doc/client_app.php +++ b/doc/client_app.php @@ -39,15 +39,6 @@ as well as the minimum checkpoint period.

Files created by the API implementation, read by the core client:

diff --git a/doc/files.php b/doc/files.php index 9c0893bba7..609bbbb5bf 100644 --- a/doc/files.php +++ b/doc/files.php @@ -14,141 +14,11 @@ Examples of files: The BOINC core client transfers files to and from project-operated data servers using HTTP.

-A file is described by an XML element of the form -".html_text(" - - foobar - http://a.b.c/foobar - http://x.y.z/foobar - ... - 123123123123 - 134423 - 200000 - 1 - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - -")." -The elements are as follows: -"; -list_start(); -list_item( - "name", - "The file's name, which must be unique within the project. - If you want to use participant hosts on which - filenames are case-insensitive (e.g. Windows) - this uniqueness is case-insensitive." -); -list_item("url", - "a URL where the file is (or will be) located on a data server." -); -list_item("md5_cksum", "The MD5 checksum of the file." -); -list_item("nbytes", - "the size of the file in bytes." -); -list_item("max_nbytes", - "The maximum allowable size of the file in bytes (may be greater than 2^32). - This is used to prevent flooding data servers with bogus data." -); -list_item("status", - "0 if the file is not present, - 1 if the file is present, or a negative error code if there was a - problem in downloading or generating the file." -); -list_item("generated_locally", - "If present, indicates that the file will be generated by an application on - the client, as opposed to being downloaded." -); -list_item("executable", - "If present, indicates that the file protections should be set to allow - execution." -); -list_item("upload_when_present", - "If present, indicates that the file should be uploaded - when the application finishes. - The file is uploaded even if the application doesn't - finish successfully. - API functions are available for - uploading files prior to - finishing computation. -"); -list_item("sticky", - "If present, indicates that the file should be retained - on the client after its initial use." -); -list_item("signature_required", - "If present, indicates that the file should be verified with an - RSA signature. - This generally only applies to executable files." -); -list_item("no_delete", - "If present for an input (workunit) file, - indicates that the file should NOT be removed from the data server's - download directory when the workunit is completed. - Use this if a particular input file or files are used by more than one - workunit, or will be used by future workunits. -

- If present for an output (result) file, - indicates that the file should NOT be removed from the data server's upload - directory when the corresponding workunit is completed. - Use with caution - this may cause your upload directory to overflow." -); -list_item("report_on_rpc", - "Include a description of this file in scheduler RPC requests, - so that the scheduler may send appropriate work - using locality scheduling." -); -list_end(); -echo " -

Once a file is created (on a data server or a participant host) it is immutable. This means that all replicas of that file are assumed to be identical. -

File references

-

-Files may be associated with workunits, -results and -application versions. -Each such association is represented by an XML element of the form -".html_text(" - - foobar - [ input ] - [ ] - -")." -The elements are as follows: -"; -list_start(); -list_item("file_name", "Specifies a file."); -list_item("open_name", - "The name by which the application will refer to the file. - Applications access files using - the following functions: -

-        char physical_name[256];
-        boinc_resolve_filename(\"input\", physical_name, 256);
-        fopen(physical_name, \"r\")
-    
- In this example, open_name is 'input'. - It is mapped, at runtime, to a path that includes - the filename ('foobar' in the example above). -"); -list_item("main_program", - "Relevant only for files associated with application versions. - It indicates that this file is the application's main program. -"); -list_end(); - -echo "

File management

BOINC's default behavior is to delete files around diff --git a/doc/sandbox.php b/doc/sandbox.php index 568bce5d73..846ebdbaba 100644 --- a/doc/sandbox.php +++ b/doc/sandbox.php @@ -1,4 +1,19 @@ +In our design, BOINC applications run under a specially-created account +having a minimal set of privileges. +Previously, the applications typically ran as the user who installed BOINC, +and had the full privileges of that account. +"; function prot($user, $group, $perm) { return " @@ -20,11 +35,15 @@ $mm6555 = prot('boinc_master', 'boinc_master', '0555+setuid+setgid'); $mm6770 = prot('boinc_master', 'boinc_master', '0770+setuid+setgid'); $mm0775 = prot('(installing user)', 'admin', '0775'); -function show_dir($name, $prot, $contents) { +$colors = array('ddddff', 'ccccff', 'bbbbff'); + +function show_dir($level, $name, $prot, $contents) { + global $colors; + $color = $colors[$level]; $x = " - +
-
$name $prot + $name $prot "; for ($i=0; $i$prot
+ $name $prot
"; } echo " -

The BOINC installer creates two users and two groups: +

+Our design uses two users and two groups, +both specially created for use by BOINC. +These users and groups are created by the installation process.

  • Group: boinc_master
  • Group: boinc_project
  • User: boinc_master
      -
    • Primary Group: boinc_master -
    • Supplementary Groups: boinc_project +
    • Primary group: boinc_master +
    • Supplementary groups: boinc_project
  • User: boinc_project
      -
    • Primary Group: boinc_project -
    • Supplementary Groups: none +
    • Primary group: boinc_project +
    • Supplementary groups: none
-Both groups boinc_project and boinc_master are added to the Supplementary Groups Lists of those other users who are members of group admin. This gives admin users full access to all BOINC and project files. -

-

The following diagram shows user, group and permissions for the BOINC file and directory tree:

+On Mac OS X, boinc_project and boinc_master +are added to the Supplementary Groups Lists of those other users +who are members of group admin. +This gives admin users full access to all BOINC and project files. +

+The following diagram shows user, group and permissions +for the BOINC file and directory tree: +

"; echo - show_dir('BOINC data', $mp0750, array( - show_dir('projects', $mp0750, array( - show_dir('setiathome.berkeley.edu', $mp0770, array( + show_dir(0, 'BOINC data', $mp0750, array( + show_dir(1, 'projects', $mp0750, array( + show_dir(2, 'setiathome.berkeley.edu', $mp0770, array( show_file('files created by BOINC Client', $mp0770), show_file('files created by project apps', $pp0770) )) )), - show_dir('slots', $mp0750, array( - show_dir('0', $mp0770, array( + show_dir(1, 'slots', $mp0750, array( + show_dir(2, '0', $mp0770, array( show_file('files created by BOINC Client', $mp0770), show_file('files created by project apps', $pp0770) )) )), - show_dir('switcher (directory)', $mm0770, array( + show_dir(1, 'switcher (directory)', $mm0770, array( show_file('switcher (executable)', $pp6550) )), - show_dir('locale', $mm0770, array( - show_dir('de', $mm0770, array( + show_dir(1, 'locale', $mm0770, array( + show_dir(2, 'de', $mm0770, array( show_file('BOINC Manager.mo', $mm0770), show_file('wxstd.mo', $mm0770) )) @@ -100,7 +127,7 @@ echo echo "

"; echo - show_dir('BOINC executables', $mm0775, array( + show_dir(0, 'BOINC executables', $mm0775, array( show_file('BOINC Manager', $mm2555), show_file('BOINC Client', $mm6555), )); @@ -111,37 +138,57 @@ echo "

  • BOINC Client runs setuid and setgid to boinc_master:boinc_master. -
  • Because user boinc_master is a member of both groups boinc_master and boinc_project, -BOINC Client can set files and directories it creates to either group and has full access to files and -directories in both groups. -
  • BOINC Client does not directly execute project applications. It runs the helper application switcher, -passing the request in the argument list. switcher runs setuid boinc_project and setgid -boinc_project, so all project applications inherit user and group boinc_project. +
  • Because user boinc_master is a member of both groups +boinc_master and boinc_project, +BOINC Client can set files and directories it creates to either group +and has full access to files and directories in both groups. +
  • BOINC Client does not directly execute project applications. +It runs the helper application switcher, +passing the request in the argument list. +switcher runs setuid boinc_project and setgid +boinc_project, +so all project applications inherit user and group boinc_project. This blocks project applications from accessing unauthorized files. -
  • BOINC Manager runs setgid to group boinc_master. It can access all files in group boinc_master. -It runs as the user who launched it, which is necessary for a number of GUI features to work correctly. -Although this means that BOINC Manager cannot directly access files created by project applications, there is no -need for it to do so. -
  • BOINC Manager and BOINC Client set their umasks to 007, which is inherited by all child applications. The -default permissions for all files and directories they create prevent access outside the user and group. -
  • Non-admin users have no direct access to BOINC or project files. They can access these files only by running -the BOINC Manager and Client. -
  • The switcher application is inside the switcher directory. This directory is accessible only -by user and group boinc_master, so that project applications cannot modify the switcher +
  • BOINC Manager runs setgid to group boinc_master. +It can access all files in group boinc_master. +It runs as the user who launched it, +which is necessary for a number of GUI features to work correctly. +Although this means that BOINC Manager cannot directly access files +created by project applications, there is no need for it to do so. +
  • BOINC Manager and BOINC Client set their umasks to 007, +which is inherited by all child applications. +The default permissions for all files and directories they create prevent +access outside the user and group. +
  • Non-admin users have no direct access to BOINC or project files. +They can access these files only by running the BOINC Manager and Client. +
  • The switcher application is inside the switcher directory. +This directory is accessible only by user and group boinc_master, +so that project applications cannot modify the switcher application's permissions or code. -
  • Users with admin access are members of groups boinc_master and boinc_project so that they do have -direct access to all BOINC and project files to simplify maintenance and administration. -
  • The RPC password file gui_rpc_auth.cfg is accessible only by user and group boinc_master. In other -words, only BOINC Manager, BOINC Client and authorized administrative users can read or modify it, limiting access to -most BOINC RPC functions. -
  • BOINC Manager restricts certain functions to authorized users: Attach to Project, Detach from Project, Reset Project. -If an unauthorized user requests these functions, the Manager requires password authentication. -
  • On Macintosh computers, the actual directory structure of the BOINC Manager application bundle is more complex -than implied by the box BOINC executables in the BOINC tree diagram shown above. -
  • Some Macintosh system administrators may wish to limit which users can perform BOINC Manager functions (Activity Menu, -etc.). This can be done by moving BOINC Manager out of the /Applications directory into a directory with restricted access. +
  • Users with admin access are members of groups boinc_master +and boinc_project so that they do have +direct access to all BOINC and project files +to simplify maintenance and administration. +
  • The RPC password file gui_rpc_auth.cfg +is accessible only by user and group boinc_master. +In other words, only BOINC Manager, BOINC Client and +authorized administrative users can read or modify it, +limiting access to most BOINC RPC functions. +
  • BOINC Manager restricts certain functions to authorized users: +Attach to Project, Detach from Project, Reset Project. +If an unauthorized user requests these functions, +the Manager requires password authentication. +
  • On Macintosh computers, the actual directory structure +of the BOINC Manager application bundle is more complex +than implied by the box BOINC executables in the BOINC +tree diagram shown above. +
  • Some Macintosh system administrators may wish to limit which users +can perform BOINC Manager functions (Activity Menu, etc.). +This can be done by moving BOINC Manager out of the +/Applications directory into a directory with restricted access.

"; +page_tail(); ?> diff --git a/doc/xml.php b/doc/xml.php new file mode 100644 index 0000000000..fe55d9fc27 --- /dev/null +++ b/doc/xml.php @@ -0,0 +1,171 @@ + +
  • The BOINC DB +
  • Scheduler request and reply messages +
  • The client state file +
  • GUI RPCs + +Some of these XML elements are described here +(not all fields are present in all contexts). + +

    Files

    +

    +A file is described by an XML element of the form +".html_text(" + + foobar + http://a.b.c/foobar + http://x.y.z/foobar + ... + 123123123123 + 134423 + 200000 + 1 + [ ] + [ ] + [ ] + [ ] + [ ] + [ ] + [ ] + +")." +The elements are as follows: +"; +list_start(); +list_item( + "name", + "The file's name, which must be unique within the project. + If you want to use participant hosts on which + filenames are case-insensitive (e.g. Windows) + this uniqueness is case-insensitive." +); +list_item("url", + "a URL where the file is (or will be) located on a data server." +); +list_item("md5_cksum", "The MD5 checksum of the file." +); +list_item("nbytes", + "the size of the file in bytes." +); +list_item("max_nbytes", + "The maximum allowable size of the file in bytes (may be greater than 2^32). + This is used to prevent flooding data servers with bogus data." +); +list_item("status", + "0 if the file is not present, + 1 if the file is present, or a negative error code if there was a + problem in downloading or generating the file." +); +list_item("generated_locally", + "If present, indicates that the file will be generated by an application on + the client, as opposed to being downloaded." +); +list_item("executable", + "If present, indicates that the file protections should be set to allow + execution." +); +list_item("upload_when_present", + "If present, indicates that the file should be uploaded + when the application finishes. + The file is uploaded even if the application doesn't + finish successfully. + API functions are available for + uploading files prior to + finishing computation. +"); +list_item("sticky", + "If present, indicates that the file should be retained + on the client after its initial use." +); +list_item("signature_required", + "If present, indicates that the file should be verified with an + RSA signature. + This generally only applies to executable files." +); +list_item("no_delete", + "If present for an input (workunit) file, + indicates that the file should NOT be removed from the data server's + download directory when the workunit is completed. + Use this if a particular input file or files are used by more than one + workunit, or will be used by future workunits. +

    + If present for an output (result) file, + indicates that the file should NOT be removed from the data server's upload + directory when the corresponding workunit is completed. + Use with caution - this may cause your upload directory to overflow." +); +list_item("report_on_rpc", + "Include a description of this file in scheduler RPC requests, + so that the scheduler may send appropriate work + using locality scheduling." +); +list_end(); +echo " + +

    File references

    +

    +Files may be associated with workunits, +results and +application versions. +Each such association is represented by an XML element of the form +".html_text(" + + foobar + [ input ] + [ ] + +")." +The elements are as follows: +"; +list_start(); +list_item("file_name", "Specifies a file."); +list_item("open_name", + "The name by which the application will refer to the file. + Applications access files using + the following functions: +

    +        char physical_name[256];
    +        boinc_resolve_filename(\"input\", physical_name, 256);
    +        fopen(physical_name, \"r\")
    +    
    + In this example, open_name is 'input'. + It is mapped, at runtime, to a path that includes + the filename ('foobar' in the example above). +"); +list_item("main_program", + "Relevant only for files associated with application versions. + It indicates that this file is the application's main program. +"); +list_end(); + +echo " + +

    App versions

    + +Each entry in the app version table includes an XML document describing the +files that make up the application version: +".html_text(" + + ... + +[ ... ] + + foobar + 4 + + program_1 + + + + library_12 + +")." +"; +page_tail(); +?> diff --git a/doc/yeti.jpg b/doc/yeti.jpg deleted file mode 100644 index 392340cb5e99120674aad9673e977da2ac254e70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31756 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�clta@~ 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 diff --git a/lib/parse.C b/lib/parse.C index 2cbed14515..558dd70b9d 100644 --- a/lib/parse.C +++ b/lib/parse.C @@ -409,7 +409,13 @@ int skip_unrecognized(char* buf, FILE* in) { // Get next XML element or tag. // If it's a close tag, or the contents pointer is NULL, just return the tag. -// Otherwise return the contents. +// Otherwise return the contents also. +// +// Skips comments, single- or multi-line () +// +// Returns false if text was found that wasn't a tag. +// (can just call again in this case). +// // Note: this is not a general XML parser, but it can parse both // X // and @@ -422,7 +428,14 @@ bool get_tag(FILE* f, char* tag, char* contents) { if (contents) *contents = 0; while (1) { - fgets(buf, 1024, f); + if (!fgets(buf, 1024, f)) return false; + if (strstr(buf, "")) break; + if (!fgets(buf, 1024, f)) return false; + } + continue; + } p = strchr(buf, '<'); if (p) break; } @@ -465,7 +478,7 @@ bool get_tag(FILE* f, char* tag, char* contents) { // Copy contents until find close tag // while (1) { - fgets(buf, 1024, f); + if (!fgets(buf, 1024, f)) return false; if (strchr(buf, '<')) return true; strip_whitespace(buf); strcat(contents, buf); diff --git a/sched/sched_config.C b/sched/sched_config.C index d724fed3f0..5ac8632ba0 100644 --- a/sched/sched_config.C +++ b/sched/sched_config.C @@ -130,14 +130,6 @@ int SCHED_CONFIG::parse_file(const char* dir) { int retval; sprintf(path, "%s/%s", dir, CONFIG_FILE); -#if 0 - char* p; - retval = read_file_malloc(path, p); - if (retval) return retval; - retval = parse(p); - free(p); - return retval; -#endif FILE* f = fopen(path, "r"); if (!f) return ERR_FOPEN; retval = parse(f);