diff options
Diffstat (limited to 'xlators/features/snapview-server/src/snapview-server-helpers.c')
-rw-r--r-- | xlators/features/snapview-server/src/snapview-server-helpers.c | 567 |
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; +} |