256ebe
From 462e3988936761317975fd811dd355b81328b60a Mon Sep 17 00:00:00 2001
256ebe
From: Amar Tumballi <amarts@redhat.com>
256ebe
Date: Thu, 14 Mar 2019 10:04:28 +0530
256ebe
Subject: [PATCH 185/192] gfapi: provide an api for setting statedump path
256ebe
256ebe
Currently for an application using glfsapi to use glusterfs, when a
256ebe
statedump is taken, it uses /var/run/gluster dir to dump info.
256ebe
256ebe
There can be concerns as this directory may be owned by some other
256ebe
user, and hence it may fail taking statedump. Such applications
256ebe
should have an option to use different path.
256ebe
256ebe
This patch provides an API to do so.
256ebe
256ebe
Upstream details:
256ebe
> Updates: bz#1689097
256ebe
> Change-Id: I8918e002bc823d83614c972b6c738baa04681b23
256ebe
> URL: https://review.gluster.org/22364
256ebe
256ebe
BUG: 1720461
256ebe
Change-Id: I6079c8d799f35eaf76e62d259b51573bf561ba5b
256ebe
Signed-off-by: Amar Tumballi <amarts@redhat.com>
256ebe
Reviewed-on: https://code.engineering.redhat.com/gerrit/173451
256ebe
Tested-by: RHGS Build Bot <nigelb@redhat.com>
256ebe
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
256ebe
---
256ebe
 api/src/gfapi.aliases |  2 ++
256ebe
 api/src/gfapi.map     |  5 ++++
256ebe
 api/src/glfs.c        | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++
256ebe
 api/src/glfs.h        | 28 +++++++++++++++++++++++
256ebe
 4 files changed, 98 insertions(+)
256ebe
256ebe
diff --git a/api/src/gfapi.aliases b/api/src/gfapi.aliases
256ebe
index 09c0fd8..8fdf734 100644
256ebe
--- a/api/src/gfapi.aliases
256ebe
+++ b/api/src/gfapi.aliases
256ebe
@@ -195,3 +195,5 @@ _pub_glfs_zerofill_async _glfs_zerofill_async$GFAPI_6.0
256ebe
 _pub_glfs_copy_file_range _glfs_copy_file_range$GFAPI_6.0
256ebe
 _pub_glfs_fsetattr _glfs_fsetattr$GFAPI_6.0
256ebe
 _pub_glfs_setattr _glfs_setattr$GFAPI_6.0
256ebe
+
256ebe
+_pub_glfs_set_statedump_path _glfs_set_statedump_path@GFAPI_future
256ebe
diff --git a/api/src/gfapi.map b/api/src/gfapi.map
256ebe
index b97a614..cf118e8 100644
256ebe
--- a/api/src/gfapi.map
256ebe
+++ b/api/src/gfapi.map
256ebe
@@ -271,3 +271,8 @@ GFAPI_PRIVATE_6.1 {
256ebe
 	global:
256ebe
 		glfs_setfspid;
256ebe
 } GFAPI_6.0;
256ebe
+
256ebe
+GFAPI_future {
256ebe
+	global:
256ebe
+		glfs_set_statedump_path;
256ebe
+} GFAPI_PRIVATE_6.1;
256ebe
diff --git a/api/src/glfs.c b/api/src/glfs.c
256ebe
index f4a8e08..ba513e6 100644
256ebe
--- a/api/src/glfs.c
256ebe
+++ b/api/src/glfs.c
256ebe
@@ -1212,6 +1212,7 @@ glusterfs_ctx_destroy(glusterfs_ctx_t *ctx)
256ebe
         glusterfs_graph_destroy_residual(trav_graph);
256ebe
     }
256ebe
 
256ebe
+    GF_FREE(ctx->statedump_path);
256ebe
     FREE(ctx);
256ebe
 
256ebe
     return ret;
256ebe
@@ -1738,3 +1739,65 @@ invalid_fs:
256ebe
 }
256ebe
 
256ebe
 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_unregister, 3.13.0);
