diff --git a/src/cm_utils/cm_file.c b/src/cm_utils/cm_file.c index 331fe0b24c08802f65b1b598b894e134d4b2bf8a..b93beb01639be7a4578d609318556731f0858c7c 100644 --- a/src/cm_utils/cm_file.c +++ b/src/cm_utils/cm_file.c @@ -29,7 +29,6 @@ #else #include #include -#include #endif #ifdef __cplusplus @@ -805,6 +804,23 @@ status_t cm_truncate_file(int32 file, int64 offset) return CM_SUCCESS; } +status_t cm_fcntl(int32 fd, int32 cmd, struct flock *lock) +{ + do { + if (fcntl(fd, cmd, lock) == 0) { + break; + } + + if (cm_get_os_error() == EAGAIN || cm_get_os_error() == EINTR) { + LOG_DEBUG_INF("Linux return EAGAIN or EINTR errno: %d, try again.", errno); + cm_sleep(1); + continue; + } + return CM_ERROR; + } while (0); + return CM_SUCCESS; +} + status_t cm_lock_fd(int32 fd) { #ifdef WIN32 @@ -816,7 +832,7 @@ status_t cm_lock_fd(int32 fd) lk.l_whence = SEEK_SET; lk.l_start = lk.l_len = 0; - if (fcntl(fd, F_SETLK, &lk) != 0) { + if (cm_fcntl(fd, F_SETLK, &lk) != CM_SUCCESS) { CM_THROW_ERROR(ERR_LOCK_FILE, errno); return CM_ERROR; } @@ -836,7 +852,7 @@ status_t cm_unlock_fd(int32 fd) lk.l_whence = SEEK_SET; lk.l_start = lk.l_len = 0; - if (fcntl(fd, F_SETLK, &lk) != 0) { + if (cm_fcntl(fd, F_SETLK, &lk) != CM_SUCCESS) { CM_THROW_ERROR(ERR_UNLOCK_FILE, errno); return CM_ERROR; } diff --git a/src/cm_utils/cm_file.h b/src/cm_utils/cm_file.h index be242fb6d606a673b62e59cbcbca065f93dbd95e..5ddd5680263f30bcf98efa593e092d278e1a766a 100644 --- a/src/cm_utils/cm_file.h +++ b/src/cm_utils/cm_file.h @@ -28,6 +28,7 @@ #include #include #else +#include #include #include @@ -138,6 +139,7 @@ status_t cm_write_file(int32 file, const void *buf, int32 size); status_t cm_pwrite_file(int32 file, const char *buf, int32 size, int64 offset); status_t cm_pread_file(int32 file, void *buf, int size, int64 offset, int32 *read_size); status_t cm_truncate_file(int32 file, int64 offset); +status_t cm_fcntl(int32 fd, int32 cmd, struct flock *lock); status_t cm_lock_fd(int32 fd); status_t cm_unlock_fd(int32 fd); int64 cm_seek_file(int32 file, int64 offset, int32 origin); diff --git a/src/ddes_cap/ddes_cap_exec.c b/src/ddes_cap/ddes_cap_exec.c index f28ad5b20a72b02053cd56221ebfa6409016caa1..c028810ed0b242ce43ca74e0cc2ad4819969dcfe 100644 --- a/src/ddes_cap/ddes_cap_exec.c +++ b/src/ddes_cap/ddes_cap_exec.c @@ -28,6 +28,7 @@ #include #include "cm_log.h" #include "cm_scsi.h" +#include "cm_file.h" #ifdef WIN32 #include @@ -218,17 +219,16 @@ status_t cap_agent_init(cap_agent_t *agent, const char *agent_name) // application server send cap command as a request to cap agent // after executing, cap agent send a response if (0 == agent->pid) { // child process - if (-1 == fcntl(agent->req_pipe.hread, F_SETFL, O_NONBLOCK)) { + if (cm_fcntl(agent->req_pipe.hread, F_SETFL, O_NONBLOCK) != CM_SUCCESS) { send_fail_response(CM_ERROR, "failed to set reading end of request pipe to non-block. errno = %d.", errno); return CM_ERROR; } - if (-1 == fcntl(agent->res_pipe.hwrite, F_SETFL, O_NONBLOCK)) { + if (cm_fcntl(agent->res_pipe.hwrite, F_SETFL, O_NONBLOCK) != CM_SUCCESS) { send_fail_response(CM_ERROR, "failed to set writing end of response pipe to non-block. errno = %d.", errno); return CM_ERROR; } - char req_rfd[MAX_FD_LEN + 1], res_wfd[MAX_FD_LEN + 1]; int32 size = vsnprintf_s(req_rfd, MAX_FD_LEN, MAX_FD_LEN, agent->req_pipe.hread); if (SECUREC_UNLIKELY(size == -1)) { @@ -261,16 +261,16 @@ status_t cap_agent_init(cap_agent_t *agent, const char *agent_name) // close the write end of response pipe close(agent->res_pipe.hwrite); - - if (-1 == fcntl(agent->req_pipe.hwrite, F_SETFL, O_NONBLOCK)) { - // log error; + if (cm_fcntl(agent->req_pipe.hwrite, F_SETFL, O_NONBLOCK) != CM_SUCCESS) { + send_fail_response(CM_ERROR, + "failed to set writing end of request pipe to non-block. errno = %d.", errno); return CM_ERROR; } - if (-1 == fcntl(agent->res_pipe.hread, F_SETFL, O_NONBLOCK)) { - // log error; + if (cm_fcntl(agent->res_pipe.hread, F_SETFL, O_NONBLOCK) != CM_SUCCESS) { + send_fail_response(CM_ERROR, + "failed to set reading end of response pipe to non-block. errno = %d.", errno); return CM_ERROR; } - return check_exec_response(agent->res_pipe.hread, NULL, 0); } }