00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 // 00003 // This file is part of Vesta. 00004 // 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // Last modified on Mon May 23 22:19:23 EDT 2005 by ken@xorian.net 00020 // modified on Fri Jul 14 16:29:50 PDT 2000 by mann 00021 // modified on Fri Feb 5 17:01:58 PST 1999 by heydon 00022 // modified on Wed Apr 10 17:35:32 PDT 1996 by levin 00023 00024 00025 // This interface defines a mechanism for running a tool (i.e., 00026 // a Unix program) as part of a Vesta evaluation. The tool runs 00027 // in an encapsulated environment in which most facilities are 00028 // controlled by the Vesta evaluator. Specifically, the evaluator 00029 // controls: 00030 // * stdin, stdout, stderr 00031 // * the environment variables 00032 // * the file system 00033 // The interface allows the tool to be executed on a specified platform. 00034 // Thus, it gives functionality similar to 'rsh', but with the additional 00035 // controls provided by the encapsulation of the environment. 00036 00037 #ifndef _RUN_TOOL_CLIENT_H 00038 #define _RUN_TOOL_CLIENT_H 00039 00040 #include <Basics.H> 00041 #include <OS.H> 00042 #include <UniqueId.H> 00043 00044 // SRPC stuff 00045 #include <SRPC.H> 00046 #include <MultiSRPC.H> 00047 00048 // Repository stuff 00049 #include <VestaSource.H> 00050 00051 // Internal stuff 00052 #include "RunToolClientPrivate.H" 00053 00054 #define DEFAULT_TOOL_WD ".WD" 00055 00056 // The following are additional values for SRPC::failure.r that 00057 // can arise from calls of RunTool::do_it. 00058 00059 enum RunToolError { 00060 client_error = 10, // probable client error 00061 configuration_error = 11, // probably Vesta set-up error 00062 implementation_error = SRPC::internal_trouble // RunTool/tool_launcher bug 00063 }; 00064 00065 extern "C" void RunTool_init(); 00066 00067 class RunTool { 00068 public: 00069 00070 struct Tool_result { // see explanation below 00071 int status; 00072 int sigval; 00073 bool stdout_written; 00074 bool stderr_written; 00075 bool dumped_core; 00076 }; 00077 00078 static Tool_result do_it( 00079 const Text &host, // hostname, or hostname:port 00080 chars_seq *argv, 00081 LongId &fsroot, // must be under the VolatileRoot 00082 const Text &wd = DEFAULT_TOOL_WD, 00083 chars_seq *ev = NULL, 00084 std::ostream *report_out = NULL, 00085 std::ostream *value_out = NULL, 00086 std::ostream *report_err = NULL, 00087 std::ostream *value_err = NULL, 00088 Basics::mutex *mu = NULL, 00089 const Text &label = "", 00090 const Text &stdin_name = "" 00091 ) throw(SRPC::failure, FS::Failure); 00092 00093 /* This single operation causes a tool to be executed. The name of 00094 the host on which execution is to occur is given by 'host'; this 00095 host must be running the server portion of the RunTool implementation. 00096 If no port is given, the default RunToolServer port is assumed. 00097 00098 The tool and its command line are specified by 'argv', which is a 00099 pointer to a vector of null-terminated strings. As usual, argv[0] 00100 is the name of the tool to be executed. This name and any other 00101 file names present on the command line or used during the tool 00102 execution are interpreted in the encapsulated file system environment 00103 given by the 'fsroot' parameter. 00104 00105 'fsroot' encapsulates the file system presented to the tool. It 00106 corresponds to a Vesta binding that is to be used as the root of 00107 the file system seen by the tool. An attempt by the tool to 00108 read the file named /a/b/c is translated to an evaluator reference to 00109 fsroot/a/b/c. Thus, "a" and "b" should be bindings, and "c" should 00110 be a file. 'wd' is the path relative to 'fsroot' that is to be used 00111 as the working directory for the tool. 00112 00113 The environment variables visible to the tool during its execution 00114 are specified by 'ev', which is a pointer to a vector of null-terminated 00115 strings. Each string is of the form "var=value" (without the quotes), 00116 where "var" is the environment variable name and "value" is its 00117 associated value. By default, no environment variables are defined. 00118 00119 report_out and value_out are streams to which the output on 00120 stdout is to be written. If either is NULL, it is not used. 00121 Writing on report_out requires holding mu. 00122 00123 report_err and value_err are streams to which the output on 00124 stderr is to be written. If either is NULL, it is not used. 00125 Writing on report_err requires holding mu. 00126 00127 label is a text that is prepended to every line of output to 00128 report_out and report_err. 00129 00130 stdin_name is the full path name of a file to be used as the input 00131 stream for the tool. This file is expected to reside in the Vesta 00132 repository. If the path name is empty (default), the tool's stdin 00133 stream is set to /dev/null. 00134 00135 After tool execution completes, the results are returned as a value 00136 of type 'Tool_result', whose fields have the following meanings: 00137 00138 'status' is the exit status returned by the tool. It is meaningful 00139 only if 'sigval' is 0. 00140 00141 'sigval' identifies the signal, if any, that terminated the execution 00142 of the tool. If the tool execution ended voluntarily, this value is 00143 0 (and 'status' is meaningful). 00144 00145 stdout_written (resp. stderr_written) is true iff one or more bytes 00146 were written on stdout_fd (resp. stderr_fd). 00147 00148 Any files written to the file system are reflected in the 'fsroot' 00149 directory and may be discovered by the caller upon return from this 00150 function (using fsroot.list). */ 00151 00152 struct Host_info { 00153 /* Unique id for this server instance */ 00154 FP::Tag uniqueid; 00155 /* Information about the host platform */ 00156 Text sysname; // Operating system implementation (uname -s) 00157 Text release; // Operating system release (uname -r) 00158 Text version; // Operating system version within release (uname -v) 00159 Text machine; // Type of machine (uname -m) 00160 int cpus; // Number of cpus 00161 int cpuMHz; // Clock rate of cpu(s) in MHz 00162 int memKB; // Physical memory in kilobytes 00163 /* Information about currently running tools */ 00164 int max_tools; // Maximum number of concurrent tools allowed 00165 int cur_tools; // Number of tools currently running 00166 float load; // Current load average on the machine 00167 int cur_pending;// Number of tools currently in the pending queue 00168 int max_pending;// Maximum number of tools allowed in the pending queue 00169 }; 00170 00171 static void get_info(const Text &host, // hostname or hostname:port 00172 /*OUT*/ Host_info& hinfo) throw(SRPC::failure); 00173 /* Get information about the host platform and how busy the server 00174 currently is, useful for the client in deciding whether to run a 00175 tool on this host. Of course, cur_tools and max_tools might change 00176 between calls to get_info and do_it, so the client cannot be 00177 certain that a subsequent call to do_it will not block or throw 00178 SRPC::failure. */ 00179 00180 private: 00181 00182 // static data; filled in by "init" 00183 static pthread_once_t init_block; 00184 static MultiSRPC *srpc_cache; 00185 00186 // initialization 00187 static void init() throw(SRPC::failure); 00188 static void ensure_init() throw(SRPC::failure); 00189 00190 // private member functions 00191 static void send_relay_socket(Tool_Relay &r, SRPC *srpc); 00192 static void send_vdir(LongId &fsroot, SRPC *srpc); 00193 00194 friend void RunTool_init(); 00195 }; 00196 00197 #endif /* _RUN_TOOL_CLIENT_H */