256ebe
+
256ebe
+int
256ebe
+pub_glfs_set_statedump_path(struct glfs *fs, const char *path)
256ebe
+{
256ebe
+    struct stat st;
256ebe
+    int ret;
256ebe
+    DECLARE_OLD_THIS;
256ebe
+    __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
256ebe
+
256ebe
+    if (!path) {
256ebe
+        gf_log("glfs", GF_LOG_ERROR, "path is NULL");
256ebe
+        errno = EINVAL;
256ebe
+        goto err;
256ebe
+    }
256ebe
+
256ebe
+    /* If path is not present OR, if it is directory AND has enough permission
256ebe
+     * to create files, then proceed */
256ebe
+    ret = sys_stat(path, &st);
256ebe
+    if (ret && errno != ENOENT) {
256ebe
+        gf_log("glfs", GF_LOG_ERROR, "%s: not a valid path (%s)", path,
256ebe
+               strerror(errno));
256ebe
+        errno = EINVAL;
256ebe
+        goto err;
256ebe
+    }
256ebe
+
256ebe
+    if (!ret) {
256ebe
+        /* file is present, now check other things */
256ebe
+        if (!S_ISDIR(st.st_mode)) {
256ebe
+            gf_log("glfs", GF_LOG_ERROR, "%s: path is not directory", path);
256ebe
+            errno = EINVAL;
256ebe
+            goto err;
256ebe
+        }
256ebe
+        if (sys_access(path, W_OK | X_OK) < 0) {
256ebe
+            gf_log("glfs", GF_LOG_ERROR,
256ebe
+                   "%s: path doesn't have write permission", path);
256ebe
+            errno = EPERM;
256ebe
+            goto err;
256ebe
+        }
256ebe
+    }
256ebe
+
256ebe
+    /* If set, it needs to be freed, so we don't have leak */
256ebe
+    GF_FREE(fs->ctx->statedump_path);
256ebe
+
256ebe
+    fs->ctx->statedump_path = gf_strdup(path);
256ebe
+    if (!fs->ctx->statedump_path) {
256ebe
+        gf_log("glfs", GF_LOG_ERROR,
256ebe
+               "%s: failed to set statedump path, no memory", path);
256ebe
+        errno = ENOMEM;
256ebe
+        goto err;
256ebe
+    }
256ebe
+
256ebe
+    __GLFS_EXIT_FS;
256ebe
+
256ebe
+    return 0;
256ebe
+err:
256ebe
+    __GLFS_EXIT_FS;
256ebe
+
256ebe
+invalid_fs:
256ebe
+    return -1;
256ebe
+}
256ebe
+
256ebe
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_statedump_path, future);
256ebe
diff --git a/api/src/glfs.h b/api/src/glfs.h
256ebe
index 6714782..a6c12e1 100644
256ebe
--- a/api/src/glfs.h
256ebe
+++ b/api/src/glfs.h
256ebe
@@ -1453,5 +1453,33 @@ int
256ebe
 glfs_setattr(struct glfs *fs, const char *path, struct glfs_stat *stat,
256ebe
              int follow) __THROW GFAPI_PUBLIC(glfs_setattr, 6.0);
256ebe
 
256ebe
+/*
256ebe
+  SYNOPSIS
256ebe
+
256ebe
+  glfs_set_statedump_path: Function to set statedump path.
256ebe
+
256ebe
+  DESCRIPTION
256ebe
+
256ebe
+  This function is used to set statedump directory
256ebe
+
256ebe
+  PARAMETERS
256ebe
+
256ebe
+  @fs: The 'virtual mount' object to be configured with the volume
256ebe
+       specification file.
256ebe
+
256ebe
+  @path: statedump path. Should be a directory. But the API won't fail if the
256ebe
+  directory doesn't exist yet, as one may create it later.
256ebe
+
256ebe
+  RETURN VALUES
256ebe
+
256ebe
+   0 : Success.
256ebe
+  -1 : Failure. @errno will be set with the type of failure.
256ebe
+
256ebe
+ */
256ebe
+
256ebe
+int
256ebe
+glfs_set_statedump_path(struct glfs *fs, const char *path) __THROW
256ebe
+    GFAPI_PUBLIC(glfs_set_statedump_path, future);
256ebe
+
256ebe
 __END_DECLS
256ebe
 #endif /* !_GLFS_H */
256ebe
-- 
256ebe
1.8.3.1
256ebe