gfapi: API/library for accessing gluster volumes
Change-Id: Ie4cbcf91b58218bebf23cf951c313aceeb29f311 BUG: 839950 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.com/3664 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Reviewed-by: Bharata B Rao <bharata.rao@gmail.com>
This commit is contained in:
parent
162505c019
commit
2475e0193c
@ -1,6 +1,7 @@
|
||||
EXTRA_DIST = autogen.sh COPYING-GPLV2 COPYING-LGPLV3 INSTALL README AUTHORS THANKS NEWS glusterfs.spec
|
||||
|
||||
SUBDIRS = argp-standalone libglusterfs rpc xlators glusterfsd $(FUSERMOUNT_SUBDIR) doc extras cli
|
||||
SUBDIRS = argp-standalone libglusterfs rpc api xlators glusterfsd \
|
||||
$(FUSERMOUNT_SUBDIR) doc extras cli
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
|
1
api/Makefile.am
Normal file
1
api/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
SUBDIRS = src
|
30
api/src/Makefile.am
Normal file
30
api/src/Makefile.am
Normal file
@ -0,0 +1,30 @@
|
||||
lib_LTLIBRARIES = libgfapi.la
|
||||
noinst_HEADERS = glfs-mem-types.h glfs-internal.h
|
||||
libgfapi_HEADERS = glfs.h
|
||||
libgfapidir = $(includedir)/glusterfs/api
|
||||
|
||||
libgfapi_la_SOURCES = glfs.c glfs-mgmt.c glfs-fops.c glfs-resolve.c
|
||||
libgfapi_la_CFLAGS = -fPIC -Wall
|
||||
libgfapi_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
|
||||
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
|
||||
$(top_builddir)/rpc/xdr/src/libgfxdr.la \
|
||||
$(GF_LDADD)
|
||||
|
||||
libgfapi_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D_GNU_SOURCE \
|
||||
-D$(GF_HOST_OS) $(GF_CFLAGS) \
|
||||
-I$(top_srcdir)/libglusterfs/src \
|
||||
-I$(top_srcdir)/rpc/rpc-lib/src \
|
||||
-I$(top_srcdir)/rpc/xdr/src
|
||||
libgfapi_la_LDFLAGS = -shared -nostartfiles
|
||||
|
||||
|
||||
xlator_LTLIBRARIES = api.la
|
||||
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mount
|
||||
|
||||
api_la_SOURCES = glfs-master.c
|
||||
|
||||
api_la_LDFLAGS = -module -avoidversion
|
||||
api_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
|
||||
|
||||
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS) -Wall \
|
||||
-I$(top_srcdir)/libglusterfs/src $(GF_CFLAGS)
|
829
api/src/glfs-fops.c
Normal file
829
api/src/glfs-fops.c
Normal file
@ -0,0 +1,829 @@
|
||||
/*
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "glfs-internal.h"
|
||||
#include "glfs-mem-types.h"
|
||||
#include "syncop.h"
|
||||
#include "glfs.h"
|
||||
|
||||
|
||||
struct glfs_fd *
|
||||
glfs_open (struct glfs *fs, const char *path, int flags)
|
||||
{
|
||||
int ret = -1;
|
||||
struct glfs_fd *glfd = NULL;
|
||||
xlator_t *subvol = NULL;
|
||||
loc_t loc = {0, };
|
||||
struct iatt iatt = {0, };
|
||||
|
||||
__glfs_entry_fs (fs);
|
||||
|
||||
subvol = glfs_active_subvol (fs);
|
||||
if (!subvol) {
|
||||
ret = -1;
|
||||
errno = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
glfd = GF_CALLOC (1, sizeof (*glfd), glfs_mt_glfs_fd_t);
|
||||
if (!glfd)
|
||||
goto out;
|
||||
|
||||
ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (IA_ISDIR (iatt.ia_type)) {
|
||||
ret = -1;
|
||||
errno = EISDIR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!IA_ISREG (iatt.ia_type)) {
|
||||
ret = -1;
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
glfd->fd = fd_create (loc.inode, getpid());
|
||||
if (!glfd->fd) {
|
||||
ret = -1;
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = syncop_open (subvol, &loc, flags, glfd->fd);
|
||||
out:
|
||||
loc_wipe (&loc);
|
||||
|
||||
if (ret && glfd) {
|
||||
glfs_fd_destroy (glfd);
|
||||
glfd = NULL;
|
||||
}
|
||||
|
||||
return glfd;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_close (struct glfs_fd *glfd)
|
||||
{
|
||||
xlator_t *subvol = NULL;
|
||||
int ret = -1;
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
subvol = glfs_fd_subvol (glfd);
|
||||
|
||||
ret = syncop_flush (subvol, glfd->fd);
|
||||
|
||||
glfs_fd_destroy (glfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_lstat (struct glfs *fs, const char *path, struct stat *stat)
|
||||
{
|
||||
int ret = -1;
|
||||
xlator_t *subvol = NULL;
|
||||
loc_t loc = {0, };
|
||||
struct iatt iatt = {0, };
|
||||
|
||||
__glfs_entry_fs (fs);
|
||||
|
||||
subvol = glfs_active_subvol (fs);
|
||||
if (!subvol) {
|
||||
ret = -1;
|
||||
errno = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
|
||||
|
||||
if (ret == 0 && stat)
|
||||
iatt_to_stat (&iatt, stat);
|
||||
out:
|
||||
loc_wipe (&loc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_fstat (struct glfs_fd *glfd, struct stat *stat)
|
||||
{
|
||||
int ret = -1;
|
||||
xlator_t *subvol = NULL;
|
||||
struct iatt iatt = {0, };
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
subvol = glfs_fd_subvol (glfd);
|
||||
if (!subvol) {
|
||||
ret = -1;
|
||||
errno = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = syncop_fstat (subvol, glfd->fd, &iatt);
|
||||
|
||||
if (ret == 0 && stat)
|
||||
iatt_to_stat (&iatt, stat);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct glfs_fd *
|
||||
glfs_creat (struct glfs *fs, const char *path, int flags, mode_t mode)
|
||||
{
|
||||
int ret = -1;
|
||||
struct glfs_fd *glfd = NULL;
|
||||
xlator_t *subvol = NULL;
|
||||
loc_t loc = {0, };
|
||||
struct iatt iatt = {0, };
|
||||
uuid_t gfid;
|
||||
dict_t *xattr_req = NULL;
|
||||
|
||||
__glfs_entry_fs (fs);
|
||||
|
||||
subvol = glfs_active_subvol (fs);
|
||||
if (!subvol) {
|
||||
ret = -1;
|
||||
errno = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
xattr_req = dict_new ();
|
||||
if (!xattr_req) {
|
||||
ret = -1;
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uuid_generate (gfid);
|
||||
ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
|
||||
if (ret) {
|
||||
ret = -1;
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
glfd = GF_CALLOC (1, sizeof (*glfd), glfs_mt_glfs_fd_t);
|
||||
if (!glfd)
|
||||
goto out;
|
||||
|
||||
ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
|
||||
if (ret == -1 && errno != ENOENT)
|
||||
/* Any other type of error is fatal */
|
||||
goto out;
|
||||
|
||||
if (ret == -1 && errno == ENOENT && !loc.parent)
|
||||
/* The parent directory or an ancestor even
|
||||
higher does not exist
|
||||
*/
|
||||
goto out;
|
||||
|
||||
if (loc.inode) {
|
||||
if (flags & O_EXCL) {
|
||||
ret = -1;
|
||||
errno = EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (IA_ISDIR (iatt.ia_type)) {
|
||||
ret = -1;
|
||||
errno = EISDIR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!IA_ISREG (iatt.ia_type)) {
|
||||
ret = -1;
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == -1 && errno == ENOENT) {
|
||||
loc.inode = inode_new (loc.parent->table);
|
||||
if (!loc.inode) {
|
||||
ret = -1;
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
glfd->fd = fd_create (loc.inode, getpid());
|
||||
if (!glfd->fd) {
|
||||
ret = -1;
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = syncop_create (subvol, &loc, flags, mode, glfd->fd, xattr_req);
|
||||
out:
|
||||
loc_wipe (&loc);
|
||||
|
||||
if (xattr_req)
|
||||
dict_destroy (xattr_req);
|
||||
|
||||
if (ret && glfd) {
|
||||
glfs_fd_destroy (glfd);
|
||||
glfd = NULL;
|
||||
}
|
||||
|
||||
return glfd;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
glfs_lseek (struct glfs_fd *glfd, off_t offset, int whence)
|
||||
{
|
||||
struct stat sb = {0, };
|
||||
int ret = -1;
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
glfd->offset = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
glfd->offset += offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
ret = glfs_fstat (glfd, &sb);
|
||||
if (ret) {
|
||||
/* seek cannot fail :O */
|
||||
break;
|
||||
}
|
||||
glfd->offset = sb.st_size + offset;
|
||||
break;
|
||||
}
|
||||
|
||||
return glfd->offset;
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
|
||||
ssize_t
|
||||
glfs_preadv (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
|
||||
off_t offset, int flags)
|
||||
{
|
||||
xlator_t *subvol = NULL;
|
||||
int ret = -1;
|
||||
size_t size = -1;
|
||||
struct iovec *iov = NULL;
|
||||
int cnt = 0;
|
||||
struct iobref *iobref = NULL;
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
subvol = glfs_fd_subvol (glfd);
|
||||
|
||||
size = iov_length (iovec, iovcnt);
|
||||
|
||||
ret = syncop_readv (subvol, glfd->fd, size, offset,
|
||||
0, &iov, &cnt, &iobref);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
size = iov_copy (iovec, iovcnt, iov, cnt); /* FIXME!!! */
|
||||
|
||||
glfd->offset = (offset + size);
|
||||
|
||||
if (iov)
|
||||
GF_FREE (iov);
|
||||
if (iobref)
|
||||
iobref_unref (iobref);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
glfs_read (struct glfs_fd *glfd, void *buf, size_t count, int flags)
|
||||
{
|
||||
struct iovec iov = {0, };
|
||||
ssize_t ret = 0;
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = count;
|
||||
|
||||
ret = glfs_preadv (glfd, &iov, 1, glfd->offset, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
glfs_pread (struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
|
||||
int flags)
|
||||
{
|
||||
struct iovec iov = {0, };
|
||||
ssize_t ret = 0;
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = count;
|
||||
|
||||
ret = glfs_preadv (glfd, &iov, 1, offset, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
glfs_readv (struct glfs_fd *glfd, const struct iovec *iov, int count,
|
||||
int flags)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
ret = glfs_preadv (glfd, iov, count, glfd->offset, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct glfs_io {
|
||||
struct glfs_fd *glfd;
|
||||
int op;
|
||||
off_t offset;
|
||||
struct iovec *iov;
|
||||
int count;
|
||||
int flags;
|
||||
glfs_io_cbk fn;
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
glfs_io_async_cbk (int ret, call_frame_t *frame, void *data)
|
||||
{
|
||||
struct glfs_io *gio = data;
|
||||
|
||||
gio->fn (gio->glfd, ret, gio->data);
|
||||
|
||||
GF_FREE (gio->iov);
|
||||
GF_FREE (gio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
glfs_io_async_task (void *data)
|
||||
{
|
||||
struct glfs_io *gio = data;
|
||||
ssize_t ret = 0;
|
||||
|
||||
switch (gio->op) {
|
||||
case GF_FOP_READ:
|
||||
ret = glfs_preadv (gio->glfd, gio->iov, gio->count,
|
||||
gio->offset, gio->flags);
|
||||
break;
|
||||
case GF_FOP_WRITE:
|
||||
ret = glfs_pwritev (gio->glfd, gio->iov, gio->count,
|
||||
gio->offset, gio->flags);
|
||||
break;
|
||||
case GF_FOP_FTRUNCATE:
|
||||
ret = glfs_ftruncate (gio->glfd, gio->offset);
|
||||
break;
|
||||
case GF_FOP_FSYNC:
|
||||
if (gio->flags)
|
||||
ret = glfs_fdatasync (gio->glfd);
|
||||
else
|
||||
ret = glfs_fsync (gio->glfd);
|
||||
break;
|
||||
}
|
||||
|
||||
return (int) ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_preadv_async (struct glfs_fd *glfd, const struct iovec *iovec, int count,
|
||||
off_t offset, int flags, glfs_io_cbk fn, void *data)
|
||||
{
|
||||
struct glfs_io *gio = NULL;
|
||||
int ret = 0;
|
||||
|
||||
gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
|
||||
if (!gio) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
gio->iov = iov_dup (iovec, count);
|
||||
if (!gio->iov) {
|
||||
GF_FREE (gio);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
gio->op = GF_FOP_READ;
|
||||
gio->glfd = glfd;
|
||||
gio->count = count;
|
||||
gio->offset = offset;
|
||||
gio->flags = flags;
|
||||
gio->fn = fn;
|
||||
gio->data = data;
|
||||
|
||||
ret = synctask_new (glfs_from_glfd (glfd)->ctx->env,
|
||||
glfs_io_async_task, glfs_io_async_cbk,
|
||||
NULL, gio);
|
||||
|
||||
if (ret) {
|
||||
GF_FREE (gio->iov);
|
||||
GF_FREE (gio);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_read_async (struct glfs_fd *glfd, void *buf, size_t count, int flags,
|
||||
glfs_io_cbk fn, void *data)
|
||||
{
|
||||
struct iovec iov = {0, };
|
||||
ssize_t ret = 0;
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = count;
|
||||
|
||||
ret = glfs_preadv_async (glfd, &iov, 1, glfd->offset, flags, fn, data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_pread_async (struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
|
||||
int flags, glfs_io_cbk fn, void *data)
|
||||
{
|
||||
struct iovec iov = {0, };
|
||||
ssize_t ret = 0;
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = count;
|
||||
|
||||
ret = glfs_preadv_async (glfd, &iov, 1, offset, flags, fn, data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_readv_async (struct glfs_fd *glfd, const struct iovec *iov, int count,
|
||||
int flags, glfs_io_cbk fn, void *data)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
ret = glfs_preadv_async (glfd, iov, count, glfd->offset, flags,
|
||||
fn, data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
///// writev /////
|
||||
|
||||
ssize_t
|
||||
glfs_pwritev (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
|
||||
off_t offset, int flags)
|
||||
{
|
||||
xlator_t *subvol = NULL;
|
||||
int ret = -1;
|
||||
size_t size = -1;
|
||||
struct iobref *iobref = NULL;
|
||||
struct iobuf *iobuf = NULL;
|
||||
struct iovec iov = {0, };
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
subvol = glfs_fd_subvol (glfd);
|
||||
|
||||
size = iov_length (iovec, iovcnt);
|
||||
|
||||
iobuf = iobuf_get2 (subvol->ctx->iobuf_pool, size);
|
||||
if (!iobuf) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
iobref = iobref_new ();
|
||||
if (!iobref) {
|
||||
iobuf_unref (iobuf);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = iobref_add (iobref, iobuf);
|
||||
if (ret) {
|
||||
iobuf_unref (iobuf);
|
||||
iobref_unref (iobref);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
iov_unload (iobuf_ptr (iobuf), iovec, iovcnt); /* FIXME!!! */
|
||||
|
||||
iov.iov_base = iobuf_ptr (iobuf);
|
||||
iov.iov_len = size;
|
||||
|
||||
ret = syncop_writev (subvol, glfd->fd, &iov, 1, offset,
|
||||
iobref, flags);
|
||||
|
||||
iobuf_unref (iobuf);
|
||||
iobref_unref (iobref);
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
glfd->offset = (offset + size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
glfs_write (struct glfs_fd *glfd, const void *buf, size_t count, int flags)
|
||||
{
|
||||
struct iovec iov = {0, };
|
||||
ssize_t ret = 0;
|
||||
|
||||
iov.iov_base = (void *) buf;
|
||||
iov.iov_len = count;
|
||||
|
||||
ret = glfs_pwritev (glfd, &iov, 1, glfd->offset, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ssize_t
|
||||
glfs_writev (struct glfs_fd *glfd, const struct iovec *iov, int count,
|
||||
int flags)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
ret = glfs_pwritev (glfd, iov, count, glfd->offset, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
glfs_pwrite (struct glfs_fd *glfd, const void *buf, size_t count, off_t offset,
|
||||
int flags)
|
||||
{
|
||||
struct iovec iov = {0, };
|
||||
ssize_t ret = 0;
|
||||
|
||||
iov.iov_base = (void *) buf;
|
||||
iov.iov_len = count;
|
||||
|
||||
ret = glfs_pwritev (glfd, &iov, 1, offset, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_pwritev_async (struct glfs_fd *glfd, const struct iovec *iovec, int count,
|
||||
off_t offset, int flags, glfs_io_cbk fn, void *data)
|
||||
{
|
||||
struct glfs_io *gio = NULL;
|
||||
int ret = 0;
|
||||
|
||||
gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
|
||||
if (!gio) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
gio->iov = iov_dup (iovec, count);
|
||||
if (!gio->iov) {
|
||||
GF_FREE (gio);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
gio->op = GF_FOP_WRITE;
|
||||
gio->glfd = glfd;
|
||||
gio->count = count;
|
||||
gio->offset = offset;
|
||||
gio->flags = flags;
|
||||
gio->fn = fn;
|
||||
gio->data = data;
|
||||
|
||||
ret = synctask_new (glfs_from_glfd (glfd)->ctx->env,
|
||||
glfs_io_async_task, glfs_io_async_cbk,
|
||||
NULL, gio);
|
||||
|
||||
if (ret) {
|
||||
GF_FREE (gio->iov);
|
||||
GF_FREE (gio);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_write_async (struct glfs_fd *glfd, const void *buf, size_t count, int flags,
|
||||
glfs_io_cbk fn, void *data)
|
||||
{
|
||||
struct iovec iov = {0, };
|
||||
ssize_t ret = 0;
|
||||
|
||||
iov.iov_base = (void *) buf;
|
||||
iov.iov_len = count;
|
||||
|
||||
ret = glfs_pwritev_async (glfd, &iov, 1, glfd->offset, flags, fn, data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_pwrite_async (struct glfs_fd *glfd, const void *buf, int count,
|
||||
off_t offset, int flags, glfs_io_cbk fn, void *data)
|
||||
{
|
||||
struct iovec iov = {0, };
|
||||
ssize_t ret = 0;
|
||||
|
||||
iov.iov_base = (void *) buf;
|
||||
iov.iov_len = count;
|
||||
|
||||
ret = glfs_pwritev_async (glfd, &iov, 1, offset, flags, fn, data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_writev_async (struct glfs_fd *glfd, const struct iovec *iov, int count,
|
||||
int flags, glfs_io_cbk fn, void *data)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
ret = glfs_pwritev_async (glfd, iov, count, glfd->offset, flags,
|
||||
fn, data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_fsync (struct glfs_fd *glfd)
|
||||
{
|
||||
int ret = -1;
|
||||
xlator_t *subvol = NULL;
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
subvol = glfs_fd_subvol (glfd);
|
||||
if (!subvol) {
|
||||
ret = -1;
|
||||
errno = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = syncop_fsync (subvol, glfd->fd);
|
||||
// ret = syncop_fsync (subvol, glfd->fd, 0);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
glfs_fsync_async_common (struct glfs_fd *glfd, glfs_io_cbk fn, void *data,
|
||||
int dataonly)
|
||||
{
|
||||
struct glfs_io *gio = NULL;
|
||||
int ret = 0;
|
||||
|
||||
gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
|
||||
if (!gio) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
gio->op = GF_FOP_FSYNC;
|
||||
gio->glfd = glfd;
|
||||
gio->flags = dataonly;
|
||||
gio->fn = fn;
|
||||
gio->data = data;
|
||||
|
||||
ret = synctask_new (glfs_from_glfd (glfd)->ctx->env,
|
||||
glfs_io_async_task, glfs_io_async_cbk,
|
||||
NULL, gio);
|
||||
|
||||
if (ret) {
|
||||
GF_FREE (gio->iov);
|
||||
GF_FREE (gio);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_fsync_async (struct glfs_fd *glfd, glfs_io_cbk fn, void *data)
|
||||
{
|
||||
return glfs_fsync_async_common (glfd, fn, data, 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_fdatasync (struct glfs_fd *glfd)
|
||||
{
|
||||
int ret = -1;
|
||||
xlator_t *subvol = NULL;
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
subvol = glfs_fd_subvol (glfd);
|
||||
if (!subvol) {
|
||||
ret = -1;
|
||||
errno = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = syncop_fsync (subvol, glfd->fd);
|
||||
// ret = syncop_fsync (subvol, glfd->fd, 1);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_fdatasync_async (struct glfs_fd *glfd, glfs_io_cbk fn, void *data)
|
||||
{
|
||||
return glfs_fsync_async_common (glfd, fn, data, 1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_ftruncate (struct glfs_fd *glfd, off_t offset)
|
||||
{
|
||||
int ret = -1;
|
||||
xlator_t *subvol = NULL;
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
subvol = glfs_fd_subvol (glfd);
|
||||
if (!subvol) {
|
||||
ret = -1;
|
||||
errno = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = syncop_ftruncate (subvol, glfd->fd, offset);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_ftruncate_async (struct glfs_fd *glfd, off_t offset,
|
||||
glfs_io_cbk fn, void *data)
|
||||
{
|
||||
struct glfs_io *gio = NULL;
|
||||
int ret = 0;
|
||||
|
||||
gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
|
||||
if (!gio) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
gio->op = GF_FOP_FTRUNCATE;
|
||||
gio->glfd = glfd;
|
||||
gio->offset = offset;
|
||||
gio->fn = fn;
|
||||
gio->data = data;
|
||||
|
||||
ret = synctask_new (glfs_from_glfd (glfd)->ctx->env,
|
||||
glfs_io_async_task, glfs_io_async_cbk,
|
||||
NULL, gio);
|
||||
|
||||
if (ret) {
|
||||
GF_FREE (gio->iov);
|
||||
GF_FREE (gio);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
74
api/src/glfs-internal.h
Normal file
74
api/src/glfs-internal.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright (c) 2012 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 _GLFS_INTERNAL_H
|
||||
#define _GLFS_INTERNAL_H
|
||||
|
||||
#include "xlator.h"
|
||||
|
||||
struct glfs;
|
||||
|
||||
typedef int (*glfs_init_cbk) (struct glfs *fs, int ret);
|
||||
|
||||
struct glfs {
|
||||
char *volname;
|
||||
|
||||
glusterfs_ctx_t *ctx;
|
||||
|
||||
pthread_t poller;
|
||||
|
||||
glfs_init_cbk init_cbk;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int init;
|
||||
int ret;
|
||||
|
||||
xlator_t *active_subvol;
|
||||
};
|
||||
|
||||
struct glfs_fd {
|
||||
off_t offset;
|
||||
fd_t *fd;
|
||||
};
|
||||
|
||||
#define DEFAULT_EVENT_POOL_SIZE 16384
|
||||
#define GF_MEMPOOL_COUNT_OF_DICT_T 4096
|
||||
#define GF_MEMPOOL_COUNT_OF_DATA_T (GF_MEMPOOL_COUNT_OF_DICT_T * 4)
|
||||
#define GF_MEMPOOL_COUNT_OF_DATA_PAIR_T (GF_MEMPOOL_COUNT_OF_DICT_T * 4)
|
||||
|
||||
int glfs_mgmt_init (struct glfs *fs);
|
||||
void glfs_init_done (struct glfs *fs, int ret);
|
||||
int glfs_process_volfp (struct glfs *fs, FILE *fp);
|
||||
int glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *path, loc_t *loc,
|
||||
struct iatt *iatt);
|
||||
void glfs_first_lookup (xlator_t *subvol);
|
||||
|
||||
static inline void
|
||||
__glfs_entry_fs (struct glfs *fs)
|
||||
{
|
||||
THIS = fs->ctx->master;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
__glfs_entry_fd (struct glfs_fd *fd)
|
||||
{
|
||||
THIS = fd->fd->inode->table->xl->ctx->master;
|
||||
}
|
||||
|
||||
|
||||
void glfs_fd_destroy (struct glfs_fd *glfd);
|
||||
|
||||
xlator_t * glfs_fd_subvol (struct glfs_fd *glfd);
|
||||
|
||||
xlator_t * glfs_active_subvol (struct glfs *fs);
|
||||
|
||||
#endif /* !_GLFS_INTERNAL_H */
|
113
api/src/glfs-master.c
Normal file
113
api/src/glfs-master.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "xlator.h"
|
||||
#include "glusterfs.h"
|
||||
#include "glfs-internal.h"
|
||||
|
||||
|
||||
int
|
||||
glfs_graph_setup (struct glfs *fs, glusterfs_graph_t *graph)
|
||||
{
|
||||
if (fs->active_subvol == graph->top)
|
||||
return 0;
|
||||
|
||||
pthread_mutex_lock (&fs->mutex);
|
||||
{
|
||||
fs->active_subvol = graph->top;
|
||||
pthread_cond_broadcast (&fs->cond);
|
||||
}
|
||||
pthread_mutex_unlock (&fs->mutex);
|
||||
|
||||
gf_log ("glfs-master", GF_LOG_INFO, "switched to graph %s (%d)",
|
||||
uuid_utoa ((unsigned char *)graph->graph_uuid), graph->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
notify (xlator_t *this, int event, void *data, ...)
|
||||
{
|
||||
glusterfs_graph_t *graph = NULL;
|
||||
struct glfs *fs = NULL;
|
||||
|
||||
graph = data;
|
||||
fs = this->private;
|
||||
|
||||
switch (event) {
|
||||
case GF_EVENT_GRAPH_NEW:
|
||||
gf_log (this->name, GF_LOG_INFO, "New graph %s (%d) coming up",
|
||||
uuid_utoa ((unsigned char *)graph->graph_uuid),
|
||||
graph->id);
|
||||
break;
|
||||
case GF_EVENT_CHILD_UP:
|
||||
glfs_graph_setup (fs, graph);
|
||||
glfs_init_done (fs, 0);
|
||||
break;
|
||||
case GF_EVENT_CHILD_DOWN:
|
||||
glfs_graph_setup (fs, graph);
|
||||
glfs_init_done (fs, 1);
|
||||
break;
|
||||
case GF_EVENT_CHILD_CONNECTING:
|
||||
break;
|
||||
default:
|
||||
gf_log (this->name, GF_LOG_DEBUG,
|
||||
"got notify event %d", event);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mem_acct_init (xlator_t *this)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
init (xlator_t *this)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fini (xlator_t *this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct xlator_dumpops dumpops = {
|
||||
};
|
||||
|
||||
|
||||
struct xlator_fops fops = {
|
||||
};
|
||||
|
||||
|
||||
struct xlator_cbks cbks = {
|
||||
};
|
28
api/src/glfs-mem-types.h
Normal file
28
api/src/glfs-mem-types.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright (c) 2012 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 _GLFS_MEM_TYPES_H
|
||||
#define _GLFS_MEM_TYPES_H
|
||||
|
||||
#include "mem-types.h"
|
||||
|
||||
#define GF_MEM_TYPE_START (gf_common_mt_end + 1)
|
||||
|
||||
enum glfs_mem_types_ {
|
||||
glfs_mt_glfs_t,
|
||||
glfs_mt_call_pool_t,
|
||||
glfs_mt_xlator_t,
|
||||
glfs_mt_glfs_fd_t,
|
||||
glfs_mt_glfs_io_t,
|
||||
glfs_mt_end
|
||||
|
||||
};
|
||||
#endif
|
||||
|
629
api/src/glfs-mgmt.c
Normal file
629
api/src/glfs-mgmt.c
Normal file
@ -0,0 +1,629 @@
|
||||
/*
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* _CONFIG_H */
|
||||
|
||||
#include "glusterfs.h"
|
||||
#include "stack.h"
|
||||
#include "dict.h"
|
||||
#include "event.h"
|
||||
#include "defaults.h"
|
||||
|
||||
#include "rpc-clnt.h"
|
||||
#include "protocol-common.h"
|
||||
#include "glusterfs3.h"
|
||||
#include "portmap-xdr.h"
|
||||
#include "xdr-generic.h"
|
||||
|
||||
#include "syncop.h"
|
||||
#include "xlator.h"
|
||||
|
||||
#include "glfs-internal.h"
|
||||
|
||||
|
||||
int glfs_volfile_fetch (struct glfs *fs);
|
||||
|
||||
int
|
||||
glfs_process_volfp (struct glfs *fs, FILE *fp)
|
||||
{
|
||||
glusterfs_graph_t *graph = NULL;
|
||||
int ret = -1;
|
||||
xlator_t *trav = NULL;
|
||||
glusterfs_ctx_t *ctx = NULL;
|
||||
|
||||
ctx = fs->ctx;
|
||||
graph = glusterfs_graph_construct (fp);
|
||||
if (!graph) {
|
||||
gf_log ("glfs", GF_LOG_ERROR, "failed to construct the graph");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (trav = graph->first; trav; trav = trav->next) {
|
||||
if (strcmp (trav->type, "mount/fuse") == 0) {
|
||||
gf_log ("glfs", GF_LOG_ERROR,
|
||||
"fuse xlator cannot be specified "
|
||||
"in volume file");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = glusterfs_graph_prepare (graph, ctx);
|
||||
if (ret) {
|
||||
glusterfs_graph_destroy (graph);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = glusterfs_graph_activate (graph, ctx);
|
||||
|
||||
if (ret) {
|
||||
glusterfs_graph_destroy (graph);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (fp)
|
||||
fclose (fp);
|
||||
|
||||
if (!ctx->active) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mgmt_cbk_spec (struct rpc_clnt *rpc, void *mydata, void *data)
|
||||
{
|
||||
struct glfs *fs = NULL;
|
||||
xlator_t *this = NULL;
|
||||
|
||||
this = mydata;
|
||||
fs = this->private;
|
||||
|
||||
glfs_volfile_fetch (fs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mgmt_cbk_event (struct rpc_clnt *rpc, void *mydata, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
rpcclnt_cb_actor_t gluster_cbk_actors[] = {
|
||||
[GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec },
|
||||
[GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY,
|
||||
mgmt_cbk_event},
|
||||
};
|
||||
|
||||
|
||||
struct rpcclnt_cb_program mgmt_cbk_prog = {
|
||||
.progname = "GlusterFS Callback",
|
||||
.prognum = GLUSTER_CBK_PROGRAM,
|
||||
.progver = GLUSTER_CBK_VERSION,
|
||||
.actors = gluster_cbk_actors,
|
||||
.numactors = GF_CBK_MAXVALUE,
|
||||
};
|
||||
|
||||
char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
|
||||
[GF_HNDSK_NULL] = "NULL",
|
||||
[GF_HNDSK_SETVOLUME] = "SETVOLUME",
|
||||
[GF_HNDSK_GETSPEC] = "GETSPEC",
|
||||
[GF_HNDSK_PING] = "PING",
|
||||
[GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
|
||||
};
|
||||
|
||||
rpc_clnt_prog_t clnt_handshake_prog = {
|
||||
.progname = "GlusterFS Handshake",
|
||||
.prognum = GLUSTER_HNDSK_PROGRAM,
|
||||
.progver = GLUSTER_HNDSK_VERSION,
|
||||
.procnames = clnt_handshake_procs,
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
mgmt_submit_request (void *req, call_frame_t *frame,
|
||||
glusterfs_ctx_t *ctx,
|
||||
rpc_clnt_prog_t *prog, int procnum,
|
||||
fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
|
||||
{
|
||||
int ret = -1;
|
||||
int count = 0;
|
||||
struct iovec iov = {0, };
|
||||
struct iobuf *iobuf = NULL;
|
||||
struct iobref *iobref = NULL;
|
||||
ssize_t xdr_size = 0;
|
||||
|
||||
iobref = iobref_new ();
|
||||
if (!iobref) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (req) {
|
||||
xdr_size = xdr_sizeof (xdrproc, req);
|
||||
|
||||
iobuf = iobuf_get2 (ctx->iobuf_pool, xdr_size);
|
||||
if (!iobuf) {
|
||||
goto out;
|
||||
};
|
||||
|
||||
iobref_add (iobref, iobuf);
|
||||
|
||||
iov.iov_base = iobuf->ptr;
|
||||
iov.iov_len = iobuf_pagesize (iobuf);
|
||||
|
||||
/* Create the xdr payload */
|
||||
ret = xdr_serialize_generic (iov, req, xdrproc);
|
||||
if (ret == -1) {
|
||||
gf_log (THIS->name, GF_LOG_WARNING,
|
||||
"failed to create XDR payload");
|
||||
goto out;
|
||||
}
|
||||
iov.iov_len = ret;
|
||||
count = 1;
|
||||
}
|
||||
|
||||
/* Send the msg */
|
||||
ret = rpc_clnt_submit (ctx->mgmt, prog, procnum, cbkfn,
|
||||
&iov, count,
|
||||
NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
|
||||
|
||||
out:
|
||||
if (iobref)
|
||||
iobref_unref (iobref);
|
||||
|
||||
if (iobuf)
|
||||
iobuf_unref (iobuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* XXX: move these into @ctx */
|
||||
static char oldvolfile[131072];
|
||||
static int oldvollen = 0;
|
||||
|
||||
static int
|
||||
xlator_equal_rec (xlator_t *xl1, xlator_t *xl2)
|
||||
{
|
||||
xlator_list_t *trav1 = NULL;
|
||||
xlator_list_t *trav2 = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (xl1 == NULL || xl2 == NULL) {
|
||||
gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
trav1 = xl1->children;
|
||||
trav2 = xl2->children;
|
||||
|
||||
while (trav1 && trav2) {
|
||||
ret = xlator_equal_rec (trav1->xlator, trav2->xlator);
|
||||
if (ret) {
|
||||
gf_log ("glfs-mgmt", GF_LOG_DEBUG,
|
||||
"xlators children not equal");
|
||||
goto out;
|
||||
}
|
||||
|
||||
trav1 = trav1->next;
|
||||
trav2 = trav2->next;
|
||||
}
|
||||
|
||||
if (trav1 || trav2) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp (xl1->name, xl2->name)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
out :
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static gf_boolean_t
|
||||
is_graph_topology_equal (glusterfs_graph_t *graph1,
|
||||
glusterfs_graph_t *graph2)
|
||||
{
|
||||
xlator_t *trav1 = NULL;
|
||||
xlator_t *trav2 = NULL;
|
||||
gf_boolean_t ret = _gf_true;
|
||||
|
||||
trav1 = graph1->first;
|
||||
trav2 = graph2->first;
|
||||
|
||||
ret = xlator_equal_rec (trav1, trav2);
|
||||
|
||||
if (ret) {
|
||||
gf_log ("glfs-mgmt", GF_LOG_DEBUG,
|
||||
"graphs are not equal");
|
||||
ret = _gf_false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = _gf_true;
|
||||
gf_log ("glfs-mgmt", GF_LOG_DEBUG,
|
||||
"graphs are equal");
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Function has 3types of return value 0, -ve , 1
|
||||
* return 0 =======> reconfiguration of options has succeeded
|
||||
* return 1 =======> the graph has to be reconstructed and all the xlators should be inited
|
||||
* return -1(or -ve) =======> Some Internal Error occurred during the operation
|
||||
*/
|
||||
static int
|
||||
glusterfs_volfile_reconfigure (struct glfs *fs, FILE *newvolfile_fp)
|
||||
{
|
||||
glusterfs_graph_t *oldvolfile_graph = NULL;
|
||||
glusterfs_graph_t *newvolfile_graph = NULL;
|
||||
FILE *oldvolfile_fp = NULL;
|
||||
glusterfs_ctx_t *ctx = NULL;
|
||||
|
||||
int ret = -1;
|
||||
|
||||
oldvolfile_fp = tmpfile ();
|
||||
if (!oldvolfile_fp)
|
||||
goto out;
|
||||
|
||||
if (!oldvollen) {
|
||||
ret = 1; // Has to call INIT for the whole graph
|
||||
goto out;
|
||||
}
|
||||
fwrite (oldvolfile, oldvollen, 1, oldvolfile_fp);
|
||||
fflush (oldvolfile_fp);
|
||||
if (ferror (oldvolfile_fp)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
oldvolfile_graph = glusterfs_graph_construct (oldvolfile_fp);
|
||||
if (!oldvolfile_graph) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
newvolfile_graph = glusterfs_graph_construct (newvolfile_fp);
|
||||
if (!newvolfile_graph) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!is_graph_topology_equal (oldvolfile_graph,
|
||||
newvolfile_graph)) {
|
||||
|
||||
ret = 1;
|
||||
gf_log ("glfs-mgmt", GF_LOG_DEBUG,
|
||||
"Graph topology not equal(should call INIT)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
gf_log ("glfs-mgmt", GF_LOG_DEBUG,
|
||||
"Only options have changed in the new "
|
||||
"graph");
|
||||
|
||||
ctx = fs->ctx;
|
||||
|
||||
if (!ctx) {
|
||||
gf_log ("glfs-mgmt", GF_LOG_ERROR,
|
||||
"glusterfs_ctx_get() returned NULL");
|
||||
goto out;
|
||||
}
|
||||
|
||||
oldvolfile_graph = ctx->active;
|
||||
|
||||
if (!oldvolfile_graph) {
|
||||
gf_log ("glfs-mgmt", GF_LOG_ERROR,
|
||||
"glusterfs_ctx->active is NULL");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* */
|
||||
ret = glusterfs_graph_reconfigure (oldvolfile_graph,
|
||||
newvolfile_graph);
|
||||
if (ret) {
|
||||
gf_log ("glfs-mgmt", GF_LOG_DEBUG,
|
||||
"Could not reconfigure new options in old graph");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (oldvolfile_fp)
|
||||
fclose (oldvolfile_fp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
|
||||
void *myframe)
|
||||
{
|
||||
gf_getspec_rsp rsp = {0,};
|
||||
call_frame_t *frame = NULL;
|
||||
glusterfs_ctx_t *ctx = NULL;
|
||||
int ret = 0;
|
||||
ssize_t size = 0;
|
||||
FILE *tmpfp = NULL;
|
||||
struct glfs *fs = NULL;
|
||||
|
||||
frame = myframe;
|
||||
ctx = frame->this->ctx;
|
||||
fs = ((xlator_t *)ctx->master)->private;
|
||||
|
||||
if (-1 == req->rpc_status) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
|
||||
if (ret < 0) {
|
||||
gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding error");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (-1 == rsp.op_ret) {
|
||||
gf_log (frame->this->name, GF_LOG_ERROR,
|
||||
"failed to get the 'volume file' from server");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
size = rsp.op_ret;
|
||||
|
||||
if (size == oldvollen && (memcmp (oldvolfile, rsp.spec, size) == 0)) {
|
||||
gf_log (frame->this->name, GF_LOG_INFO,
|
||||
"No change in volfile, continuing");
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmpfp = tmpfile ();
|
||||
if (!tmpfp) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fwrite (rsp.spec, size, 1, tmpfp);
|
||||
fflush (tmpfp);
|
||||
if (ferror (tmpfp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check if only options have changed. No need to reload the
|
||||
* volfile if topology hasn't changed.
|
||||
* glusterfs_volfile_reconfigure returns 3 possible return states
|
||||
* return 0 =======> reconfiguration of options has succeeded
|
||||
* return 1 =======> the graph has to be reconstructed and all the xlators should be inited
|
||||
* return -1(or -ve) =======> Some Internal Error occurred during the operation
|
||||
*/
|
||||
|
||||
ret = glusterfs_volfile_reconfigure (fs, tmpfp);
|
||||
if (ret == 0) {
|
||||
gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
|
||||
"No need to re-load volfile, reconfigure done");
|
||||
oldvollen = size;
|
||||
memcpy (oldvolfile, rsp.spec, size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
|
||||
"Reconfigure failed !!");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = glfs_process_volfp (fs, tmpfp);
|
||||
/* tmpfp closed */
|
||||
tmpfp = NULL;
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
oldvollen = size;
|
||||
memcpy (oldvolfile, rsp.spec, size);
|
||||
|
||||
out:
|
||||
STACK_DESTROY (frame->root);
|
||||
|
||||
if (rsp.spec)
|
||||
free (rsp.spec);
|
||||
|
||||
if (ret && ctx && !ctx->active) {
|
||||
/* Do it only for the first time */
|
||||
/* Failed to get the volume file, something wrong,
|
||||
restart the process */
|
||||
gf_log ("glfs-mgmt", GF_LOG_ERROR,
|
||||
"failed to fetch volume file (key:%s)",
|
||||
ctx->cmd_args.volfile_id);
|
||||
}
|
||||
|
||||
if (tmpfp)
|
||||
fclose (tmpfp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_volfile_fetch (struct glfs *fs)
|
||||
{
|
||||
cmd_args_t *cmd_args = NULL;
|
||||
gf_getspec_req req = {0, };
|
||||
int ret = 0;
|
||||
call_frame_t *frame = NULL;
|
||||
glusterfs_ctx_t *ctx = NULL;
|
||||
|
||||
ctx = fs->ctx;
|
||||
cmd_args = &ctx->cmd_args;
|
||||
|
||||
frame = create_frame (THIS, ctx->pool);
|
||||
|
||||
req.key = cmd_args->volfile_id;
|
||||
req.flags = 0;
|
||||
|
||||
ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,
|
||||
GF_HNDSK_GETSPEC, mgmt_getspec_cbk,
|
||||
(xdrproc_t)xdr_gf_getspec_req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
|
||||
void *data)
|
||||
{
|
||||
xlator_t *this = NULL;
|
||||
cmd_args_t *cmd_args = NULL;
|
||||
glusterfs_ctx_t *ctx = NULL;
|
||||
struct glfs *fs = NULL;
|
||||
int ret = 0;
|
||||
|
||||
this = mydata;
|
||||
ctx = this->ctx;
|
||||
fs = ((xlator_t *)ctx->master)->private;
|
||||
cmd_args = &ctx->cmd_args;
|
||||
|
||||
switch (event) {
|
||||
case RPC_CLNT_DISCONNECT:
|
||||
if (!ctx->active) {
|
||||
cmd_args->max_connect_attempts--;
|
||||
gf_log ("glfs-mgmt", GF_LOG_ERROR,
|
||||
"failed to connect with remote-host: %s",
|
||||
strerror (errno));
|
||||
gf_log ("glfs-mgmt", GF_LOG_INFO,
|
||||
"%d connect attempts left",
|
||||
cmd_args->max_connect_attempts);
|
||||
if (0 >= cmd_args->max_connect_attempts)
|
||||
glfs_init_done (fs, -1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RPC_CLNT_CONNECT:
|
||||
rpc_clnt_set_connected (&((struct rpc_clnt*)ctx->mgmt)->conn);
|
||||
|
||||
ret = glfs_volfile_fetch (fs);
|
||||
if (ret && ctx && (ctx->active == NULL)) {
|
||||
/* Do it only for the first time */
|
||||
/* Exit the process.. there is some wrong options */
|
||||
gf_log ("glfs-mgmt", GF_LOG_ERROR,
|
||||
"failed to fetch volume file (key:%s)",
|
||||
ctx->cmd_args.volfile_id);
|
||||
glfs_init_done (fs, -1);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glusterfs_mgmt_notify (int32_t op, void *data, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case GF_EN_DEFRAG_STATUS:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_mgmt_init (struct glfs *fs)
|
||||
{
|
||||
cmd_args_t *cmd_args = NULL;
|
||||
struct rpc_clnt *rpc = NULL;
|
||||
dict_t *options = NULL;
|
||||
int ret = -1;
|
||||
int port = GF_DEFAULT_BASE_PORT;
|
||||
char *host = NULL;
|
||||
glusterfs_ctx_t *ctx = NULL;
|
||||
|
||||
ctx = fs->ctx;
|
||||
cmd_args = &ctx->cmd_args;
|
||||
|
||||
if (ctx->mgmt)
|
||||
return 0;
|
||||
|
||||
if (cmd_args->volfile_server_port)
|
||||
port = cmd_args->volfile_server_port;
|
||||
|
||||
host = "localhost";
|
||||
if (cmd_args->volfile_server)
|
||||
host = cmd_args->volfile_server;
|
||||
|
||||
ret = rpc_transport_inet_options_build (&options, host, port);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
rpc = rpc_clnt_new (options, THIS->ctx, THIS->name, 8);
|
||||
if (!rpc) {
|
||||
ret = -1;
|
||||
gf_log (THIS->name, GF_LOG_WARNING,
|
||||
"failed to create rpc clnt");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rpc_clnt_register_notify (rpc, mgmt_rpc_notify, THIS);
|
||||
if (ret) {
|
||||
gf_log (THIS->name, GF_LOG_WARNING,
|
||||
"failed to register notify function");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rpcclnt_cbk_program_register (rpc, &mgmt_cbk_prog, THIS);
|
||||
if (ret) {
|
||||
gf_log (THIS->name, GF_LOG_WARNING,
|
||||
"failed to register callback function");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->notify = glusterfs_mgmt_notify;
|
||||
|
||||
/* This value should be set before doing the 'rpc_clnt_start()' as
|
||||
the notify function uses this variable */
|
||||
ctx->mgmt = rpc;
|
||||
|
||||
ret = rpc_clnt_start (rpc);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
244
api/src/glfs-resolve.c
Normal file
244
api/src/glfs-resolve.c
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "glusterfs.h"
|
||||
#include "logging.h"
|
||||
#include "stack.h"
|
||||
#include "event.h"
|
||||
#include "glfs-mem-types.h"
|
||||
#include "common-utils.h"
|
||||
#include "syncop.h"
|
||||
#include "call-stub.h"
|
||||
|
||||
#include "glfs-internal.h"
|
||||
|
||||
|
||||
void
|
||||
glfs_first_lookup (xlator_t *subvol)
|
||||
{
|
||||
loc_t loc = {0, };
|
||||
int ret = -1;
|
||||
|
||||
loc.inode = subvol->itable->root;
|
||||
memset (loc.gfid, 0, 16);
|
||||
loc.gfid[15] = 1;
|
||||
loc.path = "/";
|
||||
loc.name = "";
|
||||
|
||||
ret = syncop_lookup (subvol, &loc, 0, 0, 0, 0);
|
||||
|
||||
gf_log (subvol->name, GF_LOG_DEBUG, "first lookup complete %d", ret);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_loc_touchup (loc_t *loc)
|
||||
{
|
||||
char *path = NULL;
|
||||
int ret = -1;
|
||||
char *bn = NULL;
|
||||
|
||||
ret = inode_path (loc->parent, loc->name, &path);
|
||||
|
||||
loc->path = path;
|
||||
|
||||
if (ret < 0 || !path) {
|
||||
ret = -1;
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bn = strrchr (path, '/');
|
||||
if (bn)
|
||||
bn++;
|
||||
loc->name = bn;
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
inode_t *
|
||||
glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
|
||||
const char *component, struct iatt *iatt)
|
||||
{
|
||||
loc_t loc = {0, };
|
||||
inode_t *inode = NULL;
|
||||
int reval = 0;
|
||||
int ret = -1;
|
||||
int glret = -1;
|
||||
struct iatt ciatt = {0, };
|
||||
uuid_t gfid;
|
||||
dict_t *xattr_req = NULL;
|
||||
|
||||
loc.name = component;
|
||||
|
||||
loc.parent = inode_ref (parent);
|
||||
uuid_copy (loc.pargfid, parent->gfid);
|
||||
|
||||
xattr_req = dict_new ();
|
||||
if (!xattr_req) {
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
|
||||
if (ret) {
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
loc.inode = inode_grep (parent->table, parent, component);
|
||||
|
||||
if (loc.inode) {
|
||||
uuid_copy (loc.gfid, loc.inode->gfid);
|
||||
reval = 1;
|
||||
} else {
|
||||
uuid_generate (gfid);
|
||||
loc.inode = inode_new (parent->table);
|
||||
}
|
||||
|
||||
if (!loc.inode)
|
||||
goto out;
|
||||
|
||||
|
||||
glret = glfs_loc_touchup (&loc);
|
||||
if (glret < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = syncop_lookup (subvol, &loc, xattr_req, &ciatt, NULL, NULL);
|
||||
if (ret && reval) {
|
||||
inode_unref (loc.inode);
|
||||
loc.inode = inode_new (parent->table);
|
||||
if (!loc.inode)
|
||||
goto out;
|
||||
uuid_generate (gfid);
|
||||
ret = syncop_lookup (subvol, &loc, xattr_req, &ciatt,
|
||||
NULL, NULL);
|
||||
}
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
inode = inode_link (loc.inode, loc.parent, component, &ciatt);
|
||||
if (inode)
|
||||
inode_lookup (inode);
|
||||
if (iatt)
|
||||
*iatt = ciatt;
|
||||
out:
|
||||
if (xattr_req)
|
||||
dict_destroy (xattr_req);
|
||||
|
||||
loc_wipe (&loc);
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath,
|
||||
loc_t *loc, struct iatt *iatt)
|
||||
{
|
||||
inode_t *inode = NULL;
|
||||
inode_t *parent = NULL;
|
||||
char *saveptr = NULL;
|
||||
char *path = NULL;
|
||||
char *component = NULL;
|
||||
char *next_component = NULL;
|
||||
int ret = -1;
|
||||
struct iatt ciatt = {0, };
|
||||
|
||||
path = gf_strdup (origpath);
|
||||
if (!path) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
parent = NULL;
|
||||
inode = inode_ref (subvol->itable->root);
|
||||
|
||||
for (component = strtok_r (path, "/", &saveptr);
|
||||
component; component = next_component) {
|
||||
|
||||
next_component = strtok_r (NULL, "/", &saveptr);
|
||||
|
||||
if (parent)
|
||||
inode_unref (parent);
|
||||
|
||||
parent = inode;
|
||||
|
||||
inode = glfs_resolve_component (fs, subvol, parent,
|
||||
component, &ciatt);
|
||||
if (!inode)
|
||||
break;
|
||||
|
||||
if (!next_component)
|
||||
break;
|
||||
|
||||
if (!IA_ISDIR (ciatt.ia_type)) {
|
||||
/* next_component exists and this component is
|
||||
not a directory
|
||||
*/
|
||||
inode_unref (inode);
|
||||
inode = NULL;
|
||||
ret = -1;
|
||||
errno = ENOTDIR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent && next_component)
|
||||
/* resolution failed mid-way */
|
||||
goto out;
|
||||
|
||||
/* At this point, all components up to the last parent directory
|
||||
have been resolved successfully (@parent). Resolution of basename
|
||||
might have failed (@inode) if at all.
|
||||
*/
|
||||
|
||||
loc->parent = parent;
|
||||
if (parent) {
|
||||
uuid_copy (loc->pargfid, parent->gfid);
|
||||
loc->name = component;
|
||||
}
|
||||
|
||||
loc->inode = inode;
|
||||
if (inode) {
|
||||
uuid_copy (loc->gfid, inode->gfid);
|
||||
if (iatt)
|
||||
*iatt = ciatt;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
glfs_loc_touchup (loc);
|
||||
out:
|
||||
GF_FREE (path);
|
||||
|
||||
/* do NOT loc_wipe here as only last component might be missing */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
546
api/src/glfs.c
Normal file
546
api/src/glfs.c
Normal file
@ -0,0 +1,546 @@
|
||||
/*
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- set proper pid/lk_owner to call frames (currently buried in syncop)
|
||||
- fix logging.c/h to store logfp and loglevel in glusterfs_ctx_t and
|
||||
reach it via THIS.
|
||||
- fd migration on graph switch.
|
||||
- update syncop functions to accept/return xdata. ???
|
||||
- syncop_readv to not touch params if args.op_ret < 0.
|
||||
- protocol/client to reconnect immediately after portmap disconnect.
|
||||
- handle SEEK_END failure in _lseek()
|
||||
- handle umask (per filesystem?)
|
||||
- implement glfs_set_xlator_option(), like --xlator-option
|
||||
- make itables LRU based
|
||||
- implement glfs_fini()
|
||||
- modify syncop_fsync() to accept 'dataonly' flag
|
||||
- 0-copy for readv/writev
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "glusterfs.h"
|
||||
#include "logging.h"
|
||||
#include "stack.h"
|
||||
#include "event.h"
|
||||
#include "glfs-mem-types.h"
|
||||
#include "common-utils.h"
|
||||
#include "syncop.h"
|
||||
#include "call-stub.h"
|
||||
|
||||
#include "glfs.h"
|
||||
#include "glfs-internal.h"
|
||||
|
||||
|
||||
static gf_boolean_t
|
||||
vol_assigned (cmd_args_t *args)
|
||||
{
|
||||
return args->volfile || args->volfile_server;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
|
||||
{
|
||||
call_pool_t *pool = NULL;
|
||||
int ret = -1;
|
||||
cmd_args_t *cmd_args = NULL;
|
||||
|
||||
xlator_mem_acct_init (THIS, glfs_mt_end);
|
||||
|
||||
cmd_args = &ctx->cmd_args;
|
||||
|
||||
ctx->process_uuid = generate_glusterfs_ctx_id ();
|
||||
if (!ctx->process_uuid) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ctx->page_size = 128 * GF_UNIT_KB;
|
||||
|
||||
ctx->iobuf_pool = iobuf_pool_new ();
|
||||
if (!ctx->iobuf_pool) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ctx->event_pool = event_pool_new (DEFAULT_EVENT_POOL_SIZE);
|
||||
if (!ctx->event_pool) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ctx->env = syncenv_new (0);
|
||||
if (!ctx->env) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
pool = GF_CALLOC (1, sizeof (call_pool_t),
|
||||
glfs_mt_call_pool_t);
|
||||
if (!pool) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* frame_mem_pool size 112 * 4k */
|
||||
pool->frame_mem_pool = mem_pool_new (call_frame_t, 4096);
|
||||
if (!pool->frame_mem_pool) {
|
||||
goto err;
|
||||
}
|
||||
/* stack_mem_pool size 256 * 1024 */
|
||||
pool->stack_mem_pool = mem_pool_new (call_stack_t, 1024);
|
||||
if (!pool->stack_mem_pool) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ctx->stub_mem_pool = mem_pool_new (call_stub_t, 1024);
|
||||
if (!ctx->stub_mem_pool) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ctx->dict_pool = mem_pool_new (dict_t, GF_MEMPOOL_COUNT_OF_DICT_T);
|
||||
if (!ctx->dict_pool)
|
||||
goto err;
|
||||
|
||||
ctx->dict_pair_pool = mem_pool_new (data_pair_t,
|
||||
GF_MEMPOOL_COUNT_OF_DATA_PAIR_T);
|
||||
if (!ctx->dict_pair_pool)
|
||||
goto err;
|
||||
|
||||
ctx->dict_data_pool = mem_pool_new (data_t, GF_MEMPOOL_COUNT_OF_DATA_T);
|
||||
if (!ctx->dict_data_pool)
|
||||
goto err;
|
||||
|
||||
INIT_LIST_HEAD (&pool->all_frames);
|
||||
INIT_LIST_HEAD (&ctx->cmd_args.xlator_options);
|
||||
LOCK_INIT (&pool->lock);
|
||||
ctx->pool = pool;
|
||||
|
||||
pthread_mutex_init (&(ctx->lock), NULL);
|
||||
|
||||
ret = 0;
|
||||
err:
|
||||
if (ret && pool) {
|
||||
if (pool->frame_mem_pool)
|
||||
mem_pool_destroy (pool->frame_mem_pool);
|
||||
if (pool->stack_mem_pool)
|
||||
mem_pool_destroy (pool->stack_mem_pool);
|
||||
GF_FREE (pool);
|
||||
}
|
||||
|
||||
if (ret && ctx) {
|
||||
if (ctx->stub_mem_pool)
|
||||
mem_pool_destroy (ctx->stub_mem_pool);
|
||||
if (ctx->dict_pool)
|
||||
mem_pool_destroy (ctx->dict_pool);
|
||||
if (ctx->dict_data_pool)
|
||||
mem_pool_destroy (ctx->dict_data_pool);
|
||||
if (ctx->dict_pair_pool)
|
||||
mem_pool_destroy (ctx->dict_pair_pool);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
create_master (struct glfs *fs)
|
||||
{
|
||||
int ret = 0;
|
||||
xlator_t *master = NULL;
|
||||
|
||||
master = GF_CALLOC (1, sizeof (*master),
|
||||
glfs_mt_xlator_t);
|
||||
if (!master)
|
||||
goto err;
|
||||
|
||||
master->name = gf_strdup ("gfapi");
|
||||
if (!master->name)
|
||||
goto err;
|
||||
|
||||
if (xlator_set_type (master, "mount/api") == -1) {
|
||||
gf_log ("glfs", GF_LOG_ERROR,
|
||||
"master xlator for %s initialization failed",
|
||||
fs->volname);
|
||||
goto err;
|
||||
}
|
||||
|
||||
master->ctx = fs->ctx;
|
||||
master->private = fs;
|
||||
master->options = get_new_dict ();
|
||||
if (!master->options)
|
||||
goto err;
|
||||
|
||||
|
||||
ret = xlator_init (master);
|
||||
if (ret) {
|
||||
gf_log ("glfs", GF_LOG_ERROR,
|
||||
"failed to initialize gfapi translator");
|
||||
goto err;
|
||||
}
|
||||
|
||||
fs->ctx->master = master;
|
||||
THIS = master;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (master) {
|
||||
xlator_destroy (master);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static FILE *
|
||||
get_volfp (struct glfs *fs)
|
||||
{
|
||||
int ret = 0;
|
||||
cmd_args_t *cmd_args = NULL;
|
||||
FILE *specfp = NULL;
|
||||
struct stat statbuf;
|
||||
|
||||
cmd_args = &fs->ctx->cmd_args;
|
||||
|
||||
ret = lstat (cmd_args->volfile, &statbuf);
|
||||
if (ret == -1) {
|
||||
gf_log ("glfs", GF_LOG_ERROR,
|
||||
"%s: %s", cmd_args->volfile, strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((specfp = fopen (cmd_args->volfile, "r")) == NULL) {
|
||||
gf_log ("glfs", GF_LOG_ERROR,
|
||||
"volume file %s: %s",
|
||||
cmd_args->volfile,
|
||||
strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gf_log ("glfs", GF_LOG_DEBUG,
|
||||
"loading volume file %s", cmd_args->volfile);
|
||||
|
||||
return specfp;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_volumes_init (struct glfs *fs)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
cmd_args_t *cmd_args = NULL;
|
||||
int ret = 0;
|
||||
|
||||
cmd_args = &fs->ctx->cmd_args;
|
||||
|
||||
if (!vol_assigned (cmd_args))
|
||||
return -1;
|
||||
|
||||
if (cmd_args->volfile_server) {
|
||||
ret = glfs_mgmt_init (fs);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fp = get_volfp (fs);
|
||||
|
||||
if (!fp) {
|
||||
gf_log ("glfs", GF_LOG_ERROR,
|
||||
"Cannot reach volume specification file");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = glfs_process_volfp (fs, fp);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
struct glfs *
|
||||
glfs_from_glfd (struct glfs_fd *glfd)
|
||||
{
|
||||
return ((xlator_t *)glfd->fd->inode->table->xl->ctx->master)->private;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
glfs_fd_destroy (struct glfs_fd *glfd)
|
||||
{
|
||||
if (!glfd)
|
||||
return;
|
||||
if (glfd->fd)
|
||||
fd_unref (glfd->fd);
|
||||
GF_FREE (glfd);
|
||||
}
|
||||
|
||||
|
||||
xlator_t *
|
||||
glfs_fd_subvol (struct glfs_fd *glfd)
|
||||
{
|
||||
xlator_t *subvol = NULL;
|
||||
|
||||
if (!glfd)
|
||||
return NULL;
|
||||
|
||||
subvol = glfd->fd->inode->table->xl;
|
||||
|
||||
return subvol;
|
||||
}
|
||||
|
||||
|
||||
xlator_t *
|
||||
glfs_active_subvol (struct glfs *fs)
|
||||
{
|
||||
xlator_t *subvol = NULL;
|
||||
inode_table_t *itable = NULL;
|
||||
|
||||
pthread_mutex_lock (&fs->mutex);
|
||||
{
|
||||
while (!fs->init)
|
||||
pthread_cond_wait (&fs->cond, &fs->mutex);
|
||||
|
||||
subvol = fs->active_subvol;
|
||||
}
|
||||
pthread_mutex_unlock (&fs->mutex);
|
||||
|
||||
if (!subvol)
|
||||
return NULL;
|
||||
|
||||
if (!subvol->itable) {
|
||||
itable = inode_table_new (0, subvol);
|
||||
if (!itable) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subvol->itable = itable;
|
||||
|
||||
glfs_first_lookup (subvol);
|
||||
}
|
||||
|
||||
return subvol;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
glfs_poller (void *data)
|
||||
{
|
||||
struct glfs *fs = NULL;
|
||||
|
||||
fs = data;
|
||||
|
||||
event_dispatch (fs->ctx->event_pool);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct glfs *
|
||||
glfs_new (const char *volname)
|
||||
{
|
||||
struct glfs *fs = NULL;
|
||||
int ret = -1;
|
||||
glusterfs_ctx_t *ctx = NULL;
|
||||
|
||||
/* first globals init, for gf_mem_acct_enable_set () */
|
||||
ret = glusterfs_globals_init ();
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
ctx = glusterfs_ctx_new ();
|
||||
if (!ctx) {
|
||||
return NULL;
|
||||
}
|
||||
THIS->ctx = ctx;
|
||||
|
||||
/* then ctx_defaults_init, for xlator_mem_acct_init(THIS) */
|
||||
ret = glusterfs_ctx_defaults_init (ctx);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
fs = GF_CALLOC (1, sizeof (*fs), glfs_mt_glfs_t);
|
||||
if (!fs)
|
||||
return NULL;
|
||||
fs->ctx = ctx;
|
||||
|
||||
glfs_set_logging (fs, "/dev/null", 0);
|
||||
|
||||
fs->ctx->cmd_args.volfile_id = gf_strdup (volname);
|
||||
|
||||
fs->volname = gf_strdup (volname);
|
||||
|
||||
pthread_mutex_init (&fs->mutex, NULL);
|
||||
pthread_cond_init (&fs->cond, NULL);
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_set_volfile (struct glfs *fs, const char *volfile)
|
||||
{
|
||||
cmd_args_t *cmd_args = NULL;
|
||||
|
||||
cmd_args = &fs->ctx->cmd_args;
|
||||
|
||||
if (vol_assigned (cmd_args))
|
||||
return -1;
|
||||
|
||||
cmd_args->volfile = gf_strdup (volfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_set_volfile_server (struct glfs *fs, const char *transport,
|
||||
const char *host, int port)
|
||||
{
|
||||
cmd_args_t *cmd_args = NULL;
|
||||
|
||||
cmd_args = &fs->ctx->cmd_args;
|
||||
|
||||
if (vol_assigned (cmd_args))
|
||||
return -1;
|
||||
|
||||
cmd_args->volfile_server = gf_strdup (host);
|
||||
cmd_args->volfile_server_transport = gf_strdup (transport);
|
||||
cmd_args->max_connect_attempts = 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_set_logging (struct glfs *fs, const char *logfile, int loglevel)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = gf_log_init (logfile);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
gf_log_set_loglevel (loglevel);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_init_wait (struct glfs *fs)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
pthread_mutex_lock (&fs->mutex);
|
||||
{
|
||||
while (!fs->init)
|
||||
pthread_cond_wait (&fs->cond,
|
||||
&fs->mutex);
|
||||
ret = fs->ret;
|
||||
}
|
||||
pthread_mutex_unlock (&fs->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
glfs_init_done (struct glfs *fs, int ret)
|
||||
{
|
||||
if (fs->init_cbk) {
|
||||
fs->init_cbk (fs, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock (&fs->mutex);
|
||||
{
|
||||
fs->init = 1;
|
||||
fs->ret = ret;
|
||||
|
||||
pthread_cond_broadcast (&fs->cond);
|
||||
}
|
||||
pthread_mutex_unlock (&fs->mutex);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_init_common (struct glfs *fs)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = create_master (fs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pthread_create (&fs->poller, NULL, glfs_poller, fs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = glfs_volumes_init (fs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_init_async (struct glfs *fs, glfs_init_cbk cbk)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
fs->init_cbk = cbk;
|
||||
|
||||
ret = glfs_init_common (fs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_init (struct glfs *fs)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = glfs_init_common (fs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = glfs_init_wait (fs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_fini (struct glfs *fs)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
366
api/src/glfs.h
Normal file
366
api/src/glfs.h
Normal file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
Copyright (c) 2012 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 _GLFS_H
|
||||
#define _GLFS_H
|
||||
|
||||
/*
|
||||
Enforce the following flags as libgfapi is built
|
||||
with them, and we want programs linking against them to also
|
||||
be built with these flags. This is necessary as it affects
|
||||
some of the structures defined in libc headers (like struct stat)
|
||||
and those definitions need to be consistently compiled in
|
||||
both the library and the application.
|
||||
*/
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
#ifndef __USE_FILE_OFFSET64
|
||||
#define __USE_FILE_OFFSET64
|
||||
#endif
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* The filesystem object. One object per 'virtual mount' */
|
||||
struct glfs;
|
||||
typedef struct glfs glfs_t;
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
|
||||
glfs_new: Create a new 'virtual mount' object.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This is most likely the very first function you will use. This function
|
||||
will create a new glfs_t (virtual mount) object in memory.
|
||||
|
||||
On this newly created glfs_t, you need to be either set a volfile path
|
||||
(glfs_set_volfile) or a volfile server (glfs_set_volfile_server).
|
||||
|
||||
The glfs_t object needs to be initialized with glfs_init() before you
|
||||
can start issuing file operations on it.
|
||||
|
||||
PARAMETERS
|
||||
|
||||
@volname: Name of the volume. This identifies the server-side volume and
|
||||
the fetched volfile (equivalent of --volfile-id command line
|
||||
parameter to glusterfsd). When used with glfs_set_volfile() the
|
||||
@volname has no effect (except for appearing in log messages).
|
||||
|
||||
RETURN VALUES
|
||||
|
||||
NULL : Out of memory condition.
|
||||
Others : Pointer to the newly created glfs_t virtual mount object.
|
||||
|
||||
*/
|
||||
|
||||
glfs_t *glfs_new (const char *volname);
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
|
||||
glfs_set_volfile: Specify the path to the volume specification file.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
If you are using a static volume specification file (without dynamic
|
||||
volume management abilities from the CLI), then specify the path to
|
||||
the volume specification file.
|
||||
|
||||
This is incompatible with glfs_set_volfile_server().
|
||||
|
||||
PARAMETERS
|
||||
|
||||
@fs: The 'virtual mount' object to be configured with the volume
|
||||
specification file.
|
||||
|
||||
@volfile: Path to the locally available volume specification file.
|
||||
|
||||
RETURN VALUES
|
||||
|
||||
0 : Success.
|
||||
-1 : Failure. @errno will be set with the type of failure.
|
||||
|
||||
*/
|
||||
|
||||
int glfs_set_volfile (glfs_t *fs, const char *volfile);
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
|
||||
glfs_set_volfile_server: Specify the address of management server.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This function specifies the address of the management server (glusterd)
|
||||
to connect, and establish the volume configuration. The @volname
|
||||
parameter passed to glfs_new() is the volume which will be virtually
|
||||
mounted as the glfs_t object. All operations performed by the CLI at
|
||||
the management server will automatically be reflected in the 'virtual
|
||||
mount' object as it maintains a connection to glusterd and polls on
|
||||
configuration change notifications.
|
||||
|
||||
This is incompatible with glfs_set_volfile().
|
||||
|
||||
PARAMETERS
|
||||
|
||||
@fs: The 'virtual mount' object to be configured with the volume
|
||||
specification file.
|
||||
|
||||
@transport: String specifying the transport used to connect to the
|
||||
management daemon. Specifying NULL will result in the usage
|
||||
of the default (socket) transport type. Permitted values
|
||||
are those what you specify as transport-type in a volume
|
||||
specification file (e.g "socket", "rdma", "unix".)
|
||||
|
||||
@host: String specifying the address of where to find the management
|
||||
daemon. Depending on the transport type this would either be
|
||||
an FQDN (e.g: "storage01.company.com"), ASCII encoded IP
|
||||
address "192.168.22.1", or a UNIX domain socket path (e.g
|
||||
"/tmp/glusterd.socket".)
|
||||
|
||||
@port: The TCP port number where gluster management daemon is listening.
|
||||
Specifying 0 uses the default port number GF_DEFAULT_BASE_PORT.
|
||||
This parameter is unused if you are using a UNIX domain socket.
|
||||
|
||||
RETURN VALUES
|
||||
|
||||
0 : Success.
|
||||
-1 : Failure. @errno will be set with the type of failure.
|
||||
|
||||
*/
|
||||
|
||||
int glfs_set_volfile_server (glfs_t *fs, const char *transport,
|
||||
const char *host, int port);
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
|
||||
glfs_set_logging: Specify logging parameters.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This function specifies logging parameters for the virtual mount.
|
||||
Default log file is /dev/null.
|
||||
|
||||
PARAMETERS
|
||||
|
||||
@fs: The 'virtual mount' object to be configured with the logging parameters.
|
||||
|
||||
@logfile: The logfile to be used for logging. Will be created if it does not
|
||||
already exist (provided system permissions allow.)
|
||||
|
||||
@loglevel: Numerical value specifying the degree of verbosity. Higher the
|
||||
value, more verbose the logging.
|
||||
|
||||
RETURN VALUES
|
||||
|
||||
0 : Success.
|
||||
-1 : Failure. @errno will be set with the type of failure.
|
||||
|
||||
*/
|
||||
|
||||
int glfs_set_logging (glfs_t *fs, const char *logfile, int loglevel);
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
|
||||
glfs_init: Initialize the 'virtual mount'
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This function initializes the glfs_t object. This consists of many steps:
|
||||
- Spawn a poll-loop thread.
|
||||
- Establish connection to management daemon and receive volume specification.
|
||||
- Construct translator graph and initialize graph.
|
||||
- Wait for initialization (connecting to all bricks) to complete.
|
||||
|
||||
PARAMETERS
|
||||
|
||||
@fs: The 'virtual mount' object to be initialized.
|
||||
|
||||
RETURN VALUES
|
||||
|
||||
0 : Success.
|
||||
-1 : Failure. @errno will be set with the type of failure.
|
||||
|
||||
*/
|
||||
|
||||
int glfs_init (glfs_t *fs);
|
||||
|
||||
|
||||
int glfs_fini (glfs_t *fs);
|
||||
|
||||
/*
|
||||
* FILE OPERATION
|
||||
*
|
||||
* What follows are filesystem operations performed on the
|
||||
* 'virtual mount'. The calls here are kept as close to
|
||||
* the POSIX system calls as possible.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* - All paths specified, even if absolute, are relative to the
|
||||
* root of the virtual mount and not the system root (/).
|
||||
*
|
||||
*/
|
||||
|
||||
/* The file descriptor object. One per open file/directory. */
|
||||
|
||||
struct glfs_fd;
|
||||
typedef struct glfs_fd glfs_fd_t;
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
|
||||
glfs_open: Open a file.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This function opens a file on a virtual mount.
|
||||
|
||||
PARAMETERS
|
||||
|
||||
@fs: The 'virtual mount' object to be initialized.
|
||||
|
||||
@path: Path of the file within the virtual mount.
|
||||
|
||||
@flags: Open flags. See open(2). O_CREAT is not supported.
|
||||
Use glfs_creat() for creating files.
|
||||
|
||||
RETURN VALUES
|
||||
|
||||
NULL : Failure. @errno will be set with the type of failure.
|
||||
Others : Pointer to the opened glfs_fd_t.
|
||||
|
||||
*/
|
||||
|
||||
glfs_fd_t *glfs_open (glfs_t *fs, const char *path, int flags);
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
|
||||
glfs_creat: Create a file.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This function opens a file on a virtual mount.
|
||||
|
||||
PARAMETERS
|
||||
|
||||
@fs: The 'virtual mount' object to be initialized.
|
||||
|
||||
@path: Path of the file within the virtual mount.
|
||||
|
||||
@mode: Permission of the file to be created.
|
||||
|
||||
@flags: Create flags. See open(2). O_EXCL is supported.
|
||||
|
||||
RETURN VALUES
|
||||
|
||||
NULL : Failure. @errno will be set with the type of failure.
|
||||
Others : Pointer to the opened glfs_fd_t.
|
||||
|
||||
*/
|
||||
|
||||
glfs_fd_t *glfs_creat (glfs_t *fs, const char *path, int flags,
|
||||
mode_t mode);
|
||||
|
||||
int glfs_close (glfs_fd_t *fd);
|
||||
|
||||
glfs_t *glfs_from_glfd (glfs_fd_t *fd);
|
||||
|
||||
typedef void (*glfs_io_cbk) (glfs_fd_t *fd, ssize_t ret, void *data);
|
||||
|
||||
// glfs_{read,write}[_async]
|
||||
|
||||
ssize_t glfs_read (glfs_fd_t *fd, void *buf, size_t count, int flags);
|
||||
ssize_t glfs_write (glfs_fd_t *fd, const void *buf, size_t count, int flags);
|
||||
int glfs_read_async (glfs_fd_t *fd, void *buf, size_t count, int flags,
|
||||
glfs_io_cbk fn, void *data);
|
||||
int glfs_write_async (glfs_fd_t *fd, const void *buf, size_t count, int flags,
|
||||
glfs_io_cbk fn, void *data);
|
||||
|
||||
// glfs_{read,write}v[_async]
|
||||
|
||||
ssize_t glfs_readv (glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
|
||||
int flags);
|
||||
ssize_t glfs_writev (glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
|
||||
int flags);
|
||||
int glfs_readv_async (glfs_fd_t *fd, const struct iovec *iov, int count,
|
||||
int flags, glfs_io_cbk fn, void *data);
|
||||
int glfs_writev_async (glfs_fd_t *fd, const struct iovec *iov, int count,
|
||||
int flags, glfs_io_cbk fn, void *data);
|
||||
|
||||
// glfs_p{read,write}[_async]
|
||||
|
||||
ssize_t glfs_pread (glfs_fd_t *fd, void *buf, size_t count, off_t offset,
|
||||
int flags);
|
||||
ssize_t glfs_pwrite (glfs_fd_t *fd, const void *buf, size_t count,
|
||||
off_t offset, int flags);
|
||||
int glfs_pread_async (glfs_fd_t *fd, void *buf, size_t count, off_t offset,
|
||||
int flags, glfs_io_cbk fn, void *data);
|
||||
int glfs_pwrite_async (glfs_fd_t *fd, const void *buf, int count, off_t offset,
|
||||
int flags, glfs_io_cbk fn, void *data);
|
||||
|
||||
// glfs_p{read,write}v[_async]
|
||||
|
||||
ssize_t glfs_preadv (glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
|
||||
off_t offset, int flags);
|
||||
ssize_t glfs_pwritev (glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
|
||||
off_t offset, int flags);
|
||||
int glfs_preadv_async (glfs_fd_t *fd, const struct iovec *iov, int count,
|
||||
off_t offset, int flags, glfs_io_cbk fn, void *data);
|
||||
int glfs_pwritev_async (glfs_fd_t *fd, const struct iovec *iov, int count,
|
||||
off_t offset, int flags, glfs_io_cbk fn, void *data);
|
||||
|
||||
|
||||
off_t glfs_lseek (glfs_fd_t *fd, off_t offset, int whence);
|
||||
|
||||
int glfs_truncate (glfs_t *fs, const char *path, off_t length);
|
||||
|
||||
int glfs_ftruncate (glfs_fd_t *fd, off_t length);
|
||||
int glfs_ftruncate_async (glfs_fd_t *fd, off_t length, glfs_io_cbk fn,
|
||||
void *data);
|
||||
|
||||
int glfs_lstat (glfs_t *fs, const char *path, struct stat *buf);
|
||||
int glfs_fstat (glfs_fd_t *fd, struct stat *buf);
|
||||
|
||||
int glfs_fsync (glfs_fd_t *fd);
|
||||
int glfs_fsync_async (glfs_fd_t *fd, glfs_io_cbk fn, void *data);
|
||||
|
||||
int glfs_fdatasync (glfs_fd_t *fd);
|
||||
int glfs_fdatasync_async (glfs_fd_t *fd, glfs_io_cbk fn, void *data);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_GLFS_H */
|
@ -142,6 +142,8 @@ AC_CONFIG_FILES([Makefile
|
||||
xlators/mgmt/Makefile
|
||||
xlators/mgmt/glusterd/Makefile
|
||||
xlators/mgmt/glusterd/src/Makefile
|
||||
api/Makefile
|
||||
api/src/Makefile
|
||||
glusterfs.spec])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
Loading…
Reference in New Issue
Block a user