summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix-helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/posix/src/posix-helpers.c')
-rw-r--r--xlators/storage/posix/src/posix-helpers.c98
1 files changed, 82 insertions, 16 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index 77affc45ae0..5a3f4b129fb 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -18,6 +18,7 @@
#include <ftw.h>
#include <sys/stat.h>
#include <signal.h>
+#include <aio.h>
#ifdef HAVE_SYS_ACL_H
#ifdef HAVE_ACL_LIBACL_H /* for acl_to_any_text() */
@@ -1768,44 +1769,108 @@ posix_fs_health_check (xlator_t *this)
char timestamp[256] = {0,};
int fd = -1;
int timelen = -1;
- int nofbytes = 0;
time_t time_sec = {0,};
- char buff[64] = {0};
+ char buff[256] = {0};
char file_path[PATH_MAX] = {0};
char *op = NULL;
int op_errno = 0;
+ int cnt = 0;
+ int timeout = 0;
+ struct aiocb aiocb;
GF_VALIDATE_OR_GOTO (this->name, this, out);
priv = this->private;
GF_VALIDATE_OR_GOTO ("posix-helpers", priv, out);
subvol_path = priv->base_path;
- snprintf (file_path, sizeof (file_path), "%s/%s/health_check",
+ timeout = priv->health_check_timeout;
+ snprintf (file_path, sizeof (file_path)-1, "%s/%s/health_check",
subvol_path, GF_HIDDEN_PATH);
time_sec = time (NULL);
gf_time_fmt (timestamp, sizeof timestamp, time_sec, gf_timefmt_FT);
timelen = strlen (timestamp);
- fd = open (file_path, O_CREAT|O_RDWR, 0644);
+ fd = open (file_path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
if (fd == -1) {
op_errno = errno;
- op = "open";
+ op = "open_for_write";
goto out;
}
- nofbytes = sys_write (fd, timestamp, timelen);
- if (nofbytes < 0) {
+ memset(&aiocb, 0, sizeof(struct aiocb));
+ aiocb.aio_fildes = fd;
+ aiocb.aio_buf = timestamp;
+ aiocb.aio_nbytes = timelen;
+ aiocb.aio_sigevent.sigev_notify = SIGEV_NONE;
+ if (aio_write(&aiocb) == -1) {
op_errno = errno;
- op = "write";
+ op = "aio_write";
goto out;
}
- /* Seek the offset to the beginning of the file, so that the offset for
- read is from beginning of file */
- sys_lseek(fd, 0, SEEK_SET);
- nofbytes = sys_read (fd, buff, timelen);
- if (nofbytes == -1) {
+
+ /* Wait until write completion */
+ while ((aio_error (&aiocb) == EINPROGRESS) && (++cnt <= timeout))
+ sleep (1);
+
+ ret = aio_error (&aiocb);
+ if (ret != 0) {
+ op_errno = errno;
+ op = "aio_write_error";
+ ret = -1;
+ goto out;
+ }
+
+ ret = aio_return (&aiocb);
+ if (ret != timelen) {
+ op_errno = errno;
+ op = "aio_write_buf";
+ ret = -1;
+ goto out;
+ }
+
+ sys_close (fd);
+
+ fd = open (file_path, O_RDONLY);
+ if (fd == -1) {
+ op_errno = errno;
+ op = "open_for_read";
+ goto out;
+ }
+
+ memset(&aiocb, 0, sizeof(struct aiocb));
+ aiocb.aio_fildes = fd;
+ aiocb.aio_buf = buff;
+ aiocb.aio_nbytes = sizeof(buff);
+ if (aio_read(&aiocb) == -1) {
op_errno = errno;
- op = "read";
+ op = "aio_read";
+ goto out;
+ }
+ cnt = 0;
+ /* Wait until read completion */
+ while ((aio_error (&aiocb) == EINPROGRESS) && (++cnt <= timeout))
+ sleep (1);
+
+ ret = aio_error (&aiocb);
+ if (ret != 0) {
+ op_errno = errno;
+ op = "aio_read_error";
+ ret = -1;
+ goto out;
+ }
+
+ ret = aio_return (&aiocb);
+ if (ret != timelen) {
+ op_errno = errno;
+ op = "aio_read_buf";
+ ret = -1;
+ goto out;
+ }
+
+ if (memcmp (timestamp, buff, ret)) {
+ op_errno = EUCLEAN;
+ op = "aio_read_cmp_buf";
+ ret = -1;
goto out;
}
ret = 0;
@@ -1818,8 +1883,9 @@ out:
P_MSG_HEALTHCHECK_FAILED,
"%s() on %s returned", op, file_path);
gf_event (EVENT_POSIX_HEALTH_CHECK_FAILED,
- "op=%s;path=%s;error=%s;brick=%s:%s", op, file_path,
- strerror (op_errno), priv->hostname, priv->base_path);
+ "op=%s;path=%s;error=%s;brick=%s:%s timeout is %d",
+ op, file_path, strerror (op_errno), priv->hostname,
+ priv->base_path, timeout);
}
return ret;