diff --git a/checkin_notes b/checkin_notes index 5f01125b20..8902f037f0 100755 --- a/checkin_notes +++ b/checkin_notes @@ -27044,6 +27044,13 @@ Bruce 11 April 2005 sleep, and then try again, but DON'T find more work available, give up trying to make work for that file. + - File upload handler: to prevent multiple instances of file_upload_handler + from trying to upload the SAME file, use lockf() to place an advisory lock on + the file. David, I probably should have discussed this with you first, but it's + too early in the morning. Please revert if this is a mistake! + sched/ sched_locality.C + file_upload_handler.C + diff --git a/sched/file_upload_handler.C b/sched/file_upload_handler.C index ff9b166c2a..480aa062f9 100644 --- a/sched/file_upload_handler.C +++ b/sched/file_upload_handler.C @@ -142,13 +142,26 @@ int copy_socket_to_file(FILE* in, char* path, double offset, double nbytes) { unsigned char buf[BLOCK_SIZE]; char buf2[256]; FILE* out; - int retval, n, m; + int retval, n, m, fd, lockret; out = fopen(path, "ab"); if (!out) { return return_error(ERR_TRANSIENT, "can't open file %s: %s", path, strerror(errno)); } + // get file descriptor for locking purposes + fd=fileno(out); + if (fd<0) { + return return_error(ERR_TRANSIENT, "can't get file descriptor for file %s: %s", path, strerror(errno)); + } + + // Put an advisory lock on the file. This will prevent OTHER instances of file_upload_handler + // from being able to write to the file. + lockret=lockf(fd, F_TLOCK, 0); + if (lockret) { + return return_error(ERR_TRANSIENT, "can't get exclusive lock on file %s: %s", path, strerror(errno)); + } + // TODO: use a 64-bit variant retval = fseek(out, (long)offset, SEEK_CUR); @@ -424,8 +437,8 @@ int pid; void boinc_catch_signal(int signal_num) { log_messages.printf(SCHED_MSG_LOG::CRITICAL, - "FILE=%s (%.0f bytes left) IP=%s PID=%d caught signal %d [%s]\n", - this_filename, bytes_left, get_remote_addr(), pid, signal_num, sys_siglist[signal_num] + "PID=%d FILE=%s (%.0f bytes left) IP=%s caught signal %d [%s]\n", + pid, this_filename, bytes_left, get_remote_addr(), signal_num, sys_siglist[signal_num] ); exit(1); }