diff --git a/checkin_notes b/checkin_notes index 005cd3bb3d..20941fbc8d 100755 --- a/checkin_notes +++ b/checkin_notes @@ -6121,3 +6121,27 @@ quarl 2003/09/03 tools_other.php single_host_server.php create_project.php + +David Sept 4 2003 + - fix bug in scheduler: the buffer in insert_wu_tags() wasn't large enough. + This is a powerful argument in favor of using "string" everywhere! + NOTE: in spite of fix, test_uc.py isn't working. Problem w/ proxy? + - HTTP_OP_SET::poll(): if header read_reply() returns nonzero, + set htp->io_ready to false (to avoid lots and lots of spurious recv()s) + - in test scripts: if TEST_STOP_BEFORE_RUN is set, + go into sleep loop rather than exiting + (to avoid deleting the test setup) + - factor out get_socket_error() + + client/ + client_state.C + cs_scheduler.C + http.C + main.C + net_xfer.C,h + scheduler_op.C + sched/ + handle_request.C + main.C + test/ + testbase.py diff --git a/client/client_state.C b/client/client_state.C index 20fe9fc279..32284e585b 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -1585,11 +1585,11 @@ bool CLIENT_STATE::time_to_exit() { && app_started && (difftime(time(0), app_started) >= exit_after_app_start_secs) ) { - printf("exiting because time is up: %d\n", exit_after_app_start_secs); + msg_printf(NULL, MSG_INFO, "exiting because time is up: %d\n", exit_after_app_start_secs); return true; } if (exit_when_idle && (results.size() == 0) && contacted_sched_server) { - printf("exiting because no more results\n"); + msg_printf(NULL, MSG_INFO, "exiting because no more results\n"); return true; } return false; diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index 334d132d73..22f5d61ae0 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -383,10 +383,7 @@ int CLIENT_STATE::handle_scheduler_reply( contacted_sched_server = true; ScopeMessages scope_messages(log_messages, ClientMessages::DEBUG_SCHED_OP); - scope_messages.printf_file( - SCHED_OP_RESULT_FILE, - "CLIENT_STATE::handle_scheduler_reply(): reply: " - ); + scope_messages.printf_file(SCHED_OP_RESULT_FILE, "reply: "); f = fopen(SCHED_OP_RESULT_FILE, "r"); if (!f) return ERR_FOPEN; diff --git a/client/http.C b/client/http.C index 68e6b3d507..01b3a9068d 100644 --- a/client/http.C +++ b/client/http.C @@ -126,16 +126,14 @@ static void http_post_request_header( ); } -void HTTP_REPLY_HEADER::init() -{ +void HTTP_REPLY_HEADER::init() { status = 500; content_length = 0; redirect_location.erase(); recv_buf.erase(); } -void HTTP_REPLY_HEADER::parse() -{ +void HTTP_REPLY_HEADER::parse() { ScopeMessages scope_messages(log_messages, ClientMessages::DEBUG_HTTP); istringstream h(recv_buf); @@ -172,21 +170,26 @@ const unsigned int MAX_HEADER_SIZE = 1024; // Parse an http reply header into the header struct // -// Returns 1 if we are not done yet, 0 if done (header.status indicates -// success) -int HTTP_REPLY_HEADER::read_reply(int socket) -{ +// Returns 1 if not done yet, 0 if done (header.status indicates success) +// +int HTTP_REPLY_HEADER::read_reply(int socket) { ScopeMessages scope_messages(log_messages, ClientMessages::DEBUG_HTTP); while (recv_buf.size() < MAX_HEADER_SIZE) { char c; + errno = 0; int n = recv(socket, &c, 1, 0); + scope_messages.printf( + "HTTP_REPLY_HEADER::read_reply(): recv() on socket %d returned %d errno %d sockerr %d\n", + socket, n, errno, get_socket_error(socket) + ); if (n == -1 && errno == EAGAIN) { - scope_messages.printf("HTTP_REPLY_HEADER::read_reply(): recv() returned %d (EAGAIN)\n", n); return 1; } + + // if n is zero, we've reached EOF (and that's an error) + // if (n != 1) { - scope_messages.printf("HTTP_REPLY_HEADER::read_reply(): recv() returned %d\n", n); break; } @@ -195,15 +198,19 @@ int HTTP_REPLY_HEADER::read_reply(int socket) if (ends_with(recv_buf, "\n\n")) { scope_messages.printf_multiline(recv_buf.c_str(), - "HTTP_REPLY_HEADER::read_reply(): header: "); + "HTTP_REPLY_HEADER::read_reply(): header: " + ); parse(); return 0; } } - // error occurred - scope_messages.printf("HTTP_REPLY_HEADER::read_reply(): returning error (recv_buf.size=%d)\n", - recv_buf.size()); + // error occurred; status will be 500 (from constructor) + // + scope_messages.printf( + "HTTP_REPLY_HEADER::read_reply(): returning error (recv_buf=%s)\n", + recv_buf.c_str() + ); return 0; } @@ -471,13 +478,17 @@ bool HTTP_OP_SET::poll() { htp->io_ready = false; htp->io_done = false; } - // TODO: intentional no break here? -- quarl + break; case HTTP_STATE_REPLY_HEADER: if (htp->io_ready) { action = true; - scope_messages.printf("HTTP_OP_SET::poll(): got reply header; %p io_done %d\n", htp, htp->io_done); + scope_messages.printf( + "HTTP_OP_SET::poll(): reading reply header; io_ready %d io_done %d\n", + htp->io_ready, htp->io_done + ); if (htp->hrh.read_reply(htp->socket)) { // not done yet + htp->io_ready = false; break; } diff --git a/client/main.C b/client/main.C index abb76cfbaa..69c433886b 100644 --- a/client/main.C +++ b/client/main.C @@ -163,7 +163,12 @@ int main(int argc, char** argv) { fflush(stdout); } - if (gstate.time_to_exit() || gstate.requested_exit) { + if (gstate.time_to_exit()) { + msg_printf(NULL, MSG_INFO, "Time to exit"); + break; + } + if (gstate.requested_exit) { + msg_printf(NULL, MSG_INFO, "Exit requested by signal"); break; } } diff --git a/client/net_xfer.C b/client/net_xfer.C index 749107ea79..00e95151c5 100644 --- a/client/net_xfer.C +++ b/client/net_xfer.C @@ -73,6 +73,19 @@ typedef int socklen_t; typedef size_t socklen_t; #endif +int get_socket_error(int fd) { + socklen_t intsize = sizeof(int); + int n; +#ifdef _WIN32 + getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&n, &intsize); +#elif __APPLE__ + getsockopt(fd, SOL_SOCKET, SO_ERROR, &n, (int *)&intsize); +#else + getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&n, &intsize); +#endif + return n; +} + int NET_XFER::get_ip_addr(char *hostname, int &ip_addr) { hostent* hep; @@ -325,7 +338,6 @@ int NET_XFER_SET::do_select(double& bytes_transferred, timeval& timeout) { int n, fd, retval, nsocks_queried; socklen_t i; NET_XFER *nxp; - socklen_t intsize = sizeof(int); ScopeMessages scope_messages(log_messages, ClientMessages::DEBUG_NET_XFER); @@ -392,14 +404,14 @@ int NET_XFER_SET::do_select(double& bytes_transferred, timeval& timeout) { nxp = net_xfers[i]; fd = nxp->socket; if (FD_ISSET(fd, &read_fds) || FD_ISSET(fd, &write_fds)) { + if (FD_ISSET(fd, &read_fds)) { + scope_messages.printf("NET_XFER_SET::do_select(): read enabled on socket %d\n", fd); + } + if (FD_ISSET(fd, &write_fds)) { + scope_messages.printf("NET_XFER_SET::do_select(): write enabled on socket %d\n", fd); + } if (!nxp->is_connected) { -#ifdef _WIN32 - getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&n, &intsize); -#elif __APPLE__ - getsockopt(fd, SOL_SOCKET, SO_ERROR, &n, (int *)&intsize); -#else - getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&n, &intsize); -#endif + n = get_socket_error(fd); if (n) { scope_messages.printf( "NET_XFER_SET::do_select(): socket %d connection to %s failed\n", diff --git a/client/net_xfer.h b/client/net_xfer.h index 32177c092c..bea57314bb 100644 --- a/client/net_xfer.h +++ b/client/net_xfer.h @@ -94,4 +94,6 @@ public: void check_active(bool&, bool&); }; +extern int get_socket_error(int fd); + #endif diff --git a/client/scheduler_op.C b/client/scheduler_op.C index d9a8f7f456..2e602d767d 100644 --- a/client/scheduler_op.C +++ b/client/scheduler_op.C @@ -199,7 +199,7 @@ int SCHEDULER_OP::start_rpc() { ); } - scope_messages.printf_file(SCHED_OP_REQUEST_FILE, "SCHEDULER_OP::start_rpc(): request xml: "); + scope_messages.printf_file(SCHED_OP_REQUEST_FILE, "req:"); if (gstate.use_http_proxy) { http_op.use_http_proxy = true; diff --git a/sched/handle_request.C b/sched/handle_request.C index 3729d96985..e051454746 100644 --- a/sched/handle_request.C +++ b/sched/handle_request.C @@ -127,7 +127,7 @@ int insert_after(char* buffer, char* after, char* text) { // it to a client // int insert_wu_tags(WORKUNIT& wu, APP& app) { - char buf[256]; + char buf[MAX_BLOB_SIZE]; sprintf(buf, " %f\n" @@ -186,7 +186,7 @@ int insert_app_file_tags(APP_VERSION& av, USER& user) { vector app_files; APP_FILE af; unsigned int i; - char buf[256], name[256]; + char buf[1024], name[256]; int retval; parse_project_prefs(user.project_prefs, app_files); @@ -660,14 +660,14 @@ int send_work( WORKUNIT wu; DB_RESULT result, result_copy; - if (sreq.work_req_seconds <= 0) return 0; - log_messages.printf( SchedMessages::NORMAL, "[HOST#%d] got request for %d seconds of work\n", reply.host.id, sreq.work_req_seconds ); + if (sreq.work_req_seconds <= 0) return 0; + seconds_to_fill = sreq.work_req_seconds; if (seconds_to_fill > MAX_SECONDS_TO_SEND) { seconds_to_fill = MAX_SECONDS_TO_SEND; diff --git a/test/testbase.py b/test/testbase.py index ea74252840..3c1c8cf5e7 100644 --- a/test/testbase.py +++ b/test/testbase.py @@ -610,6 +610,11 @@ def run_check_all(): all_projects.start_progress_meter() all_projects.run_init_wait() if os.environ.get('TEST_STOP_BEFORE_HOST_RUN'): + verbose_echo(1, 'stopped') + # wait instead of killing backend procs. + # (Is there a better way to do this?) + while (1): + time.sleep(1) raise SystemExit, 'Stopped due to $TEST_STOP_BEFORE_HOST_RUN' # all_hosts.run(asynch=True) all_hosts.run()