summaryrefslogtreecommitdiffstats
path: root/xlators/features/snapview-server/src/snapview-server-helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/snapview-server/src/snapview-server-helpers.c')
-rw-r--r--xlators/features/snapview-server/src/snapview-server-helpers.c567
1 files changed, 567 insertions, 0 deletions
diff --git a/xlators/features/snapview-server/src/snapview-server-helpers.c b/xlators/features/snapview-server/src/snapview-server-helpers.c
new file mode 100644
index 00000000000..0817e145e26
--- /dev/null
+++ b/xlators/features/snapview-server/src/snapview-server-helpers.c
@@ -0,0 +1,567 @@
+/*
+ Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "snapview-server.h"
+#include "snapview-server-mem-types.h"
+
+#include "xlator.h"
+#include "rpc-clnt.h"
+#include "xdr-generic.h"
+#include "protocol-common.h"
+#include <pthread.h>
+
+
+int
+__svs_inode_ctx_set (xlator_t *this, inode_t *inode, svs_inode_t *svs_inode)
+{
+ uint64_t value = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+ GF_VALIDATE_OR_GOTO (this->name, svs_inode, out);
+
+ value = (uint64_t)(long) svs_inode;
+
+ ret = __inode_ctx_set (inode, this, &value);
+
+out:
+ return ret;
+}
+
+svs_inode_t *
+__svs_inode_ctx_get (xlator_t *this, inode_t *inode)
+{
+ svs_inode_t *svs_inode = NULL;
+ uint64_t value = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+
+ ret = __inode_ctx_get (inode, this, &value);
+ if (ret)
+ goto out;
+
+ svs_inode = (svs_inode_t *) ((long) value);
+
+out:
+ return svs_inode;
+}
+
+svs_inode_t *
+svs_inode_ctx_get (xlator_t *this, inode_t *inode)
+{
+ svs_inode_t *svs_inode = NULL;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+
+ LOCK (&inode->lock);
+ {
+ svs_inode = __svs_inode_ctx_get (this, inode);
+ }
+ UNLOCK (&inode->lock);
+
+out:
+ return svs_inode;
+}
+
+int32_t
+svs_inode_ctx_set (xlator_t *this, inode_t *inode, svs_inode_t *svs_inode)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+ GF_VALIDATE_OR_GOTO (this->name, svs_inode, out);
+
+ LOCK (&inode->lock);
+ {
+ ret = __svs_inode_ctx_set (this, inode, svs_inode);
+ }
+ UNLOCK (&inode->lock);
+
+out:
+ return ret;
+}
+
+svs_inode_t *
+svs_inode_new ()
+{
+ svs_inode_t *svs_inode = NULL;
+
+ svs_inode = GF_CALLOC (1, sizeof (*svs_inode), gf_svs_mt_svs_inode_t);
+
+ return svs_inode;
+}
+
+svs_inode_t *
+svs_inode_ctx_get_or_new (xlator_t *this, inode_t *inode)
+{
+ svs_inode_t *svs_inode = NULL;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+
+ LOCK (&inode->lock);
+ {
+ svs_inode = __svs_inode_ctx_get (this, inode);
+ if (!svs_inode) {
+ svs_inode = svs_inode_new (this, inode);
+ if (svs_inode) {
+ ret = __svs_inode_ctx_set (this, inode,
+ svs_inode);
+ if (ret) {
+ GF_FREE (svs_inode);
+ svs_inode = NULL;
+ }
+ }
+ }
+ }
+ UNLOCK (&inode->lock);
+
+out:
+ return svs_inode;
+}
+
+svs_fd_t *
+svs_fd_new ()
+{
+ svs_fd_t *svs_fd = NULL;
+
+ svs_fd = GF_CALLOC (1, sizeof (*svs_fd), gf_svs_mt_svs_fd_t);
+
+ return svs_fd;
+}
+
+int
+__svs_fd_ctx_set (xlator_t *this, fd_t *fd, svs_fd_t *svs_fd)
+{
+ uint64_t value = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ GF_VALIDATE_OR_GOTO (this->name, svs_fd, out);
+
+ value = (uint64_t)(long) svs_fd;
+
+ ret = __fd_ctx_set (fd, this, value);
+
+out:
+ return ret;
+}
+
+svs_fd_t *
+__svs_fd_ctx_get (xlator_t *this, fd_t *fd)
+{
+ svs_fd_t *svs_fd = NULL;
+ uint64_t value = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ ret = __fd_ctx_get (fd, this, &value);
+ if (ret)
+ return NULL;
+
+ svs_fd = (svs_fd_t *) ((long) value);
+
+out:
+ return svs_fd;
+}
+
+svs_fd_t *
+svs_fd_ctx_get (xlator_t *this, fd_t *fd)
+{
+ svs_fd_t *svs_fd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ LOCK (&fd->lock);
+ {
+ svs_fd = __svs_fd_ctx_get (this, fd);
+ }
+ UNLOCK (&fd->lock);
+
+out:
+ return svs_fd;
+}
+
+int32_t
+svs_fd_ctx_set (xlator_t *this, fd_t *fd, svs_fd_t *svs_fd)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ GF_VALIDATE_OR_GOTO (this->name, svs_fd, out);
+
+ LOCK (&fd->lock);
+ {
+ ret = __svs_fd_ctx_set (this, fd, svs_fd);
+ }
+ UNLOCK (&fd->lock);
+
+out:
+ return ret;
+}
+
+svs_fd_t *
+__svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd)
+{
+ svs_fd_t *svs_fd = NULL;
+ int ret = -1;
+ glfs_t *fs = NULL;
+ glfs_object_t *object = NULL;
+ svs_inode_t *inode_ctx = NULL;
+ glfs_fd_t *glfd = NULL;
+ inode_t *inode = NULL;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ inode = fd->inode;
+ svs_fd = __svs_fd_ctx_get (this, fd);
+ if (svs_fd) {
+ ret = 0;
+ goto out;
+ }
+
+ svs_fd = svs_fd_new (this, fd);
+ if (!svs_fd) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to allocate new fd "
+ "context for gfid %s", uuid_utoa (inode->gfid));
+ goto out;
+ }
+
+ if (fd_is_anonymous (fd)) {
+ inode_ctx = svs_inode_ctx_get (this, inode);
+ if (!inode_ctx) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to get inode "
+ "context for %s", uuid_utoa (inode->gfid));
+ goto out;
+ }
+
+ fs = inode_ctx->fs;
+ object = inode_ctx->object;
+
+ if (inode->ia_type == IA_IFDIR) {
+ glfd = glfs_h_opendir (fs, object);
+ if (!glfd) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to "
+ "open the directory %s",
+ uuid_utoa (inode->gfid));
+ goto out;
+ }
+ }
+
+ if (inode->ia_type == IA_IFREG) {
+ glfd = glfs_h_open (fs, object, O_RDONLY|O_LARGEFILE);
+ if (!glfd) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to "
+ "open the file %s",
+ uuid_utoa (inode->gfid));
+ goto out;
+ }
+ }
+
+ svs_fd->fd = glfd;
+ }
+
+ ret = __svs_fd_ctx_set (this, fd, svs_fd);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to set fd context "
+ "for gfid %s", uuid_utoa (inode->gfid));
+ if (svs_fd->fd) {
+ if (inode->ia_type == IA_IFDIR) {
+ ret = glfs_closedir (svs_fd->fd);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to close the fd for %s",
+ uuid_utoa (inode->gfid));
+ }
+ if (inode->ia_type == IA_IFREG) {
+ ret = glfs_close (svs_fd->fd);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to close the fd for %s",
+ uuid_utoa (inode->gfid));
+ }
+ }
+ ret = -1;
+ }
+
+out:
+ if (ret) {
+ GF_FREE (svs_fd);
+ svs_fd = NULL;
+ }
+
+ return svs_fd;
+}
+
+svs_fd_t *
+svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd)
+{
+ svs_fd_t *svs_fd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ LOCK (&fd->lock);
+ {
+ svs_fd = __svs_fd_ctx_get_or_new (this, fd);
+ }
+ UNLOCK (&fd->lock);
+
+out:
+ return svs_fd;
+}
+
+void
+svs_fill_ino_from_gfid (struct iatt *buf)
+{
+ uint64_t temp_ino = 0;
+ int j = 0;
+ int i = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, buf, out);
+
+ /* consider least significant 8 bytes of value out of gfid */
+ if (uuid_is_null (buf->ia_gfid)) {
+ buf->ia_ino = -1;
+ goto out;
+ }
+ for (i = 15; i > (15 - 8); i--) {
+ temp_ino += (uint64_t)(buf->ia_gfid[i]) << j;
+ j += 8;
+ }
+ buf->ia_ino = temp_ino;
+out:
+ return;
+}
+
+void
+svs_iatt_fill (uuid_t gfid, struct iatt *buf)
+{
+ struct timeval tv = {0, };
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, buf, out);
+
+ buf->ia_type = IA_IFDIR;
+ buf->ia_uid = 0;
+ buf->ia_gid = 0;
+ buf->ia_size = 0;
+ buf->ia_nlink = 2;
+ buf->ia_blocks = 8;
+ buf->ia_size = 4096;
+
+ uuid_copy (buf->ia_gfid, gfid);
+ svs_fill_ino_from_gfid (buf);
+
+ buf->ia_prot = ia_prot_from_st_mode (0755);
+
+ gettimeofday (&tv, 0);
+
+ buf->ia_mtime = buf->ia_atime = buf->ia_ctime = tv.tv_sec;
+ buf->ia_mtime_nsec = buf->ia_atime_nsec = buf->ia_ctime_nsec =
+ (tv.tv_usec * 1000);
+
+out:
+ return;
+}
+
+snap_dirent_t *
+svs_get_snap_dirent (xlator_t *this, const char *name)
+{
+ svs_private_t *private = NULL;
+ int i = 0;
+ snap_dirent_t *dirents = NULL;
+ snap_dirent_t *tmp_dirent = NULL;
+ snap_dirent_t *dirent = NULL;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
+ GF_VALIDATE_OR_GOTO (this->name, name, out);
+
+ private = this->private;
+
+ LOCK (&private->snaplist_lock);
+ {
+ dirents = private->dirents;
+ if (!dirents) {
+ goto unlock;
+ }
+
+ tmp_dirent = dirents;
+ for (i = 0; i < private->num_snaps; i++) {
+ if (!strcmp (tmp_dirent->name, name)) {
+ dirent = tmp_dirent;
+ break;
+ }
+ tmp_dirent++;
+ }
+ }
+unlock:
+ UNLOCK (&private->snaplist_lock);
+
+out:
+ return dirent;
+}
+
+glfs_t *
+svs_initialise_snapshot_volume (xlator_t *this, const char *name)
+{
+ svs_private_t *priv = NULL;
+ int32_t ret = -1;
+ snap_dirent_t *dirent = NULL;
+ char volname[PATH_MAX] = {0, };
+ glfs_t *fs = NULL;
+ int loglevel = GF_LOG_INFO;
+ char logfile[PATH_MAX] = {0, };
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
+ GF_VALIDATE_OR_GOTO (this->name, name, out);
+
+ priv = this->private;
+
+ dirent = svs_get_snap_dirent (this, name);
+ if (!dirent) {
+ gf_log (this->name, GF_LOG_ERROR, "snap entry for name %s "
+ "not found", name);
+ goto out;
+ }
+
+ if (dirent->fs) {
+ ret = 0;
+ fs = dirent->fs;
+ goto out;
+ }
+
+ snprintf (volname, sizeof (volname), "/snaps/%s/%s",
+ dirent->name, dirent->snap_volname);
+
+ fs = glfs_new (volname);
+ if (!fs) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "glfs instance for snap volume %s "
+ "failed", dirent->name);
+ goto out;
+ }
+
+ ret = glfs_set_volfile_server (fs, "tcp", "localhost",
+ 24007);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "setting the "
+ "volfile srever for snap volume %s "
+ "failed", dirent->name);
+ goto out;
+ }
+
+ ret = glfs_init (fs);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "initing the "
+ "fs for %s failed", dirent->name);
+ goto out;
+ }
+
+ snprintf (logfile, sizeof (logfile),
+ DEFAULT_SVD_LOG_FILE_DIRECTORY "/%s-%s.log",
+ name, dirent->uuid);
+
+ ret = glfs_set_logging(fs, logfile, loglevel);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to set the "
+ "log file path");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ if (ret && fs) {
+ glfs_fini (fs);
+ fs = NULL;
+ }
+
+ if (fs)
+ dirent->fs = fs;
+
+ return fs;
+}
+
+snap_dirent_t *
+svs_get_latest_snap_entry (xlator_t *this)
+{
+ svs_private_t *priv = NULL;
+ snap_dirent_t *dirents = NULL;
+ snap_dirent_t *dirent = NULL;
+
+ GF_VALIDATE_OR_GOTO ("svs", this, out);
+
+ priv = this->private;
+
+ LOCK (&priv->snaplist_lock);
+ {
+ dirents = priv->dirents;
+ if (!dirents) {
+ goto unlock;
+ }
+ if (priv->num_snaps)
+ dirent = &dirents[priv->num_snaps - 1];
+ }
+unlock:
+ UNLOCK (&priv->snaplist_lock);
+
+out:
+ return dirent;
+}
+
+glfs_t *
+svs_get_latest_snapshot (xlator_t *this)
+{
+ glfs_t *fs = NULL;
+ snap_dirent_t *dirent = NULL;
+ svs_private_t *priv = NULL;
+
+ GF_VALIDATE_OR_GOTO ("svs", this, out);
+ priv = this->private;
+
+ dirent = svs_get_latest_snap_entry (this);
+
+ if (dirent) {
+ LOCK (&priv->snaplist_lock);
+ {
+ fs = dirent->fs;
+ }
+ UNLOCK (&priv->snaplist_lock);
+ }
+
+out:
+ return fs;
+}