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