From 614376be84648228f8d32339d0d864967b4442eb Mon Sep 17 00:00:00 2001 From: Christian Beer Date: Fri, 1 Apr 2016 10:22:24 +0200 Subject: [PATCH] Sched: make get_file_size request in file_upload_handler read-only * If there is a size discrepancy between server and client this needs to be handled in handle_file_upload() * Setting a write lock on a read only file does not work obviously. Instead try to see if another process has a write lock and continue if not. If another process is still writing to the file there is no need to determine the size. --- sched/file_upload_handler.cpp | 9 +++++---- sched/sched_util_basic.cpp | 18 ++++++++++++++++++ sched/sched_util_basic.h | 6 ++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/sched/file_upload_handler.cpp b/sched/file_upload_handler.cpp index e3cf2a7f4e..826fd23f3b 100644 --- a/sched/file_upload_handler.cpp +++ b/sched/file_upload_handler.cpp @@ -475,7 +475,7 @@ int handle_get_file_size(char* file_name) { return return_error(ERR_TRANSIENT, "Server is out of disk space"); } - fd = open(path, O_WRONLY|O_APPEND); + fd = open(path, O_RDONLY); if (fd<0 && ENOENT==errno) { // file does not exist: return zero length @@ -495,8 +495,8 @@ int handle_get_file_size(char* file_name) { ); return return_error(ERR_TRANSIENT, "can't open file"); } - - if ((pid = mylockf(fd))) { +#ifdef LOCK_FILES + if ((pid = checklockf(fd))) { // file locked by another file_upload_handler: try again later // close(fd); @@ -507,7 +507,8 @@ int handle_get_file_size(char* file_name) { "[%s] locked by file_upload_handler PID=%d", file_name, pid ); } - // file exists, writable, not locked by anyone else, so return length. +#endif + // file exists, readable, not locked by anyone else, so return length. // retval = stat(path, &sbuf); close(fd); diff --git a/sched/sched_util_basic.cpp b/sched/sched_util_basic.cpp index 2e903ee36f..e7040b0865 100644 --- a/sched/sched_util_basic.cpp +++ b/sched/sched_util_basic.cpp @@ -239,6 +239,24 @@ int mylockf(int fd) { return -1; } +// check if there is a write lock on the given file with given fd. Returns: +// 0 if there is no write lock +// PID (>0) of the process that has the lock +// -1 if error +// +int checklockf(int fd) { + struct flock fl; + fl.l_type=F_RDLCK; + fl.l_whence=SEEK_SET; + fl.l_start=0; + fl.l_len=0; + if (-1 != fcntl(fd, F_GETLK, &fl)) { + if (fl.l_type == F_UNLCK) return 0; + if (fl.l_pid>0) return fl.l_pid; + } + return -1; +} + bool is_arg(const char* x, const char* y) { char buf[256]; strcpy(buf, "--"); diff --git a/sched/sched_util_basic.h b/sched/sched_util_basic.h index 38da19bbe0..d7a9ba8d30 100644 --- a/sched/sched_util_basic.h +++ b/sched/sched_util_basic.h @@ -60,6 +60,12 @@ extern int dir_hier_url( // extern int mylockf(int fd); +// returns zero if there is no write lock on file with file descriptor fd. +// returns < 0 if error +// returns PID > 0 of the process that has the lock +// +extern int checklockf(int fd); + // return true if x is -y or --y (for argv processing) // extern bool is_arg(const char*, const char*);