summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/bugs/read-only/bug-1134822-read-only-default-in-graph.t67
-rw-r--r--xlators/features/read-only/src/Makefile.am2
-rw-r--r--xlators/features/read-only/src/read-only-common.c255
-rw-r--r--xlators/features/read-only/src/read-only-common.h3
-rw-r--r--xlators/features/read-only/src/read-only-mem-types.h20
-rw-r--r--xlators/features/read-only/src/read-only.c68
-rw-r--r--xlators/features/read-only/src/read-only.h21
-rw-r--r--xlators/features/read-only/src/worm.c68
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c31
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c5
10 files changed, 468 insertions, 72 deletions
diff --git a/tests/bugs/read-only/bug-1134822-read-only-default-in-graph.t b/tests/bugs/read-only/bug-1134822-read-only-default-in-graph.t
new file mode 100644
index 0000000..cc27d04
--- /dev/null
+++ b/tests/bugs/read-only/bug-1134822-read-only-default-in-graph.t
@@ -0,0 +1,67 @@
+#!/bin/bash
+
+#Test case: This test checks when a volume is made read-only though volume set
+# and bricks are not restarted no write operations can be performed on
+# this volume
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+
+#Create a volume
+TEST $CLI volume create $V0 $H0:$B0/${V0}0;
+TEST $CLI volume start $V0
+
+# Mount FUSE and create file/directory, create should succeed as the read-only
+# is off by default
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
+TEST touch $M0/zerobytefile1.txt
+TEST mkdir $M0/test_dir1
+TEST dd if=/dev/zero of=$M0/file1 bs=1024 count=1024
+
+# turn on read-only option through volume set
+TEST gluster volume set $V0 read-only on
+
+# worm feature can't be enabled if read-only is enabled
+TEST ! gluster volume set $V0 worm on
+
+# turn off read-only option through volume set
+TEST gluster volume set $V0 read-only off
+
+# turn on worm option through volume set
+TEST gluster volume set $V0 worm on
+
+# read-only feature can't be enabled if worm is enabled
+TEST ! gluster volume set $V0 read-only on
+
+
+TEST gluster volume set $V0 worm off
+TEST gluster volume set $V0 read-only on
+
+# Check whether read-operations can be performed or not
+TEST cat $M0/file1
+
+# All write operations should fail now
+TEST ! touch $M0/zerobytefile2.txt
+TEST ! mkdir $M0/test_dir2
+TEST ! dd if=/dev/zero of=$M0/file2 bs=1024 count=1024
+
+# turn off read-only option through volume set
+TEST gluster volume set $V0 read-only off
+
+# All write operations should succeed now
+TEST touch $M0/zerobytefile2.txt
+TEST mkdir $M0/test_dir2
+TEST dd if=/dev/zero of=$M0/file2 bs=1024 count=1024
+
+# Turn on worm
+TEST gluster volume set $V0 worm on
+
+# unlink should fail now
+TEST ! rm -rf $M0/zerobytefile2.txt
+
+cleanup;
diff --git a/xlators/features/read-only/src/Makefile.am b/xlators/features/read-only/src/Makefile.am
index 4c14621..209e420 100644
--- a/xlators/features/read-only/src/Makefile.am
+++ b/xlators/features/read-only/src/Makefile.am
@@ -2,7 +2,7 @@ xlator_LTLIBRARIES = read-only.la worm.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-noinst_HEADERS = read-only-common.h
+noinst_HEADERS = read-only.h read-only-mem-types.h read-only-common.h
read_only_la_LDFLAGS = -module -avoid-version
diff --git a/xlators/features/read-only/src/read-only-common.c b/xlators/features/read-only/src/read-only-common.c
index 56a7a71..39937d1 100644
--- a/xlators/features/read-only/src/read-only-common.c
+++ b/xlators/features/read-only/src/read-only-common.c
@@ -12,14 +12,34 @@
#include "config.h"
#endif
-#include "xlator.h"
+#include "read-only.h"
+#include "read-only-mem-types.h"
#include "defaults.h"
+gf_boolean_t
+is_readonly_or_worm_enabled (xlator_t *this)
+{
+ read_only_priv_t *priv = NULL;
+ gf_boolean_t readonly_or_worm_enabled = _gf_false;
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ readonly_or_worm_enabled = priv->readonly_or_worm_enabled;
+
+ return readonly_or_worm_enabled;
+}
+
int32_t
ro_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
- STACK_UNWIND_STRICT (xattrop, frame, -1, EROFS, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (xattrop, frame, -1, EROFS, NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->xattrop,
+ loc, flags, dict, xdata);
return 0;
}
@@ -27,7 +47,13 @@ int32_t
ro_fxattrop (call_frame_t *frame, xlator_t *this,
fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
- STACK_UNWIND_STRICT (fxattrop, frame, -1, EROFS, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, EROFS, NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->fxattrop,
+ fd, flags, dict, xdata);
+
return 0;
}
@@ -36,15 +62,28 @@ ro_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
loc_t *loc, const char *basename, entrylk_cmd cmd,
entrylk_type type, dict_t *xdata)
{
- STACK_UNWIND_STRICT (entrylk, frame, -1, EROFS, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (entrylk, frame, -1, EROFS, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->entrylk,
+ volume, loc, basename, cmd, type, xdata);
+
return 0;
}
int32_t
ro_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+ fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fentrylk, frame, -1, EROFS, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, EROFS, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->fentrylk,
+ volume, fd, basename, cmd, type, xdata);
+
return 0;
}
@@ -52,7 +91,13 @@ int32_t
ro_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
- STACK_UNWIND_STRICT (inodelk, frame, -1, EROFS, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (inodelk, frame, -1, EROFS, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->inodelk,
+ volume, loc, cmd, lock, xdata);
+
return 0;
}
@@ -60,7 +105,13 @@ int32_t
ro_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
- STACK_UNWIND_STRICT (finodelk, frame, -1, EROFS, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (finodelk, frame, -1, EROFS, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->finodelk,
+ volume, fd, cmd, lock, xdata);
+
return 0;
}
@@ -68,7 +119,13 @@ int32_t
ro_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd,
struct gf_flock *flock, dict_t *xdata)
{
- STACK_UNWIND_STRICT (lk, frame, -1, EROFS, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (lk, frame, -1, EROFS, NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->lk, fd, cmd, flock,
+ xdata);
+
return 0;
}
@@ -76,15 +133,29 @@ int32_t
ro_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
struct iatt *stbuf, int32_t valid, dict_t *xdata)
{
- STACK_UNWIND_STRICT (setattr, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (setattr, frame, -1, EROFS, NULL, NULL,
+ xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->setattr, loc, stbuf,
+ valid, xdata);
+
+ return 0;
}
int32_t
ro_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iatt *stbuf, int32_t valid, dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsetattr, frame, -1, EROFS, NULL, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, EROFS, NULL, NULL,
+ xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->fsetattr, fd, stbuf,
+ valid, xdata);
+
return 0;
}
@@ -92,14 +163,28 @@ ro_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
ro_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata)
{
- STACK_UNWIND_STRICT (truncate, frame, -1, EROFS, NULL, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (truncate, frame, -1, EROFS, NULL, NULL,
+ xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->truncate, loc, offset,
+ xdata);
+
return 0;
}
int32_t
ro_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata)
{
- STACK_UNWIND_STRICT (ftruncate, frame, -1, EROFS, NULL, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, EROFS, NULL, NULL,
+ xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset,
+ xdata);
+
return 0;
}
@@ -107,8 +192,15 @@ int
ro_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
dev_t rdev, mode_t umask, dict_t *xdata)
{
- STACK_UNWIND_STRICT (mknod, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata);
- return 0;
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (mknod, frame, -1, EROFS, NULL, NULL, NULL,
+ NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->mknod, loc, mode,
+ rdev, umask, xdata);
+
+ return 0;
}
@@ -116,7 +208,14 @@ int
ro_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
mode_t umask, dict_t *xdata)
{
- STACK_UNWIND_STRICT (mkdir, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (mkdir, frame, -1, EROFS, NULL, NULL, NULL,
+ NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->mkdir, loc, mode,
+ umask, xdata);
+
return 0;
}
@@ -124,7 +223,14 @@ int32_t
ro_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
dict_t *xdata)
{
- STACK_UNWIND_STRICT (unlink, frame, -1, EROFS, NULL, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (unlink, frame, -1, EROFS, NULL, NULL,
+ xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->unlink, loc, xflag,
+ xdata);
+
return 0;
}
@@ -133,7 +239,14 @@ int
ro_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
dict_t *xdata)
{
- STACK_UNWIND_STRICT (rmdir, frame, -1, EROFS, NULL, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (rmdir, frame, -1, EROFS, NULL, NULL,
+ xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->rmdir, loc, flags,
+ xdata);
+
return 0;
}
@@ -142,18 +255,31 @@ int
ro_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
loc_t *loc, mode_t umask, dict_t *xdata)
{
- STACK_UNWIND_STRICT (symlink, frame, -1, EROFS, NULL, NULL, NULL,
- NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (symlink, frame, -1, EROFS, NULL, NULL,
+ NULL, NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->symlink, linkpath,
+ loc, umask, xdata);
+
return 0;
}
int32_t
-ro_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ro_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (rename, frame, -1, EROFS, NULL, NULL, NULL, NULL,
- NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (rename, frame, -1, EROFS, NULL, NULL, NULL,
+ NULL, NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->rename, oldloc,
+ newloc, xdata);
+
return 0;
}
@@ -161,7 +287,14 @@ ro_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, di
int32_t
ro_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata)
{
- STACK_UNWIND_STRICT (link, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (link, frame, -1, EROFS, NULL, NULL, NULL,
+ NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->link, oldloc, newloc,
+ xdata);
+
return 0;
}
@@ -169,8 +302,14 @@ int32_t
ro_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
{
- STACK_UNWIND_STRICT (create, frame, -1, EROFS, NULL, NULL, NULL,
- NULL, NULL, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (create, frame, -1, EROFS, NULL, NULL, NULL,
+ NULL, NULL, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->create, loc, flags,
+ mode, umask, fd, xdata);
+
return 0;
}
@@ -179,16 +318,17 @@ static int32_t
ro_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
int32_t op_errno, fd_t *fd, dict_t *xdata)
{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
- return 0;
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ return 0;
}
int32_t
ro_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
fd_t *fd, dict_t *xdata)
{
- if (((flags & O_ACCMODE) == O_WRONLY) ||
- ((flags & O_ACCMODE) == O_RDWR)) {
+ if (is_readonly_or_worm_enabled (this) &&
+ (((flags & O_ACCMODE) == O_WRONLY) ||
+ ((flags & O_ACCMODE) == O_RDWR))) {
STACK_UNWIND_STRICT (open, frame, -1, EROFS, NULL, xdata);
return 0;
}
@@ -202,23 +342,44 @@ int32_t
ro_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
int32_t flags, dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, EROFS, xdata);
- return 0;
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, EROFS, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->fsetxattr, fd, dict,
+ flags, xdata);
+
+ return 0;
}
int32_t
-ro_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
+ro_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, EROFS, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, EROFS, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->fsyncdir, fd, flags,
+ xdata);
+
return 0;
}
int32_t
ro_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
- int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ int32_t count, off_t off, uint32_t flags, struct iobref *iobref,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (writev, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (writev, frame, -1, EROFS, NULL, NULL,
+ xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->writev, fd, vector,
+ count, off, flags, iobref, xdata);
+
+ return 0;
}
@@ -226,14 +387,26 @@ int32_t
ro_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
int32_t flags, dict_t *xdata)
{
- STACK_UNWIND_STRICT (setxattr, frame, -1, EROFS, xdata);
- return 0;
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (setxattr, frame, -1, EROFS, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->setxattr, loc, dict,
+ flags, xdata);
+
+ return 0;
}
int32_t
ro_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
{
- STACK_UNWIND_STRICT (removexattr, frame, -1, EROFS, xdata);
+ if (is_readonly_or_worm_enabled (this))
+ STACK_UNWIND_STRICT (removexattr, frame, -1, EROFS, xdata);
+ else
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->removexattr, loc,
+ name, xdata);
+
return 0;
}
diff --git a/xlators/features/read-only/src/read-only-common.h b/xlators/features/read-only/src/read-only-common.h
index 5d4c7e2..c99ba03 100644
--- a/xlators/features/read-only/src/read-only-common.h
+++ b/xlators/features/read-only/src/read-only-common.h
@@ -15,6 +15,9 @@
#include "xlator.h"
#include "defaults.h"
+gf_boolean_t
+is_readonly_or_worm_enabled (xlator_t *this);
+
int32_t
ro_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata);
diff --git a/xlators/features/read-only/src/read-only-mem-types.h b/xlators/features/read-only/src/read-only-mem-types.h
new file mode 100644
index 0000000..940700a
--- /dev/null
+++ b/xlators/features/read-only/src/read-only-mem-types.h
@@ -0,0 +1,20 @@
+/*
+ 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 __READONLY_MEM_TYPES_H__
+#define __READONLY_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_read_only_mem_types_ {
+ gf_read_only_mt_priv_t = gf_common_mt_end + 1,
+ gf_read_only_mt_end
+};
+#endif
diff --git a/xlators/features/read-only/src/read-only.c b/xlators/features/read-only/src/read-only.c
index e49e54a..173c4f5 100644
--- a/xlators/features/read-only/src/read-only.c
+++ b/xlators/features/read-only/src/read-only.c
@@ -12,14 +12,31 @@
#include "config.h"
#endif
-#include "xlator.h"
#include "defaults.h"
#include "read-only-common.h"
+#include "read-only-mem-types.h"
+#include "read-only.h"
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ ret = xlator_mem_acct_init (this, gf_read_only_mt_end + 1);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting "
+ "initialization failed.");
+
+ return ret;
+}
int32_t
init (xlator_t *this)
{
- if (!this->children || this->children->next) {
+ int ret = -1;
+ read_only_priv_t *priv = NULL;
+
+ if (!this->children || this->children->next) {
gf_log (this->name, GF_LOG_ERROR,
"translator not configured with exactly one child");
return -1;
@@ -30,14 +47,50 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- return 0;
+ priv = GF_CALLOC (1, sizeof (*priv), gf_read_only_mt_priv_t);
+ if (!priv)
+ goto out;
+
+ GF_OPTION_INIT ("read-only", priv->readonly_or_worm_enabled, bool, out);
+
+ this->private = priv;
+ ret = 0;
+out:
+ return ret;
}
+int
+reconfigure (xlator_t *this, dict_t *options)
+{
+ read_only_priv_t *priv = NULL;
+ int ret = -1;
+ gf_boolean_t readonly_or_worm_enabled = _gf_false;
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ GF_OPTION_RECONF ("read-only", readonly_or_worm_enabled, options, bool,
+ out);
+ priv->readonly_or_worm_enabled = readonly_or_worm_enabled;
+ ret = 0;
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
void
fini (xlator_t *this)
{
- return;
+ read_only_priv_t *priv = NULL;
+
+ priv = this->private;
+ if (!priv)
+ return;
+
+ this->private = NULL;
+ GF_FREE (priv);
+
+ return;
}
@@ -73,5 +126,10 @@ struct xlator_cbks cbks = {
};
struct volume_options options[] = {
- { .key = {NULL} },
+ { .key = {"read-only"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "When \"on\", makes a volume read-only. It is turned "
+ "\"off\" by default."
+ },
};
diff --git a/xlators/features/read-only/src/read-only.h b/xlators/features/read-only/src/read-only.h
new file mode 100644
index 0000000..8e7e1b6
--- /dev/null
+++ b/xlators/features/read-only/src/read-only.h
@@ -0,0 +1,21 @@
+/*
+ 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 __READONLY_H__
+#define __READONLY_H__
+
+#include "read-only-mem-types.h"
+#include "xlator.h"
+
+typedef struct {
+ gf_boolean_t readonly_or_worm_enabled;
+} read_only_priv_t;
+
+#endif
diff --git a/xlators/features/read-only/src/worm.c b/xlators/features/read-only/src/worm.c
index 16c3eb3..f62ffa3 100644
--- a/xlators/features/read-only/src/worm.c
+++ b/xlators/features/read-only/src/worm.c
@@ -15,6 +15,21 @@
#include "xlator.h"
#include "defaults.h"
#include "read-only-common.h"
+#include "read-only-mem-types.h"
+#include "read-only.h"
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ ret = xlator_mem_acct_init (this, gf_read_only_mt_end + 1);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting "
+ "initialization failed.");
+
+ return ret;
+}
static int32_t
worm_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
@@ -28,9 +43,10 @@ int32_t
worm_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
fd_t *fd, dict_t *xdata)
{
- if ((((flags & O_ACCMODE) == O_WRONLY) ||
+ if (is_readonly_or_worm_enabled (this) &&
+ ((((flags & O_ACCMODE) == O_WRONLY) ||
((flags & O_ACCMODE) == O_RDWR)) &&
- !(flags & O_APPEND)) {
+ !(flags & O_APPEND))) {
STACK_UNWIND_STRICT (open, frame, -1, EROFS, NULL, NULL);
return 0;
}
@@ -43,6 +59,9 @@ worm_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
int32_t
init (xlator_t *this)
{
+ int ret = -1;
+ read_only_priv_t *priv = NULL;
+
if (!this->children || this->children->next) {
gf_log (this->name, GF_LOG_ERROR,
"translator not configured with exactly one child");
@@ -54,13 +73,49 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- return 0;
+ priv = GF_CALLOC (1, sizeof (*priv), gf_read_only_mt_priv_t);
+ if (!priv)
+ goto out;
+
+ GF_OPTION_INIT ("worm", priv->readonly_or_worm_enabled, bool, out);
+
+ this->private = priv;
+ ret = 0;
+out:
+ return ret;
}
+int
+reconfigure (xlator_t *this, dict_t *options)
+{
+ read_only_priv_t *priv = NULL;
+ int ret = -1;
+ gf_boolean_t readonly_or_worm_enabled = _gf_false;
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ GF_OPTION_RECONF ("worm", readonly_or_worm_enabled, options, bool, out);
+
+ priv->readonly_or_worm_enabled = readonly_or_worm_enabled;
+ ret = 0;
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
void
fini (xlator_t *this)
{
+ read_only_priv_t *priv = NULL;
+
+ priv = this->private;
+ if (!priv)
+ return;
+
+ this->private = NULL;
+ GF_FREE (priv);
+
return;
}
@@ -84,6 +139,11 @@ struct xlator_fops fops = {
struct xlator_cbks cbks;
struct volume_options options[] = {
- { .key = {NULL} },
+ { .key = {"worm"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "When \"on\", makes a volume get write once read many "
+ " feature. It is turned \"off\" by default."
+ },
};
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 3edd4e2..d770975 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -1852,15 +1852,12 @@ brick_graph_add_ro (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
goto out;
}
- /* Check for read-only volume option, and add it to the graph */
- if (dict_get_str_boolean (set_dict, "features.read-only", 0)){
- xl = volgen_graph_add (graph, "features/read-only",
- volinfo->volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
+ xl = volgen_graph_add (graph, "features/read-only", volinfo->volname);
+ if (!xl)
+ return -1;
+ ret = xlator_set_option (xl, "read-only", "off");
+ if (ret)
+ return -1;
ret = 0;
@@ -1886,15 +1883,9 @@ brick_graph_add_worm (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
goto out;
}
- /* Check for worm volume option, and add it to the graph */
- if (dict_get_str_boolean (set_dict, "features.worm", 0)) {
- xl = volgen_graph_add (graph, "features/worm",
- volinfo->volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
+ xl = volgen_graph_add (graph, "features/worm", volinfo->volname);
+ if (!xl)
+ return -1;
ret = 0;
@@ -3399,6 +3390,10 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
ret = -1;
goto out;
}
+ ret = xlator_set_option (xl, "read-only", "on");
+ if (ret)
+ goto out;
+
}
/* Check for compress volume option, and add it to the graph on client side */
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 1e2bbca..d95f1fc 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -1547,14 +1547,13 @@ struct volopt_map_entry glusterd_volopt_map[] = {
/* Other options which don't fit any place above */
{ .key = "features.read-only",
.voltype = "features/read-only",
- .option = "!read-only",
- .value = "off",
+ .option = "read-only",
.op_version = 1,
.flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
},
{ .key = "features.worm",
.voltype = "features/worm",
- .option = "!worm",
+ .option = "worm",
.value = "off",
.op_version = 2,
.flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT