summaryrefslogtreecommitdiffstats
path: root/cli/src/cli-cmd-misc.c
diff options
context:
space:
mode:
authorAmar Tumballi <amar@gluster.com>2010-10-04 11:01:14 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-10-04 09:48:47 -0700
commitbde5cb81e251032594e2bba57fb4a72c10e32207 (patch)
treeead19da09126011c7581f5ac99d5e6ed94a92efa /cli/src/cli-cmd-misc.c
parent98d51842863d52bab2674258c3ec12d668139539 (diff)
rpc: don't refer to 'req' after calling 'prog->actor()'
there are chances that a error reply is sent to client from actor, in which case, 'req' would be free'd and accessing it would result in error. Signed-off-by: Amar Tumballi <amar@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 1790 () URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1790
Diffstat (limited to 'cli/src/cli-cmd-misc.c')
0 files changed, 0 insertions, 0 deletions
ass='graph'>
-rw-r--r--booster/src/booster-fd.c6
-rw-r--r--booster/src/booster-fd.h6
-rw-r--r--booster/src/booster.c8
-rw-r--r--booster/src/booster_stat.c8
-rw-r--r--cli/src/Makefile.am8
-rw-r--r--cli/src/cli-cmd-misc.c12
-rw-r--r--cli/src/cli-cmd-parser.c1394
-rw-r--r--cli/src/cli-cmd-peer.c38
-rw-r--r--cli/src/cli-cmd-system.c126
-rw-r--r--cli/src/cli-cmd-volume.c1010
-rw-r--r--cli/src/cli-cmd.c41
-rw-r--r--cli/src/cli-cmd.h40
-rw-r--r--cli/src/cli-mem-types.h8
-rw-r--r--cli/src/cli-rl.c51
-rw-r--r--cli/src/cli-rpc-ops.c4700
-rw-r--r--cli/src/cli-xml-output.c2628
-rw-r--r--cli/src/cli.c339
-rw-r--r--cli/src/cli.h203
-rw-r--r--cli/src/input.c8
-rw-r--r--cli/src/registry.c62
-rwxr-xr-xcommit.sh4
-rw-r--r--configure.ac127
-rw-r--r--contrib/aclocal/mkdirp.m4146
-rw-r--r--contrib/aclocal/python.m4209
-rw-r--r--contrib/apple/daemon.c92
-rw-r--r--contrib/fuse-include/fuse-mount.h3
-rw-r--r--contrib/fuse-lib/misc.c2
-rw-r--r--contrib/fuse-lib/mount.c298
-rw-r--r--contrib/fuse-util/Makefile.am2
-rw-r--r--contrib/fuse-util/fusermount.c60
-rw-r--r--contrib/ipaddr-py/COPYING202
-rw-r--r--contrib/ipaddr-py/MANIFEST.in3
-rw-r--r--contrib/ipaddr-py/OWNERS4
-rw-r--r--contrib/ipaddr-py/README8
-rw-r--r--contrib/ipaddr-py/ipaddr.py1907
-rwxr-xr-xcontrib/ipaddr-py/ipaddr_test.py1099
-rwxr-xr-xcontrib/ipaddr-py/setup.py36
-rwxr-xr-xcontrib/ipaddr-py/test-2to3.sh15
-rw-r--r--contrib/libgen/basename_r.c40
-rw-r--r--contrib/libgen/dirname_r.c243
-rw-r--r--contrib/macfuse/mount_darwin.c3
-rw-r--r--contrib/md5/md5.c310
-rw-r--r--contrib/md5/md5.h78
-rw-r--r--contrib/rbtree/rb.c34
-rw-r--r--contrib/rbtree/rb.h36
-rw-r--r--contrib/stdlib/gf_mkostemp.c107
-rw-r--r--contrib/uuid/uuid_types.h.in (renamed from contrib/uuid/uuid_types.h)16
-rw-r--r--doc/Makefile.am14
-rw-r--r--doc/admin-guide/en-US/Administration_Guide.ent4
-rw-r--r--doc/admin-guide/en-US/Administration_Guide.xml27
-rw-r--r--doc/admin-guide/en-US/Author_Group.xml17
-rw-r--r--doc/admin-guide/en-US/Book_Info.xml28
-rw-r--r--doc/admin-guide/en-US/Chapter.xml33
-rw-r--r--doc/admin-guide/en-US/Preface.xml24
-rw-r--r--doc/admin-guide/en-US/Revision_History.xml27
-rw-r--r--doc/admin-guide/en-US/admin_ACLs.xml211
-rw-r--r--doc/admin-guide/en-US/admin_Hadoop.xml248
-rw-r--r--doc/admin-guide/en-US/admin_UFO.xml1580
-rw-r--r--doc/admin-guide/en-US/admin_commandref.xml336
-rw-r--r--doc/admin-guide/en-US/admin_console.xml29
-rw-r--r--doc/admin-guide/en-US/admin_directory_Quota.xml180
-rw-r--r--doc/admin-guide/en-US/admin_geo-replication.xml730
-rw-r--r--doc/admin-guide/en-US/admin_managing_volumes.xml742
-rw-r--r--doc/admin-guide/en-US/admin_monitoring_workload.xml878
-rw-r--r--doc/admin-guide/en-US/admin_setting_volumes.xml325
-rw-r--r--doc/admin-guide/en-US/admin_settingup_clients.xml412
-rw-r--r--doc/admin-guide/en-US/admin_start_stop_daemon.xml56
-rw-r--r--doc/admin-guide/en-US/admin_storage_pools.xml57
-rw-r--r--doc/admin-guide/en-US/admin_troubleshooting.xml508
-rw-r--r--doc/admin-guide/en-US/gfs_introduction.xml54
-rw-r--r--doc/admin-guide/en-US/glossary.xml126
-rw-r--r--doc/admin-guide/en-US/images/640px-GlusterFS_3.2_Architecture.pngbin0 -> 97477 bytes-rw-r--r--doc/admin-guide/en-US/images/Distributed_Replicated_Volume.pngbin0 -> 51326 bytes-rw-r--r--doc/admin-guide/en-US/images/Distributed_Striped_Replicated_Volume.pngbin0 -> 57210 bytes-rw-r--r--doc/admin-guide/en-US/images/Distributed_Striped_Volume.pngbin0 -> 53781 bytes-rw-r--r--doc/admin-guide/en-US/images/Distributed_Volume.pngbin0 -> 47211 bytes-rw-r--r--doc/admin-guide/en-US/images/Geo-Rep03_Internet.pngbin0 -> 131824 bytes-rw-r--r--doc/admin-guide/en-US/images/Geo-Rep04_Cascading.pngbin0 -> 187341 bytes-rw-r--r--doc/admin-guide/en-US/images/Geo-Rep_LAN.pngbin0 -> 163417 bytes-rw-r--r--doc/admin-guide/en-US/images/Geo-Rep_WAN.pngbin0 -> 96291 bytes-rw-r--r--doc/admin-guide/en-US/images/GlusterFS_3.2_Architecture.pngbin0 -> 133597 bytes-rw-r--r--doc/admin-guide/en-US/images/Hadoop_Architecture.pngbin0 -> 43815 bytes-rw-r--r--doc/admin-guide/en-US/images/Replicated_Volume.pngbin0 -> 44077 bytes-rw-r--r--doc/admin-guide/en-US/images/Striped_Replicated_Volume.pngbin0 -> 50193 bytes-rw-r--r--doc/admin-guide/en-US/images/Striped_Volume.pngbin0 -> 43316 bytes-rw-r--r--doc/admin-guide/en-US/images/UFO_Architecture.pngbin0 -> 72139 bytes-rw-r--r--doc/admin-guide/en-US/images/VSA_Architecture.pngbin0 -> 38875 bytes-rw-r--r--doc/admin-guide/en-US/images/arhitecture.png13
-rw-r--r--doc/admin-guide/en-US/images/icon.svg19
-rw-r--r--doc/admin-guide/publican.cfg12
-rw-r--r--doc/examples/Makefile.am8
-rw-r--r--doc/examples/io-threads.vol21
-rw-r--r--doc/examples/legacy/Makefile.am8
-rw-r--r--doc/examples/legacy/README (renamed from doc/examples/README)8
-rw-r--r--doc/examples/legacy/filter.vol (renamed from doc/examples/filter.vol)6
-rw-r--r--doc/examples/legacy/io-cache.vol (renamed from doc/examples/io-cache.vol)22
-rw-r--r--doc/examples/legacy/io-threads.vol22
-rw-r--r--doc/examples/legacy/posix-locks.vol (renamed from doc/examples/posix-locks.vol)7
-rw-r--r--doc/examples/legacy/protocol-client.vol12
-rw-r--r--doc/examples/legacy/protocol-server.vol (renamed from doc/examples/protocol-server.vol)16
-rw-r--r--doc/examples/legacy/read-ahead.vol (renamed from doc/examples/read-ahead.vol)14
-rw-r--r--doc/examples/legacy/replicate.vol (renamed from doc/examples/replicate.vol)17
-rw-r--r--doc/examples/legacy/stripe.vol (renamed from doc/examples/stripe.vol)17
-rw-r--r--doc/examples/legacy/trace.vol (renamed from doc/examples/trace.vol)11
-rw-r--r--doc/examples/legacy/trash.vol (renamed from doc/examples/trash.vol)8
-rw-r--r--doc/examples/legacy/write-behind.vol (renamed from doc/examples/write-behind.vol)15
-rw-r--r--doc/examples/protocol-client.vol17
-rw-r--r--doc/examples/unify.vol178
-rw-r--r--doc/gluster.8101
-rw-r--r--doc/glusterd.812
-rw-r--r--doc/glusterd.vol4
-rw-r--r--doc/glusterfs.881
-rw-r--r--doc/glusterfs.vol.sample22
-rw-r--r--doc/glusterfsd.820
-rw-r--r--doc/glusterfsd.vol.sample21
-rw-r--r--doc/legacy/authentication.txt (renamed from doc/authentication.txt)10
-rw-r--r--doc/legacy/booster.txt (renamed from doc/booster.txt)22
-rw-r--r--doc/legacy/coding-standard.pdf (renamed from doc/coding-standard.pdf)bin68627 -> 68627 bytes-rw-r--r--doc/legacy/coding-standard.tex (renamed from doc/coding-standard.tex)32
-rw-r--r--doc/legacy/errno.list.bsd.txt (renamed from doc/errno.list.bsd.txt)0
-rw-r--r--doc/legacy/errno.list.linux.txt (renamed from doc/errno.list.linux.txt)170
-rw-r--r--doc/legacy/errno.list.macosx.txt (renamed from doc/errno.list.macosx.txt)186
-rw-r--r--doc/legacy/errno.list.solaris.txt (renamed from doc/errno.list.solaris.txt)0
-rw-r--r--doc/legacy/get_put_api_using_xattr.txt (renamed from doc/get_put_api_using_xattr.txt)2
-rw-r--r--doc/legacy/hacker-guide/Makefile.am (renamed from doc/hacker-guide/Makefile.am)0
-rw-r--r--doc/legacy/hacker-guide/adding-fops.txt (renamed from doc/hacker-guide/adding-fops.txt)0
-rw-r--r--doc/legacy/hacker-guide/bdb.txt (renamed from doc/hacker-guide/bdb.txt)16
-rw-r--r--doc/legacy/hacker-guide/call-stub.txt (renamed from doc/hacker-guide/call-stub.txt)178
-rw-r--r--doc/legacy/hacker-guide/hacker-guide.tex (renamed from doc/hacker-guide/hacker-guide.tex)20
-rw-r--r--doc/legacy/hacker-guide/lock-ahead.txt (renamed from doc/hacker-guide/lock-ahead.txt)4
-rw-r--r--doc/legacy/hacker-guide/posix.txt (renamed from doc/hacker-guide/posix.txt)14
-rw-r--r--doc/legacy/hacker-guide/replicate.txt (renamed from doc/hacker-guide/replicate.txt)22
-rw-r--r--doc/legacy/hacker-guide/write-behind.txt (renamed from doc/hacker-guide/write-behind.txt)16
-rw-r--r--doc/legacy/handling-options.txt (renamed from doc/handling-options.txt)6
-rw-r--r--doc/legacy/mac-related-xattrs.txt (renamed from doc/mac-related-xattrs.txt)22
-rw-r--r--doc/legacy/porting_guide.txt (renamed from doc/porting_guide.txt)12
-rw-r--r--doc/legacy/replicate.lyx (renamed from doc/replicate.lyx)44
-rw-r--r--doc/legacy/replicate.pdf (renamed from doc/replicate.pdf)bin109057 -> 109057 bytes-rw-r--r--doc/legacy/rpc-for-glusterfs.changes-done.txt (renamed from doc/rpc-for-glusterfs.changes-done.txt)0
-rw-r--r--doc/legacy/solaris-related-xattrs.txt (renamed from doc/solaris-related-xattrs.txt)24
-rw-r--r--doc/legacy/stat-prefetch-design.txt (renamed from doc/stat-prefetch-design.txt)80
-rw-r--r--doc/legacy/translator-options.txt (renamed from doc/translator-options.txt)112
-rw-r--r--doc/mount.glusterfs.86
-rw-r--r--doc/qa/legacy/qa-client.vol (renamed from doc/qa/qa-client.vol)36
-rw-r--r--doc/qa/legacy/qa-high-avail-client.vol (renamed from doc/qa/qa-high-avail-client.vol)0
-rw-r--r--doc/qa/legacy/qa-high-avail-server.vol (renamed from doc/qa/qa-high-avail-server.vol)6
-rw-r--r--doc/qa/legacy/qa-server.vol (renamed from doc/qa/qa-server.vol)2
-rw-r--r--doc/release-notes/en-US/Author_Group.xml17
-rw-r--r--doc/release-notes/en-US/Book_Info.xml28
-rw-r--r--doc/release-notes/en-US/Chapter.xml33
-rw-r--r--doc/release-notes/en-US/Download_Install.xml107
-rw-r--r--doc/release-notes/en-US/Key_Features.xml72
-rw-r--r--doc/release-notes/en-US/Known_Issues.xml164
-rw-r--r--doc/release-notes/en-US/Preface.xml24
-rw-r--r--doc/release-notes/en-US/Product_Documentation.xml12
-rw-r--r--doc/release-notes/en-US/Product_Support.xml12
-rw-r--r--doc/release-notes/en-US/Release_Notes.ent4
-rw-r--r--doc/release-notes/en-US/Release_Notes.xml17
-rw-r--r--doc/release-notes/en-US/Revision_History.xml27
-rw-r--r--doc/release-notes/en-US/Whats_New.xml90
-rw-r--r--doc/release-notes/en-US/gfs_introduction.xml54
-rw-r--r--doc/release-notes/en-US/images/640px-GlusterFS_3.2_Architecture.pngbin0 -> 97477 bytes-rw-r--r--doc/release-notes/en-US/images/icon.svg19
-rw-r--r--doc/release-notes/publican.cfg12
-rw-r--r--doc/user-guide/legacy/Makefile.am (renamed from doc/user-guide/Makefile.am)2
-rw-r--r--doc/user-guide/legacy/advanced-stripe.odg (renamed from doc/user-guide/advanced-stripe.odg)bin12648 -> 12648 bytes-rw-r--r--doc/user-guide/legacy/advanced-stripe.pdf (renamed from doc/user-guide/advanced-stripe.pdf)bin13382 -> 13382 bytes-rw-r--r--doc/user-guide/legacy/colonO-icon.jpg (renamed from doc/user-guide/colonO-icon.jpg)bin779 -> 779 bytes-rw-r--r--doc/user-guide/legacy/fdl.texi (renamed from doc/user-guide/fdl.texi)4
-rw-r--r--doc/user-guide/legacy/fuse.odg (renamed from doc/user-guide/fuse.odg)bin13190 -> 13190 bytes-rw-r--r--doc/user-guide/legacy/fuse.pdf (renamed from doc/user-guide/fuse.pdf)bin14948 -> 14948 bytes-rw-r--r--doc/user-guide/legacy/ha.odg (renamed from doc/user-guide/ha.odg)bin37290 -> 37290 bytes-rw-r--r--doc/user-guide/legacy/ha.pdf (renamed from doc/user-guide/ha.pdf)bin19403 -> 19403 bytes-rw-r--r--doc/user-guide/legacy/stripe.odg (renamed from doc/user-guide/stripe.odg)bin10188 -> 10188 bytes-rw-r--r--doc/user-guide/legacy/stripe.pdf (renamed from doc/user-guide/stripe.pdf)bin11941 -> 11941 bytes-rw-r--r--doc/user-guide/legacy/unify.odg (renamed from doc/user-guide/unify.odg)bin12955 -> 12955 bytes-rw-r--r--doc/user-guide/legacy/unify.pdf (renamed from doc/user-guide/unify.pdf)bin18969 -> 18969 bytes-rw-r--r--doc/user-guide/legacy/user-guide.info (renamed from doc/user-guide/user-guide.info)22
-rw-r--r--doc/user-guide/legacy/user-guide.pdf (renamed from doc/user-guide/user-guide.pdf)bin353986 -> 353986 bytes-rw-r--r--doc/user-guide/legacy/user-guide.texi (renamed from doc/user-guide/user-guide.texi)300
-rw-r--r--doc/user-guide/legacy/xlator.odg (renamed from doc/user-guide/xlator.odg)bin12169 -> 12169 bytes-rw-r--r--doc/user-guide/legacy/xlator.pdf (renamed from doc/user-guide/xlator.pdf)bin14358 -> 14358 bytes-rw-r--r--extras/Makefile.am8
-rw-r--r--extras/Solaris/README.solaris2
-rw-r--r--extras/Ubuntu/README.Ubuntu24
-rw-r--r--extras/Ubuntu/glusterd.conf10
-rw-r--r--extras/Ubuntu/mounting-glusterfs.conf7
-rw-r--r--extras/benchmarking/glfs-bm.c2
-rw-r--r--extras/benchmarking/rdd.c860
-rwxr-xr-xextras/clear_xattrs.sh53
-rwxr-xr-xextras/contri-add.sh73
-rwxr-xr-xextras/file_size_contri.sh17
-rwxr-xr-xextras/generate-xdr-files.sh107
-rw-r--r--extras/glusterfs-logrotate27
-rw-r--r--extras/glusterfs-mode.el2
-rw-r--r--extras/glusterfs.vim2
-rw-r--r--extras/gnfs-loganalyse.py154
-rw-r--r--extras/hook-scripts/Makefile.am1
-rw-r--r--extras/hook-scripts/S29CTDBsetup.sh69
-rwxr-xr-xextras/hook-scripts/S30samba-start.sh62
-rwxr-xr-xextras/hook-scripts/S30samba-stop.sh60
-rwxr-xr-xextras/init.d/glusterd-Redhat.in89
-rwxr-xr-xextras/profiler/glusterfs-profiler2
-rw-r--r--extras/rhel_install.sh9
-rwxr-xr-xextras/rpc-coverage.sh3
-rwxr-xr-xextras/specgen.scm2
-rw-r--r--extras/stripe-merge.c496
-rwxr-xr-xextras/test/gluster_commands.sh2
-rw-r--r--extras/test/ld-preload-test/ld-preload-lib.c2
-rw-r--r--extras/test/ld-preload-test/ld-preload-test.c2
-rw-r--r--extras/test/open-fd-tests.c64
-rwxr-xr-xextras/test/run.sh2
-rwxr-xr-xextras/test/stop_glusterd.sh2
-rw-r--r--extras/test/test-ffop.c105
-rwxr-xr-xformat-patch.sh60
-rw-r--r--glusterfs-hadoop/0.20.2/conf/core-site.xml38
-rw-r--r--glusterfs-hadoop/0.20.2/pom.xml36
-rw-r--r--glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickClass.java109
-rw-r--r--glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickRepl.java52
-rw-r--r--glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSXattr.java472
-rw-r--r--glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEInputStream.java205
-rw-r--r--glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEOutputStream.java86
-rw-r--r--glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFileSystem.java492
-rw-r--r--glusterfs-hadoop/0.20.2/src/test/java/org/apache/hadoop/fs/glusterfs/AppTest.java38
-rwxr-xr-xglusterfs-hadoop/0.20.2/tools/build-deploy-jar.py212
-rw-r--r--glusterfs-hadoop/COPYING202
-rw-r--r--glusterfs-hadoop/README182
-rw-r--r--glusterfs.spec.in627
-rw-r--r--glusterfsd/src/Makefile.am7
-rw-r--r--glusterfsd/src/glusterfsd-mem-types.h20
-rw-r--r--glusterfsd/src/glusterfsd-mgmt.c1437
-rw-r--r--glusterfsd/src/glusterfsd.c375
-rw-r--r--glusterfsd/src/glusterfsd.h48
-rw-r--r--libglusterfs/src/Makefile.am49
-rw-r--r--libglusterfs/src/byte-order.h195
-rw-r--r--libglusterfs/src/call-stub.c832
-rw-r--r--libglusterfs/src/call-stub.h234
-rw-r--r--libglusterfs/src/checksum.c53
-rw-r--r--libglusterfs/src/checksum.h27
-rw-r--r--libglusterfs/src/circ-buff.c170
-rw-r--r--libglusterfs/src/circ-buff.h63
-rw-r--r--libglusterfs/src/common-utils.c879
-rw-r--r--libglusterfs/src/common-utils.h205
-rw-r--r--libglusterfs/src/compat-errno.c23
-rw-r--r--libglusterfs/src/compat-errno.h23
-rw-r--r--libglusterfs/src/compat.c52
-rw-r--r--libglusterfs/src/compat.h49
-rw-r--r--libglusterfs/src/daemon.c66
-rw-r--r--libglusterfs/src/daemon.h23
-rw-r--r--libglusterfs/src/defaults.c609
-rw-r--r--libglusterfs/src/defaults.h373
-rw-r--r--libglusterfs/src/dict.c617
-rw-r--r--libglusterfs/src/dict.h82
-rw-r--r--libglusterfs/src/event-history.c81
-rw-r--r--libglusterfs/src/event-history.h43
-rw-r--r--libglusterfs/src/event.c19
-rw-r--r--libglusterfs/src/event.h23
-rw-r--r--libglusterfs/src/fd-lk.c472
-rw-r--r--libglusterfs/src/fd-lk.h66
-rw-r--r--libglusterfs/src/fd.c529
-rw-r--r--libglusterfs/src/fd.h58
-rw-r--r--libglusterfs/src/gf-dirent.c68
-rw-r--r--libglusterfs/src/gf-dirent.h26
-rw-r--r--libglusterfs/src/globals.c74
-rw-r--r--libglusterfs/src/globals.h30
-rw-r--r--libglusterfs/src/glusterfs.h129
-rw-r--r--libglusterfs/src/graph-mem-types.h31
-rw-r--r--libglusterfs/src/graph-print.c22
-rw-r--r--libglusterfs/src/graph-utils.h21
-rw-r--r--libglusterfs/src/graph.c157
-rw-r--r--libglusterfs/src/graph.l8
-rw-r--r--libglusterfs/src/graph.y17
-rw-r--r--libglusterfs/src/hashfn.c19
-rw-r--r--libglusterfs/src/hashfn.h21
-rw-r--r--libglusterfs/src/iatt.h39
-rw-r--r--libglusterfs/src/inode.c632
-rw-r--r--libglusterfs/src/inode.h91
-rw-r--r--libglusterfs/src/iobuf.c531
-rw-r--r--libglusterfs/src/iobuf.h78
-rw-r--r--libglusterfs/src/latency.c19
-rw-r--r--libglusterfs/src/latency.h19
-rw-r--r--libglusterfs/src/list.h23
-rw-r--r--libglusterfs/src/lkowner.h83
-rw-r--r--libglusterfs/src/locking.h19
-rw-r--r--libglusterfs/src/logging.c204
-rw-r--r--libglusterfs/src/logging.h47
-rw-r--r--libglusterfs/src/mem-pool.c145
-rw-r--r--libglusterfs/src/mem-pool.h39
-rw-r--r--libglusterfs/src/mem-types.h34
-rw-r--r--libglusterfs/src/options.c1058
-rw-r--r--libglusterfs/src/options.h242
-rw-r--r--libglusterfs/src/rbthash.c70
-rw-r--r--libglusterfs/src/rbthash.h31
-rw-r--r--libglusterfs/src/run.c490
-rw-r--r--libglusterfs/src/run.h188
-rw-r--r--libglusterfs/src/scheduler.c19
-rw-r--r--libglusterfs/src/scheduler.h21
-rw-r--r--libglusterfs/src/stack.c268
-rw-r--r--libglusterfs/src/stack.h119
-rw-r--r--libglusterfs/src/statedump.c511
-rw-r--r--libglusterfs/src/statedump.h37
-rw-r--r--libglusterfs/src/syncop.c1029
-rw-r--r--libglusterfs/src/syncop.h183
-rw-r--r--libglusterfs/src/syscall.c66
-rw-r--r--libglusterfs/src/syscall.h22
-rw-r--r--libglusterfs/src/timer.c22
-rw-r--r--libglusterfs/src/timer.h19
-rw-r--r--libglusterfs/src/trie-mem-types.h34
-rw-r--r--libglusterfs/src/trie.c30
-rw-r--r--libglusterfs/src/trie.h19
-rw-r--r--libglusterfs/src/xlator.c1622
-rw-r--r--libglusterfs/src/xlator.h329
-rw-r--r--libglusterfsclient/src/libglusterfsclient-dentry.c19
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient-internals.h23
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.c25
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.h19
-rw-r--r--mod_glusterfs/apache/1.3/src/mod_glusterfs.c8
-rw-r--r--mod_glusterfs/apache/2.2/src/mod_glusterfs.c8
-rw-r--r--mod_glusterfs/lighttpd/1.4/mod_glusterfs.c8
-rw-r--r--mod_glusterfs/lighttpd/1.4/mod_glusterfs.h8
-rw-r--r--mod_glusterfs/lighttpd/1.5/mod_glusterfs.c8
-rw-r--r--mod_glusterfs/lighttpd/1.5/mod_glusterfs.h8
-rwxr-xr-xrfc.sh111
-rw-r--r--rpc/rpc-lib/src/Makefile.am4
-rw-r--r--rpc/rpc-lib/src/auth-glusterfs.c241
-rw-r--r--rpc/rpc-lib/src/auth-null.c23
-rw-r--r--rpc/rpc-lib/src/auth-unix.c21
-rw-r--r--rpc/rpc-lib/src/protocol-common.h165
-rw-r--r--rpc/rpc-lib/src/rpc-clnt.c460
-rw-r--r--rpc/rpc-lib/src/rpc-clnt.h51
-rw-r--r--rpc/rpc-lib/src/rpc-common.c139
-rw-r--r--rpc/rpc-lib/src/rpc-transport.c518
-rw-r--r--rpc/rpc-lib/src/rpc-transport.h70
-rw-r--r--rpc/rpc-lib/src/rpcsvc-auth.c133
-rw-r--r--rpc/rpc-lib/src/rpcsvc-common.h21
-rw-r--r--rpc/rpc-lib/src/rpcsvc.c787
-rw-r--r--rpc/rpc-lib/src/rpcsvc.h78
-rw-r--r--rpc/rpc-lib/src/xdr-common.h82
-rw-r--r--rpc/rpc-lib/src/xdr-rpc.c21
-rw-r--r--rpc/rpc-lib/src/xdr-rpc.h31
-rw-r--r--rpc/rpc-lib/src/xdr-rpcclnt.c19
-rw-r--r--rpc/rpc-lib/src/xdr-rpcclnt.h21
-rw-r--r--rpc/rpc-transport/rdma/src/Makefile.am2
-rw-r--r--rpc/rpc-transport/rdma/src/name.c70
-rw-r--r--rpc/rpc-transport/rdma/src/name.h19
-rw-r--r--rpc/rpc-transport/rdma/src/rdma.c2317
-rw-r--r--rpc/rpc-transport/rdma/src/rdma.h277
-rw-r--r--rpc/rpc-transport/socket/src/name.c99
-rw-r--r--rpc/rpc-transport/socket/src/name.h19
-rw-r--r--rpc/rpc-transport/socket/src/socket.c330
-rw-r--r--rpc/rpc-transport/socket/src/socket.h35
-rw-r--r--rpc/xdr/src/Makefile.am22
-rw-r--r--rpc/xdr/src/cli1-xdr.c677
-rw-r--r--rpc/xdr/src/cli1-xdr.h560
-rw-r--r--rpc/xdr/src/cli1-xdr.x337
-rw-r--r--rpc/xdr/src/cli1.c742
-rw-r--r--rpc/xdr/src/cli1.h330
-rw-r--r--rpc/xdr/src/glusterd1-xdr.c107
-rw-r--r--rpc/xdr/src/glusterd1-xdr.h19
-rw-r--r--rpc/xdr/src/glusterd1-xdr.x1
-rw-r--r--rpc/xdr/src/glusterd1.c262
-rw-r--r--rpc/xdr/src/glusterd1.h125
-rw-r--r--rpc/xdr/src/glusterfs3-xdr.c562
-rw-r--r--rpc/xdr/src/glusterfs3-xdr.h461
-rw-r--r--rpc/xdr/src/glusterfs3-xdr.x150
-rw-r--r--rpc/xdr/src/glusterfs3.c1137
-rw-r--r--rpc/xdr/src/glusterfs3.h516
-rw-r--r--rpc/xdr/src/mount3udp.x34
-rw-r--r--rpc/xdr/src/msg-nfs3.c (renamed from xlators/nfs/lib/src/msg-nfs3.c)264
-rw-r--r--rpc/xdr/src/msg-nfs3.h (renamed from xlators/nfs/lib/src/msg-nfs3.h)44
-rw-r--r--rpc/xdr/src/nlm4-xdr.c254
-rw-r--r--rpc/xdr/src/nlm4-xdr.h267
-rw-r--r--rpc/xdr/src/nlm4.x163
-rw-r--r--rpc/xdr/src/nlmcbk-xdr.c37
-rw-r--r--rpc/xdr/src/nlmcbk-xdr.h74
-rw-r--r--rpc/xdr/src/nlmcbk.x33
-rw-r--r--rpc/xdr/src/nsm-xdr.c105
-rw-r--r--rpc/xdr/src/nsm-xdr.h95
-rw-r--r--rpc/xdr/src/nsm.x47
-rw-r--r--rpc/xdr/src/portmap-xdr.c54
-rw-r--r--rpc/xdr/src/portmap-xdr.h34
-rw-r--r--rpc/xdr/src/portmap.c189
-rw-r--r--rpc/xdr/src/portmap.h95
-rw-r--r--rpc/xdr/src/rpc-common-xdr.c223
-rw-r--r--rpc/xdr/src/rpc-common-xdr.h104
-rw-r--r--rpc/xdr/src/rpc-common-xdr.x39
-rw-r--r--rpc/xdr/src/xdr-generic.c55
-rw-r--r--rpc/xdr/src/xdr-generic.h32
-rw-r--r--rpc/xdr/src/xdr-nfs3.c (renamed from xlators/nfs/lib/src/xdr-nfs3.c)10
-rw-r--r--rpc/xdr/src/xdr-nfs3.h (renamed from xlators/nfs/lib/src/xdr-nfs3.h)8
-rw-r--r--scheduler/alu/src/alu-mem-types.h8
-rw-r--r--scheduler/alu/src/alu.c8
-rw-r--r--scheduler/alu/src/alu.h8
-rw-r--r--scheduler/nufa/src/nufa-mem-types.h8
-rw-r--r--scheduler/nufa/src/nufa.c8
-rw-r--r--scheduler/random/src/random-mem-types.h8
-rw-r--r--scheduler/random/src/random.c8
-rw-r--r--scheduler/random/src/random.h8
-rw-r--r--scheduler/rr/src/rr-mem-types.h8
-rw-r--r--scheduler/rr/src/rr-options.c8
-rw-r--r--scheduler/rr/src/rr-options.h8
-rw-r--r--scheduler/rr/src/rr.c8
-rw-r--r--scheduler/rr/src/rr.h8
-rw-r--r--scheduler/switch/src/switch-mem-types.h8
-rw-r--r--scheduler/switch/src/switch.c8
-rwxr-xr-xsmoke.sh83
-rw-r--r--swift/1.4.8/README22
-rw-r--r--swift/1.4.8/gluster-swift-plugin.spec60
-rw-r--r--swift/1.4.8/gluster-swift.spec396
-rw-r--r--swift/1.4.8/plugins/DiskDir.py484
-rw-r--r--swift/1.4.8/plugins/DiskFile.py316
-rw-r--r--swift/1.4.8/plugins/Glusterfs.py131
-rw-r--r--swift/1.4.8/plugins/__init__.py16
-rw-r--r--swift/1.4.8/plugins/conf/account-server/1.conf22
-rw-r--r--swift/1.4.8/plugins/conf/account.builderbin0 -> 786843 bytes-rw-r--r--swift/1.4.8/plugins/conf/account.ring.gzbin0 -> 739 bytes-rw-r--r--swift/1.4.8/plugins/conf/container-server/1.conf24
-rw-r--r--swift/1.4.8/plugins/conf/container.builderbin0 -> 786843 bytes-rw-r--r--swift/1.4.8/plugins/conf/container.ring.gzbin0 -> 741 bytes-rw-r--r--swift/1.4.8/plugins/conf/db_file.db0
-rw-r--r--swift/1.4.8/plugins/conf/fs.conf9
-rw-r--r--swift/1.4.8/plugins/conf/object-server/1.conf22
-rw-r--r--swift/1.4.8/plugins/conf/object.builderbin0 -> 786843 bytes-rw-r--r--swift/1.4.8/plugins/conf/object.ring.gzbin0 -> 738 bytes-rw-r--r--swift/1.4.8/plugins/conf/proxy-server.conf21
-rw-r--r--swift/1.4.8/plugins/conf/swift.conf7
-rw-r--r--swift/1.4.8/plugins/constraints.py97
-rw-r--r--swift/1.4.8/plugins/utils.py679
-rw-r--r--swift/1.4.8/swift.diff797
-rwxr-xr-xtests/bugs/bug-874272.t48
-rw-r--r--tests/bugs/bug-887098-gmount-crash.t48
-rw-r--r--tests/bugs/bug-918437-sh-mtime.t52
-rw-r--r--xlators/Makefile.am2
-rw-r--r--xlators/cluster/afr/src/Makefile.am16
-rw-r--r--xlators/cluster/afr/src/afr-common.c3271
-rw-r--r--xlators/cluster/afr/src/afr-dir-read.c292
-rw-r--r--xlators/cluster/afr/src/afr-dir-read.h36
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c691
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.h43
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.c1227
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.h39
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c1008
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.h57
-rw-r--r--xlators/cluster/afr/src/afr-lk-common.c762
-rw-r--r--xlators/cluster/afr/src/afr-mem-types.h31
-rw-r--r--xlators/cluster/afr/src/afr-open.c696
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-algorithm.c1244
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-algorithm.h42
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c2259
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.h117
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-data.c1134
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-entry.c1326
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-metadata.c337
-rw-r--r--xlators/cluster/afr/src/afr-self-heal.h35
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.c1175
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.h45
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c422
-rw-r--r--xlators/cluster/afr/src/afr-transaction.h25
-rw-r--r--xlators/cluster/afr/src/afr.c830
-rw-r--r--xlators/cluster/afr/src/afr.h638
-rw-r--r--xlators/cluster/afr/src/pump.c969
-rw-r--r--xlators/cluster/afr/src/pump.h39
-rw-r--r--xlators/cluster/dht/src/Makefile.am15
-rw-r--r--xlators/cluster/dht/src/dht-common.c3271
-rw-r--r--xlators/cluster/dht/src/dht-common.h555
-rw-r--r--xlators/cluster/dht/src/dht-diskusage.c465
-rw-r--r--xlators/cluster/dht/src/dht-hashfn.c19
-rw-r--r--xlators/cluster/dht/src/dht-helper.c573
-rw-r--r--xlators/cluster/dht/src/dht-inode-read.c1115
-rw-r--r--xlators/cluster/dht/src/dht-inode-write.c612
-rw-r--r--xlators/cluster/dht/src/dht-layout.c98
-rw-r--r--xlators/cluster/dht/src/dht-linkfile.c299
-rw-r--r--xlators/cluster/dht/src/dht-mem-types.h23
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c1657
-rw-r--r--xlators/cluster/dht/src/dht-rename.c364
-rw-r--r--xlators/cluster/dht/src/dht-selfheal.c446
-rw-r--r--xlators/cluster/dht/src/dht.c388
-rw-r--r--xlators/cluster/dht/src/nufa.c111
-rw-r--r--xlators/cluster/dht/src/switch.c107
-rw-r--r--xlators/cluster/ha/src/ha-helpers.c8
-rw-r--r--xlators/cluster/ha/src/ha-mem-types.h8
-rw-r--r--xlators/cluster/ha/src/ha.c8
-rw-r--r--xlators/cluster/ha/src/ha.h8
-rw-r--r--xlators/cluster/map/src/map-helper.c8
-rw-r--r--xlators/cluster/map/src/map-mem-types.h8
-rw-r--r--xlators/cluster/map/src/map.c8
-rw-r--r--xlators/cluster/map/src/map.h8
-rw-r--r--xlators/cluster/stripe/src/Makefile.am4
-rw-r--r--xlators/cluster/stripe/src/stripe-helpers.c583
-rw-r--r--xlators/cluster/stripe/src/stripe-mem-types.h26
-rw-r--r--xlators/cluster/stripe/src/stripe.c2889
-rw-r--r--xlators/cluster/stripe/src/stripe.h159
-rw-r--r--xlators/cluster/unify/src/unify-mem-types.h8
-rw-r--r--xlators/cluster/unify/src/unify-self-heal.c8
-rw-r--r--xlators/cluster/unify/src/unify.c12
-rw-r--r--xlators/cluster/unify/src/unify.h8
-rw-r--r--xlators/debug/error-gen/src/Makefile.am2
-rw-r--r--xlators/debug/error-gen/src/error-gen-mem-types.h (renamed from contrib/apple/daemon.h)14
-rw-r--r--xlators/debug/error-gen/src/error-gen.c786
-rw-r--r--xlators/debug/error-gen/src/error-gen.h11
-rw-r--r--xlators/debug/io-stats/src/io-stats-mem-types.h8
-rw-r--r--xlators/debug/io-stats/src/io-stats.c823
-rw-r--r--xlators/debug/trace/src/trace.c440
-rw-r--r--xlators/encryption/rot-13/src/rot-13.c34
-rw-r--r--xlators/encryption/rot-13/src/rot-13.h8
-rw-r--r--xlators/features/Makefile.am2
-rw-r--r--xlators/features/access-control/src/Makefile.am13
-rw-r--r--xlators/features/access-control/src/access-control.c2060
-rw-r--r--xlators/features/access-control/src/access-control.h55
-rw-r--r--xlators/features/filter/src/filter-mem-types.h8
-rw-r--r--xlators/features/filter/src/filter.c8
-rw-r--r--xlators/features/index/Makefile.am (renamed from xlators/features/access-control/Makefile.am)0
-rw-r--r--xlators/features/index/src/Makefile.am15
-rw-r--r--xlators/features/index/src/index-mem-types.h32
-rw-r--r--xlators/features/index/src/index.c1184
-rw-r--r--xlators/features/index/src/index.h70
-rw-r--r--xlators/features/locks/src/Makefile.am12
-rw-r--r--xlators/features/locks/src/clear.c434
-rw-r--r--xlators/features/locks/src/clear.h86
-rw-r--r--xlators/features/locks/src/common.c144
-rw-r--r--xlators/features/locks/src/common.h37
-rw-r--r--xlators/features/locks/src/entrylk.c94
-rw-r--r--xlators/features/locks/src/inodelk.c263
-rw-r--r--xlators/features/locks/src/locks-mem-types.h9
-rw-r--r--xlators/features/locks/src/locks.h36
-rw-r--r--xlators/features/locks/src/posix.c752
-rw-r--r--xlators/features/locks/src/reservelk.c35
-rw-r--r--xlators/features/locks/tests/unit-test.c8
-rw-r--r--xlators/features/mac-compat/src/mac-compat.c33
-rw-r--r--xlators/features/marker/src/marker-common.c20
-rw-r--r--xlators/features/marker/src/marker-common.h2
-rw-r--r--xlators/features/marker/src/marker-mem-types.h12
-rw-r--r--xlators/features/marker/src/marker-quota-helper.c120
-rw-r--r--xlators/features/marker/src/marker-quota-helper.h41
-rw-r--r--xlators/features/marker/src/marker-quota.c1694
-rw-r--r--xlators/features/marker/src/marker-quota.h99
-rw-r--r--xlators/features/marker/src/marker.c1103
-rw-r--r--xlators/features/marker/src/marker.h54
-rw-r--r--xlators/features/marker/utils/Makefile.am6
-rwxr-xr-xxlators/features/marker/utils/gsyncd.in55
-rw-r--r--xlators/features/marker/utils/src/Makefile.am22
-rw-r--r--xlators/features/marker/utils/src/gsyncd.c345
-rw-r--r--xlators/features/marker/utils/src/procdiggy.c129
-rw-r--r--xlators/features/marker/utils/src/procdiggy.h30
-rw-r--r--xlators/features/marker/utils/syncdaemon/Makefile.am3
-rw-r--r--xlators/features/marker/utils/syncdaemon/__codecheck.py46
-rw-r--r--xlators/features/marker/utils/syncdaemon/configinterface.py49
-rw-r--r--xlators/features/marker/utils/syncdaemon/gconf.py5
-rw-r--r--xlators/features/marker/utils/syncdaemon/gsyncd.py107
-rw-r--r--xlators/features/marker/utils/syncdaemon/libcxattr.py10
-rw-r--r--xlators/features/marker/utils/syncdaemon/master.py223
-rw-r--r--xlators/features/marker/utils/syncdaemon/monitor.py65
-rw-r--r--xlators/features/marker/utils/syncdaemon/repce.py69
-rw-r--r--xlators/features/marker/utils/syncdaemon/resource.py585
-rw-r--r--xlators/features/marker/utils/syncdaemon/syncdutils.py127
-rw-r--r--xlators/features/path-convertor/src/path-mem-types.h8
-rw-r--r--xlators/features/path-convertor/src/path.c10
-rw-r--r--xlators/features/quiesce/src/quiesce-mem-types.h8
-rw-r--r--xlators/features/quiesce/src/quiesce.c681
-rw-r--r--xlators/features/quiesce/src/quiesce.h11
-rw-r--r--xlators/features/quota/src/quota-mem-types.h11
-rw-r--r--xlators/features/quota/src/quota.c1283
-rw-r--r--xlators/features/quota/src/quota.h28
-rw-r--r--xlators/features/read-only/src/Makefile.am12
-rw-r--r--xlators/features/read-only/src/read-only-common.c249
-rw-r--r--xlators/features/read-only/src/read-only-common.h125
-rw-r--r--xlators/features/read-only/src/read-only.c229
-rw-r--r--xlators/features/read-only/src/worm.c100
-rw-r--r--xlators/features/trash/src/trash-mem-types.h11
-rw-r--r--xlators/features/trash/src/trash.c80
-rw-r--r--xlators/features/trash/src/trash.h8
-rw-r--r--xlators/lib/src/libxlator.c358
-rw-r--r--xlators/lib/src/libxlator.h30
-rw-r--r--xlators/meta/src/meta-mem-types.h8
-rw-r--r--xlators/meta/src/meta.c8
-rw-r--r--xlators/meta/src/meta.h8
-rw-r--r--xlators/meta/src/misc.c8
-rw-r--r--xlators/meta/src/misc.h8
-rw-r--r--xlators/meta/src/tree.c8
-rw-r--r--xlators/meta/src/tree.h8
-rw-r--r--xlators/meta/src/view.c8
-rw-r--r--xlators/meta/src/view.h8
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am42
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-brick-ops.c1649
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-geo-rep.c2025
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c2606
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c209
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.c528
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.h81
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-log-ops.c282
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mem-types.h21
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.c704
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.h52
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c7787
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.h103
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.c69
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.h8
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quota.c843
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rebalance.c1000
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-replace-brick.c1813
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c1152
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c118
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.h9
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c757
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h28
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c590
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.h60
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c3053
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h209
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c2095
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.h46
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c1938
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c698
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h228
-rw-r--r--xlators/mount/fuse/src/Makefile.am1
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c2300
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h132
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c369
-rw-r--r--xlators/mount/fuse/src/fuse-mem-types.h10
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c709
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in271
-rwxr-xr-xxlators/mount/fuse/utils/mount_glusterfs.in11
-rw-r--r--xlators/nfs/lib/src/auth-null.c72
-rw-r--r--xlators/nfs/lib/src/auth-unix.c97
-rw-r--r--xlators/nfs/lib/src/rpc-socket.c361
-rw-r--r--xlators/nfs/lib/src/rpc-socket.h65
-rw-r--r--xlators/nfs/lib/src/rpcsvc-auth.c400
-rw-r--r--xlators/nfs/lib/src/rpcsvc.c2923
-rw-r--r--xlators/nfs/lib/src/rpcsvc.h728
-rw-r--r--xlators/nfs/lib/src/xdr-common.h48
-rw-r--r--xlators/nfs/lib/src/xdr-rpc.c229
-rw-r--r--xlators/nfs/lib/src/xdr-rpc.h82
-rw-r--r--xlators/nfs/server/src/Makefile.am14
-rw-r--r--xlators/nfs/server/src/mount3.c423
-rw-r--r--xlators/nfs/server/src/mount3.h13
-rw-r--r--xlators/nfs/server/src/mount3udp_svc.c201
-rw-r--r--xlators/nfs/server/src/nfs-common.c169
-rw-r--r--xlators/nfs/server/src/nfs-common.h15
-rw-r--r--xlators/nfs/server/src/nfs-fops.c315
-rw-r--r--xlators/nfs/server/src/nfs-fops.h30
-rw-r--r--xlators/nfs/server/src/nfs-generics.c37
-rw-r--r--xlators/nfs/server/src/nfs-generics.h19
-rw-r--r--xlators/nfs/server/src/nfs-inodes.c54
-rw-r--r--xlators/nfs/server/src/nfs-inodes.h10
-rw-r--r--xlators/nfs/server/src/nfs-mem-types.h17
-rw-r--r--xlators/nfs/server/src/nfs.c460
-rw-r--r--xlators/nfs/server/src/nfs.h26
-rw-r--r--xlators/nfs/server/src/nfs3-fh.c156
-rw-r--r--xlators/nfs/server/src/nfs3-fh.h31
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c2825
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.h29
-rw-r--r--xlators/nfs/server/src/nfs3.c1228
-rw-r--r--xlators/nfs/server/src/nfs3.h50
-rw-r--r--xlators/nfs/server/src/nlm4.c2451
-rw-r--r--xlators/nfs/server/src/nlm4.h89
-rw-r--r--xlators/nfs/server/src/nlmcbk_svc.c122
-rw-r--r--xlators/performance/Makefile.am2
-rw-r--r--xlators/performance/io-cache/src/io-cache.c2002
-rw-r--r--xlators/performance/io-cache/src/io-cache.h46
-rw-r--r--xlators/performance/io-cache/src/ioc-inode.c46
-rw-r--r--xlators/performance/io-cache/src/ioc-mem-types.h20
-rw-r--r--xlators/performance/io-cache/src/page.c250
-rw-r--r--xlators/performance/io-threads/src/io-threads.c1223
-rw-r--r--xlators/performance/io-threads/src/io-threads.h24
-rw-r--r--xlators/performance/io-threads/src/iot-mem-types.h21
-rw-r--r--xlators/performance/md-cache/Makefile.am (renamed from xlators/performance/stat-prefetch/Makefile.am)0
-rw-r--r--xlators/performance/md-cache/src/Makefile.am23
-rw-r--r--xlators/performance/md-cache/src/md-cache-mem-types.h24
-rw-r--r--xlators/performance/md-cache/src/md-cache.c1889
-rw-r--r--xlators/performance/quick-read/src/quick-read-mem-types.h21
-rw-r--r--xlators/performance/quick-read/src/quick-read.c1589
-rw-r--r--xlators/performance/quick-read/src/quick-read.h50
-rw-r--r--xlators/performance/read-ahead/src/page.c66
-rw-r--r--xlators/performance/read-ahead/src/read-ahead-mem-types.h20
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.c468
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.h23
-rw-r--r--xlators/performance/stat-prefetch/src/Makefile.am14
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch-mem-types.h36
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.c4124
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.h106
-rw-r--r--xlators/performance/symlink-cache/src/symlink-cache.c53
-rw-r--r--xlators/performance/write-behind/src/write-behind-mem-types.h22
-rw-r--r--xlators/performance/write-behind/src/write-behind.c714
-rw-r--r--xlators/protocol/auth/addr/src/Makefile.am3
-rw-r--r--xlators/protocol/auth/addr/src/addr.c22
-rw-r--r--xlators/protocol/auth/login/src/login.c8
-rw-r--r--xlators/protocol/client/src/client-callback.c19
-rw-r--r--xlators/protocol/client/src/client-handshake.c856
-rw-r--r--xlators/protocol/client/src/client-helpers.c93
-rw-r--r--xlators/protocol/client/src/client-lk.c86
-rw-r--r--xlators/protocol/client/src/client-mem-types.h23
-rw-r--r--xlators/protocol/client/src/client.c875
-rw-r--r--xlators/protocol/client/src/client.h120
-rw-r--r--xlators/protocol/client/src/client3_1-fops.c3914
-rw-r--r--xlators/protocol/legacy/client/src/client-mem-types.h8
-rw-r--r--xlators/protocol/legacy/client/src/client-protocol.c12
-rw-r--r--xlators/protocol/legacy/client/src/client-protocol.h8
-rw-r--r--xlators/protocol/legacy/client/src/saved-frames.c8
-rw-r--r--xlators/protocol/legacy/client/src/saved-frames.h8
-rw-r--r--xlators/protocol/legacy/lib/src/protocol.h8
-rw-r--r--xlators/protocol/legacy/lib/src/transport.c8
-rw-r--r--xlators/protocol/legacy/lib/src/transport.h8
-rw-r--r--xlators/protocol/legacy/server/src/Makefile.am1
-rw-r--r--xlators/protocol/legacy/server/src/authenticate.c8
-rw-r--r--xlators/protocol/legacy/server/src/authenticate.h8
-rw-r--r--xlators/protocol/legacy/server/src/server-helpers.c8
-rw-r--r--xlators/protocol/legacy/server/src/server-helpers.h8
-rw-r--r--xlators/protocol/legacy/server/src/server-mem-types.h8
-rw-r--r--xlators/protocol/legacy/server/src/server-protocol.c12
-rw-r--r--xlators/protocol/legacy/server/src/server-protocol.h8
-rw-r--r--xlators/protocol/legacy/server/src/server-resolve.c8
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs-mem-types.h8
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.c8
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.h8
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/name.c8
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/name.h8
-rw-r--r--xlators/protocol/legacy/transport/socket/src/name.c8
-rw-r--r--xlators/protocol/legacy/transport/socket/src/name.h8
-rw-r--r--xlators/protocol/legacy/transport/socket/src/socket-mem-types.h8
-rw-r--r--xlators/protocol/legacy/transport/socket/src/socket.c10
-rw-r--r--xlators/protocol/legacy/transport/socket/src/socket.h8
-rw-r--r--xlators/protocol/server/src/Makefile.am4
-rw-r--r--xlators/protocol/server/src/authenticate.c33
-rw-r--r--xlators/protocol/server/src/authenticate.h8
-rw-r--r--xlators/protocol/server/src/server-handshake.c130
-rw-r--r--xlators/protocol/server/src/server-helpers.c576
-rw-r--r--xlators/protocol/server/src/server-helpers.h22
-rw-r--r--xlators/protocol/server/src/server-mem-types.h9
-rw-r--r--xlators/protocol/server/src/server-resolve.c413
-rw-r--r--xlators/protocol/server/src/server.c616
-rw-r--r--xlators/protocol/server/src/server.h64
-rw-r--r--xlators/protocol/server/src/server3_1-fops.c2736
-rw-r--r--xlators/storage/bdb/src/bctx.c8
-rw-r--r--xlators/storage/bdb/src/bdb-ll.c8
-rw-r--r--xlators/storage/bdb/src/bdb-mem-types.h8
-rw-r--r--xlators/storage/bdb/src/bdb.c14
-rw-r--r--xlators/storage/bdb/src/bdb.h10
-rw-r--r--xlators/storage/posix/src/Makefile.am8
-rw-r--r--xlators/storage/posix/src/posix-aio.c519
-rw-r--r--xlators/storage/posix/src/posix-aio.h49
-rw-r--r--xlators/storage/posix/src/posix-handle.c658
-rw-r--r--xlators/storage/posix/src/posix-handle.h151
-rw-r--r--xlators/storage/posix/src/posix-helpers.c1114
-rw-r--r--xlators/storage/posix/src/posix-mem-types.h9
-rw-r--r--xlators/storage/posix/src/posix.c2638
-rw-r--r--xlators/storage/posix/src/posix.h70
-rw-r--r--xlators/system/Makefile.am1
-rw-r--r--xlators/system/posix-acl/Makefile.am1
-rw-r--r--xlators/system/posix-acl/src/Makefile.am21
-rw-r--r--xlators/system/posix-acl/src/posix-acl-xattr.c190
-rw-r--r--xlators/system/posix-acl/src/posix-acl-xattr.h50
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c2135
-rw-r--r--xlators/system/posix-acl/src/posix-acl.h87
763 files changed, 128084 insertions, 66734 deletions
diff --git a/CONTRIBUTING b/CONTRIBUTING
new file mode 100644
index 000000000..8b3baa7e5
--- /dev/null
+++ b/CONTRIBUTING
@@ -0,0 +1,25 @@
+ Developer's Certificate of Origin 1.1
+
+ By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved. \ No newline at end of file
diff --git a/COPYING b/COPYING
deleted file mode 100644
index dba13ed2d..000000000
--- a/COPYING
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-<http://www.gnu.org/licenses/>.
diff --git a/COPYING-GPLV2 b/COPYING-GPLV2
new file mode 100644
index 000000000..d159169d1
--- /dev/null
+++ b/COPYING-GPLV2
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/COPYING-LGPLV3 b/COPYING-LGPLV3
new file mode 100644
index 000000000..65c5ca88a
--- /dev/null
+++ b/COPYING-LGPLV3
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/Makefile.am b/Makefile.am
index 85e0a13f1..6693bb876 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-EXTRA_DIST = autogen.sh COPYING INSTALL README AUTHORS THANKS NEWS glusterfs.spec
+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
diff --git a/NEWS b/NEWS
index e69de29bb..ad00208d3 100644
--- a/NEWS
+++ b/NEWS
@@ -0,0 +1 @@
+Gluster moves to Gerrit.
diff --git a/README b/README
index 07e76c945..ce648743e 100644
--- a/README
+++ b/README
@@ -1 +1 @@
-For more info visit http://www.gluster.org
+For more info, please visit http://www.gluster.org/.
diff --git a/THANKS b/THANKS
index ea9816662..e1ce5105d 100644
--- a/THANKS
+++ b/THANKS
@@ -1,3 +1 @@
-
-For all of you, who use the product and help us making it more robust, useful, popular.
-
+For all of you, who use the product and help us making it more robust, useful, popular..
diff --git a/argp-standalone/configure.ac b/argp-standalone/configure.ac
index fe54d5ac9..65ebc4518 100644
--- a/argp-standalone/configure.ac
+++ b/argp-standalone/configure.ac
@@ -10,6 +10,8 @@ AC_CONFIG_AUX_DIR([.])
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)])
+
# GNU libc defaults to supplying the ISO C library functions only. The
# _GNU_SOURCE define enables these extensions, in particular we want
# errno.h to declare program_invocation_name. Enable it on all
diff --git a/autogen.sh b/autogen.sh
index e20408bf2..ca69d4624 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-aclocal
+aclocal -I ./contrib/aclocal
autoheader
(libtoolize --automake --copy --force || glibtoolize --automake --copy --force)
autoconf
diff --git a/booster/src/booster-fd.c b/booster/src/booster-fd.c
index c324b25a4..fa5b0cde2 100644
--- a/booster/src/booster-fd.c
+++ b/booster/src/booster-fd.c
@@ -3,16 +3,16 @@
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/booster/src/booster-fd.h b/booster/src/booster-fd.h
index 19e249fe3..595a112bd 100644
--- a/booster/src/booster-fd.h
+++ b/booster/src/booster-fd.h
@@ -3,16 +3,16 @@
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/booster/src/booster.c b/booster/src/booster.c
index 41f71e96f..c34ec1146 100644
--- a/booster/src/booster.c
+++ b/booster/src/booster.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/booster/src/booster_stat.c b/booster/src/booster_stat.c
index 42fd45f5a..8f76cfe37 100644
--- a/booster/src/booster_stat.c
+++ b/booster/src/booster_stat.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am
index b50b7dbca..800283618 100644
--- a/cli/src/Makefile.am
+++ b/cli/src/Makefile.am
@@ -2,13 +2,13 @@ sbin_PROGRAMS = gluster
gluster_SOURCES = cli.c registry.c input.c cli-cmd.c cli-rl.c \
cli-cmd-volume.c cli-cmd-peer.c cli-rpc-ops.c cli-cmd-parser.c\
- cli-cmd-system.c cli-cmd-misc.c
+ cli-cmd-system.c cli-cmd-misc.c cli-xml-output.c
gluster_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(GF_LDADD)\
$(RLLIBS) $(top_builddir)/rpc/xdr/src/libgfxdr.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la
-gluster_LDFLAGS = $(GF_LDFLAGS) $(GF_GLUSTERFS_LDFLAGS)
+gluster_LDFLAGS = $(GF_LDFLAGS) $(GF_GLUSTERFS_LDFLAGS) $(LIBXML2_LIBS)
noinst_HEADERS = cli.h cli-mem-types.h cli-cmd.h
AM_CFLAGS = -fPIC -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)\
@@ -17,8 +17,8 @@ AM_CFLAGS = -fPIC -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)\
-DDATADIR=\"$(localstatedir)\" \
-DCONFDIR=\"$(sysconfdir)/glusterfs\" $(GF_GLUSTERFS_CFLAGS)\
-DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
- -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) -DGFS_PREFIX=\"$(prefix)\"
-
+ -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) -DSBIN_DIR=\"$(sbindir)\"\
+ $(LIBXML2_CFLAGS)
CLEANFILES =
diff --git a/cli/src/cli-cmd-misc.c b/cli/src/cli-cmd-misc.c
index 356118e19..66d755fc2 100644
--- a/cli/src/cli-cmd-misc.c
+++ b/cli/src/cli-cmd-misc.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -80,6 +80,10 @@ struct cli_cmd cli_misc_cmds[] = {
cli_cmd_display_help,
"display command options"},
+ { "exit",
+ cli_cmd_quit_cbk,
+ "exit"},
+
{ NULL, NULL, NULL }
};
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 735dcb02b..006c8a4f5 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -36,6 +36,18 @@
#include "protocol-common.h"
#include "cli1-xdr.h"
+static const char *
+id_sel (void *wcon)
+{
+ return (const char *)wcon;
+}
+
+static char *
+str_getunamb (const char *tok, char **opwords)
+{
+ return (char *)cli_getunamb (tok, (void **)opwords, id_sel);
+}
+
int32_t
cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
char **bricks, int *brick_count)
@@ -46,11 +58,11 @@ cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
char *space = " ";
char *delimiter = NULL;
char *host_name = NULL;
- char *tmp = NULL;
char *free_list_ptr = NULL;
char *tmpptr = NULL;
int j = 0;
int brick_list_len = 0;
+ char *tmp_host = NULL;
GF_ASSERT (words);
GF_ASSERT (wordcount);
@@ -61,26 +73,32 @@ cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
strncpy (brick_list, space, strlen (space));
brick_list_len++;
while (brick_index < wordcount) {
- delimiter = strchr (words[brick_index], ':');
- if (!delimiter || delimiter == words[brick_index]
- || *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use <HOSTNAME>:"
+ if (validate_brick_name ((char *)words[brick_index])) {
+ cli_err ("Wrong brick type: %s, use <HOSTNAME>:"
"<export-dir-abs-path>", words[brick_index]);
ret = -1;
goto out;
} else {
- cli_path_strip_trailing_slashes (delimiter + 1);
+ delimiter = strrchr (words[brick_index], ':');
+ ret = cli_canonicalize_path (delimiter + 1);
+ if (ret)
+ goto out;
}
if ((brick_list_len + strlen (words[brick_index]) + 1) > sizeof (brick_list)) {
- gf_log ("cli", GF_LOG_ERROR,
- "total brick list is larger than a request "
- "can take (brick_count %d)", *brick_count);
+ cli_err ("Total brick list is larger than a request. "
+ "Can take (brick_count %d)", *brick_count);
ret = -1;
goto out;
}
- host_name = gf_strdup (words[brick_index]);
+ tmp_host = gf_strdup ((char *)words[brick_index]);
+ if (!tmp_host) {
+ gf_log ("cli", GF_LOG_ERROR, "Out of memory");
+ ret = -1;
+ goto out;
+ }
+ get_host_name (tmp_host, &host_name);
if (!host_name) {
ret = -1;
gf_log("cli",GF_LOG_ERROR, "Unable to allocate "
@@ -88,20 +106,19 @@ cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
goto out;
}
- strtok_r (host_name, ":", &tmp);
if (!(strcmp (host_name, "localhost") &&
strcmp (host_name, "127.0.0.1"))) {
- cli_out ("Please provide a valid hostname/ip other "
+ cli_err ("Please provide a valid hostname/ip other "
"than localhost or 127.0.0.1");
ret = -1;
- GF_FREE (host_name);
+ GF_FREE (tmp_host);
goto out;
}
- if (!valid_host_name(host_name, strlen(host_name))) {
- cli_out ("internet address '%s' does not comform to "
- "standards", host_name);
+ if (!valid_internet_address (host_name, _gf_false)) {
+ cli_err ("internet address '%s' does not conform to "
+ "standards", host_name);
}
- GF_FREE (host_name);
+ GF_FREE (tmp_host);
tmp_list = gf_strdup (brick_list + 1);
if (free_list_ptr) {
GF_FREE (free_list_ptr);
@@ -113,7 +130,7 @@ cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
strtok_r (tmp_list, " ", &tmpptr);
if (!(strcmp (tmp_list, words[brick_index]))) {
ret = -1;
- cli_out ("Found duplicate"
+ cli_err ("Found duplicate"
" exports %s",words[brick_index]);
goto out;
}
@@ -144,19 +161,22 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
int ret = -1;
gf1_cluster_type type = GF_CLUSTER_TYPE_NONE;
int count = 1;
+ int sub_count = 1;
int brick_index = 0;
int i = 0;
char *trans_type = NULL;
int32_t index = 0;
char *bricks = NULL;
int32_t brick_count = 0;
+ char *opwords[] = { "replica", "stripe", "transport", NULL };
+ char *w = NULL;
+ int op_count = 0;
+ int32_t replica_count = 1;
+ int32_t stripe_count = 1;
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "create")) == 0);
-
dict = dict_new ();
if (!dict)
@@ -175,7 +195,7 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
goto out;
if (!strcmp (volname, "all")) {
- cli_out ("\"all\" cannot be the name of a volume.");
+ cli_err ("\"all\" cannot be the name of a volume.");
goto out;
}
@@ -190,93 +210,122 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
goto out;
}
-
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
-
if (wordcount < 4) {
ret = -1;
goto out;
}
- if ((strcasecmp (words[3], "replica")) == 0) {
- type = GF_CLUSTER_TYPE_REPLICATE;
- if (wordcount < 5) {
- ret = -1;
- goto out;
- }
- count = strtol (words[4], NULL, 0);
- if (!count || (count < 2)) {
- cli_out ("replica count should be greater than 1");
- ret = -1;
- goto out;
- }
- ret = dict_set_int32 (dict, "replica-count", count);
- if (ret)
- goto out;
- brick_index = 5;
- } else if ((strcasecmp (words[3], "stripe")) == 0) {
- type = GF_CLUSTER_TYPE_STRIPE;
- if (wordcount < 5) {
- ret = -1;
- goto out;
- }
- count = strtol (words[4], NULL, 0);
- if (!count || (count < 2)) {
- cli_out ("stripe count should be greater than 1");
- ret = -1;
- goto out;
- }
- ret = dict_set_int32 (dict, "stripe-count", count);
- if (ret)
- goto out;
- brick_index = 5;
- } else {
- type = GF_CLUSTER_TYPE_NONE;
- brick_index = 3;
- }
- ret = dict_set_int32 (dict, "type", type);
- if (ret)
- goto out;
-
- if (type)
- index = 5;
- else
- index = 3;
+ type = GF_CLUSTER_TYPE_NONE;
+ index = 3;
- if (wordcount < (index + 1)) {
+ while (op_count < 3) {
ret = -1;
- goto out;
- }
+ w = str_getunamb (words[index], opwords);
+ if (!w) {
+ break;
+ } else if ((strcmp (w, "replica")) == 0) {
+ switch (type) {
+ case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
+ case GF_CLUSTER_TYPE_REPLICATE:
+ cli_err ("replica option given twice");
+ goto out;
+ case GF_CLUSTER_TYPE_NONE:
+ type = GF_CLUSTER_TYPE_REPLICATE;
+ break;
+ case GF_CLUSTER_TYPE_STRIPE:
+ type = GF_CLUSTER_TYPE_STRIPE_REPLICATE;
+ break;
+ }
- if (strcasecmp(words[index], "transport") == 0) {
- brick_index = index+2;
- if (wordcount < (index + 2)) {
- ret = -1;
- goto out;
- }
+ if (wordcount < (index+2)) {
+ ret = -1;
+ goto out;
+ }
+ replica_count = strtol (words[index+1], NULL, 0);
+ if (replica_count < 2) {
+ cli_err ("replica count should be greater"
+ " than 1");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_int32 (dict, "replica-count", replica_count);
+ if (ret)
+ goto out;
+
+ index += 2;
+
+ } else if ((strcmp (w, "stripe")) == 0) {
+ switch (type) {
+ case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
+ case GF_CLUSTER_TYPE_STRIPE:
+ cli_err ("stripe option given twice");
+ goto out;
+ case GF_CLUSTER_TYPE_NONE:
+ type = GF_CLUSTER_TYPE_STRIPE;
+ break;
+ case GF_CLUSTER_TYPE_REPLICATE:
+ type = GF_CLUSTER_TYPE_STRIPE_REPLICATE;
+ break;
+ }
+ if (wordcount < (index + 2)) {
+ ret = -1;
+ goto out;
+ }
+ stripe_count = strtol (words[index+1], NULL, 0);
+ if (stripe_count < 2) {
+ cli_err ("stripe count should be greater"
+ " than 1");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_int32 (dict, "stripe-count", stripe_count);
+ if (ret)
+ goto out;
- if ((strcasecmp (words[index+1], "tcp") == 0)) {
- trans_type = gf_strdup ("tcp");
- } else if ((strcasecmp (words[index+1], "rdma") == 0)) {
- trans_type = gf_strdup ("rdma");
- } else if ((strcasecmp (words[index+1], "tcp,rdma") == 0) ||
- (strcasecmp (words[index+1], "rdma,tcp") == 0)) {
- trans_type = gf_strdup ("tcp,rdma");
+ index += 2;
+
+ } else if ((strcmp (w, "transport")) == 0) {
+ if (trans_type) {
+ cli_err ("'transport' option given more"
+ " than one time");
+ goto out;
+ }
+ if ((strcasecmp (words[index+1], "tcp") == 0)) {
+ trans_type = gf_strdup ("tcp");
+ } else if ((strcasecmp (words[index+1], "rdma") == 0)) {
+ trans_type = gf_strdup ("rdma");
+ } else if ((strcasecmp (words[index+1], "tcp,rdma") == 0) ||
+ (strcasecmp (words[index+1], "rdma,tcp") == 0)) {
+ trans_type = gf_strdup ("tcp,rdma");
+ } else {
+ gf_log ("", GF_LOG_ERROR, "incorrect transport"
+ " protocol specified");
+ ret = -1;
+ goto out;
+ }
+ index += 2;
} else {
- gf_log ("", GF_LOG_ERROR, "incorrect transport"
- " protocol specified");
+ GF_ASSERT (!"opword mismatch");
ret = -1;
goto out;
}
- } else {
- trans_type = gf_strdup ("tcp");
+ op_count++;
}
- ret = dict_set_dynstr (dict, "transport", trans_type);
- if (ret)
+ if (!trans_type)
+ trans_type = gf_strdup ("tcp");
+
+ sub_count = stripe_count * replica_count;
+
+ /* reset the count value now */
+ count = 1;
+
+ if (index >= wordcount) {
+ ret = -1;
goto out;
+ }
+
+ brick_index = index;
ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks,
&brick_count);
@@ -286,22 +335,40 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
/* If brick-count is not valid when replica or stripe is
given, exit here */
if (!brick_count) {
- cli_out ("No bricks specified");
+ cli_err ("No bricks specified");
ret = -1;
goto out;
}
- if (brick_count % count) {
+ if (brick_count % sub_count) {
if (type == GF_CLUSTER_TYPE_STRIPE)
- cli_out ("number of bricks is not a multiple of "
+ cli_err ("number of bricks is not a multiple of "
"stripe count");
else if (type == GF_CLUSTER_TYPE_REPLICATE)
- cli_out ("number of bricks is not a multiple of "
+ cli_err ("number of bricks is not a multiple of "
"replica count");
+ else
+ cli_err ("number of bricks given doesn't match "
+ "required count");
+
ret = -1;
goto out;
}
+ /* Everything if parsed fine. start setting info in dict */
+ ret = dict_set_str (dict, "volname", volname);
+ if (ret)
+ goto out;
+
+ ret = dict_set_int32 (dict, "type", type);
+ if (ret)
+ goto out;
+
+ ret = dict_set_dynstr (dict, "transport", trans_type);
+ if (ret)
+ goto out;
+
+
ret = dict_set_dynstr (dict, "bricks", bricks);
if (ret)
goto out;
@@ -331,9 +398,6 @@ cli_cmd_volume_reset_parse (const char **words, int wordcount, dict_t **options)
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "reset")) == 0);
-
dict = dict_new ();
if (!dict)
@@ -342,7 +406,7 @@ cli_cmd_volume_reset_parse (const char **words, int wordcount, dict_t **options)
if (wordcount < 3)
goto out;
- if (wordcount > 4)
+ if (wordcount > 5)
goto out;
volname = (char *)words[2];
@@ -356,8 +420,29 @@ cli_cmd_volume_reset_parse (const char **words, int wordcount, dict_t **options)
if (ret)
goto out;
- if (wordcount == 4) {
- if (strcmp ("force", (char*)words[3])) {
+ if (wordcount == 3) {
+ ret = dict_set_str (dict, "key", "all");
+ if (ret)
+ goto out;
+ }
+
+ if (wordcount >= 4) {
+ if (!strcmp ("force", (char*)words[3])) {
+ ret = dict_set_int32 (dict, "force", 1);
+ if (ret)
+ goto out;
+ ret = dict_set_str (dict, "key", "all");
+ if (ret)
+ goto out;
+ } else {
+ ret = dict_set_str (dict, "key", (char *)words[3]);
+ if (ret)
+ goto out;
+ }
+ }
+
+ if (wordcount == 5) {
+ if (strcmp ("force", (char*)words[4])) {
ret = -1;
goto out;
} else {
@@ -387,15 +472,14 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
char key[20] = {0, };
uint64_t value = 0;
gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE;
+ char *opwords[] = { "enable", "disable", "limit-usage",
+ "remove", "list", "version", NULL };
+ char *w = NULL;
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "quota")) == 0);
-
dict = dict_new ();
-
if (!dict)
goto out;
@@ -403,7 +487,6 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto out;
volname = (char *)words[2];
-
if (!volname) {
ret = -1;
goto out;
@@ -415,7 +498,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto out;
if (!strcmp (volname, "all")) {
- cli_out ("\"all\" cannot be the name of a volume.");
+ cli_err ("\"all\" cannot be the name of a volume.");
goto out;
}
@@ -431,21 +514,28 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
}
ret = dict_set_str (dict, "volname", volname);
- if (ret)
+ if (ret < 0)
goto out;
+ w = str_getunamb (words[3], opwords);
+ if (!w) {
+ ret = - 1;
+ goto out;
+ }
- if ((strcasecmp (words[3], "enable")) == 0 && wordcount == 4) {
+ if ((strcmp (w, "enable")) == 0 && wordcount == 4) {
type = GF_QUOTA_OPTION_TYPE_ENABLE;
+ ret = 0;
goto set_type;
}
- if (strcasecmp (words[3], "disable") == 0 && wordcount == 4) {
+ if (strcmp (w, "disable") == 0 && wordcount == 4) {
type = GF_QUOTA_OPTION_TYPE_DISABLE;
+ ret = 0;
goto set_type;
}
- if (strcasecmp (words[3], "limit-usage") == 0) {
+ if (strcmp (w, "limit-usage") == 0) {
if (wordcount != 6) {
ret = -1;
goto out;
@@ -454,7 +544,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
type = GF_QUOTA_OPTION_TYPE_LIMIT_USAGE;
if (words[4][0] != '/') {
- cli_out ("Please enter absolute path");
+ cli_err ("Please enter absolute path");
return -2;
}
@@ -463,24 +553,24 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto out;
if (!words[5]) {
- cli_out ("Please enter the limit value to be set");
+ cli_err ("Please enter the limit value to be set");
return -2;
}
ret = gf_string2bytesize (words[5], &value);
if (ret != 0) {
- cli_out ("Please enter a correct value");
+ cli_err ("Please enter a correct value");
return -1;
}
ret = dict_set_str (dict, "limit", (char *) words[5]);
- if (ret)
+ if (ret < 0)
goto out;
goto set_type;
}
- if (strcasecmp (words[3], "remove") == 0) {
+ if (strcmp (w, "remove") == 0) {
if (wordcount != 5) {
ret = -1;
goto out;
@@ -489,57 +579,55 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
type = GF_QUOTA_OPTION_TYPE_REMOVE;
if (words[4][0] != '/') {
- cli_out ("Please enter absolute path");
+ cli_err ("Please enter absolute path");
return -2;
}
ret = dict_set_str (dict, "path", (char *) words[4]);
- if (ret)
+ if (ret < 0)
goto out;
goto set_type;
}
- if (strcasecmp (words[3], "list") == 0) {
- if (wordcount < 4) {
- ret = -1;
- goto out;
- }
-
- type = GF_QUOTA_OPTION_TYPE_LIST;
+ if (strcmp (w, "list") == 0) {
+ if (wordcount < 4) {
+ ret = -1;
+ goto out;
+ }
- i = 4;
- while (i < wordcount) {
- snprintf (key, 20, "path%d", i-4);
+ type = GF_QUOTA_OPTION_TYPE_LIST;
- ret = dict_set_str (dict, key, (char *) words [i++]);
- if (ret < 0)
- goto out;
- }
+ i = 4;
+ while (i < wordcount) {
+ snprintf (key, 20, "path%d", i-4);
- ret = dict_set_int32 (dict, "count", i - 4);
+ ret = dict_set_str (dict, key, (char *) words [i++]);
if (ret < 0)
goto out;
+ }
+
+ ret = dict_set_int32 (dict, "count", i - 4);
+ if (ret < 0)
+ goto out;
- goto set_type;
+ goto set_type;
}
- if (strcasecmp (words[3], "version") == 0) {
+ if (strcmp (w, "version") == 0) {
type = GF_QUOTA_OPTION_TYPE_VERSION;
-
} else {
- ret = -1;
- goto out;
+ GF_ASSERT (!"opword mismatch");
}
set_type:
ret = dict_set_int32 (dict, "type", type);
-
- if (ret)
+ if (ret < 0)
goto out;
+
*options = dict;
out:
- if (ret) {
+ if (ret < 0) {
if (dict)
dict_destroy (dict);
}
@@ -547,30 +635,113 @@ out:
return ret;
}
+static inline gf_boolean_t
+cli_is_key_spl (char *key)
+{
+ return (strcmp (key, "group") == 0);
+}
+
+#define GLUSTERD_DEFAULT_WORKDIR "/var/lib/glusterd"
+static int
+cli_add_key_group (dict_t *dict, char *key, char *value)
+{
+ int ret = -1;
+ int opt_count = 0;
+ char iter_key[1024] = {0,};
+ char iter_val[1024] = {0,};
+ char *saveptr = NULL;
+ char *tok_key = NULL;
+ char *tok_val = NULL;
+ char *dkey = NULL;
+ char *dval = NULL;
+ char *tagpath = NULL;
+ char *buf = NULL;
+ char line[PATH_MAX + 256] = {0,};
+ FILE *fp = NULL;
+
+ ret = gf_asprintf (&tagpath, "%s/groups/%s",
+ GLUSTERD_DEFAULT_WORKDIR, value);
+ if (ret == -1) {
+ tagpath = NULL;
+ goto out;
+ }
+
+ fp = fopen (tagpath, "r");
+ if (!fp) {
+ ret = -1;
+ goto out;
+ }
+
+ opt_count = 0;
+ buf = line;
+ while (fscanf (fp, "%s", buf) != EOF) {
+
+ opt_count++;
+ tok_key = strtok_r (line, "=", &saveptr);
+ tok_val = strtok_r (NULL, "=", &saveptr);
+ if (!tok_key || !tok_val) {
+ ret = -1;
+ goto out;
+ }
+
+ snprintf (iter_key, sizeof (iter_key), "key%d", opt_count);
+ dkey = gf_strdup (tok_key);
+ ret = dict_set_dynstr (dict, iter_key, dkey);
+ if (ret)
+ goto out;
+ dkey = NULL;
+
+ snprintf (iter_val, sizeof (iter_val), "value%d", opt_count);
+ dval = gf_strdup (tok_val);
+ ret = dict_set_dynstr (dict, iter_val, dval);
+ if (ret)
+ goto out;
+ dval = NULL;
+
+ }
+
+ if (!opt_count) {
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_int32 (dict, "count", opt_count);
+out:
+
+ GF_FREE (tagpath);
+
+ if (ret) {
+ GF_FREE (dkey);
+ GF_FREE (dval);
+ }
+
+ if (fp)
+ fclose (fp);
+
+ return ret;
+}
+#undef GLUSTERD_DEFAULT_WORKDIR
+
int32_t
cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- int ret = -1;
- int count = 0;
- char *key = NULL;
- char *value = NULL;
- int i = 0;
- char str[50] = {0,};
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
+ int count = 0;
+ char *key = NULL;
+ char *value = NULL;
+ int i = 0;
+ char str[50] = {0,};
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "set")) == 0);
-
dict = dict_new ();
if (!dict)
goto out;
- if (wordcount < 4)
+ if (wordcount < 3)
goto out;
volname = (char *)words[2];
@@ -582,19 +753,55 @@ cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options)
if (ret)
goto out;
+ if ((!strcmp (volname, "help") || !strcmp (volname, "help-xml"))
+ && wordcount == 3 ) {
+ ret = dict_set_str (dict, volname, volname);
+ if (ret)
+ goto out;
+
+ } else if (wordcount < 5) {
+ ret = -1;
+ goto out;
+
+ } else if (wordcount == 5 && cli_is_key_spl ((char *)words[3])) {
+ key = (char *) words[3];
+ value = (char *) words[4];
+ if ( !key || !value) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = gf_strip_whitespace (value, strlen (value));
+ if (ret == -1)
+ goto out;
+
+ ret = cli_add_key_group (dict, key, value);
+ if (ret == 0)
+ *options = dict;
+ goto out;
+ }
for (i = 3; i < wordcount; i+=2) {
- key = (char *) words[i];
- value = (char *) words[i+1];
+ key = (char *) words[i];
+ value = (char *) words[i+1];
- if ( !key || !value) {
- ret = -1;
- goto out;
- }
+ if ( !key || !value) {
+ ret = -1;
+ goto out;
+ }
count++;
+ ret = gf_strip_whitespace (value, strlen (value));
+ if (ret == -1)
+ goto out;
+
+ if (cli_is_key_spl (key)) {
+ ret = -1;
+ goto out;
+ }
+
sprintf (str, "key%d", count);
ret = dict_set_str (dict, str, key);
if (ret)
@@ -615,10 +822,8 @@ cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options)
*options = dict;
out:
- if (ret) {
- if (dict)
- dict_destroy (dict);
- }
+ if (ret)
+ dict_destroy (dict);
return ret;
}
@@ -632,13 +837,15 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
int ret = -1;
int brick_count = 0, brick_index = 0;
char *bricks = NULL;
+ char *opwords_cl[] = { "replica", "stripe", NULL };
+ gf1_cluster_type type = GF_CLUSTER_TYPE_NONE;
+ int count = 1;
+ char *w = NULL;
+ int index;
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "add-brick")) == 0);
-
dict = dict_new ();
if (!dict)
@@ -660,8 +867,58 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
ret = -1;
goto out;
}
+ if (wordcount < 6) {
+ /* seems no options are given, go directly to the parse_brick */
+ brick_index = 3;
+ type = GF_CLUSTER_TYPE_NONE;
+ goto parse_bricks;
+ }
- brick_index = 3;
+ w = str_getunamb (words[3], opwords_cl);
+ if (!w) {
+ type = GF_CLUSTER_TYPE_NONE;
+ index = 3;
+ } else if ((strcmp (w, "replica")) == 0) {
+ type = GF_CLUSTER_TYPE_REPLICATE;
+ if (wordcount < 5) {
+ ret = -1;
+ goto out;
+ }
+ count = strtol (words[4], NULL, 0);
+ if (!count || (count < 2)) {
+ cli_err ("replica count should be greater than 1");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_int32 (dict, "replica-count", count);
+ if (ret)
+ goto out;
+ index = 5;
+ } else if ((strcmp (w, "stripe")) == 0) {
+ type = GF_CLUSTER_TYPE_STRIPE;
+ if (wordcount < 5) {
+ ret = -1;
+ goto out;
+ }
+ count = strtol (words[4], NULL, 0);
+ if (!count || (count < 2)) {
+ cli_err ("stripe count should be greater than 1");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_int32 (dict, "stripe-count", count);
+ if (ret)
+ goto out;
+ index = 5;
+ } else {
+ GF_ASSERT (!"opword mismatch");
+ ret = -1;
+ goto out;
+ }
+
+ brick_index = index;
+
+parse_bricks:
ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks,
&brick_count);
if (ret)
@@ -691,7 +948,7 @@ out:
int32_t
cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
- dict_t **options)
+ dict_t **options, int *question)
{
dict_t *dict = NULL;
char *volname = NULL;
@@ -703,39 +960,94 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
int32_t j = 0;
char *tmp_brick = NULL;
char *tmp_brick1 = NULL;
+ char *type_opword[] = { "replica", NULL };
+ char *opwords[] = { "start", "commit", "stop", "status",
+ "force", NULL };
+ char *w = NULL;
+ int32_t command = GF_OP_CMD_NONE;
+ long count = 0;
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "remove-brick")) == 0);
+ if (wordcount < 4)
+ goto out;
dict = dict_new ();
-
if (!dict)
goto out;
- if (wordcount < 3)
- goto out;
-
volname = (char *)words[2];
GF_ASSERT (volname);
ret = dict_set_str (dict, "volname", volname);
-
if (ret)
goto out;
+ brick_index = 3;
+ w = str_getunamb (words[3], type_opword);
+ if (w && !strcmp ("replica", w)) {
+ if (wordcount < 5) {
+ ret = -1;
+ goto out;
+ }
+ count = strtol (words[4], NULL, 0);
+ if (count < 1) {
+ cli_err ("replica count should be greater than 0 in "
+ "case of remove-brick");
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_int32 (dict, "replica-count", count);
+ if (ret)
+ goto out;
+ brick_index = 5;
+ } else if (w) {
+ GF_ASSERT (!"opword mismatch");
+ }
+
+ w = str_getunamb (words[wordcount - 1], opwords);
+ if (!w) {
+ /* Should be default 'force' */
+ command = GF_OP_CMD_COMMIT_FORCE;
+ if (question)
+ *question = 1;
+ } else {
+ /* handled this option */
+ wordcount--;
+ if (!strcmp ("start", w)) {
+ command = GF_OP_CMD_START;
+ } else if (!strcmp ("commit", w)) {
+ command = GF_OP_CMD_COMMIT;
+ if (question)
+ *question = 1;
+ } else if (!strcmp ("stop", w)) {
+ command = GF_OP_CMD_STOP;
+ } else if (!strcmp ("status", w)) {
+ command = GF_OP_CMD_STATUS;
+ } else if (!strcmp ("force", w)) {
+ command = GF_OP_CMD_COMMIT_FORCE;
+ if (question)
+ *question = 1;
+ } else {
+ GF_ASSERT (!"opword mismatch");
+ ret = -1;
+ goto out;
+ }
+ }
+
if (wordcount < 4) {
ret = -1;
goto out;
}
- brick_index = 3;
-
+ ret = dict_set_int32 (dict, "command", command);
if (ret)
- goto out;
+ gf_log ("cli", GF_LOG_INFO, "failed to set 'command' %d",
+ command);
+
tmp_index = brick_index;
tmp_brick = GF_MALLOC(2048 * sizeof(*tmp_brick), gf_common_mt_char);
@@ -746,7 +1058,7 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
ret = -1;
goto out;
}
-
+
tmp_brick1 = GF_MALLOC(2048 * sizeof(*tmp_brick1), gf_common_mt_char);
if (!tmp_brick1) {
@@ -757,15 +1069,16 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
}
while (brick_index < wordcount) {
- delimiter = strchr(words[brick_index], ':');
- if (!delimiter || delimiter == words[brick_index]
- || *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use <HOSTNAME>:"
+ if (validate_brick_name ((char *)words[brick_index])) {
+ cli_err ("wrong brick type: %s, use <HOSTNAME>:"
"<export-dir-abs-path>", words[brick_index]);
ret = -1;
goto out;
} else {
- cli_path_strip_trailing_slashes (delimiter + 1);
+ delimiter = strrchr(words[brick_index], ':');
+ ret = cli_canonicalize_path (delimiter + 1);
+ if (ret)
+ goto out;
}
j = tmp_index;
@@ -775,7 +1088,7 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
if (!(strcmp (tmp_brick, tmp_brick1))) {
gf_log("",GF_LOG_ERROR, "Duplicate bricks"
" found %s", words[brick_index]);
- cli_out("Duplicate bricks found %s",
+ cli_err("Duplicate bricks found %s",
words[brick_index]);
ret = -1;
goto out;
@@ -790,7 +1103,6 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
}
ret = dict_set_int32 (dict, "count", brick_count);
-
if (ret)
goto out;
@@ -819,17 +1131,16 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
dict_t *dict = NULL;
char *volname = NULL;
int ret = -1;
- char *op = NULL;
int op_index = 0;
char *delimiter = NULL;
gf1_cli_replace_op replace_op = GF_REPLACE_OP_NONE;
+ char *opwords[] = { "start", "commit", "pause", "abort", "status",
+ NULL };
+ char *w = NULL;
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "replace-brick")) == 0);
-
dict = dict_new ();
if (!dict)
@@ -852,15 +1163,16 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
goto out;
}
- delimiter = strchr ((char *)words[3], ':');
- if (!delimiter || delimiter == words[3]
- || *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use "
- "<HOSTNAME>:<export-dir-abs-path>", words[3]);
+ if (validate_brick_name ((char *)words[3])) {
+ cli_err ("wrong brick type: %s, use "
+ "<HOSTNAME>:<export-dir-abs-path>", words[3]);
ret = -1;
goto out;
} else {
- cli_path_strip_trailing_slashes (delimiter + 1);
+ delimiter = strrchr ((char *)words[3], ':');
+ ret = cli_canonicalize_path (delimiter + 1);
+ if (ret)
+ goto out;
}
ret = dict_set_str (dict, "src-brick", (char *)words[3]);
@@ -872,15 +1184,16 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
goto out;
}
- delimiter = strchr ((char *)words[4], ':');
- if (!delimiter || delimiter == words[4]
- || *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use "
- "<HOSTNAME>:<export-dir-abs-path>", words[4]);
+ if (validate_brick_name ((char *)words[4])) {
+ cli_err ("wrong brick type: %s, use "
+ "<HOSTNAME>:<export-dir-abs-path>", words[4]);
ret = -1;
goto out;
} else {
- cli_path_strip_trailing_slashes (delimiter + 1);
+ delimiter = strrchr ((char *)words[4], ':');
+ ret = cli_canonicalize_path (delimiter + 1);
+ if (ret)
+ goto out;
}
@@ -895,21 +1208,24 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
goto out;
}
- op = (char *) words[op_index];
+ w = str_getunamb (words[op_index], opwords);
- if (!strcasecmp ("start", op)) {
+ if (!w) {
+ } else if (!strcmp ("start", w)) {
replace_op = GF_REPLACE_OP_START;
- } else if (!strcasecmp ("commit", op)) {
+ } else if (!strcmp ("commit", w)) {
replace_op = GF_REPLACE_OP_COMMIT;
- } else if (!strcasecmp ("pause", op)) {
+ } else if (!strcmp ("pause", w)) {
replace_op = GF_REPLACE_OP_PAUSE;
- } else if (!strcasecmp ("abort", op)) {
+ } else if (!strcmp ("abort", w)) {
replace_op = GF_REPLACE_OP_ABORT;
- } else if (!strcasecmp ("status", op)) {
+ } else if (!strcmp ("status", w)) {
replace_op = GF_REPLACE_OP_STATUS;
- }
+ } else
+ GF_ASSERT (!"opword mismatch");
/* commit force option */
+
op_index = 6;
if (wordcount > (op_index + 1)) {
@@ -918,8 +1234,11 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
}
if (wordcount == (op_index + 1)) {
- op = (char *) words[op_index];
- if (!strcasecmp ("force", op)) {
+ if (replace_op != GF_REPLACE_OP_COMMIT) {
+ ret = -1;
+ goto out;
+ }
+ if (!strcmp ("force", words[op_index])) {
replace_op = GF_REPLACE_OP_COMMIT_FORCE;
}
}
@@ -935,13 +1254,11 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
goto out;
-
-
*options = dict;
out:
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse remove-brick CLI");
+ gf_log ("cli", GF_LOG_ERROR, "Unable to parse replace-brick CLI");
if (dict)
dict_destroy (dict);
}
@@ -961,10 +1278,6 @@ cli_cmd_log_filename_parse (const char **words, int wordcount, dict_t **options)
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "log")) == 0);
- GF_ASSERT ((strcmp (words[2], "filename")) == 0);
-
dict = dict_new ();
if (!dict)
goto out;
@@ -981,12 +1294,14 @@ cli_cmd_log_filename_parse (const char **words, int wordcount, dict_t **options)
delimiter = strchr (words[4], ':');
if (!delimiter || delimiter == words[4]
|| *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use <HOSTNAME>:"
+ cli_err ("wrong brick type: %s, use <HOSTNAME>:"
"<export-dir-abs-path>", words[4]);
ret = -1;
goto out;
} else {
- cli_path_strip_trailing_slashes (delimiter + 1);
+ ret = cli_canonicalize_path (delimiter + 1);
+ if (ret)
+ goto out;
}
ret = dict_set_str (dict, "brick", str);
if (ret)
@@ -1012,6 +1327,63 @@ out:
}
int32_t
+cli_cmd_log_level_parse (const char **words, int worcount, dict_t **options)
+{
+ dict_t *dict = NULL;
+ int ret = -1;
+
+ GF_ASSERT (words);
+ GF_ASSERT (options);
+
+ /*
+ * loglevel command format:
+ * > volume log level <VOL> <XLATOR[*]> <LOGLEVEL>
+ * > volume log level colon-o posix WARNING
+ * > volume log level colon-o replicate* DEBUG
+ * > volume log level coon-o * TRACE
+ */
+
+ GF_ASSERT ((strncmp(words[0], "volume", 6) == 0));
+ GF_ASSERT ((strncmp(words[1], "log", 3) == 0));
+ GF_ASSERT ((strncmp(words[2], "level", 5) == 0));
+
+ ret = glusterd_check_log_level(words[5]);
+ if (ret == -1) {
+ cli_err("Invalid log level [%s] specified", words[5]);
+ cli_err("Valid values for loglevel: (DEBUG|WARNING|ERROR"
+ "|CRITICAL|NONE|TRACE)");
+ goto out;
+ }
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ GF_ASSERT(words[3]);
+ GF_ASSERT(words[4]);
+
+ ret = dict_set_str (dict, "volname", (char *)words[3]);
+ if (ret)
+ goto out;
+
+ ret = dict_set_str (dict, "xlator", (char *)words[4]);
+ if (ret)
+ goto out;
+
+ ret = dict_set_str (dict, "loglevel", (char *)words[5]);
+ if (ret)
+ goto out;
+
+ *options = dict;
+
+ out:
+ if (ret && dict)
+ dict_destroy (dict);
+
+ return ret;
+}
+
+int32_t
cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options)
{
dict_t *dict = NULL;
@@ -1023,10 +1395,6 @@ cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options)
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "log")) == 0);
- GF_ASSERT ((strcmp (words[2], "locate")) == 0);
-
dict = dict_new ();
if (!dict)
goto out;
@@ -1042,12 +1410,14 @@ cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options)
delimiter = strchr (words[4], ':');
if (!delimiter || delimiter == words[4]
|| *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use <HOSTNAME>:"
+ cli_err ("wrong brick type: %s, use <HOSTNAME>:"
"<export-dir-abs-path>", words[4]);
ret = -1;
goto out;
} else {
- cli_path_strip_trailing_slashes (delimiter + 1);
+ ret = cli_canonicalize_path (delimiter + 1);
+ if (ret)
+ goto out;
}
str = (char *)words[4];
ret = dict_set_str (dict, "brick", str);
@@ -1076,10 +1446,6 @@ cli_cmd_log_rotate_parse (const char **words, int wordcount, dict_t **options)
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "log")) == 0);
- GF_ASSERT ((strcmp (words[2], "rotate")) == 0);
-
dict = dict_new ();
if (!dict)
goto out;
@@ -1095,12 +1461,14 @@ cli_cmd_log_rotate_parse (const char **words, int wordcount, dict_t **options)
delimiter = strchr (words[4], ':');
if (!delimiter || delimiter == words[4]
|| *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use <HOSTNAME>:"
+ cli_err ("wrong brick type: %s, use <HOSTNAME>:"
"<export-dir-abs-path>", words[4]);
ret = -1;
goto out;
} else {
- cli_path_strip_trailing_slashes (delimiter + 1);
+ ret = cli_canonicalize_path (delimiter + 1);
+ if (ret)
+ goto out;
}
str = (char *)words[4];
ret = dict_set_str (dict, "brick", str);
@@ -1123,6 +1491,12 @@ gsyncd_url_check (const char *w)
return !!strpbrk (w, ":/");
}
+static gf_boolean_t
+gsyncd_glob_check (const char *w)
+{
+ return !!strpbrk (w, "*?[");
+}
+
int32_t
cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)
{
@@ -1135,14 +1509,15 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)
int i = 0;
unsigned masteri = 0;
unsigned slavei = 0;
+ unsigned glob = 0;
unsigned cmdi = 0;
+ char *opwords[] = { "status", "start", "stop", "config",
+ "log-rotate", NULL };
+ char *w = NULL;
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], GEOREP)) == 0);
-
dict = dict_new ();
if (!dict)
goto out;
@@ -1152,18 +1527,32 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)
* volume geo-replication [$m [$s]] status
* volume geo-replication [$m] $s config [[!]$opt [$val]]
* volume geo-replication $m $s start|stop
+ * volume geo-replication $m [$s] log-rotate
*/
if (wordcount < 3)
goto out;
for (i = 2; i <= 3 && i < wordcount - 1; i++) {
+ if (gsyncd_glob_check (words[i]))
+ glob = i;
if (gsyncd_url_check (words[i])) {
slavei = i;
break;
}
}
+ if (glob && !slavei)
+ /* glob is allowed only for config, thus it implies there is a
+ * slave argument; but that might have not been recognized on
+ * the first scan as it's url characteristics has been covered
+ * by the glob syntax.
+ *
+ * In this case, the slave is perforce the last glob-word -- the
+ * upcoming one is neither glob, nor url, so it's definitely not
+ * the slave.
+ */
+ slavei = glob;
if (slavei) {
cmdi = slavei + 1;
if (slavei == 3)
@@ -1188,33 +1577,43 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)
if (masteri && gsyncd_url_check (words[masteri]))
goto out;
- if (slavei && !gsyncd_url_check (words[slavei]))
+ if (slavei && !glob && !gsyncd_url_check (words[slavei]))
goto out;
- if (strcmp (words[cmdi], "status") == 0) {
+ w = str_getunamb (words[cmdi], opwords);
+ if (!w)
+ goto out;
+
+ if (strcmp (w, "status") == 0) {
type = GF_GSYNC_OPTION_TYPE_STATUS;
if (slavei && !masteri)
goto out;
- } else if (strcmp (words[cmdi], "config") == 0) {
+ } else if (strcmp (w, "config") == 0) {
type = GF_GSYNC_OPTION_TYPE_CONFIG;
if (!slavei)
goto out;
- } else if (strcmp (words[cmdi], "start") == 0) {
+ } else if (strcmp (w, "start") == 0) {
type = GF_GSYNC_OPTION_TYPE_START;
if (!masteri || !slavei)
goto out;
- } else if (strcmp (words[cmdi], "stop") == 0) {
+ } else if (strcmp (w, "stop") == 0) {
type = GF_GSYNC_OPTION_TYPE_STOP;
if (!masteri || !slavei)
goto out;
+ } else if (strcmp(w, "log-rotate") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_ROTATE;
+
+ if (slavei && !masteri)
+ goto out;
} else
- goto out;
+ GF_ASSERT (!"opword mismatch");
- if (type != GF_GSYNC_OPTION_TYPE_CONFIG && cmdi < wordcount - 1)
+ if (type != GF_GSYNC_OPTION_TYPE_CONFIG &&
+ (cmdi < wordcount - 1 || glob))
goto out;
/* If got so far, input is valid, assemble the message */
@@ -1235,7 +1634,8 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)
case 1:
if (words[cmdi + 1][0] == '!') {
(words[cmdi + 1])++;
- subop = gf_strdup ("del");
+ if (gf_asprintf (&subop, "del%s", glob ? "-glob" : "") == -1)
+ subop = NULL;
} else
subop = gf_strdup ("get");
@@ -1244,7 +1644,8 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)
goto out;
break;
default:
- subop = gf_strdup ("set");
+ if (gf_asprintf (&subop, "set%s", glob ? "-glob" : "") == -1)
+ subop = NULL;
ret = dict_set_str (dict, "op_name", ((char *)words[cmdi + 1]));
if (ret < 0)
@@ -1296,18 +1697,17 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount,
char *volname = NULL;
int ret = -1;
gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+ char *opwords[] = { "start", "stop", "info", NULL };
+ char *w = NULL;
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "profile")) == 0);
-
dict = dict_new ();
if (!dict)
goto out;
- if (wordcount != 4)
+ if (wordcount < 4 || wordcount >5)
goto out;
volname = (char *)words[2];
@@ -1316,17 +1716,32 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount,
if (ret)
goto out;
- if (strcmp (words[3], "start") == 0) {
+ w = str_getunamb (words[3], opwords);
+ if (!w) {
+ ret = -1;
+ goto out;
+ }
+ if (strcmp (w, "start") == 0) {
op = GF_CLI_STATS_START;
- } else if (strcmp (words[3], "stop") == 0) {
+ } else if (strcmp (w, "stop") == 0) {
op = GF_CLI_STATS_STOP;
- } else if (strcmp (words[3], "info") == 0) {
+ } else if (strcmp (w, "info") == 0) {
op = GF_CLI_STATS_INFO;
- } else {
- ret = -1;
+ } else
+ GF_ASSERT (!"opword mismatch");
+
+ ret = dict_set_int32 (dict, "op", (int32_t)op);
+ if (ret)
goto out;
+
+ if (wordcount == 5) {
+ if (!strcmp (words[4], "nfs")) {
+ ret = dict_set_int32 (dict, "nfs", _gf_true);
+ if (ret)
+ goto out;
+ }
}
- ret = dict_set_int32 (dict, "op", (int32_t)op);
+
*options = dict;
out:
if (ret && dict)
@@ -1348,16 +1763,18 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
int32_t list_cnt = -1;
int index = 0;
int perf = 0;
- int32_t blk_size = 0;
- int32_t count = 0;
+ uint32_t blk_size = 0;
+ uint32_t count = 0;
+ gf_boolean_t nfs = _gf_false;
char *delimiter = NULL;
+ char *opwords[] = { "open", "read", "write", "opendir",
+ "readdir", "read-perf", "write-perf",
+ NULL };
+ char *w = NULL;
GF_ASSERT (words);
GF_ASSERT (options);
- GF_ASSERT ((strcmp (words[0], "volume")) == 0);
- GF_ASSERT ((strcmp (words[1], "top")) == 0);
-
dict = dict_new ();
if (!dict)
goto out;
@@ -1376,31 +1793,44 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
if (ret)
goto out;
- if (strcmp (words[3], "open") == 0) {
+ w = str_getunamb (words[3], opwords);
+ if (!w) {
+ ret = -1;
+ goto out;
+ }
+ if (strcmp (w, "open") == 0) {
top_op = GF_CLI_TOP_OPEN;
- } else if (strcmp (words[3], "read") == 0) {
+ } else if (strcmp (w, "read") == 0) {
top_op = GF_CLI_TOP_READ;
- } else if (strcmp (words[3], "write") == 0) {
+ } else if (strcmp (w, "write") == 0) {
top_op = GF_CLI_TOP_WRITE;
- } else if (strcmp (words[3], "opendir") == 0) {
+ } else if (strcmp (w, "opendir") == 0) {
top_op = GF_CLI_TOP_OPENDIR;
- } else if (strcmp (words[3], "readdir") == 0) {
+ } else if (strcmp (w, "readdir") == 0) {
top_op = GF_CLI_TOP_READDIR;
- } else if (strcmp (words[3], "read-perf") == 0) {
+ } else if (strcmp (w, "read-perf") == 0) {
top_op = GF_CLI_TOP_READ_PERF;
perf = 1;
- } else if (strcmp (words[3], "write-perf") == 0) {
+ } else if (strcmp (w, "write-perf") == 0) {
top_op = GF_CLI_TOP_WRITE_PERF;
perf = 1;
- } else {
- ret = -1;
- goto out;
- }
+ } else
+ GF_ASSERT (!"opword mismatch");
ret = dict_set_int32 (dict, "top-op", (int32_t)top_op);
if (ret)
goto out;
- for (index = 4; index < wordcount; index+=2) {
+ if ((wordcount > 4) && !strcmp (words[4], "nfs")) {
+ nfs = _gf_true;
+ ret = dict_set_int32 (dict, "nfs", nfs);
+ if (ret)
+ goto out;
+ index = 5;
+ } else {
+ index = 4;
+ }
+
+ for (; index < wordcount; index+=2) {
key = (char *) words[index];
value = (char *) words[index+1];
@@ -1411,14 +1841,16 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
}
if (!strcmp (key, "brick")) {
delimiter = strchr (value, ':');
- if (!delimiter || delimiter == value
+ if (!delimiter || delimiter == value
|| *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use <HOSTNAME>:"
+ cli_err ("wrong brick type: %s, use <HOSTNAME>:"
"<export-dir-abs-path>", value);
ret = -1;
goto out;
} else {
- cli_path_strip_trailing_slashes (delimiter + 1);
+ ret = cli_canonicalize_path (delimiter + 1);
+ if (ret)
+ goto out;
}
ret = dict_set_str (dict, "brick", value);
@@ -1427,39 +1859,40 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
if (!ret)
list_cnt = atoi (value);
if (ret || (list_cnt < 0) || (list_cnt > 100)) {
- cli_out ("list-cnt should be between 0 to 100");
+ cli_err ("list-cnt should be between 0 to 100");
ret = -1;
goto out;
}
- } else if (perf && !strcmp (key, "bs")) {
+ } else if (perf && !nfs && !strcmp (key, "bs")) {
ret = gf_is_str_int (value);
if (!ret)
blk_size = atoi (value);
if (ret || (blk_size <= 0)) {
if (blk_size < 0)
- cli_out ("block size is an invalid number");
- else
- cli_out ("block size should be an integer "
- "greater than zero");
+ cli_err ("block size is an invalid"
+ " number");
+ else
+ cli_err ("block size should be an "
+ "integer greater than zero");
ret = -1;
goto out;
}
- ret = dict_set_int32 (dict, "blk-size", blk_size);
- } else if (perf && !strcmp (key, "count")) {
+ ret = dict_set_uint32 (dict, "blk-size", blk_size);
+ } else if (perf && !nfs && !strcmp (key, "count")) {
ret = gf_is_str_int (value);
if (!ret)
count = atoi(value);
if (ret || (count <= 0)) {
if (count < 0)
- cli_out ("count is an invalid number");
- else
- cli_out ("count should be an integer "
+ cli_err ("count is an invalid number");
+ else
+ cli_err ("count should be an integer "
"greater than zero");
ret = -1;
goto out;
}
- ret = dict_set_int32 (dict, "blk-cnt", count);
+ ret = dict_set_uint32 (dict, "blk-cnt", count);
} else {
ret = -1;
goto out;
@@ -1479,9 +1912,17 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
}
if ((blk_size > 0) ^ (count > 0)) {
+ cli_err ("Need to give both 'bs' and 'count'");
+ ret = -1;
+ goto out;
+ } else if (((uint64_t)blk_size * count) > (10 * GF_UNIT_GB)) {
+ cli_err ("'bs * count' value %"PRIu64" is greater than "
+ "maximum allowed value of 10GB",
+ ((uint64_t)blk_size * count));
ret = -1;
goto out;
}
+
*options = dict;
out:
if (ret && dict)
@@ -1489,3 +1930,372 @@ out:
return ret;
}
+uint32_t
+cli_cmd_get_statusop (const char *arg)
+{
+ int i = 0;
+ uint32_t ret = GF_CLI_STATUS_NONE;
+ char *w = NULL;
+ char *opwords[] = {"detail", "mem", "clients", "fd",
+ "inode", "callpool", NULL};
+ struct {
+ char *opname;
+ uint32_t opcode;
+ } optable[] = {
+ { "detail", GF_CLI_STATUS_DETAIL },
+ { "mem", GF_CLI_STATUS_MEM },
+ { "clients", GF_CLI_STATUS_CLIENTS },
+ { "fd", GF_CLI_STATUS_FD },
+ { "inode", GF_CLI_STATUS_INODE },
+ { "callpool", GF_CLI_STATUS_CALLPOOL },
+ { NULL }
+ };
+
+ w = str_getunamb (arg, opwords);
+ if (!w) {
+ gf_log ("cli", GF_LOG_DEBUG,
+ "Not a status op %s", arg);
+ goto out;
+ }
+
+ for (i = 0; optable[i].opname; i++) {
+ if (!strcmp (w, optable[i].opname)) {
+ ret = optable[i].opcode;
+ break;
+ }
+ }
+
+ out:
+ return ret;
+}
+
+int
+cli_cmd_volume_status_parse (const char **words, int wordcount,
+ dict_t **options)
+{
+ dict_t *dict = NULL;
+ int ret = -1;
+ uint32_t cmd = 0;
+
+ GF_ASSERT (options);
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ switch (wordcount) {
+
+ case 2:
+ cmd = GF_CLI_STATUS_ALL;
+ ret = 0;
+ break;
+
+ case 3:
+ if (!strcmp (words[2], "all")) {
+ cmd = GF_CLI_STATUS_ALL;
+ ret = 0;
+
+ } else {
+ cmd = GF_CLI_STATUS_VOL;
+ ret = dict_set_str (dict, "volname", (char *)words[2]);
+ }
+
+ break;
+
+ case 4:
+ cmd = cli_cmd_get_statusop (words[3]);
+
+ if (!strcmp (words[2], "all")) {
+ if (cmd == GF_CLI_STATUS_NONE) {
+ cli_err ("%s is not a valid status option",
+ words[3]);
+ ret = -1;
+ goto out;
+ }
+ cmd |= GF_CLI_STATUS_ALL;
+ ret = 0;
+
+ } else {
+ ret = dict_set_str (dict, "volname",
+ (char *)words[2]);
+ if (ret)
+ goto out;
+
+ if (cmd == GF_CLI_STATUS_NONE) {
+ if (!strcmp (words[3], "nfs")) {
+ cmd |= GF_CLI_STATUS_NFS;
+ } else if (!strcmp (words[3], "shd")) {
+ cmd |= GF_CLI_STATUS_SHD;
+ } else {
+ cmd = GF_CLI_STATUS_BRICK;
+ ret = dict_set_str (dict, "brick",
+ (char *)words[3]);
+ }
+
+ } else {
+ cmd |= GF_CLI_STATUS_VOL;
+ ret = 0;
+ }
+ }
+
+ break;
+
+ case 5:
+ if (!strcmp (words[2], "all")) {
+ cli_err ("Cannot specify brick/nfs for \"all\"");
+ ret = -1;
+ goto out;
+ }
+
+ cmd = cli_cmd_get_statusop (words[4]);
+ if (cmd == GF_CLI_STATUS_NONE) {
+ cli_err ("%s is not a valid status option",
+ words[4]);
+ ret = -1;
+ goto out;
+ }
+
+
+ ret = dict_set_str (dict, "volname", (char *)words[2]);
+ if (ret)
+ goto out;
+
+ if (!strcmp (words[3], "nfs")) {
+ if (cmd == GF_CLI_STATUS_FD ||
+ cmd == GF_CLI_STATUS_DETAIL) {
+ cli_err ("Detail/FD status not available"
+ " for NFS Servers");
+ ret = -1;
+ goto out;
+ }
+ cmd |= GF_CLI_STATUS_NFS;
+ } else if (!strcmp (words[3], "shd")){
+ if (cmd == GF_CLI_STATUS_FD ||
+ cmd == GF_CLI_STATUS_CLIENTS ||
+ cmd == GF_CLI_STATUS_DETAIL) {
+ cli_err ("Detail/FD/Clients status not "
+ "available for Self-heal Daemons");
+ ret = -1;
+ goto out;
+ }
+ cmd |= GF_CLI_STATUS_SHD;
+ } else {
+ cmd |= GF_CLI_STATUS_BRICK;
+ ret = dict_set_str (dict, "brick", (char *)words[3]);
+ }
+ break;
+
+ default:
+ goto out;
+ }
+
+ if (ret)
+ goto out;
+
+ ret = dict_set_int32 (dict, "cmd", cmd);
+ if (ret)
+ goto out;
+
+ *options = dict;
+
+ out:
+ if (ret && dict)
+ dict_destroy (dict);
+
+ return ret;
+}
+
+gf_boolean_t
+cli_cmd_validate_dumpoption (const char *arg, char **option)
+{
+ char *opwords[] = {"all", "nfs", "mem", "iobuf", "callpool", "priv",
+ "fd", "inode", "history", "inodectx", "fdctx",
+ NULL};
+ char *w = NULL;
+
+ w = str_getunamb (arg, opwords);
+ if (!w) {
+ gf_log ("cli", GF_LOG_DEBUG, "Unknown statedump option %s",
+ arg);
+ return _gf_false;
+ }
+ *option = w;
+ return _gf_true;
+}
+
+int
+cli_cmd_volume_statedump_options_parse (const char **words, int wordcount,
+ dict_t **options)
+{
+ int ret = 0;
+ int i = 0;
+ dict_t *dict = NULL;
+ int option_cnt = 0;
+ char *option = NULL;
+ char option_str[100] = {0,};
+
+ for (i = 3; i < wordcount; i++, option_cnt++) {
+ if (!cli_cmd_validate_dumpoption (words[i], &option)) {
+ ret = -1;
+ goto out;
+ }
+ strncat (option_str, option, strlen (option));
+ strncat (option_str, " ", 1);
+ }
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_dynstr (dict, "options", gf_strdup (option_str));
+ if (ret)
+ goto out;
+
+ ret = dict_set_int32 (dict, "option_cnt", option_cnt);
+ if (ret)
+ goto out;
+
+ *options = dict;
+out:
+ if (ret && dict)
+ dict_destroy (dict);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR, "Error parsing dumpoptions");
+ return ret;
+}
+
+int
+cli_cmd_volume_clrlks_opts_parse (const char **words, int wordcount,
+ dict_t **options)
+{
+ int ret = -1;
+ int i = 0;
+ dict_t *dict = NULL;
+ char *kind_opts[4] = {"blocked", "granted", "all", NULL};
+ char *types[4] = {"inode", "entry", "posix", NULL};
+ char *free_ptr = NULL;
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ if (strcmp (words[4], "kind"))
+ goto out;
+
+ for (i = 0; kind_opts[i]; i++) {
+ if (!strcmp (words[5], kind_opts[i])) {
+ free_ptr = gf_strdup (words[5]);
+ ret = dict_set_dynstr (dict, "kind", free_ptr);
+ if (ret)
+ goto out;
+ free_ptr = NULL;
+ break;
+ }
+ }
+ if (i == 3)
+ goto out;
+
+ ret = -1;
+ for (i = 0; types[i]; i++) {
+ if (!strcmp (words[6], types[i])) {
+ free_ptr = gf_strdup (words[6]);
+ ret = dict_set_dynstr (dict, "type", free_ptr);
+ if (ret)
+ goto out;
+ free_ptr = NULL;
+ break;
+ }
+ }
+ if (i == 3)
+ goto out;
+
+ if (wordcount == 8) {
+ free_ptr = gf_strdup (words[7]);
+ ret = dict_set_dynstr (dict, "opts", free_ptr);
+ if (ret)
+ goto out;
+ free_ptr = NULL;
+ }
+
+ ret = 0;
+ *options = dict;
+out:
+ if (ret) {
+ GF_FREE (free_ptr);
+ dict_unref (dict);
+ }
+
+ return ret;
+}
+
+int
+cli_cmd_volume_heal_options_parse (const char **words, int wordcount,
+ dict_t **options)
+{
+ int ret = 0;
+ dict_t *dict = NULL;
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_str (dict, "volname", (char *) words[2]);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to set volname");
+ goto out;
+ }
+
+ if (wordcount == 3) {
+ ret = dict_set_int32 (dict, "heal-op", GF_AFR_OP_HEAL_INDEX);
+ goto done;
+ }
+
+ if (wordcount == 4) {
+ if (!strcmp (words[3], "full")) {
+ ret = dict_set_int32 (dict, "heal-op",
+ GF_AFR_OP_HEAL_FULL);
+ goto done;
+ } else if (!strcmp (words[3], "info")) {
+ ret = dict_set_int32 (dict, "heal-op",
+ GF_AFR_OP_INDEX_SUMMARY);
+ goto done;
+ } else {
+ ret = -1;
+ goto out;
+ }
+ }
+ if (wordcount == 5) {
+ if (strcmp (words[3], "info")) {
+ ret = -1;
+ goto out;
+ }
+ if (!strcmp (words[4], "healed")) {
+ ret = dict_set_int32 (dict, "heal-op",
+ GF_AFR_OP_HEALED_FILES);
+ goto done;
+ }
+ if (!strcmp (words[4], "heal-failed")) {
+ ret = dict_set_int32 (dict, "heal-op",
+ GF_AFR_OP_HEAL_FAILED_FILES);
+ goto done;
+ }
+ if (!strcmp (words[4], "split-brain")) {
+ ret = dict_set_int32 (dict, "heal-op",
+ GF_AFR_OP_SPLIT_BRAIN_FILES);
+ goto done;
+ }
+ ret = -1;
+ goto out;
+ }
+ ret = -1;
+ goto out;
+done:
+ *options = dict;
+out:
+ if (ret && dict) {
+ dict_unref (dict);
+ *options = NULL;
+ }
+
+ return ret;
+}
diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c
index 11d029bf1..4ac1630e5 100644
--- a/cli/src/cli-cmd-peer.c
+++ b/cli/src/cli-cmd-peer.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -31,6 +31,7 @@
#include "cli.h"
#include "cli-cmd.h"
#include "cli-mem-types.h"
+#include "cli1-xdr.h"
#include "protocol-common.h"
extern struct rpc_clnt *global_rpc;
@@ -71,7 +72,7 @@ cli_cmd_peer_probe_cbk (struct cli_state *state, struct cli_cmd_word *word,
if (ret)
goto out;
- ret = valid_internet_address ((char *) words[2]);
+ ret = valid_internet_address ((char *) words[2], _gf_false);
if (ret == 1) {
ret = 0;
} else {
@@ -95,6 +96,9 @@ out:
if ((sent == 0) && (parse_error == 0))
cli_out ("Peer probe failed");
}
+
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -107,10 +111,11 @@ cli_cmd_peer_deprobe_cbk (struct cli_state *state, struct cli_cmd_word *word,
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *dict = NULL;
+ int flags = 0;
int sent = 0;
int parse_error = 0;
- if (!(wordcount == 3) ) {
+ if ((wordcount < 3) || (wordcount > 4)) {
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
@@ -134,6 +139,20 @@ cli_cmd_peer_deprobe_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
}
*/
+ if (wordcount == 4) {
+ if (!strcmp("force", words[3]))
+ flags |= GF_CLI_FLAG_OP_FORCE;
+ else {
+ ret = -1;
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+ }
+ ret = dict_set_int32 (dict, "flags", flags);
+ if (ret)
+ goto out;
+
if (proc->fn) {
ret = proc->fn (frame, THIS, dict);
}
@@ -145,6 +164,8 @@ out:
cli_out ("Peer detach failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -180,6 +201,9 @@ out:
if ((sent == 0) && (parse_error == 0))
cli_out ("Peer status failed");
}
+
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -188,7 +212,7 @@ struct cli_cmd cli_probe_cmds[] = {
cli_cmd_peer_probe_cbk,
"probe peer specified by <HOSTNAME>"},
- { "peer detach <HOSTNAME>",
+ { "peer detach <HOSTNAME> [force]",
cli_cmd_peer_deprobe_cbk,
"detach peer specified by <HOSTNAME>"},
diff --git a/cli/src/cli-cmd-system.c b/cli/src/cli-cmd-system.c
index 2dff572fd..25938b897 100644
--- a/cli/src/cli-cmd-system.c
+++ b/cli/src/cli-cmd-system.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -178,6 +178,116 @@ out:
return ret;
}
+static dict_t *
+make_seq_dict (int argc, char **argv)
+{
+ char index[] = "4294967296"; // 1<<32
+ int i = 0;
+ int ret = 0;
+ dict_t *dict = dict_new ();
+
+ if (!dict)
+ return NULL;
+
+ for (i = 0; i < argc; i++) {
+ snprintf(index, sizeof(index), "%d", i);
+ ret = dict_set_str (dict, index, argv[i]);
+ if (ret == -1)
+ break;
+ }
+
+ if (ret) {
+ dict_destroy (dict);
+ dict = NULL;
+ }
+
+ return dict;
+}
+
+int
+cli_cmd_mount_cbk (struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int ret = -1;
+ dict_t *dict = NULL;
+ void *dataa[] = {NULL, NULL};
+
+ if (wordcount < 4) {
+ cli_usage_out (word->pattern);
+ goto out;
+ }
+
+ dict = make_seq_dict (wordcount - 3, (char **)words + 3);
+ if (!dict)
+ goto out;
+
+ dataa[0] = (void *)words[2];
+ dataa[1] = dict;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_MOUNT];
+ if (proc && proc->fn) {
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+ ret = proc->fn (frame, THIS, dataa);
+ }
+
+ out:
+ if (dict)
+ dict_unref (dict);
+
+ if (!proc && ret)
+ cli_out ("Mount command failed");
+
+ return ret;
+}
+
+int
+cli_cmd_umount_cbk (struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int ret = -1;
+ dict_t *dict = NULL;
+
+ if (!(wordcount == 3 ||
+ (wordcount == 4 && strcmp (words[3], "lazy") == 0))) {
+ cli_usage_out (word->pattern);
+ goto out;
+ }
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_str (dict, "path", (char *)words[2]);
+ if (ret != 0)
+ goto out;
+ ret = dict_set_int32 (dict, "lazy", wordcount == 4);
+ if (ret != 0)
+ goto out;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_UMOUNT];
+ if (proc && proc->fn) {
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+ ret = proc->fn (frame, THIS, dict);
+ }
+
+ out:
+ if (dict)
+ dict_unref (dict);
+
+ if (!proc && ret)
+ cli_out ("Umount command failed");
+
+ return ret;
+}
+
struct cli_cmd cli_system_cmds[] = {
{ "system:: getspec <VOLID>",
cli_cmd_getspec_cbk,
@@ -195,6 +305,14 @@ struct cli_cmd cli_system_cmds[] = {
cli_cmd_getwd_cbk,
"query glusterd work directory"},
+ { "system:: mount <label> <args...>",
+ cli_cmd_mount_cbk,
+ "request a mount"},
+
+ { "system:: umount <path> [lazy]",
+ cli_cmd_umount_cbk,
+ "request an umount"},
+
{ "system:: help",
cli_cmd_system_help_cbk,
"display help for system commands"},
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 673202440..bad9351fd 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -23,6 +23,11 @@
#include <stdint.h>
#include <pthread.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
@@ -32,6 +37,7 @@
#include "cli-cmd.h"
#include "cli-mem-types.h"
#include "cli1-xdr.h"
+#include "run.h"
extern struct rpc_clnt *global_rpc;
@@ -82,9 +88,9 @@ cli_cmd_volume_info_cbk (struct cli_state *state, struct cli_cmd_word *word,
if (!local)
goto out;
- local->u.get_vol.flags = ctx.flags;
+ local->get_vol.flags = ctx.flags;
if (ctx.volname)
- local->u.get_vol.volname = gf_strdup (ctx.volname);
+ local->get_vol.volname = gf_strdup (ctx.volname);
frame->local = local;
@@ -99,6 +105,8 @@ out:
cli_out ("Getting Volume information failed!");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -110,9 +118,9 @@ cli_cmd_sync_volume_cbk (struct cli_state *state, struct cli_cmd_word *word,
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
- gf1_cli_sync_volume_req req = {0,};
int sent = 0;
int parse_error = 0;
+ dict_t *dict = NULL;
if ((wordcount < 3) || (wordcount > 4)) {
cli_usage_out (word->pattern);
@@ -120,14 +128,32 @@ cli_cmd_sync_volume_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
}
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
if ((wordcount == 3) || !strcmp(words[3], "all")) {
- req.flags = GF_CLI_SYNC_ALL;
- req.volname = "";
+ ret = dict_set_int32 (dict, "flags", (int32_t)
+ GF_CLI_SYNC_ALL);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to set"
+ "flag");
+ goto out;
+ }
} else {
- req.volname = (char *)words[3];
+ ret = dict_set_str (dict, "volname", (char *) words[3]);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to set "
+ "volume");
+ goto out;
+ }
}
- req.hostname = (char *)words[2];
+ ret = dict_set_str (dict, "hostname", (char *) words[2]);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to set hostname");
+ goto out;
+ }
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SYNC_VOLUME];
@@ -136,7 +162,7 @@ cli_cmd_sync_volume_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
if (proc->fn) {
- ret = proc->fn (frame, THIS, &req);
+ ret = proc->fn (frame, THIS, dict);
}
out:
@@ -146,6 +172,161 @@ out:
cli_out ("Volume sync failed");
}
+ if (dict)
+ dict_unref (dict);
+
+ CLI_STACK_DESTROY (frame);
+
+ return ret;
+}
+
+gf_ai_compare_t
+cli_cmd_compare_addrinfo (struct addrinfo *first, struct addrinfo *next)
+{
+ int ret = -1;
+ struct addrinfo *tmp1 = NULL;
+ struct addrinfo *tmp2 = NULL;
+ char firstip[NI_MAXHOST] = {0.};
+ char nextip[NI_MAXHOST] = {0,};
+
+ for (tmp1 = first; tmp1 != NULL; tmp1 = tmp1->ai_next) {
+ ret = getnameinfo (tmp1->ai_addr, tmp1->ai_addrlen, firstip,
+ NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ if (ret)
+ return GF_AI_COMPARE_ERROR;
+ for (tmp2 = next; tmp2 != NULL; tmp2 = tmp2->ai_next) {
+ ret = getnameinfo (tmp2->ai_addr, tmp2->ai_addrlen, nextip,
+ NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ if (ret)
+ return GF_AI_COMPARE_ERROR;
+ if (!strcmp (firstip, nextip)) {
+ return GF_AI_COMPARE_MATCH;
+ }
+ }
+ }
+ return GF_AI_COMPARE_NO_MATCH;
+}
+
+/* Check for non optimal brick order for replicate :
+ * Checks if bricks belonging to a replicate volume
+ * are present on the same server
+ */
+int32_t
+cli_cmd_check_brick_order (struct cli_state *state, const char *bricks,
+ int brick_count, int sub_count)
+{
+ int ret = -1;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ addrinfo_list_t *ai_list = NULL;
+ addrinfo_list_t *ai_list_tmp1 = NULL;
+ addrinfo_list_t *ai_list_tmp2 = NULL;
+ char *brick = NULL;
+ char *brick_list = NULL;
+ char *brick_list_dup = NULL;
+ char *tmpptr = NULL;
+ struct addrinfo *ai_info = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *failed_question = NULL;
+ const char *found_question = NULL;
+ failed_question = "Failed to perform brick order check. "
+ "Do you want to continue creating the volume? ";
+ found_question = "Multiple bricks of a replicate volume are present"
+ " on the same server. This setup is not optimal.\n"
+ "Do you still want to continue creating the volume? ";
+
+ GF_ASSERT (bricks);
+ GF_ASSERT (brick_count > 0);
+ GF_ASSERT (sub_count > 0);
+
+ ai_list = malloc (sizeof (addrinfo_list_t));
+ ai_list->info = NULL;
+ INIT_LIST_HEAD (&ai_list->list);
+ brick_list = gf_strdup (bricks);
+ if (brick_list == NULL) {
+ gf_log ("cli", GF_LOG_DEBUG, "failed to allocate memory");
+ goto check_failed;
+ }
+ brick_list_dup = brick_list;
+ /* Resolve hostnames and get addrinfo */
+ while (i < brick_count) {
+ ++i;
+ brick = strtok_r (brick_list, " \n", &tmpptr);
+ brick_list = tmpptr;
+ if (brick == NULL)
+ goto check_failed;
+ brick = strtok_r (brick, ":", &tmpptr);
+ if (brick == NULL)
+ goto check_failed;
+ ret = getaddrinfo (brick, NULL, NULL, &ai_info);
+ if (ret)
+ goto check_failed;
+ ai_list_tmp1 = malloc (sizeof (addrinfo_list_t));
+ if (ai_list_tmp1 == NULL)
+ goto check_failed;
+ ai_list_tmp1->info = ai_info;
+ list_add_tail (&ai_list_tmp1->list, &ai_list->list);
+ ai_list_tmp1 = NULL;
+ }
+
+ i = 0;
+ ai_list_tmp1 = list_entry (ai_list->list.next, addrinfo_list_t, list);
+
+ /* Check for bad brick order */
+ while (i < brick_count) {
+ ++i;
+ ai_info = ai_list_tmp1->info;
+ ai_list_tmp1 = list_entry (ai_list_tmp1->list.next,
+ addrinfo_list_t, list);
+ if ( 0 == i % sub_count) {
+ j = 0;
+ continue;
+ }
+ ai_list_tmp2 = ai_list_tmp1;
+ k = j;
+ while (k < sub_count - 1) {
+ ++k;
+ ret = cli_cmd_compare_addrinfo (ai_info,
+ ai_list_tmp2->info);
+ if (GF_AI_COMPARE_ERROR == ret)
+ goto check_failed;
+ if (GF_AI_COMPARE_MATCH == ret)
+ goto found_bad_brick_order;
+ ai_list_tmp2 = list_entry (ai_list_tmp2->list.next,
+ addrinfo_list_t, list);
+ }
+ ++j;
+ }
+ gf_log ("cli", GF_LOG_INFO, "Brick order okay");
+ ret = 0;
+ goto out;
+
+check_failed:
+ gf_log ("cli", GF_LOG_INFO, "Failed bad brick order check");
+ answer = cli_cmd_get_confirmation(state, failed_question);
+ if (GF_ANSWER_YES == answer)
+ ret = 0;
+ goto out;
+
+found_bad_brick_order:
+ gf_log ("cli", GF_LOG_INFO, "Bad brick order found");
+ answer = cli_cmd_get_confirmation (state, found_question);
+ if (GF_ANSWER_YES == answer)
+ ret = 0;
+out:
+ ai_list_tmp2 = NULL;
+ i = 0;
+ if (brick_list_dup)
+ GF_FREE (brick_list_dup);
+ list_for_each_entry (ai_list_tmp1, &ai_list->list, list) {
+ if (ai_list_tmp1->info)
+ freeaddrinfo (ai_list_tmp1->info);
+ if (ai_list_tmp2)
+ free (ai_list_tmp2);
+ ai_list_tmp2 = ai_list_tmp1;
+ }
+ free (ai_list_tmp2);
return ret;
}
@@ -159,6 +340,11 @@ cli_cmd_volume_create_cbk (struct cli_state *state, struct cli_cmd_word *word,
dict_t *options = NULL;
int sent = 0;
int parse_error = 0;
+ char *brick_list = NULL;
+ int32_t brick_count = 0;
+ int32_t sub_count = 0;
+ int32_t type = GF_CLUSTER_TYPE_NONE;
+
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_CREATE_VOLUME];
@@ -173,7 +359,37 @@ cli_cmd_volume_create_cbk (struct cli_state *state, struct cli_cmd_word *word,
parse_error = 1;
goto out;
}
-
+ /*Check brick order if type is replicate*/
+ ret = dict_get_int32 (options, "type", &type);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Could not get brick type");
+ goto out;
+ }
+ if ((type == GF_CLUSTER_TYPE_REPLICATE) ||
+ (type == GF_CLUSTER_TYPE_STRIPE_REPLICATE)) {
+ if ((ret = dict_get_str (options, "bricks", &brick_list)) != 0) {
+ gf_log ("cli", GF_LOG_ERROR, "Replica bricks check : "
+ "Could not retrieve bricks list");
+ goto out;
+ }
+ if ((ret = dict_get_int32 (options, "count", &brick_count)) != 0) {
+ gf_log ("cli", GF_LOG_ERROR, "Replica bricks check : "
+ "Could not retrieve brick count");
+ goto out;
+ }
+ if ((ret = dict_get_int32 (options, "replica-count", &sub_count)) != 0) {
+ gf_log ("cli", GF_LOG_ERROR, "Replica bricks check : "
+ "Could not retrieve replica count");
+ goto out;
+ }
+ gf_log ("cli", GF_LOG_INFO, "Replicate cluster type found."
+ " Checking brick order.");
+ ret = cli_cmd_check_brick_order (state, brick_list, brick_count, sub_count);
+ if (ret) {
+ gf_log("cli", GF_LOG_INFO, "Not creating volume because of bad brick order");
+ goto out;
+ }
+ }
if (proc->fn) {
ret = proc->fn (frame, THIS, options);
}
@@ -187,6 +403,8 @@ out:
cli_out ("Volume create failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -238,6 +456,8 @@ out:
cli_out ("Volume delete failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -248,9 +468,10 @@ cli_cmd_volume_start_cbk (struct cli_state *state, struct cli_cmd_word *word,
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
- gf1_cli_start_vol_req req = {0,};
int sent = 0;
int parse_error = 0;
+ dict_t *dict = NULL;
+ int flags = 0;
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
@@ -262,13 +483,23 @@ cli_cmd_volume_start_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
}
- req.volname = (char *)words[2];
- if (!req.volname)
+ dict = dict_new ();
+ if (!dict) {
+ goto out;
+ }
+
+ if (!words[2])
+ goto out;
+
+ ret = dict_set_str (dict, "volname", (char *)words[2]);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "dict set failed");
goto out;
+ }
if (wordcount == 4) {
if (!strcmp("force", words[3])) {
- req.flags |= GF_CLI_FLAG_OP_FORCE;
+ flags |= GF_CLI_FLAG_OP_FORCE;
} else {
ret = -1;
cli_usage_out (word->pattern);
@@ -276,20 +507,36 @@ cli_cmd_volume_start_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
}
}
+ ret = dict_set_int32 (dict, "flags", flags);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "dict set failed");
+ goto out;
+ }
+
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "failed to serialize dict");
+ goto out;
+ }
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_START_VOLUME];
if (proc->fn) {
- ret = proc->fn (frame, THIS, &req);
+ ret = proc->fn (frame, THIS, dict);
}
out:
+ if (dict)
+ dict_unref (dict);
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
cli_out ("Volume start failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -343,10 +590,11 @@ cli_cmd_volume_stop_cbk (struct cli_state *state, struct cli_cmd_word *word,
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
int flags = 0;
- gf1_cli_stop_vol_req req = {0,};
gf_answer_t answer = GF_ANSWER_NO;
int sent = 0;
int parse_error = 0;
+ dict_t *dict = NULL;
+ char *volname = NULL;
const char *question = "Stopping volume will make its data inaccessible. "
"Do you want to continue?";
@@ -361,9 +609,14 @@ cli_cmd_volume_stop_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
}
- req.volname = (char *)words[2];
- if (!req.volname)
+ volname = (char*) words[2];
+
+ dict = dict_new ();
+ ret = dict_set_str (dict, "volname", volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "dict set failed");
goto out;
+ }
if (wordcount == 4) {
if (!strcmp("force", words[3])) {
@@ -375,6 +628,12 @@ cli_cmd_volume_stop_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
}
}
+ ret = dict_set_int32 (dict, "flags", flags);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "dict set failed");
+ goto out;
+ }
answer = cli_cmd_get_confirmation (state, question);
@@ -383,19 +642,22 @@ cli_cmd_volume_stop_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
}
- req.flags = flags;
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STOP_VOLUME];
if (proc->fn) {
- ret = proc->fn (frame, THIS, &req);
+ ret = proc->fn (frame, THIS, dict);
}
out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume stop failed", req.volname);
+ cli_out ("Volume stop on '%s' failed", volname);
}
+ if (dict)
+ dict_unref (dict);
+
+ CLI_STACK_DESTROY (frame);
return ret;
}
@@ -450,9 +712,11 @@ out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume rename failed", (char *)words[2]);
+ cli_out ("Volume rename on '%s' failed", (char *)words[2]);
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -466,7 +730,6 @@ cli_cmd_volume_defrag_cbk (struct cli_state *state, struct cli_cmd_word *word,
dict_t *dict = NULL;
int sent = 0;
int parse_error = 0;
- int index = 0;
#ifdef GF_SOLARIS_HOST_OS
cli_out ("Command not supported on Solaris");
goto out;
@@ -487,24 +750,21 @@ cli_cmd_volume_defrag_cbk (struct cli_state *state, struct cli_cmd_word *word,
}
if (wordcount == 4) {
- index = 3;
+ if (strcmp (words[3], "start") && strcmp (words[3], "stop") &&
+ strcmp (words[3], "status")) {
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
} else {
- if (strcmp (words[3], "fix-layout") &&
- strcmp (words[3], "migrate-data")) {
+ if (strcmp (words[3], "fix-layout") &&
+ strcmp (words[3], "start")) {
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
- index = 4;
}
- if (strcmp (words[index], "start") && strcmp (words[index], "stop") &&
- strcmp (words[index], "status")) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
ret = dict_set_str (dict, "volname", (char *)words[2]);
if (ret)
goto out;
@@ -515,10 +775,20 @@ cli_cmd_volume_defrag_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
}
if (wordcount == 5) {
- ret = dict_set_str (dict, "start-type", (char *)words[3]);
+ if ((strcmp (words[3], "fix-layout") ||
+ strcmp (words[4], "start")) &&
+ (strcmp (words[3], "start") ||
+ strcmp (words[4], "force"))) {
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "option", (char *)words[4]);
if (ret)
goto out;
- ret = dict_set_str (dict, "command", (char *)words[4]);
+ ret = dict_set_str (dict, "command", (char *)words[3]);
if (ret)
goto out;
}
@@ -539,6 +809,8 @@ out:
cli_out ("Volume rebalance failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -582,6 +854,8 @@ out:
cli_out ("Volume reset failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -626,6 +900,8 @@ out:
cli_out ("Volume profile failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -670,6 +946,8 @@ out:
cli_out ("Volume set failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -685,6 +963,13 @@ cli_cmd_volume_add_brick_cbk (struct cli_state *state,
dict_t *options = NULL;
int sent = 0;
int parse_error = 0;
+ gf_answer_t answer = GF_ANSWER_NO;
+
+ const char *question = "Changing the 'stripe count' of the volume is "
+ "not a supported feature. In some cases it may result in data "
+ "loss on the volume. Also there may be issues with regular "
+ "filesystem operations on the volume after the change. Do you "
+ "really want to continue with 'stripe' count option ? ";
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
@@ -698,6 +983,17 @@ cli_cmd_volume_add_brick_cbk (struct cli_state *state,
goto out;
}
+ /* TODO: there are challenges in supporting changing of
+ stripe-count, untill it is properly supported give warning to user */
+ if (dict_get (options, "stripe-count")) {
+ answer = cli_cmd_get_confirmation (state, question);
+
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
+ }
+ }
+
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_ADD_BRICK];
if (proc->fn) {
@@ -714,6 +1010,8 @@ out:
cli_out ("Volume add-brick failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -724,9 +1022,13 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word,
int ret = 0;
int parse_err = 0;
+ int32_t type = 0;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *options = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question = "Disabling quota will delete all the quota "
+ "configuration. Do you want to continue?";
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_QUOTA];
if (proc == NULL) {
@@ -741,10 +1043,15 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word,
}
ret = cli_cmd_quota_parse (words, wordcount, &options);
- if (ret) {
+ if (ret < 0) {
cli_usage_out (word->pattern);
parse_err = 1;
goto out;
+ } else if (dict_get_int32 (options, "type", &type) == 0 &&
+ type == GF_QUOTA_OPTION_TYPE_DISABLE) {
+ answer = cli_cmd_get_confirmation (state, question);
+ if (answer == GF_ANSWER_NO)
+ goto out;
}
if (proc->fn)
@@ -757,6 +1064,8 @@ out:
if (ret && parse_err == 0)
cli_out ("Quota command failed");
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -773,6 +1082,7 @@ cli_cmd_volume_remove_brick_cbk (struct cli_state *state,
gf_answer_t answer = GF_ANSWER_NO;
int sent = 0;
int parse_error = 0;
+ int need_question = 0;
const char *question = "Removing brick(s) can result in data loss. "
"Do you want to Continue?";
@@ -781,7 +1091,8 @@ cli_cmd_volume_remove_brick_cbk (struct cli_state *state,
if (!frame)
goto out;
- ret = cli_cmd_volume_remove_brick_parse (words, wordcount, &options);
+ ret = cli_cmd_volume_remove_brick_parse (words, wordcount, &options,
+ &need_question);
if (ret) {
cli_usage_out (word->pattern);
@@ -789,11 +1100,13 @@ cli_cmd_volume_remove_brick_cbk (struct cli_state *state,
goto out;
}
- answer = cli_cmd_get_confirmation (state, question);
-
- if (GF_ANSWER_NO == answer) {
- ret = 0;
- goto out;
+ if (!(state->mode & GLUSTER_MODE_SCRIPT) && need_question) {
+ /* we need to ask question only in case of 'commit or force' */
+ answer = cli_cmd_get_confirmation (state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
+ }
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_REMOVE_BRICK];
@@ -811,6 +1124,9 @@ out:
if (options)
dict_unref (options);
+
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -860,6 +1176,8 @@ out:
cli_out ("Volume replace-brick failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -874,50 +1192,6 @@ cli_cmd_volume_set_transport_cbk (struct cli_state *state,
}
int
-cli_cmd_log_filename_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
-{
- int ret = -1;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- dict_t *options = NULL;
- int sent = 0;
- int parse_error = 0;
-
- if (!((wordcount == 5) || (wordcount == 6))) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LOG_FILENAME];
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- ret = cli_cmd_log_filename_parse (words, wordcount, &options);
- if (ret)
- goto out;
-
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
-
-out:
- if (options)
- dict_destroy (options);
-
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume log filename failed");
- }
-
- return ret;
-}
-
-int
cli_cmd_volume_top_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
@@ -957,53 +1231,12 @@ out:
cli_out ("Volume top failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
-int
-cli_cmd_log_locate_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
-{
- int ret = -1;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- dict_t *options = NULL;
- int sent = 0;
- int parse_error = 0;
-
- if (!((wordcount == 4) || (wordcount == 5))) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LOG_LOCATE];
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- ret = cli_cmd_log_locate_parse (words, wordcount, &options);
- if (ret)
- goto out;
-
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
-
-out:
- if (options)
- dict_destroy (options);
-
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("getting log file location information failed");
- }
-
- return ret;
-}
int
cli_cmd_log_rotate_cbk (struct cli_state *state, struct cli_cmd_word *word,
@@ -1046,6 +1279,8 @@ out:
cli_out ("Volume log rotate failed");
}
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -1053,30 +1288,10 @@ out:
static int
cli_check_gsync_present ()
{
- FILE *in = NULL;
char buff[PATH_MAX] = {0, };
- char cmd[PATH_MAX + 256] = {0, };
+ runner_t runner = {0,};
char *ptr = NULL;
int ret = 0;
- struct stat stat_buff;
-
- if (strlen (GSYNCD_PREFIX)+1 > PATH_MAX-strlen("/gsyncd")) {
- ret = -1;
- goto out;
- }
-
- ret = snprintf (cmd, sizeof(cmd), GSYNCD_PREFIX "/gsyncd");
- if (ret < 0) {
- ret = 0;
- goto out;
- }
- ret = lstat (cmd, &stat_buff);
-
- if (ret || !(stat_buff.st_mode & S_IXUSR)) {
- ret = -1;
- gf_log ("", GF_LOG_INFO, "geo-replication not installed");
- goto out;
- }
ret = setenv ("_GLUSTERD_CALLED_", "1", 1);
if (-1 == ret) {
@@ -1085,16 +1300,16 @@ cli_check_gsync_present ()
goto out;
}
- memset (cmd, 0, sizeof (cmd));
- ret = snprintf (cmd, sizeof(cmd), GSYNCD_PREFIX"/gsyncd --version");
-
- if (!(in = popen(cmd, "r"))) {
- ret = -1;
+ runinit (&runner);
+ runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "--version", NULL);
+ runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
+ ret = runner_start (&runner);
+ if (ret == -1) {
gf_log ("", GF_LOG_INFO, "geo-replication not installed");
goto out;
}
- ptr = fgets(buff, sizeof(buff), in);
+ ptr = fgets(buff, sizeof(buff), runner_chio (&runner, STDOUT_FILENO));
if (ptr) {
if (!strstr (buff, "gsyncd")) {
ret = -1;
@@ -1105,7 +1320,7 @@ cli_check_gsync_present ()
goto out;
}
- ret = pclose (in);
+ ret = runner_end (&runner);
if (ret)
gf_log ("", GF_LOG_ERROR, "geo-replication not installed");
@@ -1168,6 +1383,429 @@ out:
if (ret && parse_err == 0)
cli_out (GEOREP" command failed");
+ CLI_STACK_DESTROY (frame);
+
+ return ret;
+}
+
+int
+cli_cmd_volume_status_cbk (struct cli_state *state,
+ struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ uint32_t cmd = 0;
+
+ ret = cli_cmd_volume_status_parse (words, wordcount, &dict);
+
+ if (ret) {
+ cli_usage_out (word->pattern);
+ goto out;
+ }
+
+ ret = dict_get_uint32 (dict, "cmd", &cmd);
+ if (ret)
+ goto out;
+
+ if (!(cmd & GF_CLI_STATUS_ALL)) {
+ /* for one volume or brick */
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATUS_VOLUME];
+ } else {
+ /* volume status all or all detail */
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATUS_ALL];
+ }
+
+ if (!proc->fn)
+ goto out;
+
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ ret = proc->fn (frame, THIS, dict);
+
+ out:
+ if (dict)
+ dict_unref (dict);
+
+ CLI_STACK_DESTROY (frame);
+
+ return ret;
+}
+
+
+int
+cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status)
+{
+ uint64_t free = 0;
+ uint64_t total = 0;
+ char key[1024] = {0};
+ int ret = 0;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.free", i);
+ ret = dict_get_uint64 (dict, key, &free);
+
+ status->free = gf_uint64_2human_readable (free);
+ if (!status->free)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.total", i);
+ ret = dict_get_uint64 (dict, key, &total);
+
+ status->total = gf_uint64_2human_readable (total);
+ if (!status->total)
+ goto out;
+
+#ifdef GF_LINUX_HOST_OS
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.device", i);
+ ret = dict_get_str (dict, key, &(status->device));
+ if (ret)
+ status->device = NULL;
+#endif
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.block_size", i);
+ ret = dict_get_uint64 (dict, key, &(status->block_size));
+ if (ret) {
+ ret = 0;
+ status->block_size = 0;
+ }
+
+#ifdef GF_LINUX_HOST_OS
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mnt_options", i);
+ ret = dict_get_str (dict, key, &(status->mount_options));
+ if (ret)
+ status->mount_options = NULL;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.fs_name", i);
+ ret = dict_get_str (dict, key, &(status->fs_name));
+ if (ret) {
+ ret = 0;
+ status->fs_name = NULL;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.inode_size", i);
+ ret = dict_get_str (dict, key, &(status->inode_size));
+ if (ret)
+ status->inode_size = NULL;
+#endif /* GF_LINUX_HOST_OS */
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.total_inodes", i);
+ ret = dict_get_uint64 (dict, key,
+ &(status->total_inodes));
+ if (ret)
+ status->total_inodes = 0;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.free_inodes", i);
+ ret = dict_get_uint64 (dict, key, &(status->free_inodes));
+ if (ret) {
+ ret = 0;
+ status->free_inodes = 0;
+ }
+
+
+ out:
+ return ret;
+}
+
+void
+cli_print_detailed_status (cli_volume_status_t *status)
+{
+ cli_out ("%-20s : %-20s", "Brick", status->brick);
+ cli_out ("%-20s : %-20d", "Port", status->port);
+ cli_out ("%-20s : %-20c", "Online", (status->online) ? 'Y' : 'N');
+ cli_out ("%-20s : %-20s", "Pid", status->pid_str);
+
+#ifdef GF_LINUX_HOST_OS
+ if (status->fs_name)
+ cli_out ("%-20s : %-20s", "File System", status->fs_name);
+ else
+ cli_out ("%-20s : %-20s", "File System", "N/A");
+
+ if (status->device)
+ cli_out ("%-20s : %-20s", "Device", status->device);
+ else
+ cli_out ("%-20s : %-20s", "Device", "N/A");
+
+ if (status->mount_options) {
+ cli_out ("%-20s : %-20s", "Mount Options",
+ status->mount_options);
+ } else {
+ cli_out ("%-20s : %-20s", "Mount Options", "N/A");
+ }
+
+ if (status->inode_size) {
+ cli_out ("%-20s : %-20s", "Inode Size",
+ status->inode_size);
+ } else {
+ cli_out ("%-20s : %-20s", "Inode Size", "N/A");
+ }
+#endif
+ if (status->free)
+ cli_out ("%-20s : %-20s", "Disk Space Free", status->free);
+ else
+ cli_out ("%-20s : %-20s", "Disk Space Free", "N/A");
+
+ if (status->total)
+ cli_out ("%-20s : %-20s", "Total Disk Space", status->total);
+ else
+ cli_out ("%-20s : %-20s", "Total Disk Space", "N/A");
+
+
+ if (status->total_inodes) {
+ cli_out ("%-20s : %-20ld", "Inode Count",
+ status->total_inodes);
+ } else {
+ cli_out ("%-20s : %-20s", "Inode Count", "N/A");
+ }
+
+ if (status->free_inodes) {
+ cli_out ("%-20s : %-20ld", "Free Inodes",
+ status->free_inodes);
+ } else {
+ cli_out ("%-20s : %-20s", "Free Inodes", "N/A");
+ }
+}
+
+int
+cli_print_brick_status (cli_volume_status_t *status)
+{
+ int fieldlen = CLI_VOL_STATUS_BRICK_LEN;
+ char buf[80] = {0,};
+ int bricklen = 0;
+ int i = 0;
+ char *p = NULL;
+ int num_tabs = 0;
+
+ bricklen = strlen (status->brick);
+ p = status->brick;
+ while (bricklen > 0) {
+ if (bricklen > fieldlen) {
+ i++;
+ strncpy (buf, p, min (fieldlen, (sizeof (buf)-1)));
+ buf[strlen(buf) + 1] = '\0';
+ cli_out ("%s", buf);
+ p = status->brick + i * fieldlen;
+ bricklen -= fieldlen;
+ } else {
+ num_tabs = (fieldlen - bricklen) / CLI_TAB_LENGTH + 1;
+ printf ("%s", p);
+ while (num_tabs-- != 0)
+ printf ("\t");
+ if (status->port)
+ cli_out ("%d\t%c\t%s",
+ status->port, status->online?'Y':'N',
+ status->pid_str);
+ else
+ cli_out ("%s\t%c\t%s",
+ "N/A", status->online?'Y':'N',
+ status->pid_str);
+ bricklen = 0;
+ }
+ }
+
+ return 0;
+}
+
+int
+cli_cmd_volume_heal_cbk (struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int sent = 0;
+ int parse_error = 0;
+ dict_t *options = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame)
+ goto out;
+
+ if (wordcount < 3) {
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ ret = cli_cmd_volume_heal_options_parse (words, wordcount, &options);
+ if (ret) {
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_HEAL_VOLUME];
+
+ if (proc->fn) {
+ ret = proc->fn (frame, THIS, options);
+ }
+
+out:
+ if (ret) {
+ cli_cmd_sent_status_get (&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out ("Volume heal failed");
+ }
+
+ if (options)
+ dict_unref (options);
+
+ CLI_STACK_DESTROY (frame);
+
+ return ret;
+}
+
+int
+cli_cmd_volume_statedump_cbk (struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ int sent = 0;
+ int parse_error = 0;
+
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ if (wordcount < 3) {
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ if (wordcount >= 3) {
+ ret = cli_cmd_volume_statedump_options_parse (words, wordcount,
+ &options);
+ if (ret) {
+ parse_error = 1;
+ gf_log ("cli", GF_LOG_ERROR, "Error parsing "
+ "statedump options");
+ cli_out ("Error parsing options");
+ cli_usage_out (word->pattern);
+ }
+ }
+
+ ret = dict_set_str (options, "volname", (char *)words[2]);
+ if (ret)
+ goto out;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATEDUMP_VOLUME];
+ if (proc->fn) {
+ ret = proc->fn (frame, THIS, options);
+ }
+
+out:
+ if (ret) {
+ cli_cmd_sent_status_get (&sent);
+ if ((sent == 0) && (parse_error = 0))
+ cli_out ("Volume statedump failed");
+ }
+
+ CLI_STACK_DESTROY (frame);
+
+ return ret;
+}
+
+int
+cli_cmd_volume_list_cbk (struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ int sent = 0;
+
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_VOLUME];
+ if (proc->fn) {
+ ret = proc->fn (frame, THIS, NULL);
+ }
+
+out:
+ if (ret) {
+ cli_cmd_sent_status_get (&sent);
+ if (sent == 0)
+ cli_out ("Volume list failed");
+ }
+
+ CLI_STACK_DESTROY (frame);
+
+ return ret;
+}
+
+int
+cli_cmd_volume_clearlocks_cbk (struct cli_state *state,
+ struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ int sent = 0;
+ int parse_error = 0;
+
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ if (wordcount < 7 || wordcount > 8) {
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ ret = cli_cmd_volume_clrlks_opts_parse (words, wordcount, &options);
+ if (ret) {
+ parse_error = 1;
+ gf_log ("cli", GF_LOG_ERROR, "Error parsing "
+ "clear-locks options");
+ cli_out ("Error parsing options");
+ cli_usage_out (word->pattern);
+ }
+
+ ret = dict_set_str (options, "volname", (char *)words[2]);
+ if (ret)
+ goto out;
+
+ ret = dict_set_str (options, "path", (char *)words[3]);
+ if (ret)
+ goto out;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_CLRLOCKS_VOLUME];
+ if (proc->fn) {
+ ret = proc->fn (frame, THIS, options);
+ }
+
+out:
+ if (ret) {
+ cli_cmd_sent_status_get (&sent);
+ if ((sent == 0) && (parse_error = 0))
+ cli_out ("Volume clear-locks failed");
+ }
+
+ CLI_STACK_DESTROY (frame);
+
return ret;
}
@@ -1196,19 +1834,19 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_volume_rename_cbk,
"rename volume <VOLNAME> to <NEW-VOLNAME>"},*/
- { "volume add-brick <VOLNAME> <NEW-BRICK> ...",
+ { "volume add-brick <VOLNAME> [<stripe|replica> <COUNT>] <NEW-BRICK> ...",
cli_cmd_volume_add_brick_cbk,
"add brick to volume <VOLNAME>"},
- { "volume remove-brick <VOLNAME> <BRICK> ...",
+ { "volume remove-brick <VOLNAME> [replica <COUNT>] <BRICK> ... {start|stop|status|commit|force}",
cli_cmd_volume_remove_brick_cbk,
"remove brick from volume <VOLNAME>"},
- { "volume rebalance <VOLNAME> [fix-layout|migrate-data] {start|stop|status}",
+ { "volume rebalance <VOLNAME> [fix-layout] {start|stop|status} [force]",
cli_cmd_volume_defrag_cbk,
"rebalance operations"},
- { "volume replace-brick <VOLNAME> <BRICK> <NEW-BRICK> {start|pause|abort|status|commit}",
+ { "volume replace-brick <VOLNAME> <BRICK> <NEW-BRICK> {start|pause|abort|status|commit [force]}",
cli_cmd_volume_replace_brick_cbk,
"replace-brick operations"},
@@ -1224,14 +1862,6 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_volume_help_cbk,
"display help for the volume command"},
- { "volume log filename <VOLNAME> [BRICK] <PATH>",
- cli_cmd_log_filename_cbk,
- "set the log file for corresponding volume/brick"},
-
- { "volume log locate <VOLNAME> [BRICK]",
- cli_cmd_log_locate_cbk,
- "locate the log file for corresponding volume/brick"},
-
{ "volume log rotate <VOLNAME> [BRICK]",
cli_cmd_log_rotate_cbk,
"rotate the log file for corresponding volume/brick"},
@@ -1240,18 +1870,18 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_sync_volume_cbk,
"sync the volume information from a peer"},
- { "volume reset <VOLNAME> [force]",
+ { "volume reset <VOLNAME> [option] [force]",
cli_cmd_volume_reset_cbk,
"reset all the reconfigured options"},
#if (SYNCDAEMON_COMPILE)
- {"volume "GEOREP" [<VOLNAME>] [<SLAVE-URL>] {start|stop|config|status} [options...]",
+ {"volume "GEOREP" [<VOLNAME>] [<SLAVE-URL>] {start|stop|config|status|log-rotate} [options...]",
cli_cmd_volume_gsync_set_cbk,
"Geo-sync operations",
cli_cmd_check_gsync_exists_cbk},
#endif
- { "volume profile <VOLNAME> {start|info|stop}",
+ { "volume profile <VOLNAME> {start|info|stop} [nfs]",
cli_cmd_volume_profile_cbk,
"volume profile operations"},
@@ -1259,12 +1889,36 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_quota_cbk,
"quota translator specific operations"},
- { "volume top <VOLNAME> {[open|read|write|opendir|readdir] "
- "|[read-perf|write-perf bs <size> count <count>]} "
+ { "volume top <VOLNAME> {[open|read|write|opendir|readdir [nfs]] "
+ "|[read-perf|write-perf [nfs|{bs <size> count <count>}]]} "
" [brick <brick>] [list-cnt <count>]",
cli_cmd_volume_top_cbk,
"volume top operations"},
+ { "volume status [all | <VOLNAME> [nfs|shd|<BRICK>]]"
+ " [detail|clients|mem|inode|fd|callpool]",
+ cli_cmd_volume_status_cbk,
+ "display status of all or specified volume(s)/brick"},
+
+ { "volume heal <VOLNAME> [{full | info {healed | heal-failed | split-brain}}]",
+ cli_cmd_volume_heal_cbk,
+ "self-heal commands on volume specified by <VOLNAME>"},
+
+ {"volume statedump <VOLNAME> [nfs] [all|mem|iobuf|callpool|priv|fd|"
+ "inode|history]...",
+ cli_cmd_volume_statedump_cbk,
+ "perform statedump on bricks"},
+
+ {"volume list",
+ cli_cmd_volume_list_cbk,
+ "list all volumes in cluster"},
+
+ {"volume clear-locks <VOLNAME> <path> kind {blocked|granted|all}"
+ "{inode [range]|entry [basename]|posix [range]}",
+ cli_cmd_volume_clearlocks_cbk,
+ "Clear locks held on path"
+ },
+
{ NULL, NULL, NULL }
};
diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c
index cb0199b06..f2b434ac7 100644
--- a/cli/src/cli-cmd.c
+++ b/cli/src/cli-cmd.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -31,6 +31,7 @@
#include "cli.h"
#include "cli-cmd.h"
#include "cli-mem-types.h"
+#include "protocol-common.h"
#include <fnmatch.h>
@@ -59,6 +60,9 @@ cli_cmd_needs_connection (struct cli_cmd_word *word)
if (!strcasecmp ("getwd", word->word))
return 1;
+ if (!strcasecmp ("exit", word->word))
+ return 0;
+
return CLI_DEFAULT_CONN_TIMEOUT;
}
@@ -132,7 +136,9 @@ cli_cmd_process (struct cli_state *state, int argc, char **argv)
if ( strcmp (word->word,"help")==0 )
goto callback;
- ret = cli_cmd_await_connected (cli_cmd_needs_connection (word));
+ state->await_connected = cli_cmd_needs_connection (word);
+
+ ret = cli_cmd_await_connected (state->await_connected);
if (ret) {
cli_out ("Connection failed. Please check if gluster "
"daemon is operational.");
@@ -279,14 +285,14 @@ seconds_from_now (unsigned secs, struct timespec *ts)
}
int
-cli_cmd_await_response ()
+cli_cmd_await_response (unsigned time)
{
struct timespec ts = {0,};
int ret = 0;
cli_op_ret = -1;
- seconds_from_now (CLI_DEFAULT_CMD_TIMEOUT, &ts);
+ seconds_from_now (time, &ts);
while (!cmd_done && !ret) {
ret = pthread_cond_timedwait (&cond, &cond_mutex,
&ts);
@@ -294,8 +300,6 @@ cli_cmd_await_response ()
cmd_done = 0;
- cli_cmd_unlock ();
-
if (ret)
return ret;
@@ -362,22 +366,25 @@ int
cli_cmd_submit (void *req, call_frame_t *frame,
rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
- cli_serialize_t sfunc, xlator_t *this,
- fop_cbk_fn_t cbkfn)
+ xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
{
- int ret = -1;
+ int ret = -1;
+ unsigned timeout = 0;
+
+ timeout = (GLUSTER_CLI_PROFILE_VOLUME == procnum) ?
+ CLI_TOP_CMD_TIMEOUT : CLI_DEFAULT_CMD_TIMEOUT;
cli_cmd_lock ();
cmd_sent = 0;
ret = cli_submit_request (req, frame, prog,
- procnum, NULL, sfunc,
- this, cbkfn);
+ procnum, NULL, this, cbkfn, xdrproc);
if (!ret) {
cmd_sent = 1;
- ret = cli_cmd_await_response ();
- } else
- cli_cmd_unlock ();
+ ret = cli_cmd_await_response (timeout);
+ }
+
+ cli_cmd_unlock ();
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
diff --git a/cli/src/cli-cmd.h b/cli/src/cli-cmd.h
index acb40017a..ba877e2c4 100644
--- a/cli/src/cli-cmd.h
+++ b/cli/src/cli-cmd.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -25,7 +25,23 @@
#include "config.h"
#endif
+#include <netdb.h>
+
#include "cli.h"
+#include "list.h"
+
+#define CLI_STACK_DESTROY(_frame) \
+ do { \
+ if (_frame) { \
+ if (_frame->local) { \
+ gf_log ("cli", GF_LOG_DEBUG, "frame->local " \
+ "is not NULL (%p)", _frame->local); \
+ cli_local_wipe (_frame->local); \
+ _frame->local = NULL; \
+ } \
+ STACK_DESTROY (_frame->root); \
+ } \
+ } while (0);
typedef enum {
GF_ANSWER_YES = 1,
@@ -55,6 +71,17 @@ typedef struct cli_profile_info_ {
double percentage_avg_latency;
} cli_profile_info_t;
+typedef struct addrinfo_list {
+ struct list_head list;
+ struct addrinfo *info;
+} addrinfo_list_t;
+
+typedef enum {
+ GF_AI_COMPARE_NO_MATCH = 0,
+ GF_AI_COMPARE_MATCH = 1,
+ GF_AI_COMPARE_ERROR = 2
+} gf_ai_compare_t;
+
typedef struct cli_cmd_volume_get_ctx_ cli_cmd_volume_get_ctx_t;
int cli_cmd_volume_register (struct cli_state *state);
@@ -69,7 +96,7 @@ struct cli_cmd_word *cli_cmd_nextword (struct cli_cmd_word *word,
const char *text);
void cli_cmd_tokens_destroy (char **tokens);
-int cli_cmd_await_response ();
+int cli_cmd_await_response (unsigned time);
int cli_cmd_broadcast_response (int32_t status);
@@ -83,8 +110,7 @@ int
cli_cmd_submit (void *req, call_frame_t *frame,
rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
- cli_serialize_t sfunc, xlator_t *this,
- fop_cbk_fn_t cbkfn);
+ xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
gf_answer_t
cli_cmd_get_confirmation (struct cli_state *state, const char *question);
diff --git a/cli/src/cli-mem-types.h b/cli/src/cli-mem-types.h
index a3d74d31a..3c49d2183 100644
--- a/cli/src/cli-mem-types.h
+++ b/cli/src/cli-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/cli/src/cli-rl.c b/cli/src/cli-rl.c
index 5d1310858..f9bf7c819 100644
--- a/cli/src/cli-rl.c
+++ b/cli/src/cli-rl.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -48,7 +48,6 @@ cli_rl_out (struct cli_state *state, const char *fmt, va_list ap)
{
int tmp_rl_point = rl_point;
int n = rl_end;
- int i = 0;
int ret = 0;
if (rl_end >= 0 ) {
@@ -56,12 +55,7 @@ cli_rl_out (struct cli_state *state, const char *fmt, va_list ap)
rl_redisplay ();
}
- printf ("\r");
-
- for (i = 0; i <= strlen (state->prompt); i++)
- printf (" ");
-
- printf ("\r");
+ printf ("\r%*s\r", (int)strlen (state->prompt), "");
ret = vprintf (fmt, ap);
@@ -77,6 +71,34 @@ cli_rl_out (struct cli_state *state, const char *fmt, va_list ap)
return ret;
}
+int
+cli_rl_err (struct cli_state *state, const char *fmt, va_list ap)
+{
+ int tmp_rl_point = rl_point;
+ int n = rl_end;
+ int ret = 0;
+
+ if (rl_end >= 0 ) {
+ rl_kill_text (0, rl_end);
+ rl_redisplay ();
+ }
+
+ fprintf (stderr, "\r%*s\r", (int)strlen (state->prompt), "");
+
+ ret = vfprintf (stderr, fmt, ap);
+
+ fprintf (stderr, "\n");
+ fflush(stderr);
+
+ if (n) {
+ rl_do_undo ();
+ rl_point = tmp_rl_point;
+ rl_reset_line_state ();
+ }
+
+ return ret;
+}
+
void
cli_rl_process_line (char *line)
@@ -89,9 +111,14 @@ cli_rl_process_line (char *line)
state->rl_processing = 1;
{
ret = cli_cmd_process_line (state, line);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "failed to process line");
+
add_history (line);
}
state->rl_processing = 0;
+
}
@@ -187,7 +214,7 @@ cli_rl_tokenize (const char *text)
}
if (i < count) {
- /* symoblize that what needs to be autocompleted is
+ /* symbolize that what needs to be autocompleted is
the full set of possible nextwords, and not extend
the last word
*/
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 794eab017..ffa434e2c 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -26,7 +26,15 @@
#ifndef GSYNC_CONF
#define GSYNC_CONF GEOREP"/gsyncd.conf"
#endif
-#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+
+/* Widths of various columns in top read/write-perf output
+ * Total width of top read/write-perf should be 80 chars
+ * including one space between column
+ */
+#define VOL_TOP_PERF_FILENAME_DEF_WIDTH 47
+#define VOL_TOP_PERF_FILENAME_ALT_WIDTH 44
+#define VOL_TOP_PERF_SPEED_WIDTH 4
+#define VOL_TOP_PERF_TIME_WIDTH 26
#include "cli.h"
#include "compat-errno.h"
@@ -35,13 +43,16 @@
#include <stdlib.h>
#include <sys/mount.h>
#include "cli1-xdr.h"
-#include "cli1.h"
+#include "xdr-generic.h"
#include "protocol-common.h"
#include "cli-mem-types.h"
#include "compat.h"
+#include "syscall.h"
#include "glusterfs3.h"
-#include "portmap.h"
+#include "portmap-xdr.h"
+
+#include "run.h"
extern rpc_clnt_prog_t *cli_rpc_prog;
extern int cli_op_ret;
@@ -50,8 +61,10 @@ extern int connected;
char *cli_volume_type[] = {"Distribute",
"Stripe",
"Replicate",
+ "Striped-Replicate",
"Distributed-Stripe",
"Distributed-Replicate",
+ "Distributed-Striped-Replicate",
};
@@ -77,19 +90,19 @@ rpc_clnt_prog_t cli_pmap_prog = {
.progver = GLUSTER_PMAP_VERSION,
};
-
int
gf_cli3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_probe_rsp rsp = {0,};
- int ret = 0;
+ gf1_cli_probe_rsp rsp = {0,};
+ int ret = -1;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_probe_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_probe_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
//rsp.op_ret = -1;
@@ -98,55 +111,83 @@ gf_cli3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
}
gf_log ("cli", GF_LOG_INFO, "Received resp to probe");
- if (!rsp.op_ret) {
- switch (rsp.op_errno) {
- case GF_PROBE_SUCCESS:
- cli_out ("Probe successful");
- break;
- case GF_PROBE_LOCALHOST:
- cli_out ("Probe on localhost not needed");
- break;
- case GF_PROBE_FRIEND:
- cli_out ("Probe on host %s port %d already"
- " in peer list", rsp.hostname, rsp.port);
- break;
- default:
- cli_out ("Probe returned with unknown errno %d",
- rsp.op_errno);
- break;
- }
- }
+ if (!rsp.op_ret) {
+ switch (rsp.op_errno) {
+ case GF_PROBE_SUCCESS:
+ snprintf (msg, sizeof (msg),
+ "Probe successful");
+ break;
+ case GF_PROBE_LOCALHOST:
+ snprintf (msg, sizeof (msg),
+ "Probe on localhost not needed");
+ break;
+ case GF_PROBE_FRIEND:
+ snprintf (msg, sizeof (msg),
+ "Probe on host %s port %d already"
+ " in peer list", rsp.hostname,
+ rsp.port);
+ break;
+ default:
+ snprintf (msg, sizeof (msg),
+ "Probe returned with unknown errno %d",
+ rsp.op_errno);
+ break;
+ }
+ }
if (rsp.op_ret) {
switch (rsp.op_errno) {
case GF_PROBE_ANOTHER_CLUSTER:
- cli_out ("%s is already part of "
- "another cluster", rsp.hostname);
+ snprintf (msg, sizeof (msg),
+ "%s is already part of another"
+ " cluster", rsp.hostname);
break;
case GF_PROBE_VOLUME_CONFLICT:
- cli_out ("Atleast one volume on %s conflicts "
- "with existing volumes in the "
- "cluster", rsp.hostname);
+ snprintf (msg, sizeof (msg),
+ "Atleast one volume on %s conflicts "
+ "with existing volumes in the "
+ "cluster", rsp.hostname);
break;
case GF_PROBE_UNKNOWN_PEER:
- cli_out ("%s responded with 'unknown peer' error, "
- "this could happen if %s doesn't have"
- " localhost in its peer database",
- rsp.hostname, rsp.hostname);
+ snprintf (msg, sizeof (msg),
+ "%s responded with 'unknown peer'"
+ " error, this could happen if %s "
+ "doesn't have localhost in its peer"
+ " database", rsp.hostname,
+ rsp.hostname);
break;
case GF_PROBE_ADD_FAILED:
- cli_out ("Failed to add peer information "
- "on %s" , rsp.hostname);
+ snprintf (msg, sizeof (msg),
+ "Failed to add peer information "
+ "on %s" , rsp.hostname);
break;
default:
- cli_out ("Probe unsuccessful\nProbe returned "
- "with unknown errno %d", rsp.op_errno);
+ snprintf (msg, sizeof (msg),
+ "Probe unsuccessful\nProbe returned "
+ "with unknown errno %d",
+ rsp.op_errno);
break;
}
gf_log ("glusterd",GF_LOG_ERROR,"Probe failed with op_ret %d"
" and op_errno %d", rsp.op_ret, rsp.op_errno);
}
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("peerProbe", msg, rsp.op_ret,
+ rsp.op_errno, NULL);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+ if (!rsp.op_ret)
+ cli_out ("%s", msg);
+ else
+ cli_err ("%s", msg);
+
ret = rsp.op_ret;
out:
@@ -159,13 +200,14 @@ gf_cli3_1_deprobe_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gf1_cli_deprobe_rsp rsp = {0,};
- int ret = 0;
+ int ret = -1;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_deprobe_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_deprobe_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
//rsp.op_ret = -1;
@@ -177,29 +219,51 @@ gf_cli3_1_deprobe_cbk (struct rpc_req *req, struct iovec *iov,
if (rsp.op_ret) {
switch (rsp.op_errno) {
case GF_DEPROBE_LOCALHOST:
- cli_out ("%s is localhost",
- rsp.hostname);
+ snprintf (msg, sizeof (msg),
+ "%s is localhost", rsp.hostname);
break;
case GF_DEPROBE_NOT_FRIEND:
- cli_out ("%s is not part of cluster",
- rsp.hostname);
+ snprintf (msg, sizeof (msg),
+ "%s is not part of cluster",
+ rsp.hostname);
break;
case GF_DEPROBE_BRICK_EXIST:
- cli_out ("Brick(s) with the peer %s exist in "
- "cluster", rsp.hostname);
+ snprintf (msg, sizeof (msg),
+ "Brick(s) with the peer %s exist in "
+ "cluster", rsp.hostname);
+ break;
+ case GF_DEPROBE_FRIEND_DOWN:
+ snprintf (msg, sizeof (msg),
+ "One of the peers is probably down."
+ " Check with 'peer status'.");
break;
default:
- cli_out ("Detach unsuccessful\nDetach returned "
- "with unknown errno %d",
- rsp.op_errno);
+ snprintf (msg, sizeof (msg),
+ "Detach unsuccessful\nDetach returned"
+ " with unknown errno %d",
+ rsp.op_errno);
break;
}
gf_log ("glusterd",GF_LOG_ERROR,"Detach failed with op_ret %d"
" and op_errno %d", rsp.op_ret, rsp.op_errno);
} else {
- cli_out ("Detach successful");
+ snprintf (msg, sizeof (msg), "Detach successful");
}
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("peerDetach", msg, rsp.op_ret,
+ rsp.op_errno, NULL);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+ if (!rsp.op_ret)
+ cli_out ("%s", msg);
+ else
+ cli_err ("%s", msg);
ret = rsp.op_ret;
@@ -213,7 +277,7 @@ gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gf1_cli_peer_list_rsp rsp = {0,};
- int ret = 0;
+ int ret = -1;
dict_t *dict = NULL;
char *uuid_buf = NULL;
char *hostname_buf = NULL;
@@ -223,12 +287,13 @@ gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
int32_t port = 0;
int32_t connected = 0;
char *connected_str = NULL;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_peer_list_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
//rsp.op_ret = -1;
@@ -236,7 +301,6 @@ gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
-
gf_log ("cli", GF_LOG_INFO, "Received resp to list: %d",
rsp.op_ret);
@@ -245,7 +309,21 @@ gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
if (!rsp.op_ret) {
if (!rsp.friends.friends_len) {
- cli_out ("No peers present");
+ snprintf (msg, sizeof (msg),
+ "No peers present");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_peer_status (dict,
+ rsp.op_ret,
+ rsp.op_errno,
+ msg);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+ cli_err ("%s", msg);
ret = 0;
goto out;
}
@@ -267,6 +345,16 @@ gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_peer_status (dict, rsp.op_ret,
+ rsp.op_errno, msg);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
ret = dict_get_int32 (dict, "count", &count);
if (ret) {
@@ -318,7 +406,18 @@ gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
i++;
}
} else {
- ret = -1;
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_peer_status (dict, rsp.op_ret,
+ rsp.op_errno, NULL);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ } else
+#endif
+ {
+ ret = -1;
+ }
goto out;
}
@@ -328,7 +427,7 @@ gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
out:
cli_cmd_broadcast_response (ret);
if (ret)
- cli_out ("Peer status unsuccessful");
+ cli_err ("Peer status unsuccessful");
if (dict)
dict_destroy (dict);
@@ -365,225 +464,297 @@ cli_out_options ( char *substr, char *optstr, char *valstr)
int
gf_cli3_1_get_volume_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+ int count, void *myframe)
{
- gf1_cli_get_vol_rsp rsp = {0,};
- int ret = 0;
- dict_t *dict = NULL;
- char *volname = NULL;
- int32_t i = 0;
- char key[1024] = {0,};
- int32_t status = 0;
- int32_t type = 0;
- int32_t brick_count = 0;
- int32_t sub_count = 0;
- int32_t vol_type = 0;
- char *brick = NULL;
- int32_t j = 1;
- cli_local_t *local = NULL;
- int32_t transport = 0;
- data_pair_t *pairs = NULL;
- char *ptr = NULL;
- data_t *value = NULL;
- int opt_count = 0;
- int k = 0;
- char err_str[2048] = {0};
-
- snprintf (err_str, sizeof (err_str), "Volume info unsuccessful");
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- ret = gf_xdr_to_cli_get_vol_rsp (*iov, &rsp);
+ int ret = -1;
+ int opt_count = 0;
+ int k = 0;
+ int32_t i = 0;
+ int32_t j = 1;
+ int32_t status = 0;
+ int32_t type = 0;
+ int32_t brick_count = 0;
+ int32_t dist_count = 0;
+ int32_t stripe_count = 0;
+ int32_t replica_count = 0;
+ int32_t vol_type = 0;
+ int32_t transport = 0;
+ char *ptr = NULL;
+ char *volume_id_str = NULL;
+ char *brick = NULL;
+ char *volname = NULL;
+ dict_t *dict = NULL;
+ data_pair_t *pairs = NULL;
+ data_t *value = NULL;
+ cli_local_t *local = NULL;
+ char key[1024] = {0};
+ char err_str[2048] = {0};
+ gf_cli_rsp rsp = {0};
+
+ if (-1 == req->rpc_status)
+ goto out;
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "error");
- //rsp.op_ret = -1;
- //rsp.op_errno = EINVAL;
+ gf_log ("cli", GF_LOG_ERROR, "error");
goto out;
}
-
gf_log ("cli", GF_LOG_INFO, "Received resp to get vol: %d",
rsp.op_ret);
- if (!rsp.op_ret) {
+ if (rsp.op_ret) {
+ ret = -1;
+ goto out;
+ }
- if (!rsp.volumes.volumes_len) {
- cli_out ("No volumes present");
- ret = 0;
- goto out;
- }
+ if (!rsp.dict.dict_len) {
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML)
+ goto xml_output;
+#endif
+ cli_out ("No volumes present");
+ ret = 0;
+ goto out;
+ }
- dict = dict_new ();
+ dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_unserialize (rsp.volumes.volumes_val,
- rsp.volumes.volumes_len,
- &dict);
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to allocate memory");
- goto out;
- }
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Unable to allocate memory");
+ goto out;
+ }
- ret = dict_get_int32 (dict, "count", &count);
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret)
+ goto out;
- if (ret) {
- goto out;
- }
+ local = ((call_frame_t *)myframe)->local;
- local = ((call_frame_t *)myframe)->local;
- //cli_out ("Number of Volumes: %d", count);
+ if (!count) {
+ switch (local->get_vol.flags) {
- if (!count && (local->u.get_vol.flags ==
- GF_CLI_GET_NEXT_VOLUME)) {
- local->u.get_vol.volname = NULL;
+ case GF_CLI_GET_NEXT_VOLUME:
+ GF_FREE (local->get_vol.volname);
+ local->get_vol.volname = NULL;
ret = 0;
goto out;
- } else if (!count && (local->u.get_vol.flags ==
- GF_CLI_GET_VOLUME)) {
+
+ case GF_CLI_GET_VOLUME:
+ memset (err_str, 0, sizeof (err_str));
snprintf (err_str, sizeof (err_str),
"Volume %s does not exist",
- local->u.get_vol.volname);
+ local->get_vol.volname);
ret = -1;
- goto out;
+#if (HAVE_LIB_XML)
+ if (!(global_state->mode & GLUSTER_MODE_XML))
+#endif
+ {
+ goto out;
+ }
}
+ }
- while ( i < count) {
- cli_out ("");
- snprintf (key, 256, "volume%d.name", i);
- ret = dict_get_str (dict, key, &volname);
- if (ret)
+#if (HAVE_LIB_XML)
+xml_output:
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ /* For GET_NEXT_VOLUME output is already begun in
+ * and will also end in gf_cli3_1_get_next_volume()
+ */
+ if (local->get_vol.flags == GF_CLI_GET_VOLUME) {
+ ret = cli_xml_output_vol_info_begin
+ (local, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
goto out;
+ }
+ }
- snprintf (key, 256, "volume%d.type", i);
- ret = dict_get_int32 (dict, key, &type);
- if (ret)
+ if (dict) {
+ ret = cli_xml_output_vol_info (local, dict);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
goto out;
+ }
+ }
- snprintf (key, 256, "volume%d.status", i);
- ret = dict_get_int32 (dict, key, &status);
+ if (local->get_vol.flags == GF_CLI_GET_VOLUME) {
+ ret = cli_xml_output_vol_info_end (local);
if (ret)
- goto out;
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ }
+ goto out;
+ }
+#endif
- snprintf (key, 256, "volume%d.brick_count", i);
- ret = dict_get_int32 (dict, key, &brick_count);
- if (ret)
- goto out;
+ while ( i < count) {
+ cli_out (" ");
+ snprintf (key, 256, "volume%d.name", i);
+ ret = dict_get_str (dict, key, &volname);
+ if (ret)
+ goto out;
- snprintf (key, 256, "volume%d.sub_count", i);
- ret = dict_get_int32 (dict, key, &sub_count);
- if (ret)
- goto out;
+ snprintf (key, 256, "volume%d.type", i);
+ ret = dict_get_int32 (dict, key, &type);
+ if (ret)
+ goto out;
- snprintf (key, 256, "volume%d.transport", i);
- ret = dict_get_int32 (dict, key, &transport);
- if (ret)
- goto out;
+ snprintf (key, 256, "volume%d.status", i);
+ ret = dict_get_int32 (dict, key, &status);
+ if (ret)
+ goto out;
- vol_type = type;
+ snprintf (key, 256, "volume%d.brick_count", i);
+ ret = dict_get_int32 (dict, key, &brick_count);
+ if (ret)
+ goto out;
- // Stripe
- if ((type == 1) && (sub_count < brick_count))
- vol_type = 3;
+ snprintf (key, 256, "volume%d.dist_count", i);
+ ret = dict_get_int32 (dict, key, &dist_count);
+ if (ret)
+ goto out;
- // Replicate
- if ((type == 2) && (sub_count < brick_count))
- vol_type = 4;
+ snprintf (key, 256, "volume%d.stripe_count", i);
+ ret = dict_get_int32 (dict, key, &stripe_count);
+ if (ret)
+ goto out;
- cli_out ("Volume Name: %s", volname);
- cli_out ("Type: %s", cli_volume_type[vol_type]);
- cli_out ("Status: %s", cli_volume_status[status], brick_count);
- if ((sub_count > 1) && (brick_count > sub_count))
- cli_out ("Number of Bricks: %d x %d = %d",
- brick_count / sub_count, sub_count,
- brick_count);
- else
- cli_out ("Number of Bricks: %d", brick_count);
+ snprintf (key, 256, "volume%d.replica_count", i);
+ ret = dict_get_int32 (dict, key, &replica_count);
+ if (ret)
+ goto out;
- cli_out ("Transport-type: %s",
- ((transport == 0)?"tcp":
- (transport == 1)?"rdma":
- "tcp,rdma"));
- j = 1;
+ snprintf (key, 256, "volume%d.transport", i);
+ ret = dict_get_int32 (dict, key, &transport);
+ if (ret)
+ goto out;
+ snprintf (key, 256, "volume%d.volume_id", i);
+ ret = dict_get_str (dict, key, &volume_id_str);
+ if (ret)
+ goto out;
- GF_FREE (local->u.get_vol.volname);
- local->u.get_vol.volname = gf_strdup (volname);
+ vol_type = type;
- if (brick_count)
- cli_out ("Bricks:");
+ // Distributed (stripe/replicate/stripe-replica) setups
+ if ((type > 0) && ( dist_count < brick_count))
+ vol_type = type + 3;
- while ( j <= brick_count) {
- snprintf (key, 1024, "volume%d.brick%d",
- i, j);
- ret = dict_get_str (dict, key, &brick);
- if (ret)
- goto out;
- cli_out ("Brick%d: %s", j, brick);
- j++;
- }
- pairs = dict->members_list;
- if (!pairs) {
- ret = -1;
- goto out;
- }
+ cli_out ("Volume Name: %s", volname);
+ cli_out ("Type: %s", cli_volume_type[vol_type]);
+ cli_out ("Volume ID: %s", volume_id_str);
+ cli_out ("Status: %s", cli_volume_status[status]);
- snprintf (key, 256, "volume%d.opt_count",i);
- ret = dict_get_int32 (dict, key, &opt_count);
+ if (type == GF_CLUSTER_TYPE_STRIPE_REPLICATE) {
+ cli_out ("Number of Bricks: %d x %d x %d = %d",
+ (brick_count / dist_count),
+ stripe_count,
+ replica_count,
+ brick_count);
+
+ } else if (type == GF_CLUSTER_TYPE_NONE) {
+ cli_out ("Number of Bricks: %d", brick_count);
+
+ } else {
+ /* For both replicate and stripe, dist_count is
+ good enough */
+ cli_out ("Number of Bricks: %d x %d = %d",
+ (brick_count / dist_count),
+ dist_count, brick_count);
+ }
+
+ cli_out ("Transport-type: %s",
+ ((transport == 0)?"tcp":
+ (transport == 1)?"rdma":
+ "tcp,rdma"));
+ j = 1;
+
+ GF_FREE (local->get_vol.volname);
+ local->get_vol.volname = gf_strdup (volname);
+
+ if (brick_count)
+ cli_out ("Bricks:");
+
+ while (j <= brick_count) {
+ snprintf (key, 1024, "volume%d.brick%d", i, j);
+ ret = dict_get_str (dict, key, &brick);
if (ret)
- goto out;
-
- if (!opt_count)
- goto out;
-
- cli_out ("Options Reconfigured:");
- k = 0;
- while ( k < opt_count) {
-
- snprintf (key, 256, "volume%d.option.",i);
- while (pairs) {
- ptr = strstr (pairs->key, "option.");
- if (ptr) {
- value = pairs->value;
- if (!value) {
- ret = -1;
- goto out;
- }
- cli_out_options (key, pairs->key,
- value->data);
- }
- pairs = pairs->next;
- }
- k++;
- }
+ goto out;
- i++;
+ cli_out ("Brick%d: %s", j, brick);
+ j++;
}
+ pairs = dict->members_list;
+ if (!pairs) {
+ ret = -1;
+ goto out;
+ }
- } else {
- ret = -1;
- goto out;
+ snprintf (key, 256, "volume%d.opt_count",i);
+ ret = dict_get_int32 (dict, key, &opt_count);
+ if (ret)
+ goto out;
+
+ if (!opt_count)
+ goto out;
+
+ cli_out ("Options Reconfigured:");
+ k = 0;
+
+ while (k < opt_count) {
+
+ snprintf (key, 256, "volume%d.option.",i);
+ while (pairs) {
+ ptr = strstr (pairs->key, "option.");
+ if (ptr) {
+ value = pairs->value;
+ if (!value) {
+ ret = -1;
+ goto out;
+ }
+ cli_out_options (key, pairs->key,
+ value->data);
+ }
+ pairs = pairs->next;
+ }
+ k++;
+ }
+
+ i++;
}
ret = 0;
-
out:
cli_cmd_broadcast_response (ret);
if (ret)
- cli_out (err_str);
+ cli_err ("%s", err_str);
if (dict)
dict_destroy (dict);
- gf_log ("", GF_LOG_INFO, "Returning: %d", ret);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
+
+ if (rsp.op_errstr)
+ free (rsp.op_errstr);
+
+ gf_log ("cli", GF_LOG_INFO, "Returning: %d", ret);
return ret;
}
@@ -591,8 +762,8 @@ int
gf_cli3_1_create_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_create_vol_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
cli_local_t *local = NULL;
char *volname = NULL;
dict_t *dict = NULL;
@@ -604,19 +775,31 @@ gf_cli3_1_create_volume_cbk (struct rpc_req *req, struct iovec *iov,
local = ((call_frame_t *) (myframe))->local;
((call_frame_t *) (myframe))->local = NULL;
- ret = gf_xdr_to_cli_create_vol_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
}
- dict = local->u.create_vol.dict;
+ dict = local->dict;
ret = dict_get_str (dict, "volname", &volname);
gf_log ("cli", GF_LOG_INFO, "Received resp to create volume");
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out ("%s", rsp.op_errstr);
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_dict ("volCreate", dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
+ cli_err ("%s", rsp.op_errstr);
else
cli_out ("Creation of volume %s has been %s", volname,
(rsp.op_ret) ? "unsuccessful":
@@ -630,8 +813,8 @@ out:
dict_unref (dict);
if (local)
cli_local_wipe (local);
- if (rsp.volname)
- free (rsp.volname);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
if (rsp.op_errstr)
free (rsp.op_errstr);
return ret;
@@ -641,17 +824,18 @@ int
gf_cli3_1_delete_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_delete_vol_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
cli_local_t *local = NULL;
char *volname = NULL;
call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_delete_vol_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -662,13 +846,29 @@ gf_cli3_1_delete_volume_cbk (struct rpc_req *req, struct iovec *iov,
frame->local = NULL;
if (local)
- volname = local->u.delete_vol.volname;
-
+ dict = local->dict;
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "dict get failed");
+ goto out;
+ }
gf_log ("cli", GF_LOG_INFO, "Received resp to delete volume");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_dict ("volDelete", dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out (rsp.op_errstr);
+ cli_err ("%s", rsp.op_errstr);
else
cli_out ("Deleting volume %s has been %s", volname,
(rsp.op_ret) ? "unsuccessful": "successful");
@@ -677,8 +877,11 @@ gf_cli3_1_delete_volume_cbk (struct rpc_req *req, struct iovec *iov,
out:
cli_cmd_broadcast_response (ret);
cli_local_wipe (local);
- if (rsp.volname)
- free (rsp.volname);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
+ if (dict)
+ dict_unref (dict);
+
gf_log ("", GF_LOG_INFO, "Returning with %d", ret);
return ret;
}
@@ -687,17 +890,18 @@ int
gf_cli3_1_start_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_start_vol_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
cli_local_t *local = NULL;
char *volname = NULL;
call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_start_vol_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -711,12 +915,29 @@ gf_cli3_1_start_volume_cbk (struct rpc_req *req, struct iovec *iov,
}
if (local)
- volname = local->u.start_vol.volname;
+ dict = local->dict;
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "dict get failed");
+ goto out;
+ }
gf_log ("cli", GF_LOG_INFO, "Received resp to start volume");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_dict ("volStart", dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out ("%s", rsp.op_errstr);
+ cli_err ("%s", rsp.op_errstr);
else
cli_out ("Starting volume %s has been %s", volname,
(rsp.op_ret) ? "unsuccessful": "successful");
@@ -727,10 +948,12 @@ out:
cli_cmd_broadcast_response (ret);
if (local)
cli_local_wipe (local);
- if (rsp.volname)
- free (rsp.volname);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
if (rsp.op_errstr)
free (rsp.op_errstr);
+ if (dict)
+ dict_unref (dict);
return ret;
}
@@ -738,17 +961,18 @@ int
gf_cli3_1_stop_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_stop_vol_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
cli_local_t *local = NULL;
char *volname = NULL;
call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_stop_vol_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -756,16 +980,36 @@ gf_cli3_1_stop_volume_cbk (struct rpc_req *req, struct iovec *iov,
frame = myframe;
- if (frame)
+ if (frame) {
local = frame->local;
+ frame->local = NULL;
+ }
- if (local)
- volname = local->u.start_vol.volname;
+ if (local) {
+ dict = local->dict;
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Unable to get volname from dict");
+ goto out;
+ }
+ }
gf_log ("cli", GF_LOG_INFO, "Received resp to stop volume");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_dict ("volStop", dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out (rsp.op_errstr);
+ cli_err ("%s", rsp.op_errstr);
else
cli_out ("Stopping volume %s has been %s", volname,
(rsp.op_ret) ? "unsuccessful": "successful");
@@ -775,8 +1019,11 @@ out:
cli_cmd_broadcast_response (ret);
if (rsp.op_errstr)
free (rsp.op_errstr);
- if (rsp.volname)
- free (rsp.volname);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
+ if (local)
+ cli_local_wipe (local);
+
return ret;
}
@@ -784,18 +1031,33 @@ int
gf_cli3_1_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf2_cli_defrag_vol_rsp rsp = {0,};
+ gf_cli_rsp rsp = {0,};
cli_local_t *local = NULL;
char *volname = NULL;
call_frame_t *frame = NULL;
+ char *status = "unknown";
int cmd = 0;
- int ret = 0;
+ int ret = -1;
+ dict_t *dict = NULL;
+ dict_t *local_dict = NULL;
+ uint64_t files = 0;
+ uint64_t size = 0;
+ uint64_t lookup = 0;
+ char msg[1024] = {0,};
+ gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
+ int32_t counter = 0;
+ char *node_uuid = NULL;
+ char key[256] = {0,};
+ int32_t i = 1;
+ uint64_t failures = 0;
+ char *size_str = NULL;
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_defrag_vol_rsp_v2 (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp,
+ (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -803,95 +1065,193 @@ gf_cli3_1_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov,
frame = myframe;
- if (frame)
+ if (frame) {
local = frame->local;
+ frame->local = NULL;
+ }
if (local) {
- volname = local->u.defrag_vol.volname;
- cmd = local->u.defrag_vol.cmd;
+ local_dict = local->dict;
+ }
+
+ ret = dict_get_str (local_dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to get volname");
+ goto out;
+ }
+
+ ret = dict_get_int32 (local_dict, "rebalance-command", (int32_t*)&cmd);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to get command");
+ goto out;
+ }
+
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ }
}
- if ((cmd == GF_DEFRAG_CMD_START) ||
- (cmd == GF_DEFRAG_CMD_START_LAYOUT_FIX) ||
- (cmd == GF_DEFRAG_CMD_START_MIGRATE_DATA)) {
+
+ if (!((cmd == GF_DEFRAG_CMD_STOP) || (cmd == GF_DEFRAG_CMD_STATUS))) {
+ /* All other possibility is about starting a volume */
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out (rsp.op_errstr);
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
else
- cli_out ("starting rebalance on volume %s has been %s",
- volname, (rsp.op_ret) ? "unsuccessful":
- "successful");
+ snprintf (msg, sizeof (msg),
+ "Starting rebalance on volume %s has been %s",
+ volname, (rsp.op_ret) ? "unsuccessful":
+ "successful");
+ goto done;
}
+
+ ret = dict_get_int32 (dict, "count", &counter);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "count not set");
+ goto out;
+ }
+
if (cmd == GF_DEFRAG_CMD_STOP) {
if (rsp.op_ret == -1) {
if (strcmp (rsp.op_errstr, ""))
- cli_out (rsp.op_errstr);
+ snprintf (msg, sizeof (msg),
+ "%s", rsp.op_errstr);
else
- cli_out ("rebalance volume %s stop failed",
- volname);
+ snprintf (msg, sizeof (msg),
+ "rebalance volume %s stop failed",
+ volname);
+ goto done;
} else {
- cli_out ("stopped rebalance process of volume %s \n"
- "(after rebalancing %"PRId64" files totaling "
- "%"PRId64" bytes)", volname, rsp.files, rsp.size);
+ snprintf (msg, sizeof (msg),
+ "Stopped rebalance process on volume %s \n",
+ volname);
}
}
if (cmd == GF_DEFRAG_CMD_STATUS) {
if (rsp.op_ret == -1) {
if (strcmp (rsp.op_errstr, ""))
- cli_out (rsp.op_errstr);
+ snprintf (msg, sizeof (msg),
+ "%s", rsp.op_errstr);
else
- cli_out ("failed to get the status of "
- "rebalance process");
- } else {
- char *status = "unknown";
- if (rsp.op_errno == 0)
- status = "not started";
- if (rsp.op_errno == 1)
- status = "step 1: layout fix in progress";
- if (rsp.op_errno == 2)
- status = "step 2: data migration in progress";
- if (rsp.op_errno == 3)
- status = "stopped";
- if (rsp.op_errno == 4)
- status = "completed";
- if (rsp.op_errno == 5)
- status = "failed";
- if (rsp.op_errno == 6)
- status = "step 1: layout fix complete";
- if (rsp.op_errno == 7)
- status = "step 2: data migration complete";
-
- if (rsp.files && (rsp.op_errno == 1)) {
- cli_out ("rebalance %s: fixed layout %"PRId64,
- status, rsp.files);
- goto done;
- }
- if (rsp.files && (rsp.op_errno == 6)) {
- cli_out ("rebalance %s: fixed layout %"PRId64,
- status, rsp.files);
- goto done;
- }
- if (rsp.files) {
- cli_out ("rebalance %s: rebalanced %"PRId64
- " files of size %"PRId64" (total files"
- " scanned %"PRId64")", status,
- rsp.files, rsp.size, rsp.lookedup_files);
- goto done;
- }
-
- cli_out ("rebalance %s", status);
+ snprintf (msg, sizeof (msg),
+ "Failed to get the status of "
+ "rebalance process");
+ goto done;
}
}
+ cli_out ("%40s %16s %13s %13s %13s %14s", "Node", "Rebalanced-files",
+ "size", "scanned", "failures","status");
+ cli_out ("%40s %16s %13s %13s %13s %14s", "---------", "-----------",
+ "-----------", "-----------", "-----------", "------------");
-done:
- if (volname)
- GF_FREE (volname);
+ do {
+ snprintf (key, 256, "node-uuid-%d", i);
+ ret = dict_get_str (dict, key, &node_uuid);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get node-uuid");
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "files-%d", i);
+ ret = dict_get_uint64 (dict, key, &files);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get file count");
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "size-%d", i);
+ ret = dict_get_uint64 (dict, key, &size);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get size of xfer");
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "lookups-%d", i);
+ ret = dict_get_uint64 (dict, key, &lookup);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get lookedup file count");
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "status-%d", i);
+ ret = dict_get_int32 (dict, key, (int32_t *)&status_rcd);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get status");
+ memset (key, 0, 256);
+ snprintf (key, 256, "failures-%d", i);
+ ret = dict_get_uint64 (dict, key, &failures);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get failures count");
+
+ switch (status_rcd) {
+ case GF_DEFRAG_STATUS_NOT_STARTED:
+ status = "not started";
+ break;
+ case GF_DEFRAG_STATUS_STARTED:
+ status = "in progress";
+ break;
+ case GF_DEFRAG_STATUS_STOPPED:
+ status = "stopped";
+ break;
+ case GF_DEFRAG_STATUS_COMPLETE:
+ status = "completed";
+ break;
+ case GF_DEFRAG_STATUS_FAILED:
+ status = "failed";
+ break;
+ }
+
+ size_str = gf_uint64_2human_readable(size);
+ cli_out ("%40s %16"PRId64 " %13s" " %13"PRId64 " %13"PRId64
+ " %14s", node_uuid, files, size_str, lookup, failures,
+ status);
+ GF_FREE(size_str);
+
+ i++;
+ } while (i <= counter);
+
+
+done:
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volRebalance", msg, rsp.op_ret,
+ status_rcd, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
ret = rsp.op_ret;
out:
if (rsp.op_errstr)
free (rsp.op_errstr); //malloced by xdr
- if (rsp.volname)
- free (rsp.volname); //malloced by xdr
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val); //malloced by xdr
+ if (dict)
+ dict_unref (dict);
+ if (local_dict)
+ dict_unref (local_dict);
+ if (local)
+ cli_local_wipe (local);
cli_cmd_broadcast_response (ret);
return ret;
}
@@ -900,14 +1260,15 @@ int
gf_cli3_1_rename_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_rename_vol_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_rename_vol_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -915,9 +1276,24 @@ gf_cli3_1_rename_volume_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("cli", GF_LOG_INFO, "Received resp to probe");
- cli_out ("Rename volume %s", (rsp.op_ret) ? "unsuccessful":
- "successful");
+ snprintf (msg, sizeof (msg), "Rename volume %s",
+ (rsp.op_ret) ? "unsuccessful": "successful");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volRename", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
ret = rsp.op_ret;
out:
@@ -929,14 +1305,15 @@ int
gf_cli3_1_reset_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_reset_vol_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_reset_vol_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -945,11 +1322,26 @@ gf_cli3_1_reset_volume_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("cli", GF_LOG_INFO, "Received resp to reset");
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out ("%s", rsp.op_errstr);
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
else
- cli_out ("reset volume %s", (rsp.op_ret) ? "unsuccessful":
- "successful");
+ snprintf (msg, sizeof (msg), "reset volume %s",
+ (rsp.op_ret) ? "unsuccessful": "successful");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volReset", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
ret = rsp.op_ret;
out:
@@ -961,14 +1353,17 @@ int
gf_cli3_1_set_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_set_vol_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *help_str = NULL;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_set_vol_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -976,11 +1371,40 @@ gf_cli3_1_set_volume_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("cli", GF_LOG_INFO, "Received resp to set");
+ dict = dict_new ();
+
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+
+ if (ret)
+ goto out;
+
+ if (dict_get_str (dict, "help-str", &help_str) && !msg[0])
+ snprintf (msg, sizeof (msg), "Set volume %s",
+ (rsp.op_ret) ? "unsuccessful": "successful");
+
+#if (HAVE_LIB_XML)
+ if ((global_state->mode & GLUSTER_MODE_XML) && (help_str == NULL)) {
+ ret = cli_xml_output_str ("volSet", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out ("%s", rsp.op_errstr);
+ cli_err ("%s", rsp.op_errstr);
+
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
else
- cli_out ("Set volume %s", (rsp.op_ret) ? "unsuccessful":
- "successful");
+ cli_out ("%s", ((help_str == NULL) ? msg : help_str));
ret = rsp.op_ret;
@@ -993,14 +1417,15 @@ int
gf_cli3_1_add_brick_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_add_brick_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_add_brick_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -1010,55 +1435,285 @@ gf_cli3_1_add_brick_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("cli", GF_LOG_INFO, "Received resp to add brick");
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out ("%s", rsp.op_errstr);
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
else
- cli_out ("Add Brick %s", (rsp.op_ret) ? "unsuccessful":
- "successful");
+ snprintf (msg, sizeof (msg), "Add Brick %s",
+ (rsp.op_ret) ? "unsuccessful": "successful");
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volAddBrick", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
ret = rsp.op_ret;
out:
cli_cmd_broadcast_response (ret);
- if (rsp.volname)
- free (rsp.volname);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
if (rsp.op_errstr)
free (rsp.op_errstr);
return ret;
}
+int
+gf_cli3_remove_brick_status_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf_cli_rsp rsp = {0,};
+ char *status = "unknown";
+ int ret = -1;
+ uint64_t files = 0;
+ uint64_t size = 0;
+ uint64_t lookup = 0;
+ dict_t *dict = NULL;
+ //char msg[1024] = {0,};
+ char key[256] = {0,};
+ int32_t i = 1;
+ int32_t counter = 0;
+ char *node_uuid = 0;
+ gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
+ uint64_t failures = 0;
+ char *size_str = NULL;
+
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp,
+ (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_ERROR, "error");
+ goto out;
+ }
+
+ ret = rsp.op_ret;
+ if (rsp.op_ret == -1) {
+ if (strcmp (rsp.op_errstr, ""))
+ cli_err ("%s", rsp.op_errstr);
+ else
+ cli_err ("failed to get the status of "
+ "remove-brick process");
+ goto out;
+ }
+
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ }
+ }
+
+ ret = dict_get_int32 (dict, "count", &counter);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "count not set");
+ goto out;
+ }
+
+
+ cli_out ("%40s %16s %13s %13s %13s %14s", "Node", "Rebalanced-files",
+ "size", "scanned", "failures", "status");
+ cli_out ("%40s %16s %13s %13s %13s %14s", "---------", "-----------",
+ "-----------", "-----------", "-----------", "------------");
+
+ do {
+ snprintf (key, 256, "node-uuid-%d", i);
+ ret = dict_get_str (dict, key, &node_uuid);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get node-uuid");
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "files-%d", i);
+ ret = dict_get_uint64 (dict, key, &files);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get file count");
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "size-%d", i);
+ ret = dict_get_uint64 (dict, key, &size);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get size of xfer");
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "lookups-%d", i);
+ ret = dict_get_uint64 (dict, key, &lookup);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get lookedup file count");
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "status-%d", i);
+ ret = dict_get_int32 (dict, key, (int32_t *)&status_rcd);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get status");
+
+ snprintf (key, 256, "failures-%d", i);
+ ret = dict_get_uint64 (dict, key, &failures);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "Failed to get failure on files");
+
+ switch (status_rcd) {
+ case GF_DEFRAG_STATUS_NOT_STARTED:
+ status = "not started";
+ break;
+ case GF_DEFRAG_STATUS_STARTED:
+ status = "in progress";
+ break;
+ case GF_DEFRAG_STATUS_STOPPED:
+ status = "stopped";
+ break;
+ case GF_DEFRAG_STATUS_COMPLETE:
+ status = "completed";
+ break;
+ case GF_DEFRAG_STATUS_FAILED:
+ status = "failed";
+ break;
+ }
+
+ size_str = gf_uint64_2human_readable(size);
+ cli_out ("%40s %16"PRId64 " %13s" " %13"PRId64 " %13"PRId64
+ " %14s", node_uuid, files, size_str, lookup, failures,
+ status);
+ GF_FREE(size_str);
+
+ i++;
+ } while (i <= counter);
+
+ //TODO: Do proper xml output
+ /*
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volRemoveBrick", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ cli_out ("%s", msg);
+ */
+out:
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val); //malloced by xdr
+ if (dict)
+ dict_unref (dict);
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
int
gf_cli3_1_remove_brick_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_remove_brick_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ char msg[1024] = {0,};
+ gf1_op_commands cmd = GF_OP_CMD_NONE;
+ char *cmd_str = "unknown";
+ cli_local_t *local = NULL;
+ call_frame_t *frame = NULL;
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_remove_brick_rsp (*iov, &rsp);
+ frame = myframe;
+ local = frame->local;
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
}
+ ret = dict_get_int32 (local->dict, "command", (int32_t *)&cmd);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "failed to get command");
+ goto out;
+ }
+
+ switch (cmd) {
+
+ case GF_OP_CMD_START:
+ cmd_str = "start";
+ break;
+ case GF_OP_CMD_COMMIT:
+ cmd_str = "commit";
+ break;
+ case GF_OP_CMD_COMMIT_FORCE:
+ cmd_str = "commit force";
+ break;
+ default:
+ cmd_str = "unknown";
+ break;
+ }
+
gf_log ("cli", GF_LOG_INFO, "Received resp to remove brick");
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out ("%s", rsp.op_errstr);
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
else
- cli_out ("Remove Brick %s", (rsp.op_ret) ? "unsuccessful":
- "successful");
+ snprintf (msg, sizeof (msg), "Remove Brick %s %s", cmd_str,
+ (rsp.op_ret) ? "unsuccessful": "successful");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volRemoveBrick", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
ret = rsp.op_ret;
out:
+ if (frame)
+ frame->local = NULL;
+
+ if (local) {
+ dict_unref (local->dict);
+ cli_local_wipe (local);
+ }
+
cli_cmd_broadcast_response (ret);
- if (rsp.volname)
- free (rsp.volname);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
if (rsp.op_errstr)
free (rsp.op_errstr);
+
return ret;
}
@@ -1068,8 +1723,8 @@ int
gf_cli3_1_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_replace_brick_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
cli_local_t *local = NULL;
call_frame_t *frame = NULL;
dict_t *dict = NULL;
@@ -1078,6 +1733,8 @@ gf_cli3_1_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
char *status_reply = NULL;
gf1_cli_replace_op replace_op = 0;
char *rb_operation_str = NULL;
+ dict_t *rsp_dict = NULL;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
@@ -1085,7 +1742,7 @@ gf_cli3_1_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
frame = (call_frame_t *) myframe;
- ret = gf_xdr_to_cli_replace_brick_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -1093,7 +1750,7 @@ gf_cli3_1_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
local = frame->local;
GF_ASSERT (local);
- dict = local->u.replace_brick.dict;
+ dict = local->dict;
ret = dict_get_int32 (dict, "operation", (int32_t *)&replace_op);
if (ret) {
@@ -1112,11 +1769,33 @@ gf_cli3_1_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
case GF_REPLACE_OP_STATUS:
- status_reply = rsp.status;
if (rsp.op_ret || ret)
rb_operation_str = "replace-brick status unknown";
- else
+ else {
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ rsp_dict = dict_new ();
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &rsp_dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ }
+ }
+ ret = dict_get_str (rsp_dict, "status-reply",
+ &status_reply);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to"
+ "get status");
+ goto out;
+ }
+
rb_operation_str = status_reply;
+ }
break;
@@ -1169,93 +1848,58 @@ gf_cli3_1_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
}
gf_log ("cli", GF_LOG_INFO, "Received resp to replace brick");
- cli_out ("%s",
- rb_operation_str ? rb_operation_str : "Unknown operation");
-
- ret = rsp.op_ret;
+ snprintf (msg,sizeof (msg), "%s",
+ rb_operation_str ? rb_operation_str : "Unknown operation");
-out:
- if (local) {
- dict_unref (local->u.replace_brick.dict);
- GF_FREE (local->u.replace_brick.volname);
- cli_local_wipe (local);
- }
-
- cli_cmd_broadcast_response (ret);
- return ret;
-}
-
-static int
-gf_cli3_1_log_filename_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf1_cli_log_filename_rsp rsp = {0,};
- int ret = -1;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- ret = gf_xdr_to_cli_log_filename_rsp (*iov, &rsp);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "error");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volReplaceBrick", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
goto out;
}
+#endif
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to log filename");
-
- if (rsp.op_ret && strcmp (rsp.errstr, ""))
- cli_out (rsp.errstr);
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
else
- cli_out ("log filename : %s",
- (rsp.op_ret) ? "unsuccessful": "successful");
-
+ cli_out ("%s", msg);
ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
-}
-
-static int
-gf_cli3_1_log_locate_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf1_cli_log_locate_rsp rsp = {0,};
- int ret = -1;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
+ if (frame)
+ frame->local = NULL;
- ret = gf_xdr_to_cli_log_locate_rsp (*iov, &rsp);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "error");
- goto out;
+ if (local) {
+ dict_unref (local->dict);
+ cli_local_wipe (local);
}
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to log locate");
- cli_out ("log file location: %s", rsp.path);
-
- ret = rsp.op_ret;
-
-out:
cli_cmd_broadcast_response (ret);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
+ if (rsp_dict)
+ dict_unref (rsp_dict);
+
return ret;
}
+
static int
gf_cli3_1_log_rotate_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_log_rotate_rsp rsp = {0,};
+ gf_cli_rsp rsp = {0,};
int ret = -1;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_log_rotate_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -1263,16 +1907,34 @@ gf_cli3_1_log_rotate_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("cli", GF_LOG_DEBUG, "Received resp to log rotate");
- if (rsp.op_ret && strcmp (rsp.errstr, ""))
- cli_out (rsp.errstr);
+ if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
else
- cli_out ("log rotate %s", (rsp.op_ret) ? "unsuccessful":
- "successful");
+ snprintf (msg, sizeof (msg), "log rotate %s",
+ (rsp.op_ret) ? "unsuccessful": "successful");
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volLogRotate", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
ret = rsp.op_ret;
out:
cli_cmd_broadcast_response (ret);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
+
return ret;
}
@@ -1280,14 +1942,15 @@ static int
gf_cli3_1_sync_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_sync_volume_rsp rsp = {0,};
+ gf_cli_rsp rsp = {0,};
int ret = -1;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_sync_volume_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -1296,10 +1959,26 @@ gf_cli3_1_sync_volume_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("cli", GF_LOG_DEBUG, "Received resp to sync");
if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_out (rsp.op_errstr);
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
else
- cli_out ("volume sync: %s",
+ snprintf (msg, sizeof (msg), "volume sync: %s",
(rsp.op_ret) ? "unsuccessful": "successful");
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volSync", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
ret = rsp.op_ret;
out:
@@ -1308,17 +1987,20 @@ out:
}
int32_t
-print_limit_list (char *volname, char *limit_list)
+gf_cli3_1_print_limit_list (char *volname, char *limit_list,
+ char *op_errstr)
{
int64_t size = 0;
int64_t limit_value = 0;
int32_t i, j, k;
int32_t len = 0, ret = -1;
+ char *size_str = NULL;
char path [PATH_MAX] = {0, };
char ret_str [1024] = {0, };
char value [1024] = {0, };
char mountdir [] = "/tmp/mntXXXXXX";
- char cmd_str [PATH_MAX + 1024] = {0, };
+ char abspath [PATH_MAX] = {0, };
+ runner_t runner = {0,};
GF_VALIDATE_OR_GOTO ("cli", volname, out);
GF_VALIDATE_OR_GOTO ("cli", limit_list, out);
@@ -1326,6 +2008,12 @@ print_limit_list (char *volname, char *limit_list)
if (!connected)
goto out;
+ len = strlen (limit_list);
+ if (len == 0) {
+ cli_err ("%s", op_errstr?op_errstr:"quota limit not set ");
+ goto out;
+ }
+
if (mkdtemp (mountdir) == NULL) {
gf_log ("cli", GF_LOG_WARNING, "failed to create a temporary "
"mount directory");
@@ -1336,10 +2024,10 @@ print_limit_list (char *volname, char *limit_list)
/* Mount a temporary client to fetch the disk usage
* of the directory on which the limit is set.
*/
- snprintf (cmd_str, sizeof (cmd_str), GFS_PREFIX "/sbin/glusterfs -s localhost "
- "--volfile-id %s %s", volname, mountdir);
-
- ret = system (cmd_str);
+ ret = runcmd (SBIN_DIR"/glusterfs", "-s",
+ "localhost", "--volfile-id", volname, "-l",
+ DEFAULT_LOG_FILE_DIRECTORY"/quota-list.log",
+ mountdir, NULL);
if (ret) {
gf_log ("cli", GF_LOG_WARNING, "failed to mount glusterfs client");
ret = -1;
@@ -1373,33 +2061,40 @@ print_limit_list (char *volname, char *limit_list)
}
value [j] = '\0';
- memset (&cmd_str, 0, sizeof (cmd_str));
- snprintf (cmd_str, sizeof (cmd_str), "%s/%s", mountdir, path);
+ snprintf (abspath, sizeof (abspath), "%s/%s", mountdir, path);
- ret = getxattr (cmd_str, "trusted.limit.list", (void *) ret_str, 4096);
+ ret = sys_lgetxattr (abspath, "trusted.limit.list", (void *) ret_str, 4096);
if (ret < 0) {
cli_out ("%-20s %10s", path, value);
} else {
sscanf (ret_str, "%"PRId64",%"PRId64, &size,
&limit_value);
- cli_out ("%-20s %10"PRId64" %20"PRId64, path,
- limit_value, size);
+ size_str = gf_uint64_2human_readable ((uint64_t) size);
+ if (size_str == NULL) {
+ cli_out ("%-20s %10s %20"PRId64, path,
+ value, size);
+ } else {
+ cli_out ("%-20s %10s %20s", path,
+ value, size_str);
+ GF_FREE (size_str);
+ }
}
i++;
}
unmount:
- memset (&cmd_str, 0, sizeof (cmd_str));
+ runinit (&runner);
+ runner_add_args (&runner, "umount",
#if GF_LINUX_HOST_OS
- usleep (200000);
- snprintf (cmd_str, sizeof (cmd_str), "umount -l %s", mountdir);
-#else
- snprintf (cmd_str, sizeof (cmd_str), "umount %s", mountdir);
+ "-l",
#endif
- ret = system (cmd_str);
+ mountdir, NULL);
+ ret = runner_run_reuse (&runner);
if (ret)
- gf_log ("cli", GF_LOG_WARNING, "error executing: %s", cmd_str);
+ runner_log (&runner, "cli", GF_LOG_WARNING, "error executing");
+ runner_end (&runner);
+
rm_dir:
rmdir (mountdir);
out:
@@ -1410,14 +2105,19 @@ int
gf_cli3_1_quota_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_quota_rsp rsp = {0,};
- int ret = 0;
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ char *limit_list = NULL;
+ int32_t type = 0;
+ char msg[1024] = {0,};
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_quota_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -1425,25 +2125,103 @@ gf_cli3_1_quota_cbk (struct rpc_req *req, struct iovec *iov,
if (rsp.op_ret &&
strcmp (rsp.op_errstr, "") == 0) {
- cli_out ("command unsuccessful %s", rsp.op_errstr);
+ snprintf (msg, sizeof (msg), "command unsuccessful %s",
+ rsp.op_errstr);
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML)
+ goto xml_output;
+#endif
goto out;
}
- if (rsp.type == GF_QUOTA_OPTION_TYPE_LIST) {
- if (rsp.limit_list)
- print_limit_list (rsp.volname, rsp.limit_list);
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ }
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get volname");
+
+ ret = dict_get_str (dict, "limit_list", &limit_list);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get limit_list");
+
+ ret = dict_get_int32 (dict, "type", &type);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "failed to get type");
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST) {
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_quota_limit_list
+ (volname, limit_list, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+
+ }
+#endif
+ if (limit_list) {
+ gf_cli3_1_print_limit_list (volname,
+ limit_list,
+ rsp.op_errstr);
+ } else {
+ gf_log ("cli", GF_LOG_INFO, "Received resp to quota "
+ "command ");
+ if (rsp.op_errstr)
+ snprintf (msg, sizeof (msg), "%s",
+ rsp.op_errstr);
+ }
} else {
gf_log ("cli", GF_LOG_INFO, "Received resp to quota command ");
if (rsp.op_errstr)
- cli_out ("%s", rsp.op_errstr);
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
else
- cli_out ("%s", "successful");
+ snprintf (msg, sizeof (msg), "successful");
}
-out:
- ret = rsp.op_ret;
+#if (HAVE_LIB_XML)
+xml_output:
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volQuota", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ if (strlen (msg) > 0) {
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
+ }
+ ret = rsp.op_ret;
+out:
cli_cmd_broadcast_response (ret);
+
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
+
return ret;
}
@@ -1452,14 +2230,14 @@ gf_cli3_1_getspec_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gf_getspec_rsp rsp = {0,};
- int ret = 0;
+ int ret = -1;
char *spec = NULL;
if (-1 == req->rpc_status) {
goto out;
}
- ret = xdr_to_getspec_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
if (ret < 0 || rsp.op_ret == -1) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -1489,14 +2267,14 @@ gf_cli3_1_pmap_b2p_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
pmap_port_by_brick_rsp rsp = {0,};
- int ret = 0;
+ int ret = -1;
char *spec = NULL;
if (-1 == req->rpc_status) {
goto out;
}
- ret = xdr_to_pmap_port_by_brick_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp);
if (ret < 0 || rsp.op_ret == -1) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -1543,8 +2321,9 @@ gf_cli3_1_probe (call_frame_t *frame, xlator_t *this,
req.port = port;
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
- GLUSTER_CLI_PROBE, NULL, gf_xdr_from_cli_probe_req,
- this, gf_cli3_1_probe_cbk);
+ GLUSTER_CLI_PROBE, NULL,
+ this, gf_cli3_1_probe_cbk,
+ (xdrproc_t)xdr_gf1_cli_probe_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1560,6 +2339,7 @@ gf_cli3_1_deprobe (call_frame_t *frame, xlator_t *this,
dict_t *dict = NULL;
char *hostname = NULL;
int port = 0;
+ int flags = 0;
if (!frame || !this || !data) {
ret = -1;
@@ -1575,13 +2355,17 @@ gf_cli3_1_deprobe (call_frame_t *frame, xlator_t *this,
if (ret)
port = CLI_GLUSTERD_PORT;
+ ret = dict_get_int32 (dict, "flags", &flags);
+ if (ret)
+ flags = 0;
+
req.hostname = hostname;
req.port = port;
-
+ req.flags = flags;
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_DEPROBE, NULL,
- gf_xdr_from_cli_deprobe_req,
- this, gf_cli3_1_deprobe_cbk);
+ this, gf_cli3_1_deprobe_cbk,
+ (xdrproc_t)xdr_gf1_cli_deprobe_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1604,8 +2388,8 @@ gf_cli3_1_list_friends (call_frame_t *frame, xlator_t *this,
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_LIST_FRIENDS, NULL,
- gf_xdr_from_cli_peer_list_req,
- this, gf_cli3_1_list_friends_cbk);
+ this, gf_cli3_1_list_friends_cbk,
+ (xdrproc_t) xdr_gf1_cli_peer_list_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1627,26 +2411,51 @@ gf_cli3_1_get_next_volume (call_frame_t *frame, xlator_t *this,
}
ctx = data;
+ local = frame->local;
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_info_begin (local, 0, 0, "");
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Error outputting to xml");
+ goto out;
+ }
+ }
+#endif
ret = gf_cli3_1_get_volume (frame, this, data);
- local = frame->local;
- if (!local || !local->u.get_vol.volname) {
+ if (!local || !local->get_vol.volname) {
+#if (HAVE_LIB_XML)
+ if ((global_state->mode & GLUSTER_MODE_XML))
+ goto end_xml;
+#endif
cli_out ("No volumes present");
goto out;
}
- ctx->volname = local->u.get_vol.volname;
+
+ ctx->volname = local->get_vol.volname;
while (ctx->volname) {
ret = gf_cli3_1_get_volume (frame, this, ctx);
if (ret)
goto out;
- ctx->volname = local->u.get_vol.volname;
+ ctx->volname = local->get_vol.volname;
+ }
+
+#if (HAVE_LIB_XML)
+end_xml:
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_info_end (local);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR, "Error outputting to xml");
}
+#endif
out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
@@ -1654,10 +2463,11 @@ int32_t
gf_cli3_1_get_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_get_vol_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
cli_cmd_volume_get_ctx_t *ctx = NULL;
dict_t *dict = NULL;
+ int32_t flags = 0;
if (!frame || !this || !data) {
ret = -1;
@@ -1665,7 +2475,6 @@ gf_cli3_1_get_volume (call_frame_t *frame, xlator_t *this,
}
ctx = data;
- req.flags = ctx->flags;
dict = dict_new ();
if (!dict)
@@ -1677,16 +2486,28 @@ gf_cli3_1_get_volume (call_frame_t *frame, xlator_t *this,
goto out;
}
- ret = dict_allocate_and_serialize (dict,
- &req.dict.dict_val,
- (size_t *)&req.dict.dict_len);
+ flags = ctx->flags;
+ ret = dict_set_int32 (dict, "flags", flags);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to set flags");
+ goto out;
+ }
+
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_GET_VOLUME, NULL,
- gf_xdr_from_cli_get_vol_req,
- this, gf_cli3_1_get_volume_cbk);
+ this, gf_cli3_1_get_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
+ if (dict)
+ dict_unref (dict);
+
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
+
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
@@ -1696,7 +2517,7 @@ int32_t
gf_cli3_1_create_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_create_vol_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
dict_t *dict = NULL;
cli_local_t *local = NULL;
@@ -1708,23 +2529,8 @@ gf_cli3_1_create_volume (call_frame_t *frame, xlator_t *this,
dict = dict_ref ((dict_t *)data);
- ret = dict_get_str (dict, "volname", &req.volname);
-
- if (ret)
- goto out;
-
- ret = dict_get_int32 (dict, "type", (int32_t *)&req.type);
-
- if (ret)
- goto out;
-
- ret = dict_get_int32 (dict, "count", &req.count);
- if (ret)
- goto out;
-
- ret = dict_allocate_and_serialize (dict,
- &req.bricks.bricks_val,
- (size_t *)&req.bricks.bricks_len);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"failed to get serialized length of dict");
@@ -1734,14 +2540,14 @@ gf_cli3_1_create_volume (call_frame_t *frame, xlator_t *this,
local = cli_local_get ();
if (local) {
- local->u.create_vol.dict = dict_ref (dict);
+ local->dict = dict_ref (dict);
frame->local = local;
}
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_CREATE_VOLUME, NULL,
- gf_xdr_from_cli_create_vol_req,
- this, gf_cli3_1_create_volume_cbk);
+ this, gf_cli3_1_create_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
@@ -1751,8 +2557,8 @@ out:
if (dict)
dict_unref (dict);
- if (req.bricks.bricks_val) {
- GF_FREE (req.bricks.bricks_val);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
}
return ret;
@@ -1762,9 +2568,10 @@ int32_t
gf_cli3_1_delete_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_delete_vol_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
cli_local_t *local = NULL;
+ dict_t *dict = NULL;
if (!frame || !this || !data) {
ret = -1;
@@ -1773,19 +2580,35 @@ gf_cli3_1_delete_volume (call_frame_t *frame, xlator_t *this,
local = cli_local_get ();
+ dict = dict_new ();
+ ret = dict_set_str (dict, "volname", data);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_WARNING, "dict set failed");
+ goto out;
+ }
if (local) {
- local->u.delete_vol.volname = data;
+ local->dict = dict_ref (dict);
frame->local = local;
}
- req.volname = data;
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get serialize dict");
+ goto out;
+ }
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_DELETE_VOLUME, NULL,
- gf_xdr_from_cli_delete_vol_req,
- this, gf_cli3_1_delete_volume_cbk);
+ this, gf_cli3_1_delete_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req);
out:
+ if (dict)
+ dict_unref (dict);
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
@@ -1795,28 +2618,37 @@ int32_t
gf_cli3_1_start_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_start_vol_req *req = NULL;
+ gf_cli_req req = {{0,}};
int ret = 0;
cli_local_t *local = NULL;
+ dict_t *dict = NULL;
if (!frame || !this || !data) {
ret = -1;
goto out;
}
- req = data;
+ dict = data;
local = cli_local_get ();
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize dict");
+ goto out;
+ }
+
+
if (local) {
- local->u.start_vol.volname = req->volname;
- local->u.start_vol.flags = req->flags;
+ local->dict = dict_ref (dict);
frame->local = local;
}
- ret = cli_cmd_submit (req, frame, cli_rpc_prog,
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_START_VOLUME, NULL,
- gf_xdr_from_cli_start_vol_req,
- this, gf_cli3_1_start_volume_cbk);
+ this, gf_cli3_1_start_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1828,28 +2660,37 @@ int32_t
gf_cli3_1_stop_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_stop_vol_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
cli_local_t *local = NULL;
+ dict_t *dict = data;
if (!frame || !this || !data) {
ret = -1;
goto out;
}
- req = *((gf1_cli_stop_vol_req*)data);
local = cli_local_get ();
+ dict = data;
if (local) {
- local->u.stop_vol.volname = req.volname;
- local->u.stop_vol.flags = req.flags;
+ local->dict = dict_ref (dict);
frame->local = local;
}
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize the data");
+
+ goto out;
+ }
+
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_STOP_VOLUME, NULL,
- gf_xdr_from_cli_stop_vol_req,
- this, gf_cli3_1_stop_volume_cbk);
+ this, gf_cli3_1_stop_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1861,12 +2702,14 @@ int32_t
gf_cli3_1_defrag_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_defrag_vol_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
cli_local_t *local = NULL;
char *volname = NULL;
char *cmd_str = NULL;
dict_t *dict = NULL;
+ gf_cli_defrag_type cmd = 0;
+ dict_t *req_dict = NULL;
if (!frame || !this || !data) {
ret = -1;
@@ -1886,41 +2729,69 @@ gf_cli3_1_defrag_volume (call_frame_t *frame, xlator_t *this,
}
if (strcmp (cmd_str, "start") == 0) {
- req.cmd = GF_DEFRAG_CMD_START;
- ret = dict_get_str (dict, "start-type", &cmd_str);
+ cmd = GF_DEFRAG_CMD_START;
+ ret = dict_get_str (dict, "option", &cmd_str);
if (!ret) {
- if (strcmp (cmd_str, "fix-layout") == 0) {
- req.cmd = GF_DEFRAG_CMD_START_LAYOUT_FIX;
- }
- if (strcmp (cmd_str, "migrate-data") == 0) {
- req.cmd = GF_DEFRAG_CMD_START_MIGRATE_DATA;
+ if (strcmp (cmd_str, "force") == 0) {
+ cmd = GF_DEFRAG_CMD_START_FORCE;
}
}
goto done;
}
+
+ if (strcmp (cmd_str, "fix-layout") == 0) {
+ cmd = GF_DEFRAG_CMD_START_LAYOUT_FIX;
+ goto done;
+ }
if (strcmp (cmd_str, "stop") == 0) {
- req.cmd = GF_DEFRAG_CMD_STOP;
+ cmd = GF_DEFRAG_CMD_STOP;
goto done;
}
if (strcmp (cmd_str, "status") == 0) {
- req.cmd = GF_DEFRAG_CMD_STATUS;
+ cmd = GF_DEFRAG_CMD_STATUS;
}
done:
local = cli_local_get ();
+ req_dict = dict_new ();
+ if (!req_dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_str (req_dict, "volname", volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to set dict");
+ goto out;
+ }
+
+ ret = dict_set_int32 (req_dict, "rebalance-command", (int32_t) cmd);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to set dict");
+ goto out;
+ }
+
if (local) {
- local->u.defrag_vol.volname = gf_strdup (volname);
- local->u.defrag_vol.cmd = req.cmd;
+ local->dict = dict_ref (req_dict);
frame->local = local;
}
- req.volname = volname;
+ ret = dict_allocate_and_serialize (req_dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize the data");
+
+ goto out;
+ }
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_DEFRAG_VOLUME, NULL,
- gf_xdr_from_cli_defrag_vol_req,
- this, gf_cli3_1_defrag_volume_cbk);
+ this, gf_cli3_1_defrag_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1932,7 +2803,7 @@ int32_t
gf_cli3_1_rename_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_rename_vol_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
dict_t *dict = NULL;
@@ -1943,20 +2814,20 @@ gf_cli3_1_rename_volume (call_frame_t *frame, xlator_t *this,
dict = data;
- ret = dict_get_str (dict, "old-volname", &req.old_volname);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize the data");
- if (ret)
goto out;
+ }
- ret = dict_get_str (dict, "new-volname", &req.new_volname);
-
- if (ret)
- goto out;
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_RENAME_VOLUME, NULL,
- gf_xdr_from_cli_rename_vol_req,
- this, gf_cli3_1_rename_volume_cbk);
+ this, gf_cli3_1_rename_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1965,10 +2836,10 @@ out:
}
int32_t
-gf_cli3_1_reset_volume (call_frame_t *frame, xlator_t *this,
+gf_cli3_1_reset_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_reset_vol_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
dict_t *dict = NULL;
@@ -1979,25 +2850,18 @@ gf_cli3_1_reset_volume (call_frame_t *frame, xlator_t *this,
dict = data;
- ret = dict_get_str (dict, "volname", &req.volname);
-
- if (ret)
- goto out;
-
- ret = dict_allocate_and_serialize (dict,
- &req.dict.dict_val,
- (size_t *)&req.dict.dict_len);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR,
"failed to get serialized length of dict");
goto out;
}
-
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_RESET_VOLUME, NULL,
- gf_xdr_from_cli_reset_vol_req,
- this, gf_cli3_1_reset_volume_cbk);
+ this, gf_cli3_1_reset_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -2009,7 +2873,7 @@ int32_t
gf_cli3_1_set_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_set_vol_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
dict_t *dict = NULL;
@@ -2020,25 +2884,18 @@ gf_cli3_1_set_volume (call_frame_t *frame, xlator_t *this,
dict = data;
- ret = dict_get_str (dict, "volname", &req.volname);
-
- if (ret)
- goto out;
-
- ret = dict_allocate_and_serialize (dict,
- &req.dict.dict_val,
- (size_t *)&req.dict.dict_len);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"failed to get serialized length of dict");
goto out;
}
-
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_SET_VOLUME, NULL,
- gf_xdr_from_cli_set_vol_req,
- this, gf_cli3_1_set_volume_cbk);
+ this, gf_cli3_1_set_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -2050,9 +2907,11 @@ int32_t
gf_cli3_1_add_brick (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_add_brick_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
dict_t *dict = NULL;
+ char *volname = NULL;
+ int32_t count = 0;
if (!frame || !this || !data) {
ret = -1;
@@ -2061,19 +2920,18 @@ gf_cli3_1_add_brick (call_frame_t *frame, xlator_t *this,
dict = data;
- ret = dict_get_str (dict, "volname", &req.volname);
+ ret = dict_get_str (dict, "volname", &volname);
if (ret)
goto out;
- ret = dict_get_int32 (dict, "count", &req.count);
+ ret = dict_get_int32 (dict, "count", &count);
if (ret)
goto out;
- ret = dict_allocate_and_serialize (dict,
- &req.bricks.bricks_val,
- (size_t *)&req.bricks.bricks_len);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"failed to get serialized length of dict");
@@ -2082,14 +2940,14 @@ gf_cli3_1_add_brick (call_frame_t *frame, xlator_t *this,
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_ADD_BRICK, NULL,
- gf_xdr_from_cli_add_brick_req,
- this, gf_cli3_1_add_brick_cbk);
+ this, gf_cli3_1_add_brick_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- if (req.bricks.bricks_val) {
- GF_FREE (req.bricks.bricks_val);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
}
return ret;
@@ -2099,49 +2957,114 @@ int32_t
gf_cli3_1_remove_brick (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_remove_brick_req req = {0,};
+ gf_cli_req req = {{0,}};;
+ gf_cli_req status_req = {{0,}};;
int ret = 0;
- dict_t *dict = NULL;
+ dict_t *dict = NULL;
+ int32_t command = 0;
+ char *volname = NULL;
+ dict_t *req_dict = NULL;
+ int32_t cmd = 0;
+ cli_local_t *local = NULL;
if (!frame || !this || !data) {
ret = -1;
goto out;
}
+ local = cli_local_get ();
+ if (!local) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto out;
+ }
+
+ frame->local = local;
+
dict = data;
- ret = dict_get_str (dict, "volname", &req.volname);
+ local->dict = dict_ref (dict);
+ ret = dict_get_str (dict, "volname", &volname);
if (ret)
goto out;
- ret = dict_get_int32 (dict, "count", &req.count);
-
+ ret = dict_get_int32 (dict, "command", &command);
if (ret)
goto out;
- ret = dict_allocate_and_serialize (dict,
- &req.bricks.bricks_val,
- (size_t *)&req.bricks.bricks_len);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get serialized length of dict");
- goto out;
- }
+ if ((command != GF_OP_CMD_STATUS) &&
+ (command != GF_OP_CMD_STOP)) {
- ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
- GLUSTER_CLI_REMOVE_BRICK, NULL,
- gf_xdr_from_cli_remove_brick_req,
- this, gf_cli3_1_remove_brick_cbk);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get serialized length of dict");
+ goto out;
+ }
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_REMOVE_BRICK, NULL,
+ this, gf_cli3_1_remove_brick_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
+ } else {
+ /* Need rebalance status to e sent :-) */
+ req_dict = dict_new ();
+ if (!req_dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_str (req_dict, "volname", volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to set dict");
+ goto out;
+ }
+
+ if (command == GF_OP_CMD_STATUS)
+ cmd |= GF_DEFRAG_CMD_STATUS;
+ else
+ cmd |= GF_DEFRAG_CMD_STOP;
+
+ ret = dict_set_int32 (req_dict, "rebalance-command", (int32_t) cmd);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to set dict");
+ goto out;
+ }
+
+ ret = dict_allocate_and_serialize (req_dict, &status_req.dict.dict_val,
+ &status_req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize the data");
+
+ goto out;
+ }
+
+ ret = cli_cmd_submit (&status_req, frame, cli_rpc_prog,
+ GLUSTER_CLI_DEFRAG_VOLUME, NULL,
+ this, gf_cli3_remove_brick_status_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
+
+ }
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- if (req.bricks.bricks_val) {
- GF_FREE (req.bricks.bricks_val);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
}
+ if (status_req.dict.dict_val)
+ GF_FREE (status_req.dict.dict_val);
+
+ if (req_dict)
+ dict_unref (req_dict);
+
return ret;
}
@@ -2149,19 +3072,21 @@ int32_t
gf_cli3_1_replace_brick (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_replace_brick_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
cli_local_t *local = NULL;
dict_t *dict = NULL;
char *src_brick = NULL;
char *dst_brick = NULL;
+ char *volname = NULL;
+ int32_t op = 0;
if (!frame || !this || !data) {
ret = -1;
goto out;
}
- dict = data;
+ dict = data;
local = cli_local_get ();
if (!local) {
@@ -2171,30 +3096,22 @@ gf_cli3_1_replace_brick (call_frame_t *frame, xlator_t *this,
goto out;
}
- local->u.replace_brick.dict = dict_ref (dict);
- frame->local = local;
+ local->dict = dict_ref (dict);
+ frame->local = local;
- ret = dict_get_int32 (dict, "operation", (int32_t *)&req.op);
+ ret = dict_get_int32 (dict, "operation", &op);
if (ret) {
gf_log (this->name, GF_LOG_DEBUG,
"dict_get on operation failed");
goto out;
}
- ret = dict_get_str (dict, "volname", &req.volname);
+ ret = dict_get_str (dict, "volname", &volname);
if (ret) {
gf_log (this->name, GF_LOG_DEBUG,
"dict_get on volname failed");
goto out;
}
- local->u.replace_brick.volname = gf_strdup (req.volname);
- if (!local->u.replace_brick.volname) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory");
- ret = -1;
- goto out;
- }
-
ret = dict_get_str (dict, "src-brick", &src_brick);
if (ret) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -2210,14 +3127,13 @@ gf_cli3_1_replace_brick (call_frame_t *frame, xlator_t *this,
}
gf_log (this->name, GF_LOG_DEBUG,
- "Recevied command replace-brick %s with "
+ "Received command replace-brick %s with "
"%s with operation=%d", src_brick,
- dst_brick, req.op);
+ dst_brick, op);
- ret = dict_allocate_and_serialize (dict,
- &req.bricks.bricks_val,
- (size_t *)&req.bricks.bricks_len);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"failed to get serialized length of dict");
@@ -2226,97 +3142,25 @@ gf_cli3_1_replace_brick (call_frame_t *frame, xlator_t *this,
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_REPLACE_BRICK, NULL,
- gf_xdr_from_cli_replace_brick_req,
- this, gf_cli3_1_replace_brick_cbk);
+ this, gf_cli3_1_replace_brick_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- if (req.bricks.bricks_val) {
- GF_FREE (req.bricks.bricks_val);
- }
-
- return ret;
-}
-
-int32_t
-gf_cli3_1_log_filename (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf1_cli_log_filename_req req = {0,};
- int ret = 0;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
}
- dict = data;
-
- ret = dict_get_str (dict, "volname", &req.volname);
- if (ret)
- goto out;
-
- ret = dict_get_str (dict, "brick", &req.brick);
- if (ret)
- req.brick = "";
-
- ret = dict_get_str (dict, "path", &req.path);
- if (ret)
- goto out;
-
- ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
- GLUSTER_CLI_LOG_FILENAME, NULL,
- gf_xdr_from_cli_log_filename_req,
- this, gf_cli3_1_log_filename_cbk);
-
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
return ret;
}
int32_t
-gf_cli3_1_log_locate (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf1_cli_log_locate_req req = {0,};
- int ret = 0;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
-
- ret = dict_get_str (dict, "volname", &req.volname);
- if (ret)
- goto out;
-
- ret = dict_get_str (dict, "brick", &req.brick);
- if (ret)
- req.brick = "";
-
- ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
- GLUSTER_CLI_LOG_LOCATE, NULL,
- gf_xdr_from_cli_log_locate_req,
- this, gf_cli3_1_log_locate_cbk);
-
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int32_t
gf_cli3_1_log_rotate (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_log_locate_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
dict_t *dict = NULL;
@@ -2327,23 +3171,25 @@ gf_cli3_1_log_rotate (call_frame_t *frame, xlator_t *this,
dict = data;
- ret = dict_get_str (dict, "volname", &req.volname);
- if (ret)
- goto out;
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
- ret = dict_get_str (dict, "brick", &req.brick);
- if (ret)
- req.brick = "";
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to serialize dict");
+ goto out;
+ }
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_LOG_ROTATE, NULL,
- gf_xdr_from_cli_log_rotate_req,
- this, gf_cli3_1_log_rotate_cbk);
+ this, gf_cli3_1_log_rotate_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
return ret;
}
@@ -2352,19 +3198,32 @@ gf_cli3_1_sync_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
int ret = 0;
+ gf_cli_req req = {{0,}};
+ dict_t *dict = NULL;
if (!frame || !this || !data) {
ret = -1;
goto out;
}
- ret = cli_cmd_submit ((gf1_cli_sync_volume_req*)data, frame,
+ dict = data;
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to serialize dict");
+ goto out;
+ }
+
+ ret = cli_cmd_submit (&req, frame,
cli_rpc_prog, GLUSTER_CLI_SYNC_VOLUME,
- NULL, gf_xdr_from_cli_sync_volume_req,
- this, gf_cli3_1_sync_volume_cbk);
+ NULL, this, gf_cli3_1_sync_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
return ret;
}
@@ -2390,8 +3249,8 @@ gf_cli3_1_getspec (call_frame_t *frame, xlator_t *this,
ret = cli_cmd_submit (&req, frame, &cli_handshake_prog,
GF_HNDSK_GETSPEC, NULL,
- xdr_from_getspec_req,
- this, gf_cli3_1_getspec_cbk);
+ this, gf_cli3_1_getspec_cbk,
+ (xdrproc_t) xdr_gf_getspec_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -2403,7 +3262,7 @@ int32_t
gf_cli3_1_quota (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_quota_req req = {0,};
+ gf_cli_req req = {{0,}};
int ret = 0;
dict_t *dict = NULL;
@@ -2414,25 +3273,18 @@ gf_cli3_1_quota (call_frame_t *frame, xlator_t *this,
dict = data;
- ret = dict_get_str (dict, "volname", &req.volname);
-
- if (ret)
- goto out;
-
- ret = dict_allocate_and_serialize (dict,
- &req.dict.dict_val,
- (size_t *)&req.dict.dict_len);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR,
"failed to get serialized length of dict");
goto out;
}
-
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
- GLUSTER_CLI_QUOTA, NULL,
- gf_xdr_from_cli_quota_req,
- this, gf_cli3_1_quota_cbk);
+ GLUSTER_CLI_QUOTA, NULL,
+ this, gf_cli3_1_quota_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
GF_FREE (req.dict.dict_val);
out:
@@ -2459,8 +3311,8 @@ gf_cli3_1_pmap_b2p (call_frame_t *frame, xlator_t *this, void *data)
ret = cli_cmd_submit (&req, frame, &cli_pmap_prog,
GF_PMAP_PORTBYBRICK, NULL,
- xdr_from_pmap_port_by_brick_req,
- this, gf_cli3_1_pmap_b2p_cbk);
+ this, gf_cli3_1_pmap_b2p_cbk,
+ (xdrproc_t) xdr_pmap_port_by_brick_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -2487,18 +3339,16 @@ gf_cli3_1_fsm_log_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- ret = gf_xdr_to_cli_fsm_log_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_fsm_log_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
}
if (rsp.op_ret) {
- if (strcmp (rsp.op_errstr, "")) {
- cli_out (rsp.op_errstr);
- } else if (rsp.op_ret) {
- cli_out ("fsm log unsuccessful");
- }
+ if (strcmp (rsp.op_errstr, ""))
+ cli_err ("%s", rsp.op_errstr);
+ cli_err ("fsm log unsuccessful");
ret = rsp.op_ret;
goto out;
}
@@ -2514,7 +3364,7 @@ gf_cli3_1_fsm_log_cbk (struct rpc_req *req, struct iovec *iov,
&dict);
if (ret) {
- cli_out ("bad response");
+ cli_err ("bad response");
goto out;
}
@@ -2575,8 +3425,8 @@ gf_cli3_1_fsm_log (call_frame_t *frame, xlator_t *this, void *data)
req.name = data;
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_FSM_LOG, NULL,
- gf_xdr_from_cli_fsm_log_req,
- this, gf_cli3_1_fsm_log_cbk);
+ this, gf_cli3_1_fsm_log_cbk,
+ (xdrproc_t) xdr_gf1_cli_fsm_log_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -2584,35 +3434,44 @@ out:
return ret;
}
-
int
-gf_cli3_1_gsync_config_command (gf1_cli_gsync_set_rsp rsp)
+gf_cli3_1_gsync_config_command (dict_t *dict)
{
- char cmd[PATH_MAX] = {0,};
- int ret = -1;
-
- if (rsp.op_ret < 0)
- return 0;
-
- if (!rsp.gsync_prefix || !rsp.master || !rsp.slave || !rsp.glusterd_workdir)
+ runner_t runner = {0,};
+ char *subop = NULL;
+ char *gwd = NULL;
+ char *slave = NULL;
+ char *master = NULL;
+ char *op_name = NULL;
+
+ if (dict_get_str (dict, "subop", &subop) != 0)
return -1;
- if (strcmp (rsp.subop, "get") != 0 && strcmp (rsp.subop, "get-all") != 0) {
+ if (strcmp (subop, "get") != 0 && strcmp (subop, "get-all") != 0) {
cli_out (GEOREP" config updated successfully");
return 0;
}
- snprintf (cmd, PATH_MAX,
- GSYNCD_PREFIX"/gsyncd -c %s/"GSYNC_CONF" %s%s %s --config-%s%s%s",
- rsp.glusterd_workdir,
- *rsp.master ? ":" : "", rsp.master, rsp.slave, rsp.subop,
- *rsp.op_name ? " " : "", rsp.op_name);
- ret = system (cmd);
- /*
- * gf_log() failure from system() ?
- */
+ if (dict_get_str (dict, "glusterd_workdir", &gwd) != 0 ||
+ dict_get_str (dict, "slave", &slave) != 0)
+ return -1;
- return ret ? -1 : 0;
+ if (dict_get_str (dict, "master", &master) != 0)
+ master = NULL;
+ if (dict_get_str (dict, "op_name", &op_name) != 0)
+ op_name = NULL;
+
+ runinit (&runner);
+ runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
+ runner_argprintf (&runner, "%s/"GSYNC_CONF, gwd);
+ if (master)
+ runner_argprintf (&runner, ":%s", master);
+ runner_add_arg (&runner, slave);
+ runner_argprintf (&runner, "--config-%s", subop);
+ if (op_name)
+ runner_add_arg (&runner, op_name);
+
+ return runner_run (&runner);
}
int
@@ -2676,16 +3535,20 @@ int
gf_cli3_1_gsync_set_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- int ret = 0;
- gf1_cli_gsync_set_rsp rsp = {0, };
+ int ret = -1;
+ gf_cli_rsp rsp = {0, };
dict_t *dict = NULL;
+ char *gsync_status = NULL;
+ char *master = NULL;
+ char *slave = NULL;
+ int32_t type = 0;
if (req->rpc_status == -1) {
ret = -1;
goto out;
}
- ret = gf_xdr_to_cli_gsync_set_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR,
"Unable to get response structure");
@@ -2699,33 +3562,58 @@ gf_cli3_1_gsync_set_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- ret = dict_unserialize (rsp.status_dict.status_dict_val,
- rsp.status_dict.status_dict_len,
- &dict);
+ ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
if (ret)
goto out;
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_dict ("volGeoRep", dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
if (rsp.op_ret) {
- cli_out ("%s", rsp.op_errstr ? rsp.op_errstr :
+ cli_err ("%s", rsp.op_errstr ? rsp.op_errstr :
GEOREP" command unsuccessful");
ret = rsp.op_ret;
goto out;
}
- switch (rsp.type) {
- case GF_GSYNC_OPTION_TYPE_START:
- cli_out ("Starting " GEOREP " session between %s & %s"
- " has been successful", rsp.master, rsp.slave);
- break;
+ ret = dict_get_str (dict, "gsync-status", &gsync_status);
+ if (!ret)
+ cli_out ("%s", gsync_status);
+ else
+ ret = 0;
+ ret = dict_get_int32 (dict, "type", &type);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to get type");
+ goto out;
+ }
+
+ switch (type) {
+ case GF_GSYNC_OPTION_TYPE_START:
case GF_GSYNC_OPTION_TYPE_STOP:
- cli_out ("Stopping " GEOREP " session between %s & %s"
- " has been successful", rsp.master, rsp.slave);
+ if (dict_get_str (dict, "master", &master) != 0)
+ master = "???";
+ if (dict_get_str (dict, "slave", &slave) != 0)
+ slave = "???";
+
+ cli_out ("%s " GEOREP " session between %s & %s"
+ " has been successful",
+ type == GF_GSYNC_OPTION_TYPE_START ?
+ "Starting" : "Stopping",
+ master, slave);
break;
case GF_GSYNC_OPTION_TYPE_CONFIG:
- ret = gf_cli3_1_gsync_config_command (rsp);
+ ret = gf_cli3_1_gsync_config_command (dict);
break;
case GF_GSYNC_OPTION_TYPE_STATUS:
@@ -2739,6 +3627,9 @@ out:
cli_cmd_broadcast_response (ret);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
+
return ret;
}
@@ -2748,7 +3639,7 @@ gf_cli3_1_gsync_set (call_frame_t *frame, xlator_t *this,
{
int ret = 0;
dict_t *dict = NULL;
- gf1_cli_gsync_set_req req;
+ gf_cli_req req = {{0,}};
if (!frame || !this || !data) {
ret = -1;
@@ -2757,9 +3648,8 @@ gf_cli3_1_gsync_set (call_frame_t *frame, xlator_t *this,
dict = data;
- ret = dict_allocate_and_serialize (dict,
- &req.dict.dict_val,
- (size_t *) &req.dict.dict_len);
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR,
"failed to serialize the data");
@@ -2769,18 +3659,16 @@ gf_cli3_1_gsync_set (call_frame_t *frame, xlator_t *this,
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_GSYNC_SET, NULL,
- gf_xdr_from_cli_gsync_set_req,
- this, gf_cli3_1_gsync_set_cbk);
+ this, gf_cli3_1_gsync_set_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
+
return ret;
}
-void*
-cli_profile_info_elem (void *a, int index)
-{
- return ((cli_profile_info_t *)a) + index;
-}
int
cli_profile_info_percentage_cmp (void *a, void *b)
@@ -2800,19 +3688,6 @@ cli_profile_info_percentage_cmp (void *a, void *b)
return ret;
}
-void
-cli_profile_info_swap (void *a, void *b)
-{
- cli_profile_info_t *ia = NULL;
- cli_profile_info_t *ib = NULL;
- cli_profile_info_t tmp = {0};
-
- ia = a;
- ib = b;
- tmp = *ia;
- *ia = *ib;
- *ib = tmp;
-}
void
cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
@@ -2822,7 +3697,6 @@ cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
uint64_t sec = 0;
uint64_t r_count = 0;
uint64_t w_count = 0;
- char *brick = NULL;
uint64_t rb_counts[32] = {0};
uint64_t wb_counts[32] = {0};
cli_profile_info_t profile_info[GF_FOP_MAXVALUE] = {{0}};
@@ -2835,9 +3709,6 @@ cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
int ret = 0;
double total_percentage_latency = 0;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-brick", count);
- ret = dict_get_str (dict, key, &brick);
for (i = 0; i < 32; i++) {
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%d-%d-read-%d", count,
@@ -2900,17 +3771,16 @@ cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
ret = dict_get_uint64 (dict, key, &w_count);
if (ret == 0) {
- cli_out ("Brick: %s", brick);
}
if (interval == -1)
cli_out ("Cumulative Stats:");
else
cli_out ("Interval %d Stats:", interval);
- snprintf (output, sizeof (output), "%12s", "Block Size: ");
- snprintf (read_blocks, sizeof (read_blocks), "%12s", "Read: ");
- snprintf (write_blocks, sizeof (write_blocks), "%12s", "Write: ");
- index = 12;
+ snprintf (output, sizeof (output), "%14s", "Block Size:");
+ snprintf (read_blocks, sizeof (read_blocks), "%14s", "No. of Reads:");
+ snprintf (write_blocks, sizeof (write_blocks), "%14s", "No. of Writes:");
+ index = 14;
for (i = 0; i < 32; i++) {
if ((rb_counts[i] == 0) && (wb_counts[i] == 0))
continue;
@@ -2932,38 +3802,43 @@ cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
}
index += 22;
if (per_line == 3) {
- cli_out (output);
- cli_out (read_blocks);
- cli_out (write_blocks);
- cli_out ("");
+ cli_out ("%s", output);
+ cli_out ("%s", read_blocks);
+ cli_out ("%s", write_blocks);
+ cli_out (" ");
per_line = 0;
memset (output, 0, sizeof (output));
memset (read_blocks, 0, sizeof (read_blocks));
memset (write_blocks, 0, sizeof (write_blocks));
- snprintf (output, sizeof (output), "%12s", "Block Size: ");
- snprintf (read_blocks, sizeof (read_blocks), "%12s",
- "Read: ");
- snprintf (write_blocks, sizeof (write_blocks), "%12s",
- "Write: ");
- index = 12;
+ snprintf (output, sizeof (output), "%14s", "Block Size:");
+ snprintf (read_blocks, sizeof (read_blocks), "%14s",
+ "No. of Reads:");
+ snprintf (write_blocks, sizeof (write_blocks), "%14s",
+ "No. of Writes:");
+ index = 14;
}
}
if (per_line != 0) {
- cli_out (output);
- cli_out (read_blocks);
- cli_out (write_blocks);
+ cli_out ("%s", output);
+ cli_out ("%s", read_blocks);
+ cli_out ("%s", write_blocks);
}
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
if (profile_info[i].fop_hits == 0)
continue;
if (is_header_printed == 0) {
- cli_out ("%11s %11s %11s %11s %20s %10s", "%-latency", "Avg-latency", "Min-Latency", "Max-Latency", "calls", "Fop");
- cli_out ("%11s %11s %11s %11s %20s %10s", "---------", "-----------", "-----------", "-----------", "-----", "----");
+ cli_out ("%10s %13s %13s %13s %14s %11s", "%-latency",
+ "Avg-latency", "Min-Latency", "Max-Latency",
+ "No. of calls", "Fop");
+ cli_out ("%10s %13s %13s %13s %14s %11s", "---------",
+ "-----------", "-----------", "-----------",
+ "------------", "----");
is_header_printed = 1;
}
if (profile_info[i].fop_hits) {
- cli_out ("%11.2lf %11.2lf %11.2lf %11.2lf %20"PRId64" %10s",
+ cli_out ("%10.2lf %10.2lf us %10.2lf us %10.2lf us"
+ " %14"PRId64" %11s",
profile_info[i].percentage_avg_latency,
profile_info[i].avg_latency,
profile_info[i].min_latency,
@@ -2972,32 +3847,35 @@ cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
profile_info[i].fop_name);
}
}
- cli_out ("");
- cli_out ("%12s : %"PRId64, "Duration", sec);
- cli_out ("%12s : %"PRId64, "BytesRead", r_count);
- cli_out ("%12s : %"PRId64, "BytesWritten", w_count);
- cli_out ("");
+ cli_out (" ");
+ cli_out ("%12s: %"PRId64" seconds", "Duration", sec);
+ cli_out ("%12s: %"PRId64" bytes", "Data Read", r_count);
+ cli_out ("%12s: %"PRId64" bytes", "Data Written", w_count);
+ cli_out (" ");
}
int32_t
gf_cli3_1_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_stats_volume_rsp rsp = {0,};
+ gf_cli_rsp rsp = {0,};
int ret = -1;
dict_t *dict = NULL;
- gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+ gf1_cli_stats_op op = GF_CLI_STATS_NONE;
char key[256] = {0};
int interval = 0;
int i = 1;
int32_t brick_count = 0;
char *volname = NULL;
+ char *brick = NULL;
+ char str[1024] = {0,};
+
if (-1 == req->rpc_status) {
goto out;
}
gf_log ("cli", GF_LOG_DEBUG, "Received resp to profile");
- ret = gf_xdr_to_cli_stats_volume_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -3010,8 +3888,8 @@ gf_cli3_1_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- ret = dict_unserialize (rsp.stats_info.stats_info_val,
- rsp.stats_info.stats_info_len,
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
&dict);
if (ret) {
@@ -3019,9 +3897,21 @@ gf_cli3_1_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
"Unable to allocate memory");
goto out;
} else {
- dict->extra_stdfree = rsp.stats_info.stats_info_val;
+ dict->extra_stdfree = rsp.dict.dict_val;
}
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_profile (dict, rsp.op_ret,
+ rsp.op_errno,
+ rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
ret = dict_get_str (dict, "volname", &volname);
if (ret)
goto out;
@@ -3031,7 +3921,7 @@ gf_cli3_1_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
if (rsp.op_ret && strcmp (rsp.op_errstr, "")) {
- cli_out (rsp.op_errstr);
+ cli_err ("%s", rsp.op_errstr);
} else {
switch (op) {
case GF_CLI_STATS_START:
@@ -3067,7 +3957,30 @@ gf_cli3_1_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
ret = dict_get_int32 (dict, "count", &brick_count);
if (ret)
goto out;
+
+ if (!brick_count) {
+ cli_out ("All bricks of volume %s are down.", volname);
+ goto out;
+ }
+
while (i <= brick_count) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-brick", i);
+ ret = dict_get_str (dict, key, &brick);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Couldn't get brick name");
+ goto out;
+ }
+
+ ret = dict_get_str_boolean (dict, "nfs", _gf_false);
+ if (ret)
+ snprintf (str, sizeof (str), "NFS Server : %s", brick);
+ else
+ snprintf (str, sizeof (str), "Brick: %s", brick);
+ cli_out ("%s", str);
+ memset (str, '-', strlen (str));
+ cli_out ("%s", str);
+
snprintf (key, sizeof (key), "%d-cumulative", i);
ret = dict_get_int32 (dict, key, &interval);
if (ret == 0) {
@@ -3095,8 +4008,8 @@ int32_t
gf_cli3_1_profile_volume (call_frame_t *frame, xlator_t *this, void *data)
{
int ret = -1;
- gf1_cli_stats_volume_req req = {0,};
- dict_t *dict = NULL;
+ gf_cli_req req = {{0,}};
+ dict_t *dict = NULL;
GF_ASSERT (frame);
GF_ASSERT (this);
@@ -3105,21 +4018,28 @@ gf_cli3_1_profile_volume (call_frame_t *frame, xlator_t *this, void *data)
if (!frame || !this || !data)
goto out;
dict = data;
- ret = dict_get_str (dict, "volname", &req.volname);
- if (ret)
- goto out;
- ret = dict_get_int32 (dict, "op", (int32_t*)&req.op);
- if (ret)
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize the data");
+
goto out;
+ }
+
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_PROFILE_VOLUME, NULL,
- gf_xdr_from_cli_stats_volume_req,
- this, gf_cli3_1_profile_volume_cbk);
+ this, gf_cli3_1_profile_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
return ret;
}
@@ -3127,18 +4047,18 @@ int32_t
gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_stats_volume_rsp rsp = {0,};
+ gf_cli_rsp rsp = {0,};
int ret = -1;
- dict_t *dict = NULL;
- gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+ dict_t *dict = NULL;
+ gf1_cli_stats_op op = GF_CLI_STATS_NONE;
char key[256] = {0};
int i = 0;
int32_t brick_count = 0;
char brick[1024];
int32_t members = 0;
- char *filename;
- char *bricks;
- uint64_t value = 0;
+ char *filename;
+ char *bricks;
+ uint64_t value = 0;
int32_t j = 0;
gf1_cli_top_op top_op = GF_CLI_TOP_NONE;
uint64_t nr_open = 0;
@@ -3146,29 +4066,25 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
double throughput = 0;
double time = 0;
long int time_sec = 0;
- long int time_usec = 0;
- struct tm *tm = NULL;
+ long int time_usec = 0;
char timestr[256] = {0, };
+ char *openfd_str = NULL;
if (-1 == req->rpc_status) {
goto out;
}
gf_log ("cli", GF_LOG_DEBUG, "Received resp to top");
- ret = gf_xdr_to_cli_stats_volume_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "Unable to decode response");
goto out;
}
- if (rsp.op_ret && strcmp (rsp.op_errstr, "")) {
- cli_out (rsp.op_errstr);
- } else {
- cli_out ("volume top %s ",
- (rsp.op_ret) ? "unsuccessful": "successful");
- }
-
if (rsp.op_ret) {
+ if (strcmp (rsp.op_errstr, ""))
+ cli_err ("%s", rsp.op_errstr);
+ cli_err ("volume top unsuccessful");
ret = rsp.op_ret;
goto out;
}
@@ -3180,8 +4096,8 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- ret = dict_unserialize (rsp.stats_info.stats_info_val,
- rsp.stats_info.stats_info_len,
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
&dict);
if (ret) {
@@ -3196,6 +4112,20 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
ret = 0;
goto out;
}
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_top (dict, rsp.op_ret,
+ rsp.op_errno,
+ rsp.op_errstr);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ }
+ goto out;
+ }
+#endif
+
ret = dict_get_int32 (dict, "count", &brick_count);
if (ret)
goto out;
@@ -3203,13 +4133,18 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
ret = dict_get_int32 (dict, key, (int32_t*)&top_op);
if (ret)
goto out;
- while (i <= brick_count) {
+ while (i < brick_count) {
i++;
snprintf (brick, sizeof (brick), "%d-brick", i);
ret = dict_get_str (dict, brick, &bricks);
if (ret)
goto out;
- cli_out ("Brick: %s", bricks);
+ ret = dict_get_str_boolean (dict, "nfs", _gf_false);
+ if (ret)
+ cli_out ("NFS Server : %s", bricks);
+ else
+ cli_out ("Brick: %s", bricks);
+
snprintf(key, sizeof (key), "%d-members", i);
ret = dict_get_int32 (dict, key, &members);
@@ -3223,14 +4158,18 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
ret = dict_get_uint64 (dict, key, &max_nr_open);
if (ret)
goto out;
+ snprintf (key, sizeof (key), "%d-max-openfd-time", i);
+ ret = dict_get_str (dict, key, &openfd_str);
+ if (ret)
+ goto out;
cli_out ("Current open fds: %"PRIu64", Max open"
- " fds: %"PRIu64, nr_open, max_nr_open);
+ " fds: %"PRIu64", Max openfd time: %s", nr_open,
+ max_nr_open, openfd_str);
case GF_CLI_TOP_READ:
case GF_CLI_TOP_WRITE:
case GF_CLI_TOP_OPENDIR:
case GF_CLI_TOP_READDIR:
if (!members) {
- cli_out ("No entries in list");
continue;
}
cli_out ("Count\t\tfilename\n=======================");
@@ -3248,10 +4187,16 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
time / 1e6);
if (!members) {
- cli_out ("No entries in list");
continue;
}
- cli_out ("MBps\t\tfilename\t\t time\n========================");
+ cli_out ("%*s %-*s %-*s",
+ VOL_TOP_PERF_SPEED_WIDTH, "MBps",
+ VOL_TOP_PERF_FILENAME_DEF_WIDTH, "Filename",
+ VOL_TOP_PERF_TIME_WIDTH, "Time");
+ cli_out ("%*s %-*s %-*s",
+ VOL_TOP_PERF_SPEED_WIDTH, "====",
+ VOL_TOP_PERF_FILENAME_DEF_WIDTH, "========",
+ VOL_TOP_PERF_TIME_WIDTH, "====");
break;
default:
goto out;
@@ -3276,14 +4221,27 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
ret = dict_get_int32 (dict, key, (int32_t *)&time_usec);
if (ret)
goto out;
- tm = localtime (&time_sec);
- if (!tm)
- goto out;
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
+ gf_time_fmt (timestr, sizeof timestr,
+ time_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
".%"GF_PRI_SUSECONDS, time_usec);
-
- cli_out ("%"PRIu64"\t\t%s\t\t%s", value, filename, timestr);
+ if (strlen (filename) < VOL_TOP_PERF_FILENAME_DEF_WIDTH)
+ cli_out ("%*"PRIu64" %-*s %-*s",
+ VOL_TOP_PERF_SPEED_WIDTH,
+ value,
+ VOL_TOP_PERF_FILENAME_DEF_WIDTH,
+ filename,
+ VOL_TOP_PERF_TIME_WIDTH,
+ timestr);
+ else
+ cli_out ("%*"PRIu64" ...%-*s %-*s",
+ VOL_TOP_PERF_SPEED_WIDTH,
+ value,
+ VOL_TOP_PERF_FILENAME_ALT_WIDTH ,
+ filename + strlen (filename) -
+ VOL_TOP_PERF_FILENAME_ALT_WIDTH,
+ VOL_TOP_PERF_TIME_WIDTH,
+ timestr);
} else {
cli_out ("%"PRIu64"\t\t%s", value, filename);
}
@@ -3297,8 +4255,8 @@ out:
if (dict)
dict_unref (dict);
- if (rsp.stats_info.stats_info_val)
- free (rsp.stats_info.stats_info_val);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
return ret;
}
@@ -3306,7 +4264,7 @@ int32_t
gf_cli3_1_top_volume (call_frame_t *frame, xlator_t *this, void *data)
{
int ret = -1;
- gf1_cli_stats_volume_req req = {0,};
+ gf_cli_req req = {{0,}};
dict_t *dict = NULL;
GF_ASSERT (frame);
@@ -3316,25 +4274,26 @@ gf_cli3_1_top_volume (call_frame_t *frame, xlator_t *this, void *data)
if (!frame || !this || !data)
goto out;
dict = data;
- ret = dict_get_str (dict, "volname", &req.volname);
- if (ret)
- goto out;
- ret = dict_get_int32 (dict, "op", (int32_t*)&req.op);
- if (ret)
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize the data");
+
goto out;
+ }
- ret = dict_allocate_and_serialize (dict,
- &req.dict_req.dict_req_val,
- (size_t *)&req.dict_req.dict_req_len);
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_PROFILE_VOLUME, NULL,
- gf_xdr_from_cli_stats_volume_req,
- this, gf_cli3_1_top_volume_cbk);
+ this, gf_cli3_1_top_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
return ret;
}
@@ -3344,13 +4303,13 @@ gf_cli3_1_getwd_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gf1_cli_getwd_rsp rsp = {0,};
- int ret = 0;
+ int ret = -1;
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_getwd_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_getwd_rsp);
if (ret < 0 || rsp.op_ret == -1) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -3358,7 +4317,7 @@ gf_cli3_1_getwd_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("cli", GF_LOG_INFO, "Received resp to getwd");
- cli_out (rsp.wd);
+ cli_out ("%s", rsp.wd);
ret = 0;
@@ -3381,8 +4340,8 @@ gf_cli3_1_getwd (call_frame_t *frame, xlator_t *this, void *data)
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GLUSTER_CLI_GETWD, NULL,
- gf_xdr_from_cli_getwd_req,
- this, gf_cli3_1_getwd_cbk);
+ this, gf_cli3_1_getwd_cbk,
+ (xdrproc_t) xdr_gf1_cli_getwd_req);
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
@@ -3390,6 +4349,1965 @@ out:
return ret;
}
+void
+cli_print_volume_status_mempool (dict_t *dict, char *prefix)
+{
+ int ret = -1;
+ int32_t mempool_count = 0;
+ char *name = NULL;
+ int32_t hotcount = 0;
+ int32_t coldcount = 0;
+ uint64_t paddedsizeof = 0;
+ uint64_t alloccount = 0;
+ int32_t maxalloc = 0;
+ uint64_t pool_misses = 0;
+ int32_t maxstdalloc = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (prefix);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.mempool-count",prefix);
+ ret = dict_get_int32 (dict, key, &mempool_count);
+ if (ret)
+ goto out;
+
+ cli_out ("Mempool Stats\n-------------");
+ cli_out ("%-30s %9s %9s %12s %10s %8s %8s %12s", "Name", "HotCount",
+ "ColdCount", "PaddedSizeof", "AllocCount", "MaxAlloc",
+ "Misses", "Max-StdAlloc");
+ cli_out ("%-30s %9s %9s %12s %10s %8s %8s %12s", "----", "--------",
+ "---------", "------------", "----------",
+ "--------", "--------", "------------");
+
+ for (i = 0; i < mempool_count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.name", prefix, i);
+ ret = dict_get_str (dict, key, &name);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.hotcount", prefix, i);
+ ret = dict_get_int32 (dict, key, &hotcount);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.coldcount", prefix, i);
+ ret = dict_get_int32 (dict, key, &coldcount);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.paddedsizeof",
+ prefix, i);
+ ret = dict_get_uint64 (dict, key, &paddedsizeof);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.alloccount", prefix, i);
+ ret = dict_get_uint64 (dict, key, &alloccount);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.max_alloc", prefix, i);
+ ret = dict_get_int32 (dict, key, &maxalloc);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.max-stdalloc", prefix, i);
+ ret = dict_get_int32 (dict, key, &maxstdalloc);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.pool-misses", prefix, i);
+ ret = dict_get_uint64 (dict, key, &pool_misses);
+ if (ret)
+ goto out;
+
+ cli_out ("%-30s %9d %9d %12"PRIu64" %10"PRIu64" %8d %8"PRIu64
+ " %12d", name, hotcount, coldcount, paddedsizeof,
+ alloccount, maxalloc, pool_misses, maxstdalloc);
+ }
+
+out:
+ return;
+
+}
+
+void
+cli_print_volume_status_mem (dict_t *dict, gf_boolean_t notbrick)
+{
+ int ret = -1;
+ char *volname = NULL;
+ char *hostname = NULL;
+ char *path = NULL;
+ int online = -1;
+ char key[1024] = {0,};
+ int brick_index_max = -1;
+ int other_count = 0;
+ int index_max = 0;
+ int val = 0;
+ int i = 0;
+
+ GF_ASSERT (dict);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out ("Memory status for volume : %s", volname);
+
+ ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32 (dict, "other-count", &other_count);
+ if (ret)
+ goto out;
+
+ index_max = brick_index_max + other_count;
+
+ for (i = 0; i <= index_max; i++) {
+ cli_out ("----------------------------------------------");
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.hostname", i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ continue;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", i);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ continue;
+ if (notbrick)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", i);
+ ret = dict_get_int32 (dict, key, &online);
+ if (ret)
+ goto out;
+ if (!online) {
+ if (notbrick)
+ cli_out ("%s is offline", hostname);
+ else
+ cli_out ("Brick is offline");
+ continue;
+ }
+
+ cli_out ("Mallinfo\n--------");
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.arena", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if (ret)
+ goto out;
+ cli_out ("%-8s : %d","Arena", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.ordblks", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if(ret)
+ goto out;
+ cli_out ("%-8s : %d","Ordblks", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.smblks", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if(ret)
+ goto out;
+ cli_out ("%-8s : %d","Smblks", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.hblks", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if(ret)
+ goto out;
+ cli_out ("%-8s : %d", "Hblks", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.hblkhd", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if (ret)
+ goto out;
+ cli_out ("%-8s : %d", "Hblkhd", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.usmblks", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if (ret)
+ goto out;
+ cli_out ("%-8s : %d", "Usmblks", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.fsmblks", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if (ret)
+ goto out;
+ cli_out ("%-8s : %d", "Fsmblks", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.uordblks", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if (ret)
+ goto out;
+ cli_out ("%-8s : %d", "Uordblks", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.fordblks", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if (ret)
+ goto out;
+ cli_out ("%-8s : %d", "Fordblks", val);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.keepcost", i);
+ ret = dict_get_int32 (dict, key, &val);
+ if (ret)
+ goto out;
+ cli_out ("%-8s : %d", "Keepcost", val);
+
+ cli_out (" ");
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d", i);
+ cli_print_volume_status_mempool (dict, key);
+ }
+out:
+ cli_out ("----------------------------------------------\n");
+ return;
+}
+
+void
+cli_print_volume_status_clients (dict_t *dict, gf_boolean_t notbrick)
+{
+ int ret = -1;
+ char *volname = NULL;
+ int brick_index_max = -1;
+ int other_count = 0;
+ int index_max = 0;
+ char *hostname = NULL;
+ char *path = NULL;
+ int online = -1;
+ int client_count = 0;
+ char *clientname = NULL;
+ uint64_t bytesread = 0;
+ uint64_t byteswrite = 0;
+ char key[1024] = {0,};
+ int i = 0;
+ int j = 0;
+
+ GF_ASSERT (dict);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out ("Client connections for volume %s", volname);
+
+ ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32 (dict, "other-count", &other_count);
+ if (ret)
+ goto out;
+
+ index_max = brick_index_max + other_count;
+
+ for (i = 0; i <= index_max; i++) {
+ cli_out ("----------------------------------------------");
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.hostname", i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", i);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ goto out;
+
+ if (notbrick)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", i);
+ ret = dict_get_int32 (dict, key, &online);
+ if (ret)
+ goto out;
+ if (!online) {
+ if (notbrick)
+ cli_out ("%s is offline", hostname);
+ else
+ cli_out ("Brick is offline");
+ continue;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.clientcount", i);
+ ret = dict_get_int32 (dict, key, &client_count);
+ if (ret)
+ goto out;
+
+ cli_out ("Clients connected : %d", client_count);
+ if (client_count == 0)
+ continue;
+
+ cli_out ("%-48s %15s %15s", "Hostname", "BytesRead",
+ "BytesWritten");
+ cli_out ("%-48s %15s %15s", "--------", "---------",
+ "------------");
+ for (j =0; j < client_count; j++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key),
+ "brick%d.client%d.hostname", i, j);
+ ret = dict_get_str (dict, key, &clientname);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key),
+ "brick%d.client%d.bytesread", i, j);
+ ret = dict_get_uint64 (dict, key, &bytesread);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key),
+ "brick%d.client%d.byteswrite", i, j);
+ ret = dict_get_uint64 (dict, key, &byteswrite);
+ if (ret)
+ goto out;
+
+ cli_out ("%-48s %15"PRIu64" %15"PRIu64,
+ clientname, bytesread, byteswrite);
+ }
+ }
+out:
+ cli_out ("----------------------------------------------\n");
+ return;
+}
+
+void
+cli_print_volume_status_inode_entry (dict_t *dict, char *prefix)
+{
+ int ret = -1;
+ char key[1024] = {0,};
+ char *gfid = NULL;
+ uint64_t nlookup = 0;
+ uint32_t ref = 0;
+ int ia_type = 0;
+ char inode_type;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (prefix);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.gfid", prefix);
+ ret = dict_get_str (dict, key, &gfid);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.nlookup", prefix);
+ ret = dict_get_uint64 (dict, key, &nlookup);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.ref", prefix);
+ ret = dict_get_uint32 (dict, key, &ref);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.ia_type", prefix);
+ ret = dict_get_int32 (dict, key, &ia_type);
+ if (ret)
+ goto out;
+
+ switch (ia_type) {
+ case IA_IFREG:
+ inode_type = 'R';
+ break;
+ case IA_IFDIR:
+ inode_type = 'D';
+ break;
+ case IA_IFLNK:
+ inode_type = 'L';
+ break;
+ case IA_IFBLK:
+ inode_type = 'B';
+ break;
+ case IA_IFCHR:
+ inode_type = 'C';
+ break;
+ case IA_IFIFO:
+ inode_type = 'F';
+ break;
+ case IA_IFSOCK:
+ inode_type = 'S';
+ break;
+ default:
+ inode_type = 'I';
+ break;
+ }
+
+ cli_out ("%-40s %14"PRIu64" %14"PRIu32" %9c",
+ gfid, nlookup, ref, inode_type);
+
+out:
+ return;
+
+}
+
+void
+cli_print_volume_status_itables (dict_t *dict, char *prefix)
+{
+ int ret = -1;
+ char key[1024] = {0,};
+ uint32_t active_size = 0;
+ uint32_t lru_size = 0;
+ uint32_t purge_size = 0;
+ int i =0;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (prefix);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.active_size", prefix);
+ ret = dict_get_uint32 (dict, key, &active_size);
+ if (ret)
+ goto out;
+ if (active_size != 0) {
+ cli_out ("Active inodes:");
+ cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref",
+ "IA type");
+ cli_out ("%-40s %14s %14s %9s", "----", "-------", "---",
+ "-------");
+ }
+ for (i = 0; i < active_size; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.active%d", prefix, i);
+ cli_print_volume_status_inode_entry (dict, key);
+ }
+ cli_out (" ");
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.lru_size", prefix);
+ ret = dict_get_uint32 (dict, key, &lru_size);
+ if (ret)
+ goto out;
+ if (lru_size != 0) {
+ cli_out ("LRU inodes:");
+ cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref",
+ "IA type");
+ cli_out ("%-40s %14s %14s %9s", "----", "-------", "---",
+ "-------");
+ }
+ for (i = 0; i < lru_size; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.lru%d", prefix, i);
+ cli_print_volume_status_inode_entry (dict, key);
+ }
+ cli_out (" ");
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.purge_size", prefix);
+ ret = dict_get_uint32 (dict, key, &purge_size);
+ if (ret)
+ goto out;
+ if (purge_size != 0) {
+ cli_out ("Purged inodes:");
+ cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref",
+ "IA type");
+ cli_out ("%-40s %14s %14s %9s", "----", "-------", "---",
+ "-------");
+ }
+ for (i = 0; i < purge_size; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.purge%d", prefix, i);
+ cli_print_volume_status_inode_entry (dict, key);
+ }
+
+out:
+ return;
+}
+
+void
+cli_print_volume_status_inode (dict_t *dict, gf_boolean_t notbrick)
+{
+ int ret = -1;
+ char *volname = NULL;
+ int brick_index_max = -1;
+ int other_count = 0;
+ int index_max = 0;
+ char *hostname = NULL;
+ char *path = NULL;
+ int online = -1;
+ int conn_count = 0;
+ char key[1024] = {0,};
+ int i = 0;
+ int j = 0;
+
+ GF_ASSERT (dict);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out ("Inode tables for volume %s", volname);
+
+ ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32 (dict, "other-count", &other_count);
+ if (ret)
+ goto out;
+
+ index_max = brick_index_max + other_count;
+
+ for ( i = 0; i <= index_max; i++) {
+ cli_out ("----------------------------------------------");
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.hostname", i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", i);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ goto out;
+ if (notbrick)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", i);
+ ret = dict_get_int32 (dict, key, &online);
+ if (ret)
+ goto out;
+ if (!online) {
+ if (notbrick)
+ cli_out ("%s is offline", hostname);
+ else
+ cli_out ("Brick is offline");
+ continue;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.conncount", i);
+ ret = dict_get_int32 (dict, key, &conn_count);
+ if (ret)
+ goto out;
+
+ for (j = 0; j < conn_count; j++) {
+ if (conn_count > 1)
+ cli_out ("Connection %d:", j+1);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.conn%d.itable",
+ i, j);
+ cli_print_volume_status_itables (dict, key);
+ cli_out (" ");
+ }
+ }
+out:
+ cli_out ("----------------------------------------------");
+ return;
+}
+
+void
+cli_print_volume_status_fdtable (dict_t *dict, char *prefix)
+{
+ int ret = -1;
+ char key[1024] = {0,};
+ int refcount = 0;
+ uint32_t maxfds = 0;
+ int firstfree = 0;
+ int openfds = 0;
+ int fd_pid = 0;
+ int fd_refcount = 0;
+ int fd_flags = 0;
+ int i = 0;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (prefix);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.refcount", prefix);
+ ret = dict_get_int32 (dict, key, &refcount);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.maxfds", prefix);
+ ret = dict_get_uint32 (dict, key, &maxfds);
+ if (ret)
+ goto out;
+
+ memset (key, 0 ,sizeof (key));
+ snprintf (key, sizeof (key), "%s.firstfree", prefix);
+ ret = dict_get_int32 (dict, key, &firstfree);
+ if (ret)
+ goto out;
+
+ cli_out ("RefCount = %d MaxFDs = %d FirstFree = %d",
+ refcount, maxfds, firstfree);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.openfds", prefix);
+ ret = dict_get_int32 (dict, key, &openfds);
+ if (ret)
+ goto out;
+ if (0 == openfds) {
+ cli_out ("No open fds");
+ goto out;
+ }
+
+ cli_out ("%-19s %-19s %-19s %-19s", "FD Entry", "PID",
+ "RefCount", "Flags");
+ cli_out ("%-19s %-19s %-19s %-19s", "--------", "---",
+ "--------", "-----");
+
+ for (i = 0; i < maxfds ; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdentry%d.pid", prefix, i);
+ ret = dict_get_int32 (dict, key, &fd_pid);
+ if (ret)
+ continue;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdentry%d.refcount",
+ prefix, i);
+ ret = dict_get_int32 (dict, key, &fd_refcount);
+ if (ret)
+ continue;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdentry%d.flags", prefix, i);
+ ret = dict_get_int32 (dict, key, &fd_flags);
+ if (ret)
+ continue;
+
+ cli_out ("%-19d %-19d %-19d %-19d", i, fd_pid, fd_refcount,
+ fd_flags);
+ }
+
+out:
+ return;
+}
+
+void
+cli_print_volume_status_fd (dict_t *dict, gf_boolean_t notbrick)
+{
+ int ret = -1;
+ char *volname = NULL;
+ int brick_index_max = -1;
+ int other_count = 0;
+ int index_max = 0;
+ char *hostname = NULL;
+ char *path = NULL;
+ int online = -1;
+ int conn_count = 0;
+ char key[1024] = {0,};
+ int i = 0;
+ int j = 0;
+
+ GF_ASSERT (dict);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out ("FD tables for volume %s", volname);
+
+ ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32 (dict, "other-count", &other_count);
+ if (ret)
+ goto out;
+
+ index_max = brick_index_max + other_count;
+
+ for (i = 0; i <= index_max; i++) {
+ cli_out ("----------------------------------------------");
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.hostname", i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", i);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ goto out;
+
+ if (notbrick)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", i);
+ ret = dict_get_int32 (dict, key, &online);
+ if (ret)
+ goto out;
+ if (!online) {
+ if (notbrick)
+ cli_out ("%s is offline", hostname);
+ else
+ cli_out ("Brick is offline");
+ continue;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.conncount", i);
+ ret = dict_get_int32 (dict, key, &conn_count);
+ if (ret)
+ goto out;
+
+ for (j = 0; j < conn_count; j++) {
+ cli_out ("Connection %d:", j+1);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.conn%d.fdtable",
+ i, j);
+ cli_print_volume_status_fdtable (dict, key);
+ cli_out (" ");
+ }
+ }
+out:
+ cli_out ("----------------------------------------------");
+ return;
+}
+
+void
+cli_print_volume_status_call_frame (dict_t *dict, char *prefix)
+{
+ int ret = -1;
+ char key[1024] = {0,};
+ int ref_count = 0;
+ char *translator = 0;
+ int complete = 0;
+ char *parent = NULL;
+ char *wind_from = NULL;
+ char *wind_to = NULL;
+ char *unwind_from = NULL;
+ char *unwind_to = NULL;
+
+ if (!dict || !prefix)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.refcount", prefix);
+ ret = dict_get_int32 (dict, key, &ref_count);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.translator", prefix);
+ ret = dict_get_str (dict, key, &translator);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.complete", prefix);
+ ret = dict_get_int32 (dict, key, &complete);
+ if (ret)
+ return;
+
+ cli_out (" Ref Count = %d", ref_count);
+ cli_out (" Translator = %s", translator);
+ cli_out (" Completed = %s", (complete ? "Yes" : "No"));
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.parent", prefix);
+ ret = dict_get_str (dict, key, &parent);
+ if (!ret)
+ cli_out (" Parent = %s", parent);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.windfrom", prefix);
+ ret = dict_get_str (dict, key, &wind_from);
+ if (!ret)
+ cli_out (" Wind From = %s", wind_from);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.windto", prefix);
+ ret = dict_get_str (dict, key, &wind_to);
+ if (!ret)
+ cli_out (" Wind To = %s", wind_to);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unwindfrom", prefix);
+ ret = dict_get_str (dict, key, &unwind_from);
+ if (!ret)
+ cli_out (" Unwind From = %s", unwind_from);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unwindto", prefix);
+ ret = dict_get_str (dict, key, &unwind_to);
+ if (!ret)
+ cli_out (" Unwind To = %s", unwind_to);
+}
+
+void
+cli_print_volume_status_call_stack (dict_t *dict, char *prefix)
+{
+ int ret = -1;
+ char key[1024] = {0,};
+ int uid = 0;
+ int gid = 0;
+ int pid = 0;
+ uint64_t unique = 0;
+ //char *op = NULL;
+ int count = 0;
+ int i = 0;
+
+ if (!dict || !prefix)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.uid", prefix);
+ ret = dict_get_int32 (dict, key, &uid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.gid", prefix);
+ ret = dict_get_int32 (dict, key, &gid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pid", prefix);
+ ret = dict_get_int32 (dict, key, &pid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unique", prefix);
+ ret = dict_get_uint64 (dict, key, &unique);
+ if (ret)
+ return;
+
+ /*
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.op", prefix);
+ ret = dict_get_str (dict, key, &op);
+ if (ret)
+ return;
+ */
+
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.count", prefix);
+ ret = dict_get_int32 (dict, key, &count);
+ if (ret)
+ return;
+
+ cli_out (" UID : %d", uid);
+ cli_out (" GID : %d", gid);
+ cli_out (" PID : %d", pid);
+ cli_out (" Unique : %"PRIu64, unique);
+ //cli_out ("\tOp : %s", op);
+ cli_out (" Frames : %d", count);
+
+ for (i = 0; i < count; i++) {
+ cli_out (" Frame %d", i+1);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.frame%d", prefix, i);
+ cli_print_volume_status_call_frame (dict, key);
+ }
+
+ cli_out (" ");
+}
+
+void
+cli_print_volume_status_callpool (dict_t *dict, gf_boolean_t notbrick)
+{
+ int ret = -1;
+ char *volname = NULL;
+ int brick_index_max = -1;
+ int other_count = 0;
+ int index_max = 0;
+ char *hostname = NULL;
+ char *path = NULL;
+ int online = -1;
+ int call_count = 0;
+ char key[1024] = {0,};
+ int i = 0;
+ int j = 0;
+
+ GF_ASSERT (dict);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out ("Pending calls for volume %s", volname);
+
+ ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32 (dict, "other-count", &other_count);
+ if (ret)
+ goto out;
+
+ index_max = brick_index_max + other_count;
+
+ for (i = 0; i <= index_max; i++) {
+ cli_out ("----------------------------------------------");
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.hostname", i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", i);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ goto out;
+
+ if (notbrick)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", i);
+ ret = dict_get_int32 (dict, key, &online);
+ if (ret)
+ goto out;
+ if (!online) {
+ if (notbrick)
+ cli_out ("%s is offline", hostname);
+ else
+ cli_out ("Brick is offline");
+ continue;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.callpool.count", i);
+ ret = dict_get_int32 (dict, key, &call_count);
+ if (ret)
+ goto out;
+ cli_out ("Pending calls: %d", call_count);
+
+ if (0 == call_count)
+ continue;
+
+ for (j = 0; j < call_count; j++) {
+ cli_out ("Call Stack%d", j+1);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key),
+ "brick%d.callpool.stack%d", i, j);
+ cli_print_volume_status_call_stack (dict, key);
+ }
+ }
+
+out:
+ cli_out ("----------------------------------------------");
+ return;
+}
+
+static int
+gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ int ret = -1;
+ int brick_index_max = -1;
+ int other_count = 0;
+ int index_max = 0;
+ int i = 0;
+ int pid = -1;
+ uint32_t cmd = 0;
+ gf_boolean_t notbrick = _gf_false;
+ char key[1024] = {0,};
+ char *hostname = NULL;
+ char *path = NULL;
+ char *volname = NULL;
+ dict_t *dict = NULL;
+ gf_cli_rsp rsp = {0,};
+ cli_volume_status_t status = {0};
+ cli_local_t *local = NULL;
+ char msg[1024] = {0,};
+
+ if (req->rpc_status == -1)
+ goto out;
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR, "Volume status response error");
+ goto out;
+ }
+
+ gf_log ("cli", GF_LOG_DEBUG, "Received response to status cmd");
+
+ local = ((call_frame_t *)myframe)->local;
+
+ if (rsp.op_ret) {
+ if (strcmp (rsp.op_errstr, ""))
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
+ else
+ snprintf (msg, sizeof (msg), "Unable to obtain volume "
+ "status information.");
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ cli_xml_output_str ("volStatus", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ ret = 0;
+ goto out;
+ }
+#endif
+ cli_err ("%s", msg);
+ if (local && local->all) {
+ ret = 0;
+ cli_out (" ");
+ } else
+ ret = -1;
+
+ goto out;
+ }
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+ if (ret)
+ goto out;
+
+ ret = dict_get_uint32 (dict, "cmd", &cmd);
+ if (ret)
+ goto out;
+
+ if ((cmd & GF_CLI_STATUS_ALL)) {
+ if (local) {
+ local->dict = dict;
+ ret = 0;
+ } else {
+ gf_log ("cli", GF_LOG_ERROR, "local not found");
+ ret = -1;
+ }
+ goto out;
+ }
+
+ if ((cmd & GF_CLI_STATUS_NFS) || (cmd & GF_CLI_STATUS_SHD))
+ notbrick = _gf_true;
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret)
+ goto out;
+ if (count == 0) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32 (dict, "other-count", &other_count);
+ if (ret)
+ goto out;
+
+ index_max = brick_index_max + other_count;
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_status (dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ }
+ goto out;
+ }
+#endif
+
+ status.brick = GF_CALLOC (1, PATH_MAX + 256, gf_common_mt_strdup);
+
+ switch (cmd & GF_CLI_STATUS_MASK) {
+ case GF_CLI_STATUS_MEM:
+ cli_print_volume_status_mem (dict, notbrick);
+ goto cont;
+ break;
+ case GF_CLI_STATUS_CLIENTS:
+ cli_print_volume_status_clients (dict, notbrick);
+ goto cont;
+ break;
+ case GF_CLI_STATUS_INODE:
+ cli_print_volume_status_inode (dict, notbrick);
+ goto cont;
+ break;
+ case GF_CLI_STATUS_FD:
+ cli_print_volume_status_fd (dict, notbrick);
+ goto cont;
+ break;
+ case GF_CLI_STATUS_CALLPOOL:
+ cli_print_volume_status_callpool (dict, notbrick);
+ goto cont;
+ break;
+ default:
+ break;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+
+ cli_out ("Status of volume: %s", volname);
+
+ if ((cmd & GF_CLI_STATUS_DETAIL) == 0) {
+ cli_out ("Gluster process\t\t\t\t\t\tPort\tOnline\tPid");
+ cli_print_line (CLI_BRICK_STATUS_LINE_LEN);
+ }
+
+ for (i = 0; i <= index_max; i++) {
+
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.hostname", i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ continue;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", i);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ continue;
+
+ /* Brick/not-brick is handled seperately here as all
+ * types of nodes are contained in the default output
+ */
+ memset (status.brick, 0, PATH_MAX + 255);
+ if (!strcmp (hostname, "NFS Server") ||
+ !strcmp (hostname, "Self-heal Daemon"))
+ snprintf (status.brick, PATH_MAX + 255, "%s on %s",
+ hostname, path);
+ else
+ snprintf (status.brick, PATH_MAX + 255, "Brick %s:%s",
+ hostname, path);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.port", i);
+ ret = dict_get_int32 (dict, key, &(status.port));
+ if (ret)
+ continue;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", i);
+ ret = dict_get_int32 (dict, key, &(status.online));
+ if (ret)
+ continue;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.pid", i);
+ ret = dict_get_int32 (dict, key, &pid);
+ if (ret)
+ continue;
+ if (pid == -1)
+ ret = gf_asprintf (&(status.pid_str), "%s", "N/A");
+ else
+ ret = gf_asprintf (&(status.pid_str), "%d", pid);
+
+ if (ret == -1)
+ goto out;
+
+ if ((cmd & GF_CLI_STATUS_DETAIL)) {
+ ret = cli_get_detail_status (dict, i, &status);
+ if (ret)
+ goto out;
+ cli_print_line (CLI_BRICK_STATUS_LINE_LEN);
+ cli_print_detailed_status (&status);
+
+ } else {
+ cli_print_brick_status (&status);
+ }
+ }
+ cli_out (" ");
+cont:
+ ret = rsp.op_ret;
+
+out:
+ if (status.brick)
+ GF_FREE (status.brick);
+
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_status_volume (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ gf_cli_req req = {{0,}};
+ int ret = -1;
+ dict_t *dict = NULL;
+
+ if (!frame || !this || !data)
+ goto out;
+
+ dict = data;
+
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "failed to serialize the data");
+
+ goto out;
+ }
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_STATUS_VOLUME, NULL,
+ this, gf_cli3_1_status_cbk,
+ (xdrproc_t)xdr_gf_cli_req);
+
+ out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning: %d", ret);
+ return ret;
+}
+
+int
+gf_cli_status_volume_all (call_frame_t *frame, xlator_t *this, void *data)
+{
+ int i = 0;
+ int ret = -1;
+ int vol_count = -1;
+ uint32_t cmd = 0;
+ char key[1024] = {0};
+ char *volname = NULL;
+ dict_t *vol_dict = NULL;
+ dict_t *dict = NULL;
+ cli_local_t *local = NULL;
+
+ dict = (dict_t *)data;
+ ret = dict_get_uint32 (dict, "cmd", &cmd);
+ if (ret)
+ goto out;
+
+ local = cli_local_get ();
+ if (!local) {
+ ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Failed to allocate local");
+ goto out;
+ }
+ frame->local = local;
+ local->all = _gf_true;
+
+ ret = gf_cli3_1_status_volume (frame, this, data);
+ if (ret)
+ goto out;
+
+ vol_dict = local->dict;
+
+ ret = dict_get_int32 (vol_dict, "vol_count", &vol_count);
+ if (ret) {
+ cli_err ("Failed to get names of volumes");
+ goto out;
+ }
+
+ if (vol_count == 0) {
+ cli_out ("No volumes present");
+ ret = 0;
+ goto out;
+ }
+
+ /* remove the "all" flag in cmd */
+ cmd &= ~GF_CLI_STATUS_ALL;
+ cmd |= GF_CLI_STATUS_VOL;
+
+ for (i = 0; i < vol_count; i++) {
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "vol%d", i);
+ ret = dict_get_str (vol_dict, key, &volname);
+ if (ret)
+ goto out;
+
+ ret = dict_set_dynstr (dict, "volname", volname);
+ if (ret)
+ goto out;
+
+ ret = dict_set_uint32 (dict, "cmd", cmd);
+ if (ret)
+ goto out;
+
+ ret = gf_cli3_1_status_volume (frame, this, dict);
+ if (ret)
+ goto out;
+
+ dict_unref (dict);
+ }
+
+ out:
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR, "status all failed");
+ if (ret && dict)
+ dict_unref (dict);
+ if (frame)
+ frame->local = NULL;
+ return ret;
+}
+
+static int
+gf_cli3_1_mount_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf1_cli_mount_rsp rsp = {0,};
+ int ret = -1;
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_mount_rsp);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_ERROR, "error");
+ goto out;
+ }
+
+ gf_log ("cli", GF_LOG_INFO, "Received resp to mount");
+
+ if (rsp.op_ret == 0) {
+ ret = 0;
+ cli_out ("%s", rsp.path);
+ } else {
+ /* weird sounding but easy to parse... */
+ cli_err ("%d : failed with this errno (%s)",
+ rsp.op_errno, strerror (rsp.op_errno));
+ ret = 1;
+ }
+
+out:
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_mount (call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf1_cli_mount_req req = {0,};
+ int ret = -1;
+ void **dataa = data;
+ char *label = NULL;
+ dict_t *dict = NULL;
+
+ if (!frame || !this || !data)
+ goto out;
+
+ label = dataa[0];
+ dict = dataa[1];
+
+ req.label = label;
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_MOUNT, NULL,
+ this, gf_cli3_1_mount_cbk,
+ (xdrproc_t)xdr_gf1_cli_mount_req);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+gf_cli3_1_umount_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf1_cli_umount_rsp rsp = {0,};
+ int ret = -1;
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_umount_rsp);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_ERROR, "error");
+ goto out;
+ }
+
+ gf_log ("cli", GF_LOG_INFO, "Received resp to mount");
+
+ if (rsp.op_ret == 0)
+ ret = 0;
+ else {
+ cli_err ("umount failed");
+ ret = 1;
+ }
+
+out:
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_umount (call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf1_cli_umount_req req = {0,};
+ int ret = -1;
+ dict_t *dict = NULL;
+
+ if (!frame || !this || !data)
+ goto out;
+
+ dict = data;
+
+ ret = dict_get_str (dict, "path", &req.path);
+ if (ret == 0)
+ ret = dict_get_int32 (dict, "lazy", &req.lazy);
+
+ if (ret) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_UMOUNT, NULL,
+ this, gf_cli3_1_umount_cbk,
+ (xdrproc_t)xdr_gf1_cli_umount_req);
+
+ out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+void
+cmd_heal_volume_brick_out (dict_t *dict, int brick)
+{
+ uint64_t num_entries = 0;
+ int ret = 0;
+ char key[256] = {0};
+ char *hostname = NULL;
+ char *path = NULL;
+ char *status = NULL;
+ uint64_t i = 0;
+ uint32_t time = 0;
+ char timestr[32] = {0};
+
+ snprintf (key, sizeof key, "%d-hostname", brick);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+ snprintf (key, sizeof key, "%d-path", brick);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ goto out;
+ cli_out ("\nBrick %s:%s", hostname, path);
+ snprintf (key, sizeof key, "%d-count", brick);
+ ret = dict_get_uint64 (dict, key, &num_entries);
+ cli_out ("Number of entries: %"PRIu64, num_entries);
+ snprintf (key, sizeof key, "%d-status", brick);
+ ret = dict_get_str (dict, key, &status);
+ if (status && strlen (status))
+ cli_out ("Status: %s", status);
+ for (i = 0; i < num_entries; i++) {
+ snprintf (key, sizeof key, "%d-%"PRIu64, brick, i);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ continue;
+ time = 0;
+ snprintf (key, sizeof key, "%d-%"PRIu64"-time", brick, i);
+ ret = dict_get_uint32 (dict, key, &time);
+ if (!time) {
+ cli_out ("%s", path);
+ } else {
+ gf_time_fmt (timestr, sizeof timestr,
+ time, gf_timefmt_FT);
+ if (i == 0) {
+ cli_out ("at path on brick");
+ cli_out ("-----------------------------------");
+ }
+ cli_out ("%s %s", timestr, path);
+ }
+ }
+out:
+ return;
+}
+
+int
+gf_cli3_1_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ cli_local_t *local = NULL;
+ char *volname = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *input_dict = NULL;
+ dict_t *dict = NULL;
+ int brick_count = 0;
+ int i = 0;
+ gf_xl_afr_op_t heal_op = GF_AFR_OP_INVALID;
+ char *operation = NULL;
+ char *substr = NULL;
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_ERROR, "error");
+ goto out;
+ }
+
+ frame = myframe;
+
+ if (frame) {
+ local = frame->local;
+ frame->local = NULL;
+ }
+
+ if (local) {
+ input_dict = local->dict;
+ ret = dict_get_int32 (input_dict, "heal-op",
+ (int32_t*)&heal_op);
+ }
+//TODO: Proper XML output
+//#if (HAVE_LIB_XML)
+// if (global_state->mode & GLUSTER_MODE_XML) {
+// ret = cli_xml_output_dict ("volHeal", dict, rsp.op_ret,
+// rsp.op_errno, rsp.op_errstr);
+// if (ret)
+// gf_log ("cli", GF_LOG_ERROR,
+// "Error outputting to xml");
+// goto out;
+// }
+//#endif
+
+ ret = dict_get_str (input_dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname");
+ goto out;
+ }
+
+ gf_log ("cli", GF_LOG_INFO, "Received resp to heal volume");
+
+ if ((heal_op == GF_AFR_OP_HEAL_FULL) ||
+ (heal_op == GF_AFR_OP_HEAL_INDEX)) {
+ operation = "Launching Heal operation";
+ substr = "\nUse heal info commands to check status";
+ } else {
+ operation = "Gathering Heal info";
+ substr = "";
+ }
+
+ if (rsp.op_ret) {
+ if (strcmp (rsp.op_errstr, "")) {
+ cli_err ("%s", rsp.op_errstr);
+ } else {
+ cli_err ("%s on volume %s has been unsuccessful",
+ operation, volname);
+ }
+ } else {
+ cli_out ("%s on volume %s has been successful%s", operation,
+ volname, substr);
+ }
+
+ ret = rsp.op_ret;
+ if ((heal_op == GF_AFR_OP_HEAL_FULL) ||
+ (heal_op == GF_AFR_OP_HEAL_INDEX))
+ goto out;
+
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Unable to allocate memory");
+ goto out;
+ } else {
+ dict->extra_stdfree = rsp.dict.dict_val;
+ }
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret)
+ goto out;
+
+ if (!brick_count) {
+ cli_out ("All bricks of volume %s are down.", volname);
+ goto out;
+ }
+
+ for (i = 0; i < brick_count; i++)
+ cmd_heal_volume_brick_out (dict, i);
+ ret = rsp.op_ret;
+
+out:
+ cli_cmd_broadcast_response (ret);
+ if (local)
+ cli_local_wipe (local);
+ if (rsp.op_errstr)
+ free (rsp.op_errstr);
+ if (dict)
+ dict_unref (dict);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_heal_volume (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ gf_cli_req req = {{0,}};
+ int ret = 0;
+ cli_local_t *local = NULL;
+ dict_t *dict = NULL;
+
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+ local = cli_local_get ();
+
+ if (local) {
+ local->dict = dict_ref (dict);
+ frame->local = local;
+ }
+
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize the data");
+
+ goto out;
+ }
+
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_HEAL_VOLUME, NULL,
+ this, gf_cli3_1_heal_volume_cbk,
+ (xdrproc_t) xdr_gf_cli_req);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
+
+ return ret;
+}
+
+int32_t
+gf_cli3_1_statedump_volume_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ char msg[1024] = {0,};
+
+ if (-1 == req->rpc_status)
+ goto out;
+ ret = xdr_to_generic (*iov, &rsp,
+ (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "XDR decoding failed");
+ goto out;
+ }
+ gf_log ("cli", GF_LOG_DEBUG, "Received response to statedump");
+ if (rsp.op_ret)
+ snprintf (msg, sizeof(msg), "%s", rsp.op_errstr);
+ else
+ snprintf (msg, sizeof (msg), "Volume statedump successful");
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volStatedump", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+
+ if (rsp.op_ret)
+ cli_err ("%s", msg);
+ else
+ cli_out ("%s", msg);
+ ret = rsp.op_ret;
+
+out:
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_statedump_volume (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ gf_cli_req req = {{0,}};
+ dict_t *options = NULL;
+ int ret = -1;
+
+ if (!frame || !this || !data)
+ goto out;
+
+ options = data;
+
+ ret = dict_allocate_and_serialize (options, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize the data");
+
+ goto out;
+ }
+
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_STATEDUMP_VOLUME, NULL,
+ this, gf_cli3_1_statedump_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req);
+
+out:
+ if (options)
+ dict_destroy (options);
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_list_volume_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ int ret = -1;
+ gf_cli_rsp rsp = {0,};
+ dict_t *dict = NULL;
+ int vol_count = 0;;
+ char *volname = NULL;
+ char key[1024] = {0,};
+ int i = 0;
+
+ if (-1 == req->rpc_status)
+ goto out;
+ ret = xdr_to_generic (*iov, &rsp,
+ (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "XDR decoding failed");
+ goto out;
+ }
+
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to allocate memory");
+ goto out;
+ }
+
+#if (HAVE_LIB_XML)
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_list (dict, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+#endif
+ if (rsp.op_ret)
+ cli_err ("%s", rsp.op_errstr);
+ else {
+ ret = dict_get_int32 (dict, "count", &vol_count);
+ if (ret)
+ goto out;
+
+ if (vol_count == 0) {
+ cli_out ("No volumes present in cluster");
+ goto out;
+ }
+ for (i = 0; i < vol_count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d", i);
+ ret = dict_get_str (dict, key, &volname);
+ if (ret)
+ goto out;
+ cli_out ("%s", volname);
+ }
+ }
+
+ ret = rsp.op_ret;
+
+out:
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_list_volume (call_frame_t *frame, xlator_t *this, void *data)
+{
+ int ret = -1;
+ gf_cli_req req = {{0,}};
+
+ if (!frame || !this)
+ goto out;
+
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_LIST_VOLUME, NULL,
+ this, gf_cli3_1_list_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_clearlocks_volume_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ char *lk_summary = NULL;
+ char *volname = NULL;
+ dict_t *dict = NULL;
+
+ if (-1 == req->rpc_status)
+ goto out;
+ ret = xdr_to_generic (*iov, &rsp,
+ (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+
+ gf_log ("cli", GF_LOG_ERROR, "XDR decoding failed");
+ goto out;
+ }
+ gf_log ("cli", GF_LOG_DEBUG, "Received response to clear-locks");
+
+ if (rsp.op_ret) {
+ cli_err ("Volume clear-locks unsuccessful");
+ cli_err ("%s", rsp.op_errstr);
+
+ } else {
+ if (!rsp.dict.dict_len) {
+ cli_out ("Possibly no locks cleared");
+ ret = 0;
+ goto out;
+ }
+
+ dict = dict_new ();
+
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Unable to serialize response dictionary");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to get volname "
+ "from dictionary");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "lk-summary", &lk_summary);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to get lock "
+ "summary from dictionary");
+ goto out;
+ }
+ cli_out ("Volume clear-locks successful");
+ cli_out ("%s", lk_summary);
+
+ }
+
+ ret = rsp.op_ret;
+
+out:
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_clearlocks_volume (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ gf_cli_req req = {{0,}};
+ dict_t *options = NULL;
+ int ret = -1;
+
+ if (!frame || !this || !data)
+ goto out;
+
+ options = data;
+
+ ret = dict_allocate_and_serialize (options, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "failed to serialize the data");
+
+ goto out;
+ }
+
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_CLRLOCKS_VOLUME, NULL,
+ this, gf_cli3_1_clearlocks_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req);
+
+out:
+ if (options)
+ dict_destroy (options);
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
+ return ret;
+}
struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_NULL] = {"NULL", NULL },
@@ -3408,8 +6326,6 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_ADD_BRICK] = {"ADD_BRICK", gf_cli3_1_add_brick},
[GLUSTER_CLI_REMOVE_BRICK] = {"REMOVE_BRICK", gf_cli3_1_remove_brick},
[GLUSTER_CLI_REPLACE_BRICK] = {"REPLACE_BRICK", gf_cli3_1_replace_brick},
- [GLUSTER_CLI_LOG_FILENAME] = {"LOG FILENAME", gf_cli3_1_log_filename},
- [GLUSTER_CLI_LOG_LOCATE] = {"LOG LOCATE", gf_cli3_1_log_locate},
[GLUSTER_CLI_LOG_ROTATE] = {"LOG ROTATE", gf_cli3_1_log_rotate},
[GLUSTER_CLI_GETSPEC] = {"GETSPEC", gf_cli3_1_getspec},
[GLUSTER_CLI_PMAP_PORTBYBRICK] = {"PMAP PORTBYBRICK", gf_cli3_1_pmap_b2p},
@@ -3420,13 +6336,21 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_PROFILE_VOLUME] = {"PROFILE_VOLUME", gf_cli3_1_profile_volume},
[GLUSTER_CLI_QUOTA] = {"QUOTA", gf_cli3_1_quota},
[GLUSTER_CLI_TOP_VOLUME] = {"TOP_VOLUME", gf_cli3_1_top_volume},
- [GLUSTER_CLI_GETWD] = {"GETWD", gf_cli3_1_getwd}
+ [GLUSTER_CLI_GETWD] = {"GETWD", gf_cli3_1_getwd},
+ [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", gf_cli3_1_status_volume},
+ [GLUSTER_CLI_STATUS_ALL] = {"STATUS_ALL", gf_cli_status_volume_all},
+ [GLUSTER_CLI_MOUNT] = {"MOUNT", gf_cli3_1_mount},
+ [GLUSTER_CLI_UMOUNT] = {"UMOUNT", gf_cli3_1_umount},
+ [GLUSTER_CLI_HEAL_VOLUME] = {"HEAL_VOLUME", gf_cli3_1_heal_volume},
+ [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", gf_cli3_1_statedump_volume},
+ [GLUSTER_CLI_LIST_VOLUME] = {"LIST_VOLUME", gf_cli3_1_list_volume},
+ [GLUSTER_CLI_CLRLOCKS_VOLUME] = {"CLEARLOCKS_VOLUME", gf_cli3_1_clearlocks_volume},
};
struct rpc_clnt_program cli_prog = {
.progname = "Gluster CLI",
.prognum = GLUSTER_CLI_PROGRAM,
.progver = GLUSTER_CLI_VERSION,
- .numproc = GLUSTER_CLI_PROCCNT,
+ .numproc = GLUSTER_CLI_MAXVALUE,
.proctable = gluster_cli_actors,
};
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c
new file mode 100644
index 000000000..83a442055
--- /dev/null
+++ b/cli/src/cli-xml-output.c
@@ -0,0 +1,2628 @@
+/*
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "cli.h"
+#include "cli1-xdr.h"
+#include "run.h"
+#include "compat.h"
+#include "syscall.h"
+
+
+#if (HAVE_LIB_XML)
+
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+
+#define XML_RET_CHECK_AND_GOTO(ret, label) do { \
+ if (ret < 0) { \
+ ret = -1; \
+ goto label; \
+ } \
+ else \
+ ret = 0; \
+ }while (0) \
+
+int
+cli_begin_xml_output (xmlTextWriterPtr *writer, xmlBufferPtr *buf)
+{
+ int ret = -1;
+
+ *buf = xmlBufferCreateSize (8192);
+ if (buf == NULL) {
+ ret = -1;
+ goto out;
+ }
+ xmlBufferSetAllocationScheme (*buf, XML_BUFFER_ALLOC_DOUBLEIT);
+
+ *writer = xmlNewTextWriterMemory (*buf, 0);
+ if (writer == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = xmlTextWriterStartDocument (*writer, "1.0", "UTF-8", "yes");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* <cliOutput> */
+ ret = xmlTextWriterStartElement (*writer, (xmlChar *)"cliOutput");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_end_xml_output (xmlTextWriterPtr writer, xmlBufferPtr buf)
+{
+ int ret = -1;
+
+ /* </cliOutput> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterEndDocument (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ cli_out ("%s", (const char *)buf->content);
+
+ xmlFreeTextWriter (writer);
+ xmlBufferFree (buf);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_common (xmlTextWriterPtr writer, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"opRet",
+ "%d", op_ret);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"opErrno",
+ "%d", op_errno);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"opErrstr",
+ "%s", op_errstr);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_str (char *op, char *str, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlBufferPtr buf = NULL;
+
+ ret = cli_begin_xml_output (&writer, &buf);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"cliOp",
+ "%s", op);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"output",
+ "%s", str);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_end_xml_output (writer, buf);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+void
+cli_xml_output_data_pair (dict_t *this, char *key, data_t *value,
+ void *data)
+{
+ int ret = -1;
+ xmlTextWriterPtr *writer = NULL;
+
+ writer = (xmlTextWriterPtr *)data;
+
+ ret = xmlTextWriterWriteFormatElement (*writer, (xmlChar *)key,
+ "%s", value->data);
+
+ return;
+}
+
+int
+cli_xml_output_dict ( char *op, dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlBufferPtr buf = NULL;
+
+ ret = cli_begin_xml_output (&writer, &buf);
+ if (ret)
+ goto out;
+ /* <"op"> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)op);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ dict_foreach (dict, cli_xml_output_data_pair, &writer);
+
+ /* </"op"> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_end_xml_output (writer, buf);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_common (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index, int *online,
+ gf_boolean_t *node_present)
+{
+ int ret = -1;
+ char *hostname = NULL;
+ char *path = NULL;
+ int port = 0;
+ int status = 0;
+ int pid = 0;
+ char key[1024] = {0,};
+
+ snprintf (key, sizeof (key), "brick%d.hostname", brick_index);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret) {
+ *node_present = _gf_false;
+ goto out;
+ }
+ *node_present = _gf_true;
+
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"hostname",
+ "%s", hostname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", brick_index);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"path",
+ "%s", path);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.port", brick_index);
+ ret = dict_get_int32 (dict, key, &port);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"port",
+ "%d", port);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", brick_index);
+ ret = dict_get_int32 (dict, key, &status);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"status",
+ "%d", status);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ *online = status;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.pid", brick_index);
+ ret = dict_get_int32 (dict, key, &pid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"pid",
+ "%d", pid);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_detail (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index)
+{
+ int ret = -1;
+ uint64_t size_total = 0;
+ uint64_t size_free = 0;
+ char *device = NULL;
+ uint64_t block_size = 0;
+ char *mnt_options = NULL;
+ char *fs_name = NULL;
+ char *inode_size = NULL;
+ uint64_t inodes_total = 0;
+ uint64_t inodes_free = 0;
+ char key[1024] = {0,};
+
+ snprintf (key, sizeof (key), "brick%d.total", brick_index);
+ ret = dict_get_uint64 (dict, key, &size_total);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"sizeTotal",
+ "%"PRIu64, size_total);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.free", brick_index);
+ ret = dict_get_uint64 (dict, key, &size_free);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"sizeFree",
+ "%"PRIu64, size_free);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.device", brick_index);
+ ret = dict_get_str (dict, key, &device);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"device",
+ "%s", device);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.block_size", brick_index);
+ ret = dict_get_uint64 (dict, key, &block_size);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"blockSize",
+ "%"PRIu64, block_size);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mnt_options", brick_index);
+ ret = dict_get_str (dict, key, &mnt_options);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"mntOptions",
+ "%s", mnt_options);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.fs_name", brick_index);
+ ret = dict_get_str (dict, key, &fs_name);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"fsName",
+ "%s", fs_name);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* inode details are only available for ext 2/3/4 & xfs */
+ if (!IS_EXT_FS(fs_name) || strcmp (fs_name, "xfs")) {
+ ret = 0;
+ goto out;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.inode_size", brick_index);
+ ret = dict_get_str (dict, key, &inode_size);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodeSize",
+ "%s", fs_name);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.total_inodes", brick_index);
+ ret = dict_get_uint64 (dict, key, &inodes_total);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodesTotal",
+ "%"PRIu64, inodes_total);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.free_inodes", brick_index);
+ ret = dict_get_uint64 (dict, key, &inodes_free);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodesFree",
+ "%"PRIu64, inodes_free);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_mempool (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+ int ret = -1;
+ int mempool_count = 0;
+ char *name = NULL;
+ int hotcount = 0;
+ int coldcount = 0;
+ uint64_t paddedsizeof = 0;
+ uint64_t alloccount = 0;
+ int maxalloc = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ /* <mempool> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"mempool");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%s.mempool-count", prefix);
+ ret = dict_get_int32 (dict, key, &mempool_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"count",
+ "%d", mempool_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < mempool_count; i++) {
+ /* <pool> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"pool");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.name", prefix, i);
+ ret = dict_get_str (dict, key, &name);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"name",
+ "%s", name);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.hotcount", prefix, i);
+ ret = dict_get_int32 (dict, key, &hotcount);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"hotCount",
+ "%d", hotcount);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.coldcount", prefix, i);
+ ret = dict_get_int32 (dict, key, &coldcount);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"coldCount",
+ "%d", coldcount);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.paddedsizeof",
+ prefix, i);
+ ret = dict_get_uint64 (dict, key, &paddedsizeof);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"padddedSizeOf", "%"PRIu64,
+ paddedsizeof);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.alloccount", prefix, i);
+ ret = dict_get_uint64 (dict, key, &alloccount);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"allocCount",
+ "%"PRIu64, alloccount);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.max_alloc", prefix, i);
+ ret = dict_get_int32 (dict, key, &maxalloc);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"maxAlloc",
+ "%d", maxalloc);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.pool-misses", prefix, i);
+ ret = dict_get_uint64 (dict, key, &alloccount);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"poolMisses",
+ "%"PRIu64, alloccount);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pool%d.max-stdalloc", prefix, i);
+ ret = dict_get_int32 (dict, key, &maxalloc);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"maxStdAlloc",
+ "%d", maxalloc);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+
+ /* </pool> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </mempool> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_mem (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index)
+{
+ int ret = -1;
+ int arena = 0;
+ int ordblks = 0;
+ int smblks = 0;
+ int hblks = 0;
+ int hblkhd = 0;
+ int usmblks = 0;
+ int fsmblks = 0;
+ int uordblks = 0;
+ int fordblks = 0;
+ int keepcost = 0;
+ char key[1024] = {0,};
+
+ /* <memStatus> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"memStatus");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* <mallinfo> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"mallinfo");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "brick%d.mallinfo.arena", brick_index);
+ ret = dict_get_int32 (dict, key, &arena);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"arena",
+ "%d", arena);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.ordblks", brick_index);
+ ret = dict_get_int32 (dict, key, &ordblks);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"ordblks",
+ "%d", ordblks);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.smblks", brick_index);
+ ret = dict_get_int32 (dict, key, &smblks);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"smblks",
+ "%d", smblks);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.hblks", brick_index);
+ ret = dict_get_int32 (dict, key, &hblks);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"hblks",
+ "%d", hblks);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.hblkhd", brick_index);
+ ret = dict_get_int32 (dict, key, &hblkhd);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"hblkhd",
+ "%d", hblkhd);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.usmblks", brick_index);
+ ret = dict_get_int32 (dict, key, &usmblks);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"usmblks",
+ "%d", usmblks);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.fsmblks", brick_index);
+ ret = dict_get_int32 (dict, key, &fsmblks);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"fsmblks",
+ "%d", fsmblks);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.uordblks", brick_index);
+ ret = dict_get_int32 (dict, key, &uordblks);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"uordblks",
+ "%d", uordblks);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.fordblks", brick_index);
+ ret = dict_get_int32 (dict, key, &fordblks);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"fordblks",
+ "%d", fordblks);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.mallinfo.keepcost", brick_index);
+ ret = dict_get_int32 (dict, key, &keepcost);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"keepcost",
+ "%d", keepcost);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </mallinfo> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d", brick_index);
+ ret = cli_xml_output_vol_status_mempool (writer, dict, key);
+ if (ret)
+ goto out;
+
+ /* </memStatus> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_clients (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index)
+{
+ int ret = -1;
+ int client_count = 0;
+ char *hostname = NULL;
+ uint64_t bytes_read = 0;
+ uint64_t bytes_write = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ /* <clientsStatus> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"clientsStatus");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "brick%d.clientcount", brick_index);
+ ret = dict_get_int32 (dict, key, &client_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"clientCount",
+ "%d", client_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < client_count; i++) {
+ /* <client> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"client");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.client%d.hostname",
+ brick_index, i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"hostname",
+ "%s", hostname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.client%d.bytesread",
+ brick_index, i);
+ ret = dict_get_uint64 (dict, key, &bytes_read);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"bytesRead",
+ "%"PRIu64, bytes_read);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.client%d.byteswrite",
+ brick_index, i);
+ ret = dict_get_uint64 (dict, key, &bytes_write);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"bytesWrite",
+ "%"PRIu64, bytes_write);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </client> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </clientsStatus> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_inode_entry (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+ int ret = -1;
+ char *gfid = NULL;
+ uint64_t nlookup = 0;
+ uint32_t ref = 0;
+ int ia_type = 0;
+ char key[1024] = {0,};
+
+ /* <inode> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"inode");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%s.gfid", prefix);
+ ret = dict_get_str (dict, key, &gfid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"gfid",
+ "%s", gfid);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key,0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.nlookup", prefix);
+ ret = dict_get_uint64 (dict, key, &nlookup);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"nLookup",
+ "%"PRIu64, nlookup);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key,0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.ref", prefix);
+ ret = dict_get_uint32 (dict, key, &ref);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"ref",
+ "%"PRIu32, ref);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key,0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.ia_type", prefix);
+ ret = dict_get_int32 (dict, key, &ia_type);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"iaType",
+ "%d", ia_type);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </inode> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_itable (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+ int ret = -1;
+ uint32_t active_size = 0;
+ uint32_t lru_size = 0;
+ uint32_t purge_size = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ snprintf (key, sizeof (key), "%s.active_size", prefix);
+ ret = dict_get_uint32 (dict, key, &active_size);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"activeSize",
+ "%"PRIu32, active_size);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ if (active_size != 0) {
+ /* <active> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"active");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < active_size; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.active%d", prefix, i);
+ ret = cli_xml_output_vol_status_inode_entry
+ (writer, dict, key);
+ if (ret)
+ goto out;
+ }
+ /* </active> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.lru_size", prefix);
+ ret = dict_get_uint32 (dict, key, &lru_size);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"lruSize",
+ "%"PRIu32, lru_size);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ if (lru_size != 0) {
+ /* <lru> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"lru");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < lru_size; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.lru%d", prefix, i);
+ ret = cli_xml_output_vol_status_inode_entry
+ (writer, dict, key);
+ if (ret)
+ goto out;
+ }
+ /* </lru> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.purge_size", prefix);
+ ret = dict_get_uint32 (dict, key, &purge_size);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"purgeSize",
+ "%"PRIu32, purge_size);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ if (purge_size != 0) {
+ /* <purge> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"purge");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < purge_size; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.purge%d", prefix, i);
+ ret = cli_xml_output_vol_status_inode_entry
+ (writer, dict, key);
+ if (ret)
+ goto out;
+ }
+ /* </purge> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_inode (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index)
+{
+ int ret = -1;
+ int conn_count = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ /* <inodeStatus> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"inodeStatus");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "brick%d.conncount", brick_index);
+ ret = dict_get_int32 (dict, key, &conn_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"connections",
+ "%d", conn_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < conn_count; i++) {
+ /* <connection> */
+ ret = xmlTextWriterStartElement (writer,
+ (xmlChar *)"connection");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.conn%d.itable",
+ brick_index, i);
+ ret = cli_xml_output_vol_status_itable (writer, dict, key);
+ if (ret)
+ goto out;
+
+ /* </connection> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </inodeStatus> */
+ ret= xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_fdtable (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+ int ret = -1;
+ int refcount = 0;
+ uint32_t maxfds = 0;
+ int firstfree = 0;
+ int openfds = 0;
+ int fd_pid = 0;
+ int fd_refcount = 0;
+ int fd_flags = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ /* <fdTable> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"fdTable");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%s.refcount", prefix);
+ ret = dict_get_int32 (dict, key, &refcount);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"refCount",
+ "%d", refcount);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.maxfds", prefix);
+ ret = dict_get_uint32 (dict, key, &maxfds);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"maxFds",
+ "%"PRIu32, maxfds);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.firstfree", prefix);
+ ret = dict_get_int32 (dict, key, &firstfree);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"firstFree",
+ "%d", firstfree);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.openfds", prefix);
+ ret = dict_get_int32 (dict, key, &openfds);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"openFds",
+ "%d", openfds);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < maxfds; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdentry%d.pid", prefix, i);
+ ret = dict_get_int32 (dict, key, &fd_pid);
+ if (ret)
+ continue;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdentry%d.refcount",
+ prefix, i);
+ ret = dict_get_int32 (dict, key, &fd_refcount);
+ if (ret)
+ continue;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdentry%d.flags", prefix, i);
+ ret = dict_get_int32 (dict, key, &fd_flags);
+ if (ret)
+ continue;
+
+ /* <fd> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"fd");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"entry",
+ "%d", i+1);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"pid",
+ "%d", fd_pid);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"refCount",
+ "%d", fd_refcount);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"flags",
+ "%d", fd_flags);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </fd> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </fdTable> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_fd (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index)
+{
+ int ret = -1;
+ int conn_count = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ /* <fdStatus> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"fdStatus");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "brick%d.conncount", brick_index);
+ ret = dict_get_int32 (dict, key, &conn_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"connections",
+ "%d", conn_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < conn_count; i++) {
+ /* <connection> */
+ ret = xmlTextWriterStartElement (writer,
+ (xmlChar *)"connection");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.conn%d.fdtable",
+ brick_index, i);
+ ret = cli_xml_output_vol_status_fdtable (writer, dict, key);
+ if (ret)
+ goto out;
+
+ /* </connection> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </fdStatus> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_callframe (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+ int ret = -1;
+ int ref_count = 0;
+ char *translator = NULL;
+ int complete = 0;
+ char *parent = NULL;
+ char *wind_from = NULL;
+ char *wind_to = NULL;
+ char *unwind_from = NULL;
+ char *unwind_to = NULL;
+ char key[1024] = {0,};
+
+ /* <callFrame> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"callFrame");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%s.refcount", prefix);
+ ret = dict_get_int32 (dict, key, &ref_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"refCount",
+ "%d", ref_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.translator", prefix);
+ ret = dict_get_str (dict, key, &translator);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"translator",
+ "%s", translator);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.complete", prefix);
+ ret = dict_get_int32 (dict, key, &complete);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"complete",
+ "%d", complete);
+ XML_RET_CHECK_AND_GOTO (ret ,out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.parent", prefix);
+ ret = dict_get_str (dict, key, &parent);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"parent",
+ "%s", parent);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.windfrom", prefix);
+ ret = dict_get_str (dict, key, &wind_from);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"windFrom",
+ "%s", wind_from);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.windto", prefix);
+ ret = dict_get_str (dict, key, &wind_to);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"windTo",
+ "%s", wind_to);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unwindfrom", prefix);
+ ret = dict_get_str (dict, key, &unwind_from);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"unwindFrom",
+ "%s", unwind_from);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unwindto", prefix);
+ ret = dict_get_str (dict, key, &unwind_to);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"unwindTo",
+ "%s", unwind_to);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </callFrame> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_callstack (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+ int ret = -1;
+ int uid = 0;
+ int gid = 0;
+ int pid = 0;
+ uint64_t unique = 0;
+ int frame_count = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ /* <callStack> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"callStack");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%s.uid", prefix);
+ ret = dict_get_int32 (dict, key, &uid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"uid",
+ "%d", uid);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.gid", prefix);
+ ret = dict_get_int32 (dict, key, &gid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"gid",
+ "%d", gid);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pid", prefix);
+ ret = dict_get_int32 (dict, key, &pid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"pid",
+ "%d", pid);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unique", prefix);
+ ret = dict_get_uint64 (dict, key, &unique);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"unique",
+ "%"PRIu64, unique);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.count", prefix);
+ ret = dict_get_int32 (dict, key, &frame_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"frameCount",
+ "%d", frame_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < frame_count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.frame%d", prefix, i);
+ ret = cli_xml_output_vol_status_callframe (writer, dict,
+ key);
+ if (ret)
+ goto out;
+ }
+
+ /* </callStack> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status_callpool (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index)
+{
+ int ret = -1;
+ int call_count = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ /* <callpoolStatus> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"callpoolStatus");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "brick%d.callpool.count", brick_index);
+ ret = dict_get_int32 (dict, key, &call_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"count",
+ "%d", call_count);
+
+ for (i = 0; i < call_count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.callpool.stack%d",
+ brick_index, i);
+ ret = cli_xml_output_vol_status_callstack (writer, dict,
+ key);
+ if (ret)
+ goto out;
+ }
+
+ /* </callpoolStatus> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_status (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlBufferPtr buf = NULL;
+ char *volname = NULL;
+ int brick_count = 0;
+ int brick_index_max = -1;
+ int other_count = 0;
+ int index_max = 0;
+ uint32_t cmd = GF_CLI_STATUS_NONE;
+ int online = 0;
+ gf_boolean_t node_present = _gf_true;
+ int i;
+
+ ret = cli_begin_xml_output (&writer, &buf);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ /* <volStatus> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"volStatus");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"volName",
+ "%s", volname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"nodeCount",
+ "%d", brick_count);
+ if (ret)
+ goto out;
+
+ ret = dict_get_uint32 (dict, "cmd", &cmd);
+ if (ret)
+ goto out;
+
+ ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32 (dict, "other-count", &other_count);
+ if (ret)
+ goto out;
+
+ index_max = brick_index_max + other_count;
+
+ for (i = 0; i <= index_max; i++) {
+ /* <node> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"node");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_xml_output_vol_status_common (writer, dict, i,
+ &online, &node_present);
+ if (ret) {
+ if (node_present)
+ goto out;
+ else
+ continue;
+ }
+
+ switch (cmd & GF_CLI_STATUS_MASK) {
+ case GF_CLI_STATUS_DETAIL:
+ ret = cli_xml_output_vol_status_detail (writer,
+ dict, i);
+ if (ret)
+ goto out;
+ break;
+
+ case GF_CLI_STATUS_MEM:
+ if (online) {
+ ret = cli_xml_output_vol_status_mem
+ (writer, dict, i);
+ if (ret)
+ goto out;
+ }
+ break;
+
+ case GF_CLI_STATUS_CLIENTS:
+ if (online) {
+ ret = cli_xml_output_vol_status_clients
+ (writer, dict, i);
+ if (ret)
+ goto out;
+ }
+ break;
+
+ case GF_CLI_STATUS_INODE:
+ if (online) {
+ ret = cli_xml_output_vol_status_inode
+ (writer, dict, i);
+ if (ret)
+ goto out;
+ }
+ break;
+
+ case GF_CLI_STATUS_FD:
+ if (online) {
+ ret = cli_xml_output_vol_status_fd
+ (writer, dict, i);
+ if (ret)
+ goto out;
+ }
+ break;
+
+ case GF_CLI_STATUS_CALLPOOL:
+ if (online) {
+ ret = cli_xml_output_vol_status_callpool
+ (writer, dict, i);
+ if (ret)
+ goto out;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+ /* </node> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </volStatus> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ ret = cli_end_xml_output (writer, buf);
+ if (ret)
+ goto out;
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_top_rw_perf (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index, int member_index)
+{
+ int ret = -1;
+ char *filename = NULL;
+ uint64_t throughput = 0;
+ long int time_sec = 0;
+ long int time_usec = 0;
+ char timestr[256] = {0,};
+ char key[1024] = {0,};
+
+ /* <file> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"file");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%d-filename-%d", brick_index,
+ member_index);
+ ret = dict_get_str (dict, key, &filename);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"filename",
+ "%s", filename);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-value-%d", brick_index, member_index);
+ ret = dict_get_uint64 (dict, key, &throughput);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"count",
+ "%"PRIu64, throughput);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-time-sec-%d", brick_index,
+ member_index);
+ ret = dict_get_int32 (dict, key, (int32_t *)&time_sec);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-time-usec-%d", brick_index,
+ member_index);
+ ret = dict_get_int32 (dict, key, (int32_t *)&time_usec);
+ if (ret)
+ goto out;
+
+ gf_time_fmt (timestr, sizeof timestr, time_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, time_usec);
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"time",
+ "%s", timestr);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </file> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_top_other (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index, int member_index)
+{
+ int ret = -1;
+ char *filename = NULL;
+ uint64_t count = 0;
+ char key[1024] = {0,};
+
+ /* <file> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"file");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%d-filename-%d", brick_index,
+ member_index);
+ ret = dict_get_str (dict, key, &filename);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"filename",
+ "%s", filename);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-value-%d", brick_index, member_index);
+ ret = dict_get_uint64 (dict, key, &count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"count",
+ "%"PRIu64, count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </file> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlBufferPtr buf = NULL;
+ int brick_count = 0;
+ int top_op = GF_CLI_TOP_NONE;
+ char *brick_name = NULL;
+ int members = 0;
+ uint64_t current_open = 0;
+ uint64_t max_open = 0;
+ char *max_open_time = NULL;
+ double throughput = 0.0;
+ double time_taken = 0.0;
+ char key[1024] = {0,};
+ int i = 0;
+ int j = 0;
+
+ ret = cli_begin_xml_output (&writer, &buf);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ /* <volTop> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"volTop");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"brickCount",
+ "%d", brick_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = dict_get_int32 (dict, "1-top-op", &top_op);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"topOp",
+ "%d", top_op);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ while (i < brick_count) {
+ i++;
+
+ /* <brick> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"brick");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-brick", i);
+ ret = dict_get_str (dict, key, &brick_name);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"name",
+ "%s", brick_name);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key , sizeof (key), "%d-members", i);
+ ret = dict_get_int32 (dict, key, &members);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"members",
+ "%d", members);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ switch (top_op) {
+ case GF_CLI_TOP_OPEN:
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-current-open", i);
+ ret = dict_get_uint64 (dict, key, &current_open);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"currentOpen", "%"PRIu64,
+ current_open);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-max-open", i);
+ ret = dict_get_uint64 (dict, key, &max_open);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"maxOpen", "%"PRIu64,
+ max_open);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-max-openfd-time", i);
+ ret = dict_get_str (dict, key, &max_open_time);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"maxOpenTime", "%s",
+ max_open_time);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ case GF_CLI_TOP_READ:
+ case GF_CLI_TOP_WRITE:
+ case GF_CLI_TOP_OPENDIR:
+ case GF_CLI_TOP_READDIR:
+ if (!members)
+ continue;
+
+ break;
+
+ case GF_CLI_TOP_READ_PERF:
+ case GF_CLI_TOP_WRITE_PERF:
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-throughput", i);
+ ret = dict_get_double (dict, key, &throughput);
+ if (!ret) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-time", i);
+ ret = dict_get_double (dict, key, &time_taken);
+ }
+
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"throughput",
+ "%f", throughput);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"timeTaken",
+ "%f", time_taken);
+ }
+
+ if (!members)
+ continue;
+
+ break;
+
+ default:
+ ret = -1;
+ goto out;
+ }
+
+ for (j = 1; j <= members; j++) {
+ if (top_op == GF_CLI_TOP_READ_PERF ||
+ top_op == GF_CLI_TOP_WRITE_PERF) {
+ ret = cli_xml_output_vol_top_rw_perf
+ (writer, dict, i, j);
+ } else {
+ ret = cli_xml_output_vol_top_other
+ (writer, dict, i, j);
+ }
+ if (ret)
+ goto out;
+ }
+
+
+ /* </brick> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </volTop> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = cli_end_xml_output (writer, buf);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_profile_stats (xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index, int interval)
+{
+ int ret = -1;
+ uint64_t read_count = 0;
+ uint64_t write_count = 0;
+ uint64_t hits = 0;
+ double avg_latency = 0.0;
+ double max_latency = 0.0;
+ double min_latency = 0.0;
+ uint64_t duration = 0;
+ uint64_t total_read = 0;
+ uint64_t total_write = 0;
+ char key[1024] = {0};
+ int i = 0;
+
+ /* <cumulativeStats> || <intervalStats> */
+ if (interval == -1)
+ ret = xmlTextWriterStartElement (writer,
+ (xmlChar *)"cumulativeStats");
+ else
+ ret = xmlTextWriterStartElement (writer,
+ (xmlChar *)"intervalStats");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* <blockStats> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"blockStats");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < 32; i++) {
+ /* <block> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"block");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"size", "%"PRIu32, (1 << i));
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-read-%d", brick_index,
+ interval, (1 << i));
+ ret = dict_get_uint64 (dict, key, &read_count);
+ if (ret)
+ read_count = 0;
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"reads", "%"PRIu64, read_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-write-%d", brick_index,
+ interval, (1 << i));
+ ret = dict_get_uint64 (dict, key, &write_count);
+ if (ret)
+ write_count = 0;
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"writes", "%"PRIu64, write_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </block> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </blockStats> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* <fopStats> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"fopStats");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-%d-hits", brick_index,
+ interval, i);
+ ret = dict_get_uint64 (dict, key, &hits);
+ if (ret)
+ goto cont;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-%d-avglatency", brick_index,
+ interval, i);
+ ret = dict_get_double (dict, key, &avg_latency);
+ if (ret)
+ goto cont;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-%d-minlatency", brick_index,
+ interval, i);
+ ret = dict_get_double (dict, key, &min_latency);
+ if (ret)
+ goto cont;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-%d-maxlatency", brick_index,
+ interval, i);
+ ret = dict_get_double (dict, key, &max_latency);
+ if (ret)
+ goto cont;
+
+ /* <fop> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"fop");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"name","%s", gf_fop_list[i]);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"hits", "%"PRIu64, hits);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"avgLatency", "%f", avg_latency);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"minLatency", "%f", min_latency);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"maxLatency", "%f", max_latency);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </fop> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+cont:
+ hits = 0;
+ avg_latency = 0.0;
+ min_latency = 0.0;
+ max_latency = 0.0;
+ }
+
+ /* </fopStats> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-duration", brick_index, interval);
+ ret = dict_get_uint64 (dict, key, &duration);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"duration",
+ "%"PRIu64, duration);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-total-read", brick_index, interval);
+ ret = dict_get_uint64 (dict, key, &total_read);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"totalRead",
+ "%"PRIu64, total_read);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-total-write", brick_index, interval);
+ ret = dict_get_uint64 (dict, key, &total_write);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"totalWrite",
+ "%"PRIu64, total_write);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </cumulativeStats> || </intervalStats> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlBufferPtr buf = NULL;
+ char *volname = NULL;
+ int op = GF_CLI_STATS_NONE;
+ int brick_count = 0;
+ char *brick_name = NULL;
+ int interval = 0;
+ char key[1024] = {0,};
+ int i = 0;
+
+ ret = cli_begin_xml_output (&writer, &buf);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ /* <volProfile> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"volProfile");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"volname",
+ "%s", volname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = dict_get_int32 (dict, "op", &op);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"profileOp",
+ "%d", op);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ if (op != GF_CLI_STATS_INFO)
+ goto cont;
+
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"brickCount",
+ "%d", brick_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ while (i < brick_count) {
+ i++;
+
+ /* <brick> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"brick");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%d-brick", i);
+ ret = dict_get_str (dict, key, &brick_name);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"brickName", "%s", brick_name);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%d-cumulative", i);
+ ret = dict_get_int32 (dict, key, &interval);
+ if (ret == 0) {
+ ret = cli_xml_output_vol_profile_stats
+ (writer, dict, i, interval);
+ if (ret)
+ goto out;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-interval", i);
+ ret = dict_get_int32 (dict, key, &interval);
+ if (ret == 0) {
+ ret = cli_xml_output_vol_profile_stats
+ (writer, dict, i, interval);
+ if (ret)
+ goto out;
+ }
+
+ /* </brick> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+cont:
+ /* </volProfile> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_end_xml_output (writer, buf);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+
+}
+
+int
+cli_xml_output_vol_list (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlBufferPtr buf = NULL;
+ int count = 0;
+ char *volname = NULL;
+ char key[1024] = {0,};
+ int i = 0;
+
+ ret = cli_begin_xml_output (&writer, &buf);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ /* <volList> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"volList");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"count",
+ "%d", count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d", i);
+ ret = dict_get_str (dict, key, &volname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"volume",
+ "%s", volname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ /* </volList> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_end_xml_output (writer, buf);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_info_option (xmlTextWriterPtr writer, char *substr,
+ char *optstr, char *valstr)
+{
+ int ret = -1;
+ char *ptr1 = NULL;
+ char *ptr2 = NULL;
+
+ ptr1 = substr;
+ ptr2 = optstr;
+
+ while (ptr1) {
+ if (*ptr1 != *ptr2)
+ break;
+ ptr1++;
+ ptr2++;
+ if (!ptr1)
+ goto out;
+ if (!ptr2)
+ goto out;
+ }
+ if (*ptr2 == '\0')
+ goto out;
+
+ /* <option> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"option");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"name",
+ "%s", ptr2);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"value",
+ "%s", valstr);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </option> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_info_options (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+ int ret = -1;
+ int opt_count = 0;
+ data_pair_t *pairs = 0;
+ data_t *value = 0;
+ char *ptr = NULL;
+ char key[1024] = {0,};
+ int i = 0;
+
+ pairs = dict->members_list;
+ if (!pairs) {
+ ret = -1;
+ goto out;
+ }
+
+ snprintf (key, sizeof (key), "%s.opt_count", prefix);
+ ret = dict_get_int32 (dict, key, &opt_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"optCount",
+ "%d", opt_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* <options> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"options");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ while (i < opt_count) {
+ snprintf (key, sizeof (key), "%s.option.", prefix);
+ while (pairs) {
+ ptr = strstr (pairs->key, "option.");
+ if (ptr) {
+ value = pairs->value;
+ if (!value) {
+ ret = -1;
+ goto out;
+ }
+ ret = cli_xml_output_vol_info_option
+ (writer, key, pairs->key, value->data);
+ if (ret)
+ goto out;
+ }
+ pairs = pairs->next;
+ }
+ i++;
+ }
+ /* </options> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_info (cli_local_t *local, dict_t *dict)
+{
+ int ret = 0;
+ int count = 0;
+ char *volname = NULL;
+ char *volume_id = NULL;
+ int type = 0;
+ int status = 0;
+ int brick_count = 0;
+ int dist_count = 0;
+ int stripe_count = 0;
+ int replica_count = 0;
+ int transport = 0;
+ char *brick = NULL;
+ char key[1024] = {0,};
+ int i = 0;
+ int j = 1;
+
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret)
+ goto out;
+
+ for (i = 0; i < count; i++) {
+ /* <volume> */
+ ret = xmlTextWriterStartElement (local->writer,
+ (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.name", i);
+ ret = dict_get_str (dict, key, &volname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"name",
+ "%s", volname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.volume_id", i);
+ ret = dict_get_str (dict, key, &volume_id);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"id",
+ "%s", volume_id);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.type", i);
+ ret = dict_get_int32 (dict, key, &type);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"type",
+ "%d", type);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.status", i);
+ ret = dict_get_int32 (dict, key, &status);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"status",
+ "%d", status);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick_count", i);
+ ret = dict_get_int32 (dict, key, &brick_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"brickCount",
+ "%d", brick_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.dist_count", i);
+ ret = dict_get_int32 (dict, key, &dist_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"distCount",
+ "%d", dist_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.stripe_count", i);
+ ret = dict_get_int32 (dict, key, &stripe_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"stripeCount",
+ "%d", stripe_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.replica_count", i);
+ ret = dict_get_int32 (dict, key, &replica_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"replicaCount",
+ "%d", replica_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.transport", i);
+ ret = dict_get_int32 (dict, key, &transport);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"transport",
+ "%d", transport);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* <bricks> */
+ ret = xmlTextWriterStartElement (local->writer,
+ (xmlChar *)"bricks");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ while (j <= brick_count) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d", i, j);
+ ret = dict_get_str (dict, key, &brick);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement
+ (local->writer, (xmlChar *)"brick", "%s",
+ brick);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ j++;
+ }
+ /* </bricks> */
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d", i);
+ ret = cli_xml_output_vol_info_options (local->writer, dict,
+ key);
+ if (ret)
+ goto out;
+
+ /* </volume> */
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+ GF_FREE (local->get_vol.volname);
+ local->get_vol.volname = gf_strdup (volname);
+ local->vol_count += count;
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_info_begin (cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+
+ GF_ASSERT (local);
+
+ ret = cli_begin_xml_output (&(local->writer), &(local->buf));
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common (local->writer, op_ret, op_errno,
+ op_errstr);
+ if (ret)
+ goto out;
+
+ /* <volInfo> */
+ ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volInfo");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* <volumes> */
+ ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volumes");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* Init vol count */
+ local->vol_count = 0;
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_info_end (cli_local_t *local)
+{
+ int ret = -1;
+
+ GF_ASSERT (local);
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"count",
+ "%d", local->vol_count);
+
+ /* </volumes> */
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </volInfo> */
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_end_xml_output (local->writer, local->buf);
+
+out:
+ gf_log ("cli", GF_LOG_ERROR, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_vol_quota_limit_list (char *volname, char *limit_list,
+ int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlBufferPtr buf = NULL;
+ int64_t size = 0;
+ int64_t limit_value = 0;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ int len = 0;
+ char *size_str = NULL;
+ char path[PATH_MAX] = {0,};
+ char ret_str[1024] = {0,};
+ char value[1024] = {0,};
+ char mountdir[] = "/tmp/mountXXXXXX";
+ char abspath[PATH_MAX] = {0,};
+ runner_t runner = {0,};
+
+ GF_ASSERT (volname);
+ GF_ASSERT (limit_list);
+
+ ret = cli_begin_xml_output (&writer, &buf);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ /* <volQuota> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"volQuota");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ if (!limit_list)
+ goto cont;
+
+ len = strlen (limit_list);
+ if (len == 0)
+ goto cont;
+
+ if (mkdtemp (mountdir) == NULL) {
+ gf_log ("cli", GF_LOG_ERROR, "failed to create a temporary"
+ " mount directory");
+ ret = -1;
+ goto out;
+ }
+
+ ret = runcmd (SBIN_DIR"/glusterfs", "-s", "localhost",
+ "--volfile-id", volname, "-l",
+ DEFAULT_LOG_FILE_DIRECTORY"/quota-list-xml.log",
+ mountdir, NULL);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "failed to mount glusterfs client");
+ ret = -1;
+ goto rm_dir;
+ }
+
+ while (i < len) {
+ j = 0;
+ k = 0;
+ size = 0;
+
+ while (limit_list[i] != ':')
+ path[k++] = limit_list[i++];
+ path[k] = '\0';
+
+ i++;
+
+ while (limit_list[i] != ',' && limit_list[i] != '\0')
+ value[j++] = limit_list[i++];
+ i++;
+
+ snprintf (abspath, sizeof (abspath), "%s/%s", mountdir, path);
+ ret = sys_lgetxattr (abspath, "trusted.limit.list",
+ (void *)ret_str, 4096);
+ if (ret >= 0) {
+ sscanf (ret_str, "%"SCNd64",%"SCNd64, &size,
+ &limit_value);
+ size_str = gf_uint64_2human_readable ((uint64_t)size);
+ }
+
+ /* <quota> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"quota");
+ XML_RET_CHECK_AND_GOTO (ret, unmount);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"path", "%s", path);
+ XML_RET_CHECK_AND_GOTO (ret, unmount);
+
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"limit", "%s", value);
+ XML_RET_CHECK_AND_GOTO (ret, unmount);
+
+ if (size_str) {
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"size", "%s", size_str);
+ XML_RET_CHECK_AND_GOTO (ret, unmount);
+ GF_FREE (size_str);
+ } else {
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"size", "%"PRId64, size);
+ XML_RET_CHECK_AND_GOTO (ret, unmount);
+ }
+
+ /* </quota> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, unmount);
+
+ }
+
+unmount:
+ runinit (&runner);
+ runner_add_args (&runner, "umount",
+#if GF_LINUX_HOST_OS
+ "-l",
+#endif
+ mountdir, NULL);
+ ret = runner_run_reuse (&runner);
+ if (ret)
+ runner_log (&runner, "cli", GF_LOG_WARNING, "error executing");
+ runner_end (&runner);
+
+rm_dir:
+ rmdir (mountdir);
+
+cont:
+ /* </volQuota> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_end_xml_output (writer, buf);
+
+out:
+ if (size_str)
+ GF_FREE (size_str);
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
+{
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlBufferPtr buf = NULL;
+ int count = 0;
+ char *uuid = NULL;
+ char *hostname = NULL;
+ int connected = 0;
+ int state_id = 0;
+ char *state_str = NULL;
+ int port = 0;
+ int i = 1;
+ char key[1024] = {0,};
+
+ ret = cli_begin_xml_output (&writer, &buf);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ /* <peerStatus> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"peerStatus");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ if (!dict)
+ goto cont;
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret)
+ goto out;
+
+ while (i <= count) {
+ /* <peer> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"peer");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.uuid", i);
+ ret = dict_get_str (dict, key, &uuid);
+ if (ret)
+ goto out;
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"uuid",
+ "%s", uuid);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.hostname", i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"hostname",
+ "%s", hostname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.connected", i);
+ ret = dict_get_int32 (dict, key, &connected);
+ if (ret)
+ goto out;
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"connected",
+ "%d", connected);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.stateId", i);
+ ret = dict_get_int32 (dict, key, &state_id);
+ if (ret)
+ goto out;
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"state",
+ "%d", state_id);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.state", i);
+ ret = dict_get_str (dict, key, &state_str);
+ if (ret)
+ goto out;
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"stateStr",
+ "%s", state_str);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.port", i);
+ ret = dict_get_int32 (dict, key, &port);
+ if (port != 0) {
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"port", "%d", port);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ port = 0;
+ }
+
+ /* </peer> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ i++;
+ }
+
+cont:
+ /* </peerStatus> */
+ ret = xmlTextWriterEndElement (writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_end_xml_output (writer, buf);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+#endif
diff --git a/cli/src/cli.c b/cli/src/cli.c
index 93fcd6204..62a3a94ea 100644
--- a/cli/src/cli.c
+++ b/cli/src/cli.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -74,27 +74,23 @@
#include "call-stub.h"
#include <fnmatch.h>
+#include "xdr-generic.h"
+
extern int connected;
/* using argp for command line parsing */
-static char gf_doc[] = "";
-
-static char argp_doc[] = "";
const char *argp_program_version = "" \
PACKAGE_NAME" "PACKAGE_VERSION" built on "__DATE__" "__TIME__ \
"\nRepository revision: " GLUSTERFS_REPOSITORY_REVISION "\n" \
- "Copyright (c) 2006-2010 Gluster Inc. " \
+ "Copyright (c) 2006-2011 Gluster Inc. " \
"<http://www.gluster.com>\n" \
"GlusterFS comes with ABSOLUTELY NO WARRANTY.\n" \
"You may redistribute copies of GlusterFS under the terms of "\
- "the GNU Affero General Public License.";
+ "the GNU General Public License.";
const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
-static struct argp_option gf_options[] = {
- {0, 0, 0, 0, "Basic options:"},
- {0, }
-};
+
struct rpc_clnt *global_rpc;
@@ -103,39 +99,6 @@ rpc_clnt_prog_t *cli_rpc_prog;
extern struct rpc_clnt_program cli_prog;
-static error_t
-parse_opts (int key, char *arg, struct argp_state *argp_state)
-{
- struct cli_state *state = NULL;
- char **argv = NULL;
-
- state = argp_state->input;
-
- switch (key) {
- case ARGP_KEY_ARG:
- if (!state->argc) {
- argv = calloc (state->argc + 2,
- sizeof (*state->argv));
- } else {
- argv = realloc (state->argv, (state->argc + 2) *
- sizeof (*state->argv));
- }
- if (!argv)
- return -1;
-
- state->argv = argv;
-
- argv[state->argc] = strdup (arg);
- if (!argv[state->argc])
- return -1;
- state->argc++;
- argv[state->argc] = NULL;
-
- break;
- }
-
- return 0;
-}
@@ -145,7 +108,6 @@ generate_uuid ()
char tmp_str[1024] = {0,};
char hostname[256] = {0,};
struct timeval tv = {0,};
- struct tm now = {0, };
char now_str[32];
if (gettimeofday (&tv, NULL) == -1) {
@@ -160,9 +122,8 @@ generate_uuid ()
strerror (errno));
}
- localtime_r (&tv.tv_sec, &now);
- strftime (now_str, 32, "%Y/%m/%d-%H:%M:%S", &now);
- snprintf (tmp_str, 1024, "%s-%d-%s:%"
+ gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T);
+ snprintf (tmp_str, sizeof tmp_str, "%s-%d-%s:%"
#ifdef GF_DARWIN_HOST_OS
PRId32,
#else
@@ -188,7 +149,7 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
ctx->page_size = 128 * GF_UNIT_KB;
- ctx->iobuf_pool = iobuf_pool_new (8 * GF_UNIT_MB, ctx->page_size);
+ ctx->iobuf_pool = iobuf_pool_new ();
if (!ctx->iobuf_pool)
return -1;
@@ -201,22 +162,33 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
if (!pool)
return -1;
- /* frame_mem_pool size 112 * 16k */
- pool->frame_mem_pool = mem_pool_new (call_frame_t, 16384);
-
+ /* frame_mem_pool size 112 * 64 */
+ pool->frame_mem_pool = mem_pool_new (call_frame_t, 32);
if (!pool->frame_mem_pool)
return -1;
- /* stack_mem_pool size 256 * 8k */
- pool->stack_mem_pool = mem_pool_new (call_stack_t, 8192);
+ /* stack_mem_pool size 256 * 128 */
+ pool->stack_mem_pool = mem_pool_new (call_stack_t, 16);
if (!pool->stack_mem_pool)
return -1;
- ctx->stub_mem_pool = mem_pool_new (call_stub_t, 1024);
+ ctx->stub_mem_pool = mem_pool_new (call_stub_t, 16);
if (!ctx->stub_mem_pool)
return -1;
+ ctx->dict_pool = mem_pool_new (dict_t, 32);
+ if (!ctx->dict_pool)
+ return -1;
+
+ ctx->dict_pair_pool = mem_pool_new (data_pair_t, 512);
+ if (!ctx->dict_pair_pool)
+ return -1;
+
+ ctx->dict_data_pool = mem_pool_new (data_t, 512);
+ if (!ctx->dict_data_pool)
+ return -1;
+
INIT_LIST_HEAD (&pool->all_frames);
LOCK_INIT (&pool->lock);
ctx->pool = pool;
@@ -236,27 +208,21 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
static int
-logging_init (glusterfs_ctx_t *ctx)
+logging_init (struct cli_state *state)
{
- int ret = 0;
- cmd_args_t *cmd_args = NULL;
-
- cmd_args = &ctx->cmd_args;
-
- /* CLI should not have something to DEBUG after the release,
- hence defaulting to INFO loglevel */
- cmd_args->log_level = GF_LOG_INFO;
+ char *log_file = state->log_file ? state->log_file :
+ DEFAULT_CLI_LOG_FILE_DIRECTORY "/cli.log";
- ret = gf_asprintf (&cmd_args->log_file,
- DEFAULT_CLI_LOG_FILE_DIRECTORY "/cli.log");
-
- if (gf_log_init (cmd_args->log_file) == -1) {
+ if (gf_log_init (log_file) == -1) {
fprintf (stderr, "ERROR: failed to open logfile %s\n",
- cmd_args->log_file);
+ log_file);
return -1;
}
- gf_log_set_loglevel (cmd_args->log_level);
+ /* CLI should not have something to DEBUG after the release,
+ hence defaulting to INFO loglevel */
+ gf_log_set_loglevel ((state->log_level == -1) ? GF_LOG_INFO :
+ state->log_level);
return 0;
}
@@ -265,41 +231,41 @@ int
cli_submit_request (void *req, call_frame_t *frame,
rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
- cli_serialize_t sfunc, xlator_t *this,
- fop_cbk_fn_t cbkfn)
+ xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
{
int ret = -1;
int count = 0;
- char start_ping = 0;
struct iovec iov = {0, };
struct iobuf *iobuf = NULL;
char new_iobref = 0;
+ ssize_t xdr_size = 0;
GF_ASSERT (this);
- iobuf = iobuf_get (this->ctx->iobuf_pool);
- if (!iobuf) {
- goto out;
- };
+ if (req) {
+ xdr_size = xdr_sizeof (xdrproc, req);
+ iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size);
+ if (!iobuf) {
+ goto out;
+ };
- if (!iobref) {
- iobref = iobref_new ();
if (!iobref) {
- goto out;
- }
+ iobref = iobref_new ();
+ if (!iobref) {
+ goto out;
+ }
- new_iobref = 1;
- }
+ new_iobref = 1;
+ }
- iobref_add (iobref, iobuf);
+ iobref_add (iobref, iobuf);
- iov.iov_base = iobuf->ptr;
- iov.iov_len = 128 * GF_UNIT_KB;
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_size (iobuf);
- /* Create the xdr payload */
- if (req && sfunc) {
- ret = sfunc (iov, req);
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic (iov, req, xdrproc);
if (ret == -1) {
goto out;
}
@@ -311,22 +277,13 @@ cli_submit_request (void *req, call_frame_t *frame,
ret = rpc_clnt_submit (global_rpc, prog, procnum, cbkfn,
&iov, count,
NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
-
- if (ret == 0) {
- pthread_mutex_lock (&global_rpc->conn.lock);
- {
- if (!global_rpc->conn.ping_started) {
- start_ping = 1;
- }
- }
- pthread_mutex_unlock (&global_rpc->conn.lock);
- }
-
ret = 0;
out:
if (new_iobref)
iobref_unref (iobref);
+ if (iobuf)
+ iobuf_unref (iobuf);
return ret;
}
@@ -352,6 +309,12 @@ cli_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
{
gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
connected = 0;
+ if (!global_state->prompt && global_state->await_connected) {
+ ret = 1;
+ cli_out ("Connection failed. Please check if gluster "
+ "daemon is operational.");
+ exit (ret);
+ }
break;
}
@@ -370,6 +333,16 @@ cli_opt_parse (char *opt, struct cli_state *state)
{
char *oarg;
+ if (strcmp (opt, "version") == 0) {
+ puts (argp_program_version);
+ exit (0);
+ }
+
+ if (strcmp (opt, "xml") == 0) {
+ state->mode |= GLUSTER_MODE_XML;
+ return 0;
+ }
+
oarg = strtail (opt, "mode=");
if (oarg) {
if (strcmp (oarg, "script") == 0) {
@@ -387,6 +360,20 @@ cli_opt_parse (char *opt, struct cli_state *state)
return 0;
}
+ oarg = strtail (opt, "log-file=");
+ if (oarg) {
+ state->log_file = oarg;
+ return 0;
+ }
+
+ oarg = strtail (opt, "log-level=");
+ if (oarg) {
+ state->log_level = glusterd_check_log_level(oarg);
+ if (state->log_level == -1)
+ return -1;
+ return 0;
+ }
+
return -1;
}
@@ -397,29 +384,26 @@ parse_cmdline (int argc, char *argv[], struct cli_state *state)
int i = 0;
int j = 0;
char *opt = NULL;
- struct argp argp = { 0,};
- argp.options = gf_options;
- argp.parser = parse_opts;
- argp.args_doc = argp_doc;
- argp.doc = gf_doc;
+ state->argc=argc-1;
+ state->argv=&argv[1];
- for (i = 0; i < argc; i++) {
- opt = strtail (argv[i], "--");
+ for (i = 0; i < state->argc; i++) {
+ opt = strtail (state->argv[i], "--");
if (opt) {
ret = cli_opt_parse (opt, state);
if (ret == -1) {
- break;
+ cli_out ("unrecognized option --%s", opt);
+ return ret;
}
- for (j = i; j < argc - 1; j++)
- argv[j] = argv[j + 1];
- argc--;
+ for (j = i; j < state->argc - 1; j++)
+ state->argv[j] = state->argv[j + 1];
+ state->argc--;
+ /* argv shifted, next check should be at i again */
+ i--;
}
}
- ret = argp_parse (&argp, argc, argv,
- ARGP_IN_ORDER, NULL, state);
-
return ret;
}
@@ -445,6 +429,7 @@ cli_state_init (struct cli_state *state)
state->remote_host = "localhost";
+ state->log_level = -1;
tree = &state->tree;
tree->state = state;
@@ -463,12 +448,36 @@ cli_usage_out (const char *usage)
if (!usage || usage[0] == '\0')
return -1;
- cli_out ("Usage: %s", usage);
+ cli_err ("Usage: %s", usage);
return 0;
}
int
-cli_out (const char *fmt, ...)
+_cli_err (const char *fmt, ...)
+{
+ struct cli_state *state = NULL;
+ va_list ap;
+ int ret = 0;
+
+ state = global_state;
+
+ va_start (ap, fmt);
+
+#ifdef HAVE_READLINE
+ if (state->rl_enabled && !state->rl_processing)
+ return cli_rl_err(state, fmt, ap);
+#endif
+
+ ret = vfprintf (stderr, fmt, ap);
+ fprintf (stderr, "\n");
+ va_end (ap);
+
+ return ret;
+}
+
+
+int
+_cli_out (const char *fmt, ...)
{
struct cli_state *state = NULL;
va_list ap;
@@ -521,7 +530,7 @@ cli_rpc_init (struct cli_state *state)
if (ret)
goto out;
- rpc = rpc_clnt_new (options, this->ctx, this->name);
+ rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
if (!rpc)
goto out;
@@ -556,30 +565,78 @@ void
cli_local_wipe (cli_local_t *local)
{
if (local) {
+ if (local->get_vol.volname)
+ GF_FREE (local->get_vol.volname);
+ if (local->dict)
+ dict_unref (local->dict);
GF_FREE (local);
}
return;
}
-void
-cli_path_strip_trailing_slashes (char *path)
+/* If the path exists use realpath(3) to handle extra slashes and to resolve
+ * symlinks else strip the extra slashes in the path and return */
+
+int
+cli_canonicalize_path (char *path)
{
- int i = 0;
- int len = 0;
+ struct stat sb = {0};
+ int ret = -1;
+ char *tmppath = NULL;
+ char *dir = NULL;
+ char *tmpstr = NULL;
+ int path_len = 0;
if (!path)
- return;
-
- len = strlen (path);
- for (i = len - 1; i > 0 ; i--) {
- if (path[i] != '/')
- break;
+ return ret;
+ ret = stat (path, &sb);
+ if (ret == -1) {
+ /* Strip the extra slashes and return */
+ tmppath = gf_strdup (path);
+ if (tmppath == NULL) {
+ ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Out of memory.");
+ goto out;
+ }
+ bzero (path, strlen(path));
+ path[0] = '/';
+ dir = strtok_r(tmppath, "/", &tmpstr);
+ while (dir) {
+ strncpy ((path + path_len + 1), dir, strlen(dir));
+ path_len = strlen (path);
+ dir = strtok_r(NULL, "/", &tmpstr);
+ if (dir)
+ strncpy((path + path_len), "/", 1);
+ }
+ if (path_len == 0)
+ path[1] = '\0';
+ else
+ path[path_len] = '\0';
+ ret = 0;
+ goto out;
+ } else {
+ tmppath = gf_strdup(path);
+ if (tmppath == NULL) {
+ ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Out of memory.");
+ goto out;
+ }
+ if (realpath (tmppath, path) == NULL) {
+ cli_out ("Path manipulation failed: %s",
+ strerror(errno));
+ gf_log ("cli", GF_LOG_ERROR, "Path manipulation "
+ "failed: %s", strerror(errno));
+ ret = -1;
+ goto out;
+ }
+ ret = 0;
}
-
- if (i < (len - 1))
- path[i + 1] = '\0';
+out:
+ if (tmppath)
+ GF_FREE(tmppath);
+ return ret;
}
struct cli_state *global_state;
@@ -614,12 +671,7 @@ main (int argc, char *argv[])
if (ret)
goto out;
- if (geteuid ()) {
- printf ("Only super user can run this command\n");
- return EPERM;
- }
-
- ret = logging_init (ctx);
+ ret = logging_init (&state);
if (ret)
goto out;
@@ -646,3 +698,14 @@ out:
return ret;
}
+
+void
+cli_print_line (int len)
+{
+ GF_ASSERT (len > 0);
+
+ while (len--)
+ printf ("-");
+
+ printf ("\n");
+}
diff --git a/cli/src/cli.h b/cli/src/cli.h
index 70d6cfb27..03b51414d 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -29,11 +29,22 @@
#include "glusterfs.h"
#include "protocol-common.h"
+#if (HAVE_LIB_XML)
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#endif
+
#define DEFAULT_EVENT_POOL_SIZE 16384
#define CLI_GLUSTERD_PORT 24007
#define CLI_DEFAULT_CONN_TIMEOUT 120
#define CLI_DEFAULT_CMD_TIMEOUT 120
+#define CLI_TOP_CMD_TIMEOUT 600 //Longer timeout for volume top
#define DEFAULT_CLI_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+#define DEFAULT_VAR_RUN_DIRECTORY DATADIR "/run/gluster"
+#define CLI_VOL_STATUS_BRICK_LEN 55
+#define CLI_TAB_LENGTH 8
+#define CLI_BRICK_STATUS_LINE_LEN 78
enum argp_option_keys {
ARGP_DEBUG_KEY = 133,
@@ -42,7 +53,7 @@ enum argp_option_keys {
#define GLUSTER_MODE_SCRIPT (1 << 0)
#define GLUSTER_MODE_ERR_FATAL (1 << 1)
-
+#define GLUSTER_MODE_XML (1 << 2)
struct cli_state;
struct cli_cmd_word;
struct cli_cmd_tree;
@@ -105,51 +116,58 @@ struct cli_state {
char *remote_host;
int remote_port;
int mode;
+ int await_connected;
+
+ char *log_file;
+ gf_loglevel_t log_level;
};
struct cli_local {
- union {
- struct {
- dict_t *dict;
- } create_vol;
-
- struct {
- char *volname;
- int flags;
- } start_vol;
-
- struct {
- char *volname;
- int flags;
- } stop_vol;
-
- struct {
- char *volname;
- } delete_vol;
-
- struct {
- char *volname;
- int cmd;
- } defrag_vol;
-
- struct {
- char *volname;
- dict_t *dict;
- } replace_brick;
-
- struct {
- char *volname;
- int flags;
- } get_vol;
- } u;
+ struct {
+ char *volname;
+ int flags;
+ } get_vol;
+
+ dict_t *dict;
+ /* Marker for volume status all */
+ gf_boolean_t all;
+#if (HAVE_LIB_XML)
+ xmlTextWriterPtr writer;
+ xmlBufferPtr buf;
+ int vol_count;
+#endif
+};
+
+struct cli_volume_status {
+ int port;
+ int online;
+ uint64_t block_size;
+ uint64_t total_inodes;
+ uint64_t free_inodes;
+ char *brick;
+ char *pid_str;
+ char *free;
+ char *total;
+#ifdef GF_LINUX_HOST_OS
+ char *fs_name;
+ char *mount_options;
+ char *device;
+ char *inode_size;
+#endif
};
+typedef struct cli_volume_status cli_volume_status_t;
+
typedef struct cli_local cli_local_t;
typedef ssize_t (*cli_serialize_t) (struct iovec outmsg, void *args);
extern struct cli_state *global_state; /* use only in readline callback */
+typedef const char *(*cli_selector_t) (void *wcon);
+
+void *cli_getunamb (const char *tok, void **choices, cli_selector_t sel);
+
int cli_cmd_register (struct cli_cmd_tree *tree, struct cli_cmd *cmd);
int cli_cmds_register (struct cli_state *state);
@@ -160,16 +178,32 @@ int cli_cmd_process_line (struct cli_state *state, const char *line);
int cli_rl_enable (struct cli_state *state);
int cli_rl_out (struct cli_state *state, const char *fmt, va_list ap);
+int cli_rl_err (struct cli_state *state, const char *fmt, va_list ap);
int cli_usage_out (const char *usage);
-int cli_out (const char *fmt, ...);
+
+int _cli_out (const char *fmt, ...);
+int _cli_err (const char *fmt, ...);
+
+#define cli_out(fmt...) do { \
+ FMT_WARN (fmt); \
+ \
+ _cli_out(fmt); \
+ \
+ } while (0)
+
+#define cli_err(fmt...) do { \
+ FMT_WARN (fmt); \
+ \
+ _cli_err(fmt); \
+ \
+ } while (0)
int
cli_submit_request (void *req, call_frame_t *frame,
rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
- cli_serialize_t sfunc, xlator_t *this,
- fop_cbk_fn_t cbkfn);
+ xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
int32_t
cli_cmd_volume_create_parse (const char **words, int wordcount,
@@ -194,7 +228,7 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
int32_t
cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
- dict_t **options);
+ dict_t **options, int *question);
int32_t
cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
@@ -207,6 +241,13 @@ cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options);
int32_t
cli_cmd_log_filename_parse (const char **words, int wordcount, dict_t **options);
+int32_t
+cli_cmd_volume_statedump_options_parse (const char **words, int wordcount,
+ dict_t **options);
+int32_t
+cli_cmd_volume_clrlks_opts_parse (const char **words, int wordcount,
+ dict_t **options);
+
cli_local_t * cli_local_get ();
void
@@ -221,12 +262,84 @@ cli_cmd_broadcast_connected ();
int
cli_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
void *data);
-void
-cli_path_strip_trailing_slashes (char *path);
+
+int
+cli_canonicalize_path (char *path);
+
int32_t
cli_cmd_volume_profile_parse (const char **words, int wordcount,
dict_t **options);
int32_t
cli_cmd_volume_top_parse (const char **words, int wordcount,
dict_t **options);
+
+int32_t
+cli_cmd_log_level_parse (const char **words, int wordcount,
+ dict_t **options);
+
+int32_t
+cli_cmd_volume_status_parse (const char **words, int wordcount,
+ dict_t **options);
+
+int
+cli_cmd_volume_heal_options_parse (const char **words, int wordcount,
+ dict_t **options);
+
+int
+cli_print_brick_status (cli_volume_status_t *status);
+
+void
+cli_print_detailed_status (cli_volume_status_t *status);
+
+int
+cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status);
+
+void
+cli_print_line (int len);
+
+#if (HAVE_LIB_XML)
+int
+cli_xml_output_str (char *op, char *str, int op_ret, int op_errno,
+ char *op_errstr);
+
+int
+cli_xml_output_dict (char *op, dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
+
+int
+cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
+
+int
+cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
+
+int
+cli_xml_output_vol_status (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
+
+int
+cli_xml_output_vol_list (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
+
+int
+cli_xml_output_vol_info_begin (cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr);
+
+int
+cli_xml_output_vol_info_end (cli_local_t *local);
+
+int
+cli_xml_output_vol_info (cli_local_t *local, dict_t *dict);
+
+int
+cli_xml_output_vol_quota_limit_list (char *volname, char *limit_list,
+ int op_ret, int op_errno,
+ char *op_errstr);
+
+int
+cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
+#endif
+
#endif /* __CLI_H__ */
diff --git a/cli/src/input.c b/cli/src/input.c
index b9d1d24e6..a88d35874 100644
--- a/cli/src/input.c
+++ b/cli/src/input.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/cli/src/registry.c b/cli/src/registry.c
index 8fa116a48..fc3b2decd 100644
--- a/cli/src/registry.c
+++ b/cli/src/registry.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -260,29 +260,49 @@ err:
return NULL;
}
-
-struct cli_cmd_word *
-cli_cmd_nextword (struct cli_cmd_word *word, const char *token)
+void *
+cli_getunamb (const char *tok, void **choices, cli_selector_t sel)
{
- struct cli_cmd_word *next = NULL;
- struct cli_cmd_word **trav = NULL;
- int ret = 0;
+ void **wcon = NULL;
+ char *w = NULL;
+ unsigned mn = 0;
+ void *ret = NULL;
- if (!word->nextwords)
+ if (!choices || !tok || !*tok)
return NULL;
- for (trav = word->nextwords; (next = *trav); trav++) {
- if (next->match) {
-// ret = next->match ();
- } else {
- ret = strcmp (next->word, token);
- }
+ for (wcon = choices; *wcon; wcon++) {
+ w = strtail ((char *)sel (*wcon), tok);
+ if (!w)
+ /* no match */
+ continue;
+ if (!*w)
+ /* exact match */
+ return *wcon;
- if (ret == 0)
- break;
+ ret = *wcon;
+ mn++;
}
- return next;
+#ifdef FORCE_MATCH_EXACT
+ return NULL;
+#else
+ return (mn == 1) ? ret : NULL;
+#endif
+}
+
+static const char *
+sel_cmd_word (void *wcon)
+{
+ return ((struct cli_cmd_word *)wcon)->word;
+}
+
+struct cli_cmd_word *
+cli_cmd_nextword (struct cli_cmd_word *word, const char *token)
+{
+ return (struct cli_cmd_word *)cli_getunamb (token,
+ (void **)word->nextwords,
+ sel_cmd_word);
}
@@ -367,7 +387,7 @@ cli_cmd_register (struct cli_cmd_tree *tree, struct cli_cmd *cmd)
char **tokens = NULL;
int ret = 0;
- GF_ASSERT (cmd)
+ GF_ASSERT (cmd);
if (cmd->reg_cbk)
cmd->reg_cbk (cmd);
diff --git a/commit.sh b/commit.sh
deleted file mode 100755
index 9cc55c52e..000000000
--- a/commit.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-export EDITOR="emacs"
-git commit -a -e "$@"
diff --git a/configure.ac b/configure.ac
index 16a9e9b35..0b64774ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,23 +1,38 @@
-dnl Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+dnl Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+
dnl This file is part of GlusterFS.
dnl
dnl GlusterFS is free software; you can redistribute it and/or modify
-dnl it under the terms of the GNU Affero General Public License as published by
+dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 3 of the License, or
dnl (at your option) any later version.
dnl
dnl GlusterFS is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-dnl GNU Affero General Public License for more details.
+dnl GNU General Public License for more details.
dnl
-dnl You should have received a copy of the GNU Affero General Public License
+dnl You should have received a copy of the GNU General Public License
dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
-AC_INIT([glusterfs],[3.2git],[gluster-users@gluster.org])
+AC_INIT([glusterfs],[3.3git],[gluster-users@gluster.org],,[https://github.com/gluster/glusterfs.git])
AM_INIT_AUTOMAKE
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)])
+
+if make --help 2>&1 | grep -q no-print-directory; then
+ AM_MAKEFLAGS="$AM_MAKEFLAGS --no-print-directory";
+fi
+
+if make --help 2>&1 | grep -q quiet; then
+ AM_MAKEFLAGS="$AM_MAKEFLAGS --quiet"
+fi
+
+if libtool --help 2>&1 | grep -q quiet; then
+ AM_LIBTOOLFLAGS="--quiet";
+fi
+
AM_CONFIG_HEADER([config.h])
AC_CONFIG_FILES([Makefile
@@ -65,8 +80,8 @@ AC_CONFIG_FILES([Makefile
xlators/performance/symlink-cache/src/Makefile
xlators/performance/quick-read/Makefile
xlators/performance/quick-read/src/Makefile
- xlators/performance/stat-prefetch/Makefile
- xlators/performance/stat-prefetch/src/Makefile
+ xlators/performance/md-cache/Makefile
+ xlators/performance/md-cache/src/Makefile
xlators/debug/Makefile
xlators/debug/trace/Makefile
xlators/debug/trace/src/Makefile
@@ -87,14 +102,12 @@ AC_CONFIG_FILES([Makefile
xlators/features/Makefile
xlators/features/locks/Makefile
xlators/features/locks/src/Makefile
- xlators/features/trash/Makefile
- xlators/features/trash/src/Makefile
xlators/features/quota/Makefile
xlators/features/quota/src/Makefile
xlators/features/marker/Makefile
xlators/features/marker/src/Makefile
xlators/features/marker/utils/Makefile
- xlators/features/marker/utils/gsyncd
+ xlators/features/marker/utils/src/Makefile
xlators/features/marker/utils/syncdaemon/Makefile
xlators/features/read-only/Makefile
xlators/features/read-only/src/Makefile
@@ -102,14 +115,17 @@ AC_CONFIG_FILES([Makefile
xlators/features/mac-compat/src/Makefile
xlators/features/quiesce/Makefile
xlators/features/quiesce/src/Makefile
+ xlators/features/index/Makefile
+ xlators/features/index/src/Makefile
xlators/encryption/Makefile
xlators/encryption/rot-13/Makefile
xlators/encryption/rot-13/src/Makefile
+ xlators/system/Makefile
+ xlators/system/posix-acl/Makefile
+ xlators/system/posix-acl/src/Makefile
cli/Makefile
cli/src/Makefile
doc/Makefile
- doc/examples/Makefile
- doc/hacker-guide/Makefile
extras/Makefile
extras/init.d/Makefile
extras/init.d/glusterd.plist
@@ -117,9 +133,9 @@ AC_CONFIG_FILES([Makefile
extras/init.d/glusterd-Redhat
extras/init.d/glusterd-SuSE
extras/benchmarking/Makefile
+ extras/hook-scripts/Makefile
contrib/fuse-util/Makefile
- xlators/features/access-control/Makefile
- xlators/features/access-control/src/Makefile
+ contrib/uuid/uuid_types.h
xlators/nfs/Makefile
xlators/nfs/server/Makefile
xlators/nfs/server/src/Makefile
@@ -157,6 +173,22 @@ if test "x${LEX}" != "xflex" -a "x${FLEX}" != "xlex"; then
AC_MSG_ERROR([Flex or lex required to build glusterfs.])
fi
+dnl
+dnl Word sizes...
+dnl
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+SIZEOF_SHORT=$ac_cv_sizeof_short
+SIZEOF_INT=$ac_cv_sizeof_int
+SIZEOF_LONG=$ac_cv_sizeof_long
+SIZEOF_LONG_LONG=$ac_cv_sizeof_long_long
+AC_SUBST(SIZEOF_SHORT)
+AC_SUBST(SIZEOF_INT)
+AC_SUBST(SIZEOF_LONG)
+AC_SUBST(SIZEOF_LONG_LONG)
+
# YACC needs a check
AC_PROG_YACC
if test "x${YACC}" = "xbyacc" -o "x${YACC}" = "xyacc" -o "x${YACC}" = "x"; then
@@ -165,8 +197,10 @@ fi
AC_CHECK_TOOL([LD],[ld])
+AC_CHECK_LIB([crypto], [MD5], , AC_MSG_ERROR([OpenSSL crypto library is required to build glusterfs]))
+
AC_CHECK_LIB([pthread], [pthread_mutex_init], , AC_MSG_ERROR([Posix threads library is required to build glusterfs]))
-
+
AC_CHECK_FUNC([dlopen], [has_dlopen=yes], AC_CHECK_LIB([dl], [dlopen], , AC_MSG_ERROR([Dynamic linking library required to build glusterfs])))
@@ -174,6 +208,8 @@ AC_CHECK_HEADERS([sys/xattr.h])
AC_CHECK_HEADERS([sys/extattr.h])
+AC_CHECK_HEADERS([openssl/md5.h])
+
case $host_os in
darwin*)
if ! test "`/usr/bin/sw_vers | grep ProductVersion: | cut -f 2 | cut -d. -f2`" -ge 5; then
@@ -291,6 +327,9 @@ case $host_os in
linux*)
#do nothing
;;
+ netbsd*)
+#do nothing
+ ;;
*)
#disabling geo replication for non-linux platforms
enable_georeplication=no
@@ -322,6 +361,15 @@ AC_SUBST(SYNCDAEMON_COMPILE)
AC_SUBST(SYNCDAEMON_SUBDIR)
# end SYNCDAEMON section
+#check if libxml is present if so enable HAVE_LIB_XML
+echo -n "checking if libxml2 is present... "
+
+PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.6.19],
+ [echo "yes (features requiring libxml2 enabled)" AC_DEFINE(HAVE_LIB_XML, 1, [define if libxml2 is present])],
+ [echo "no"] )
+
+AC_SUBST(LIBXML2_CFLAGS)
+AC_SUBST(LIBXML2_LIBS)
dnl FreeBSD > 5 has execinfo as a Ported library for giving a workaround
dnl solution to GCC backtrace functionality
@@ -346,6 +394,16 @@ dnl Linux, Solaris, Cygwin
AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec])
dnl FreeBSD, NetBSD
AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec])
+case $host_os in
+ *netbsd*)
+ CFLAGS=-D_INCOMPLETE_XOPEN_C063
+ ;;
+esac
+AC_CHECK_FUNC([linkat], [have_linkat=yes])
+if test "x${have_linkat}" = "xyes"; then
+ AC_DEFINE(HAVE_LINKAT, 1, [define if found linkat])
+fi
+AC_SUBST(HAVE_LINKAT)
dnl Check for argp
AC_CHECK_HEADER([argp.h], AC_DEFINE(HAVE_ARGP, 1, [have argp]))
@@ -394,7 +452,6 @@ AC_SUBST(GF_DISTRIBUTION)
GF_HOST_OS=""
GF_LDFLAGS="-rdynamic"
-GF_FUSE_LDADD="-lfuse"
case $host_os in
linux*)
dnl GF_LINUX_HOST_OS=1
@@ -414,20 +471,38 @@ case $host_os in
BUILD_FUSE_CLIENT=no
FUSE_CLIENT_SUBDIR=""
;;
+ *netbsd*)
+ GF_HOST_OS="GF_BSD_HOST_OS"
+ GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D_INCOMPLETE_XOPEN_C063"
+ GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
+ GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
+ GF_GLUSTERFS_CFLAGS="${GF_CFLAGS}"
+ GF_LDADD="${ARGP_STANDALONE_LDADD}"
+ if test "x$ac_cv_header_execinfo_h" = "xyes"; then
+ GF_GLUSTERFS_LDFLAGS="-lexecinfo"
+ fi
+ GF_FUSE_LDADD="-lperfuse"
+ BUILD_FUSE_CLIENT=yes
+ LEXLIB=""
+ ;;
*bsd*)
GF_HOST_OS="GF_BSD_HOST_OS"
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -O0"
+ GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
+ GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
GF_GLUSTERFS_CFLAGS="${GF_CFLAGS}"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
if test "x$ac_cv_header_execinfo_h" = "xyes"; then
GF_GLUSTERFS_LDFLAGS="-lexecinfo"
- fi
+ fi
BUILD_FUSE_CLIENT=no
;;
darwin*)
GF_HOST_OS="GF_DARWIN_HOST_OS"
LIBTOOL=glibtool
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D__DARWIN_64_BIT_INO_T -bundle -undefined suppress -flat_namespace -D_XOPEN_SOURCE -O0"
+ GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
+ GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
GF_GLUSTERFS_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D__DARWIN_64_BIT_INO_T -undefined suppress -flat_namespace -O0"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
GF_FUSE_CFLAGS="-I\$(CONTRIBDIR)/macfuse"
@@ -444,14 +519,27 @@ if test "x$RLLIBS" != "x"; then
BUILD_READLINE=yes
fi
+BUILD_LIBAIO=no
+AC_CHECK_LIB([aio],[io_setup],[LIBAIO="-laio"])
+
+if test "x$LIBAIO" != "x"; then
+ AC_DEFINE(HAVE_LIBAIO, 1, [libaio based POSIX enabled])
+ BUILD_LIBAIO=yes
+fi
+
+
AC_SUBST(GF_HOST_OS)
AC_SUBST(GF_GLUSTERFS_LDFLAGS)
AC_SUBST(GF_GLUSTERFS_CFLAGS)
AC_SUBST(GF_CFLAGS)
AC_SUBST(GF_LDFLAGS)
AC_SUBST(GF_LDADD)
+AC_SUBST(GF_FUSE_LDADD)
AC_SUBST(GF_FUSE_CFLAGS)
AC_SUBST(RLLIBS)
+AC_SUBST(LIBAIO)
+AC_SUBST(AM_MAKEFLAGS)
+AC_SUBST(AM_LIBTOOLFLAGS)
CONTRIBDIR='$(top_srcdir)/contrib'
AC_SUBST(CONTRIBDIR)
@@ -459,7 +547,9 @@ AC_SUBST(CONTRIBDIR)
INCLUDES='-I$(top_srcdir)/libglusterfs/src -I$(CONTRIBDIR)/uuid'
AC_SUBST(INCLUDES)
-AM_CONDITIONAL([GF_DARWIN_HOST_OS], test "${GF_HOST_OS}" = "GF_DARWIN_HOST_OS")
+AM_CONDITIONAL([GF_DARWIN_HOST_OS], test "${GF_HOST_OS}" = "GF_DARWIN_HOST_OS")
+
+AM_CONDITIONAL([GF_INSTALL_VAR_LIB_GLUSTERD], test ! -d ${localstatedir}/lib/glusterd && test -d ${sysconfdir}/glusterd )
AC_OUTPUT
@@ -473,4 +563,5 @@ echo "argp-standalone : $BUILD_ARGP_STANDALONE"
echo "fusermount : $BUILD_FUSERMOUNT"
echo "readline : $BUILD_READLINE"
echo "georeplication : $BUILD_SYNCDAEMON"
+echo "Linux-AIO : $BUILD_LIBAIO"
echo
diff --git a/contrib/aclocal/mkdirp.m4 b/contrib/aclocal/mkdirp.m4
new file mode 100644
index 000000000..d2f7edd5c
--- /dev/null
+++ b/contrib/aclocal/mkdirp.m4
@@ -0,0 +1,146 @@
+# Excerpt from autoconf/autoconf/programs.m4
+# This file is part of Autoconf. -*- Autoconf -*-
+# Checking for programs.
+
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+
+# This file is part of Autoconf. This program is free
+# software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# Under Section 7 of GPL version 3, you are granted additional
+# permissions described in the Autoconf Configure Script Exception,
+# version 3.0, as published by the Free Software Foundation.
+#
+# You should have received a copy of the GNU General Public License
+# and a copy of the Autoconf Configure Script Exception along with
+# this program; see the files COPYINGv3 and COPYING.EXCEPTION
+# respectively. If not, see <http://www.gnu.org/licenses/>.
+
+# Written by David MacKenzie, with help from
+# Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
+# Roland McGrath, Noah Friedman, david d zuhn, and many others.
+
+# AC_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is known to be thread-safe, and fall back to
+# install-sh -d otherwise.
+#
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake. There are at least two reasons why we must not
+# use `-m 0755':
+# - it causes special bits like SGID to be ignored,
+# - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are vulnerable to race conditions:
+# if a parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out. Consequently we
+# restrict ourselves to known race-free implementations.
+#
+# Automake used to define mkdir_p as `mkdir -p .', in order to
+# allow $(mkdir_p) to be used without argument. As in
+# $(mkdir_p) $(somedir)
+# where $(somedir) is conditionally defined. However we don't do
+# that for MKDIR_P.
+# 1. before we restricted the check to GNU mkdir, `mkdir -p .' was
+# reported to fail in read-only directories. The system where this
+# happened has been forgotten.
+# 2. in practice we call $(MKDIR_P) on directories such as
+# $(MKDIR_P) "$(DESTDIR)$(somedir)"
+# and we don't want to create $(DESTDIR) if $(somedir) is empty.
+# To support the latter case, we have to write
+# test -z "$(somedir)" || $(MKDIR_P) "$(DESTDIR)$(somedir)"
+# so $(MKDIR_P) always has an argument.
+# We will have better chances of detecting a missing test if
+# $(MKDIR_P) complains about missing arguments.
+# 3. $(MKDIR_P) is named after `mkdir -p' and we don't expect this
+# to accept no argument.
+# 4. having something like `mkdir .' in the output is unsightly.
+#
+# On NextStep and OpenStep, the `mkdir' command does not
+# recognize any option. It will interpret all options as
+# directories to create.
+AN_MAKEVAR([MKDIR_P], [AC_PROG_MKDIR_P])
+AC_DEFUN_ONCE([AC_PROG_MKDIR_P],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+
+AC_MSG_CHECKING([for a thread-safe mkdir -p])
+if test -z "$MKDIR_P"; then
+ AC_CACHE_VAL([ac_cv_path_mkdir],
+ [_AS_PATH_WALK([$PATH$PATH_SEPARATOR/opt/sfw/bin],
+ [for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ AS_EXECUTABLE_P(["$as_dir/$ac_prog$ac_exec_ext"]) || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done])])
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+dnl status.m4 does special magic for MKDIR_P instead of AC_SUBST,
+dnl to get relative names right. However, also AC_SUBST here so
+dnl that Automake versions before 1.10 will pick it up (they do not
+dnl trace AC_SUBST_TRACE).
+dnl FIXME: Remove this once we drop support for Automake < 1.10.
+AC_SUBST([MKDIR_P])dnl
+AC_MSG_RESULT([$MKDIR_P])
+])# AC_PROG_MKDIR_P
+
+
+# From automake/m4/mkdirp.m4
+## -*- Autoconf -*-
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
diff --git a/contrib/aclocal/python.m4 b/contrib/aclocal/python.m4
new file mode 100644
index 000000000..a39a90090
--- /dev/null
+++ b/contrib/aclocal/python.m4
@@ -0,0 +1,209 @@
+## ------------------------ -*- Autoconf -*-
+## Python file handling
+## From Andrew Dalke
+## Updated by James Henstridge
+## ------------------------
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# ---------------------------------------------------------------------------
+# Adds support for distributing Python modules and packages. To
+# install modules, copy them to $(pythondir), using the python_PYTHON
+# automake variable. To install a package with the same name as the
+# automake package, install to $(pkgpythondir), or use the
+# pkgpython_PYTHON automake variable.
+#
+# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
+# locations to install python extension modules (shared libraries).
+# Another macro is required to find the appropriate flags to compile
+# extension modules.
+#
+# If your package is configured with a different prefix to python,
+# users will have to add the install directory to the PYTHONPATH
+# environment variable, or create a .pth file (see the python
+# documentation for details).
+#
+# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
+# cause an error if the version of python installed on the system
+# doesn't meet the requirement. MINIMUM-VERSION should consist of
+# numbers and dots only.
+AC_DEFUN([AM_PATH_PYTHON],
+ [
+ dnl Find a Python interpreter. Python versions prior to 2.0 are not
+ dnl supported. (2.0 was released on October 16, 2000).
+ m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
+ [python python2 python3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 dnl
+python2.1 python2.0])
+
+ m4_if([$1],[],[
+ dnl No version check is needed.
+ # Find any Python interpreter.
+ if test -z "$PYTHON"; then
+ AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
+ fi
+ am_display_PYTHON=python
+ ], [
+ dnl A version check is needed.
+ if test -n "$PYTHON"; then
+ # If the user set $PYTHON, use it and don't search something else.
+ AC_MSG_CHECKING([whether $PYTHON version >= $1])
+ AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
+ [AC_MSG_RESULT(yes)],
+ [AC_MSG_ERROR(too old)])
+ am_display_PYTHON=$PYTHON
+ else
+ # Otherwise, try each interpreter until we find one that satisfies
+ # VERSION.
+ AC_CACHE_CHECK([for a Python interpreter with version >= $1],
+ [am_cv_pathless_PYTHON],[
+ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
+ test "$am_cv_pathless_PYTHON" = none && break
+ AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
+ done])
+ # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
+ if test "$am_cv_pathless_PYTHON" = none; then
+ PYTHON=:
+ else
+ AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
+ fi
+ am_display_PYTHON=$am_cv_pathless_PYTHON
+ fi
+ ])
+
+ if test "$PYTHON" = :; then
+ dnl Run any user-specified action, or abort.
+ m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
+ else
+
+ dnl Query Python for its version number. Getting [:3] seems to be
+ dnl the best way to do this; it's what "site.py" does in the standard
+ dnl library.
+
+ AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
+ [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
+ AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
+
+ dnl Use the values of $prefix and $exec_prefix for the corresponding
+ dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made
+ dnl distinct variables so they can be overridden if need be. However,
+ dnl general consensus is that you shouldn't need this ability.
+
+ AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
+ AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
+
+ dnl At times (like when building shared libraries) you may want
+ dnl to know which OS platform Python thinks this is.
+
+ AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
+ [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
+ AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
+
+
+ dnl Set up 4 directories:
+
+ dnl pythondir -- where to install python scripts. This is the
+ dnl site-packages directory, not the python standard library
+ dnl directory like in previous automake betas. This behavior
+ dnl is more consistent with lispdir.m4 for example.
+ dnl Query distutils for this directory. distutils does not exist in
+ dnl Python 1.5, so we fall back to the hardcoded directory if it
+ dnl doesn't work.
+ AC_CACHE_CHECK([for $am_display_PYTHON script directory],
+ [am_cv_python_pythondir],
+ [if test "x$prefix" = xNONE
+ then
+ am_py_prefix=$ac_default_prefix
+ else
+ am_py_prefix=$prefix
+ fi
+ am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null ||
+ echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"`
+ case $am_cv_python_pythondir in
+ $am_py_prefix*)
+ am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
+ am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
+ ;;
+ *)
+ case $am_py_prefix in
+ /usr|/System*) ;;
+ *)
+ am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
+ ;;
+ esac
+ ;;
+ esac
+ ])
+ AC_SUBST([pythondir], [$am_cv_python_pythondir])
+
+ dnl pkgpythondir -- $PACKAGE directory under pythondir. Was
+ dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is
+ dnl more consistent with the rest of automake.
+
+ AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])
+
+ dnl pyexecdir -- directory for installing python extension modules
+ dnl (shared libraries)
+ dnl Query distutils for this directory. distutils does not exist in
+ dnl Python 1.5, so we fall back to the hardcoded directory if it
+ dnl doesn't work.
+ AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
+ [am_cv_python_pyexecdir],
+ [if test "x$exec_prefix" = xNONE
+ then
+ am_py_exec_prefix=$am_py_prefix
+ else
+ am_py_exec_prefix=$exec_prefix
+ fi
+ am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null ||
+ echo "$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages"`
+ case $am_cv_python_pyexecdir in
+ $am_py_exec_prefix*)
+ am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
+ am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
+ ;;
+ *)
+ case $am_py_exec_prefix in
+ /usr|/System*) ;;
+ *)
+ am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
+ ;;
+ esac
+ ;;
+ esac
+ ])
+ AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])
+
+ dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
+
+ AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])
+
+ dnl Run any user-specified action.
+ $2
+ fi
+
+])
+
+
+# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+# ---------------------------------------------------------------------------
+# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
+# Run ACTION-IF-FALSE otherwise.
+# This test uses sys.hexversion instead of the string equivalent (first
+# word of sys.version), in order to cope with versions such as 2.2c1.
+# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
+AC_DEFUN([AM_PYTHON_CHECK_VERSION],
+ [prog="import sys
+# split strings by '.' and convert to numeric. Append some zeros
+# because we need at least 4 digits for the hex conversion.
+# map returns an iterator in Python 3.0 and a list in 2.x
+minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
+minverhex = 0
+# xrange is not present in Python 3.0 and range returns an iterator
+for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
+sys.exit(sys.hexversion < minverhex)"
+ AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
diff --git a/contrib/apple/daemon.c b/contrib/apple/daemon.c
deleted file mode 100644
index 9389201a1..000000000
--- a/contrib/apple/daemon.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
-
- Based on http://www.opensource.apple.com/source/Libc/Libc-583/gen/FreeBSD/daemon.c
- */
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <paths.h>
-#include <signal.h>
-#include <unistd.h>
-
-int
-os_daemon(nochdir, noclose)
- int nochdir, noclose;
-{
- struct sigaction osa, sa;
- int fd;
- pid_t newgrp;
- int oerrno;
- int osa_ok;
-
- /* A SIGHUP may be thrown when the parent exits below. */
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = SIG_IGN;
- sa.sa_flags = 0;
- osa_ok = sigaction(SIGHUP, &sa, &osa);
-
- switch (fork()) {
- case -1:
- return (-1);
- case 0:
- break;
- default:
- _exit(0);
- }
-
- newgrp = setsid();
- oerrno = errno;
- if (osa_ok != -1)
- sigaction(SIGHUP, &osa, NULL);
-
- if (newgrp == -1) {
- errno = oerrno;
- return (-1);
- }
-
- if (!nochdir)
- (void)chdir("/");
-
- if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
- (void)dup2(fd, STDIN_FILENO);
- (void)dup2(fd, STDOUT_FILENO);
- (void)dup2(fd, STDERR_FILENO);
- if (fd > 2)
- (void)close(fd);
- }
- return (0);
-}
diff --git a/contrib/fuse-include/fuse-mount.h b/contrib/fuse-include/fuse-mount.h
index ca571ce5e..7a3756d92 100644
--- a/contrib/fuse-include/fuse-mount.h
+++ b/contrib/fuse-include/fuse-mount.h
@@ -8,4 +8,5 @@
*/
void gf_fuse_unmount (const char *mountpoint, int fd);
-int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param);
+int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
+ pid_t *mtab_pid, int status_fd);
diff --git a/contrib/fuse-lib/misc.c b/contrib/fuse-lib/misc.c
index 28a9284bf..0c41b1a19 100644
--- a/contrib/fuse-lib/misc.c
+++ b/contrib/fuse-lib/misc.c
@@ -50,5 +50,5 @@ convert_fuse_file_lock (struct fuse_file_lock *fl, struct gf_flock *flock,
else
flock->l_len = fl->end - fl->start + 1;
flock->l_pid = fl->pid;
- flock->l_owner = lk_owner;
+ set_lk_owner_from_uint64 (&flock->l_owner, lk_owner);
}
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c
index 47592a62d..759014fe2 100644
--- a/contrib/fuse-lib/mount.c
+++ b/contrib/fuse-lib/mount.c
@@ -20,14 +20,27 @@
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
+#include <signal.h>
+#ifndef __NetBSD__
#include <mntent.h>
+#endif /* __NetBSD__ */
#include <sys/stat.h>
#include <sys/poll.h>
-#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <sys/mount.h>
+#ifdef __NetBSD__
+#include <perfuse.h>
+#define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)
+#endif
+
+#ifdef linux
+#define _PATH_MOUNT "/bin/mount"
+#else /* NetBSD, MacOS X */
+#define _PATH_MOUNT "/sbin/mount"
+#endif
+
#ifdef FUSE_UTIL
#define MALLOC(size) malloc (size)
#define FREE(ptr) free (ptr)
@@ -42,7 +55,7 @@
#else
#define FUSERMOUNT_PROG "fusermount"
#endif
-#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
+#define FUSE_DEVFD_ENV "_FUSE_DEVFD"
#define GFFUSE_LOGERR(...) \
gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)
@@ -58,6 +71,7 @@
* - there are some other minor things
*/
+#ifndef __NetBSD__
static int
mtab_needs_update (const char *mnt)
{
@@ -91,6 +105,9 @@ mtab_needs_update (const char *mnt)
return 1;
}
+#else /* __NetBSD__ */
+#define mtab_needs_update(x) 1
+#endif /* __NetBSD__ */
#ifndef FUSE_UTIL
static
@@ -125,21 +142,6 @@ fuse_mnt_add_mount (const char *progname, const char *fsname,
char templ[] = "/tmp/fusermountXXXXXX";
char *tmp;
- /* mtab update done async, just log if fails */
- res = fork ();
- if (res)
- exit (res == -1 ? 1 : 0);
- res = fork ();
- if (res) {
- if (res != -1)
- res = waitpid (res, &status, 0);
- if (res == -1)
- GFFUSE_LOGERR ("%s: /etc/mtab update failed",
- progname);
-
- exit (0);
- }
-
sigprocmask (SIG_SETMASK, &oldmask, NULL);
setuid (geteuid ());
@@ -159,18 +161,17 @@ fuse_mnt_add_mount (const char *progname, const char *fsname,
exit (1);
}
rmdir (tmp);
- execl ("/bin/mount", "/bin/mount", "-i", "-f", "-t", type,
+ execl (_PATH_MOUNT, _PATH_MOUNT, "-i", "-f", "-t", type,
"-o", opts, fsname, mnt, NULL);
- GFFUSE_LOGERR ("%s: failed to execute /bin/mount: %s",
- progname, strerror (errno));
+ GFFUSE_LOGERR ("%s: failed to execute %s: %s",
+ progname, _PATH_MOUNT, strerror (errno));
exit (1);
}
+
res = waitpid (res, &status, 0);
if (res == -1)
GFFUSE_LOGERR ("%s: waitpid: %s", progname, strerror (errno));
-
- if (status != 0)
- res = -1;
+ res = (res != -1 && status == 0) ? 0 : -1;
out_restore:
sigprocmask (SIG_SETMASK, &oldmask, NULL);
@@ -248,76 +249,75 @@ char
}
#ifndef FUSE_UTIL
-/* return value:
- * >= 0 => fd
- * -1 => error
- */
-static int
-receive_fd (int fd)
+static char *
+escape (char *s)
{
- struct msghdr msg;
- struct iovec iov;
- char buf[1];
- int rv;
- size_t ccmsg[CMSG_SPACE (sizeof (int)) / sizeof (size_t)];
- struct cmsghdr *cmsg;
- int *recv_fd;
-
- iov.iov_base = buf;
- iov.iov_len = 1;
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- /* old BSD implementations should use msg_accrights instead of
- * msg_control; the interface is different. */
- msg.msg_control = ccmsg;
- msg.msg_controllen = sizeof (ccmsg);
-
- while (((rv = recvmsg (fd, &msg, 0)) == -1) && errno == EINTR);
- if (rv == -1) {
- GFFUSE_LOGERR ("recvmsg failed: %s", strerror (errno));
- return -1;
- }
- if (!rv) {
- /* EOF */
- return -1;
+ size_t len = 0;
+ char *p = NULL;
+ char *q = NULL;
+ char *e = NULL;
+
+ for (p = s; *p; p++) {
+ if (*p == ',')
+ len++;
+ len++;
}
- cmsg = CMSG_FIRSTHDR (&msg);
- /*
- * simplify condition expression
- */
- if (cmsg->cmsg_type != SCM_RIGHTS) {
- GFFUSE_LOGERR ("got control message of unknown type %d",
- cmsg->cmsg_type);
- return -1;
+ e = CALLOC (1, len + 1);
+ if (!e)
+ return NULL;
+
+ for (p = s, q = e; *p; p++, q++) {
+ if (*p == ',') {
+ *q = '\\';
+ q++;
+ }
+ *q = *p;
}
- recv_fd = (int *) CMSG_DATA (cmsg);
- return (*recv_fd);
+ return e;
}
static int
-fuse_mount_fusermount (const char *mountpoint, const char *opts)
+fuse_mount_fusermount (const char *mountpoint, char *fsname, char *mnt_param,
+ int fd)
{
- int fds[2], pid;
- int res;
- int rv;
+ int pid = -1;
+ int res = 0;
+ int ret = -1;
+ char *fm_mnt_params = NULL;
+ char *efsname = NULL;
+
+#ifndef GF_FUSERMOUNT
+ GFFUSE_LOGERR ("Mounting via helper utility "
+ "(unprivileged mounting) is supported "
+ "only if glusterfs is compiled with "
+ "--enable-fusermount");
+ return -1;
+#endif
+
+ efsname = escape (fsname);
+ if (!efsname) {
+ GFFUSE_LOGERR ("Out of memory");
- res = socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
- if (res == -1) {
- GFFUSE_LOGERR ("socketpair() failed: %s", strerror (errno));
return -1;
}
+ ret = asprintf (&fm_mnt_params,
+ "%s,fsname=%s,nonempty,subtype=glusterfs",
+ mnt_param, efsname);
+ FREE (efsname);
+ if (ret == -1) {
+ GFFUSE_LOGERR ("Out of memory");
+
+ goto out;
+ }
+ /* fork to exec fusermount */
pid = fork ();
if (pid == -1) {
GFFUSE_LOGERR ("fork() failed: %s", strerror (errno));
- close (fds[0]);
- close (fds[1]);
- return -1;
+ ret = -1;
+ goto out;
}
if (pid == 0) {
@@ -326,30 +326,25 @@ fuse_mount_fusermount (const char *mountpoint, const char *opts)
int a = 0;
argv[a++] = FUSERMOUNT_PROG;
- if (opts) {
- argv[a++] = "-o";
- argv[a++] = opts;
- }
+ argv[a++] = "-o";
+ argv[a++] = fm_mnt_params;
argv[a++] = "--";
argv[a++] = mountpoint;
argv[a++] = NULL;
- close (fds[1]);
- fcntl (fds[0], F_SETFD, 0);
- snprintf (env, sizeof (env), "%i", fds[0]);
- setenv (FUSE_COMMFD_ENV, env, 1);
+ snprintf (env, sizeof (env), "%i", fd);
+ setenv (FUSE_DEVFD_ENV, env, 1);
execvp (FUSERMOUNT_PROG, (char **)argv);
GFFUSE_LOGERR ("failed to exec fusermount: %s",
strerror (errno));
_exit (1);
}
- close (fds[0]);
- rv = receive_fd (fds[1]);
- close (fds[1]);
- waitpid (pid, NULL, 0); /* bury zombie */
-
- return rv;
+ ret = waitpid (pid, &res, 0);
+ ret = (ret == pid && res == 0) ? 0 : -1;
+ out:
+ FREE (fm_mnt_params);
+ return ret;
}
#endif
@@ -519,21 +514,14 @@ gf_fuse_unmount (const char *mountpoint, int fd)
#ifndef FUSE_UTIL
static int
-fuse_mount_sys (const char *mountpoint, char *fsname, char *mnt_param)
+fuse_mount_sys (const char *mountpoint, char *fsname, char *mnt_param, int fd)
{
- int fd = -1, ret = -1;
+ int ret = -1;
unsigned mounted = 0;
char *mnt_param_mnt = NULL;
char *fstype = "fuse.glusterfs";
char *source = fsname;
- fd = open ("/dev/fuse", O_RDWR);
- if (fd == -1) {
- GFFUSE_LOGERR ("cannot open /dev/fuse (%s)", strerror (errno));
-
- return -1;
- }
-
ret = asprintf (&mnt_param_mnt,
"%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i",
mnt_param, fd, S_IFDIR, getuid (), getgid ());
@@ -563,6 +551,7 @@ fuse_mount_sys (const char *mountpoint, char *fsname, char *mnt_param)
else
mounted = 1;
+#ifndef __NetBSD__
if (geteuid () == 0) {
char *newmnt = fuse_mnt_resolve_path ("fuse", mountpoint);
@@ -581,94 +570,75 @@ fuse_mount_sys (const char *mountpoint, char *fsname, char *mnt_param)
goto out;
}
}
+#endif /* __NetBSD__ */
- out:
+out:
if (ret == -1) {
if (mounted)
umount2 (mountpoint, 2); /* lazy umount */
- close (fd);
- fd = -1;
}
FREE (mnt_param_mnt);
if (source != fsname)
FREE (source);
- return fd;
-}
-
-static char *
-escape (char *s)
-{
- size_t len = 0;
- char *p = NULL;
- char *q = NULL;
- char *e = NULL;
- for (p = s; *p; p++) {
- if (*p == ',')
- len++;
- len++;
- }
-
- e = CALLOC (1, len + 1);
- if (!e)
- return NULL;
-
- for (p = s, q = e; *p; p++, q++) {
- if (*p == ',') {
- *q = '\\';
- q++;
- }
- *q = *p;
- }
-
- return e;
+ return ret;
}
int
-gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param)
+gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
+ pid_t *mnt_pid, int status_fd)
{
- int fd = -1, rv = -1;
- char *fm_mnt_params = NULL, *p = NULL;
- char *efsname = NULL;
+ int fd = -1;
+ pid_t pid = -1;
+ int ret = -1;
- fd = fuse_mount_sys (mountpoint, fsname, mnt_param);
+ fd = open ("/dev/fuse", O_RDWR);
if (fd == -1) {
- gf_log ("glusterfs-fuse", GF_LOG_INFO,
- "direct mount failed (%s), "
- "retry to mount via fusermount",
- strerror (errno));
-
- efsname = escape (fsname);
- if (!efsname) {
- GFFUSE_LOGERR ("Out of memory");
-
- return -1;
- }
- rv = asprintf (&fm_mnt_params,
- "%s,fsname=%s,nonempty,subtype=glusterfs",
- mnt_param, efsname);
- FREE (efsname);
- if (rv == -1) {
- GFFUSE_LOGERR ("Out of memory");
+ GFFUSE_LOGERR ("cannot open /dev/fuse (%s)",
+ strerror (errno));
+ return -1;
+ }
- return -1;
+ /* start mount agent */
+ pid = fork();
+ switch (pid) {
+ case 0:
+ /* hello it's mount agent */
+ if (!mnt_pid) {
+ /* daemonize mount agent, caller is
+ * not interested in waiting for it
+ */
+ pid = fork ();
+ if (pid)
+ exit (pid == -1 ? 1 : 0);
}
- fd = fuse_mount_fusermount (mountpoint, fm_mnt_params);
- if (fd == -1) {
- p = fm_mnt_params + strlen (fm_mnt_params);
- while (*--p != ',');
- *p = '\0';
+ ret = fuse_mount_sys (mountpoint, fsname, mnt_param, fd);
+ if (ret == -1) {
+ gf_log ("glusterfs-fuse", GF_LOG_INFO,
+ "direct mount failed (%s), "
+ "retry to mount via fusermount",
+ strerror (errno));
- fd = fuse_mount_fusermount (mountpoint, fm_mnt_params);
+ ret = fuse_mount_fusermount (mountpoint, fsname,
+ mnt_param, fd);
}
- FREE (fm_mnt_params);
+ if (ret == -1)
+ GFFUSE_LOGERR ("mount failed");
- if (fd == -1)
- GFFUSE_LOGERR ("mount failed");
+ if (status_fd >= 0)
+ (void)write (status_fd, &ret, sizeof (ret));
+ exit (!!ret);
+ /* bye mount agent */
+ case -1:
+ close (fd);
+ fd = -1;
}
+ if (mnt_pid)
+ *mnt_pid = pid;
+
return fd;
}
#endif
diff --git a/contrib/fuse-util/Makefile.am b/contrib/fuse-util/Makefile.am
index 42609a688..a72e3832b 100644
--- a/contrib/fuse-util/Makefile.am
+++ b/contrib/fuse-util/Makefile.am
@@ -3,7 +3,7 @@ bin_PROGRAMS = fusermount-glusterfs
fusermount_glusterfs_SOURCES = fusermount.c $(CONTRIBDIR)/fuse-lib/mount.c
noinst_HEADERS = mount_util.h
-AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -DFUSE_UTIL $(GF_CFLAGS)
+AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -DFUSE_UTIL $(GF_CFLAGS) -D_GNU_SOURCE
install-exec-hook:
-chown root $(DESTDIR)$(bindir)/fusermount-glusterfs
diff --git a/contrib/fuse-util/fusermount.c b/contrib/fuse-util/fusermount.c
index 39da9b6a0..4e7e4f950 100644
--- a/contrib/fuse-util/fusermount.c
+++ b/contrib/fuse-util/fusermount.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
+#include <limits.h>
#include <mntent.h>
#include <sys/wait.h>
#include <sys/stat.h>
@@ -28,6 +29,7 @@
#include <sys/utsname.h>
#include <sched.h>
+#define FUSE_DEVFD_ENV "_FUSE_DEVFD"
#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
#define FUSE_DEV_OLD "/proc/fs/fuse/dev"
@@ -1016,8 +1018,36 @@ static int open_fuse_device(char **devp)
return -1;
}
+static int check_fuse_device(char *devfd, char **devp)
+{
+ int res;
+ char *devlink;
+
+ res = asprintf(&devlink, "/proc/self/fd/%s", devfd);
+ if (res == -1) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ return -1;
+ }
+
+ *devp = (char *) calloc(1, PATH_MAX + 1);
+ if (!*devp) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ free(devlink);
+ return -1;
+ }
+
+ res = readlink (devlink, *devp, PATH_MAX);
+ free (devlink);
+ if (res == -1) {
+ fprintf(stderr, "%s: specified fuse fd is invalid\n",
+ progname);
+ return -1;
+ }
+
+ return atoi(devfd);
+}
-static int mount_fuse(const char *mnt, const char *opts)
+static int mount_fuse(const char *mnt, const char *opts, char *devfd)
{
int res;
int fd;
@@ -1030,7 +1060,7 @@ static int mount_fuse(const char *mnt, const char *opts)
int currdir_fd = -1;
int mountpoint_fd = -1;
- fd = open_fuse_device(&dev);
+ fd = devfd ? check_fuse_device(devfd, &dev) : open_fuse_device(&dev);
if (fd == -1)
return -1;
@@ -1154,6 +1184,7 @@ int main(int argc, char *argv[])
static int unmount = 0;
static int lazy = 0;
static int quiet = 0;
+ char *devfd;
char *commfd;
int cfd;
const char *opts = "";
@@ -1242,21 +1273,26 @@ int main(int argc, char *argv[])
return 0;
}
- commfd = getenv(FUSE_COMMFD_ENV);
- if (commfd == NULL) {
- fprintf(stderr, "%s: old style mounting not supported\n",
- progname);
- exit(1);
+ devfd = getenv(FUSE_DEVFD_ENV);
+ if (devfd == NULL) {
+ commfd = getenv(FUSE_COMMFD_ENV);
+ if (commfd == NULL) {
+ fprintf(stderr, "%s: old style mounting not supported\n",
+ progname);
+ exit(1);
+ }
}
- fd = mount_fuse(mnt, opts);
+ fd = mount_fuse(mnt, opts, devfd);
if (fd == -1)
exit(1);
- cfd = atoi(commfd);
- res = send_fd(cfd, fd);
- if (res == -1)
- exit(1);
+ if (devfd == NULL) {
+ cfd = atoi(commfd);
+ res = send_fd(cfd, fd);
+ if (res == -1)
+ exit(1);
+ }
return 0;
}
diff --git a/contrib/ipaddr-py/COPYING b/contrib/ipaddr-py/COPYING
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/contrib/ipaddr-py/COPYING
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/contrib/ipaddr-py/MANIFEST.in b/contrib/ipaddr-py/MANIFEST.in
new file mode 100644
index 000000000..f57280444
--- /dev/null
+++ b/contrib/ipaddr-py/MANIFEST.in
@@ -0,0 +1,3 @@
+include COPYING
+include ipaddr_test.py
+include RELEASENOTES
diff --git a/contrib/ipaddr-py/OWNERS b/contrib/ipaddr-py/OWNERS
new file mode 100644
index 000000000..501673e03
--- /dev/null
+++ b/contrib/ipaddr-py/OWNERS
@@ -0,0 +1,4 @@
+pmoody
+harro
+mshields
+smart
diff --git a/contrib/ipaddr-py/README b/contrib/ipaddr-py/README
new file mode 100644
index 000000000..1b54294bb
--- /dev/null
+++ b/contrib/ipaddr-py/README
@@ -0,0 +1,8 @@
+ipaddr.py is a library for working with IP addresses, both IPv4 and IPv6.
+It was developed by Google for internal use, and is now open source.
+
+Project home page: http://code.google.com/p/ipaddr-py/
+
+Please send contributions to ipaddr-py-dev@googlegroups.com. Code should
+include unit tests and follow the Google Python style guide:
+http://code.google.com/p/soc/wiki/PythonStyleGuide
diff --git a/contrib/ipaddr-py/ipaddr.py b/contrib/ipaddr-py/ipaddr.py
new file mode 100644
index 000000000..a89298a31
--- /dev/null
+++ b/contrib/ipaddr-py/ipaddr.py
@@ -0,0 +1,1907 @@
+#!/usr/bin/python
+#
+# Copyright 2007 Google Inc.
+# Licensed to PSF under a Contributor Agreement.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+"""A fast, lightweight IPv4/IPv6 manipulation library in Python.
+
+This library is used to create/poke/manipulate IPv4 and IPv6 addresses
+and networks.
+
+"""
+
+__version__ = 'trunk'
+
+import struct
+
+IPV4LENGTH = 32
+IPV6LENGTH = 128
+
+
+class AddressValueError(ValueError):
+ """A Value Error related to the address."""
+
+
+class NetmaskValueError(ValueError):
+ """A Value Error related to the netmask."""
+
+
+def IPAddress(address, version=None):
+ """Take an IP string/int and return an object of the correct type.
+
+ Args:
+ address: A string or integer, the IP address. Either IPv4 or
+ IPv6 addresses may be supplied; integers less than 2**32 will
+ be considered to be IPv4 by default.
+ version: An Integer, 4 or 6. If set, don't try to automatically
+ determine what the IP address type is. important for things
+ like IPAddress(1), which could be IPv4, '0.0.0.1', or IPv6,
+ '::1'.
+
+ Returns:
+ An IPv4Address or IPv6Address object.
+
+ Raises:
+ ValueError: if the string passed isn't either a v4 or a v6
+ address.
+
+ """
+ if version:
+ if version == 4:
+ return IPv4Address(address)
+ elif version == 6:
+ return IPv6Address(address)
+
+ try:
+ return IPv4Address(address)
+ except (AddressValueError, NetmaskValueError):
+ pass
+
+ try:
+ return IPv6Address(address)
+ except (AddressValueError, NetmaskValueError):
+ pass
+
+ raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
+ address)
+
+
+def IPNetwork(address, version=None, strict=False):
+ """Take an IP string/int and return an object of the correct type.
+
+ Args:
+ address: A string or integer, the IP address. Either IPv4 or
+ IPv6 addresses may be supplied; integers less than 2**32 will
+ be considered to be IPv4 by default.
+ version: An Integer, if set, don't try to automatically
+ determine what the IP address type is. important for things
+ like IPNetwork(1), which could be IPv4, '0.0.0.1/32', or IPv6,
+ '::1/128'.
+
+ Returns:
+ An IPv4Network or IPv6Network object.
+
+ Raises:
+ ValueError: if the string passed isn't either a v4 or a v6
+ address. Or if a strict network was requested and a strict
+ network wasn't given.
+
+ """
+ if version:
+ if version == 4:
+ return IPv4Network(address, strict)
+ elif version == 6:
+ return IPv6Network(address, strict)
+
+ try:
+ return IPv4Network(address, strict)
+ except (AddressValueError, NetmaskValueError):
+ pass
+
+ try:
+ return IPv6Network(address, strict)
+ except (AddressValueError, NetmaskValueError):
+ pass
+
+ raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
+ address)
+
+
+def v4_int_to_packed(address):
+ """The binary representation of this address.
+
+ Args:
+ address: An integer representation of an IPv4 IP address.
+
+ Returns:
+ The binary representation of this address.
+
+ Raises:
+ ValueError: If the integer is too large to be an IPv4 IP
+ address.
+ """
+ if address > _BaseV4._ALL_ONES:
+ raise ValueError('Address too large for IPv4')
+ return struct.pack('!I', address)
+
+
+def v6_int_to_packed(address):
+ """The binary representation of this address.
+
+ Args:
+ address: An integer representation of an IPv4 IP address.
+
+ Returns:
+ The binary representation of this address.
+ """
+ return struct.pack('!QQ', address >> 64, address & (2**64 - 1))
+
+
+def _find_address_range(addresses):
+ """Find a sequence of addresses.
+
+ Args:
+ addresses: a list of IPv4 or IPv6 addresses.
+
+ Returns:
+ A tuple containing the first and last IP addresses in the sequence.
+
+ """
+ first = last = addresses[0]
+ for ip in addresses[1:]:
+ if ip._ip == last._ip + 1:
+ last = ip
+ else:
+ break
+ return (first, last)
+
+def _get_prefix_length(number1, number2, bits):
+ """Get the number of leading bits that are same for two numbers.
+
+ Args:
+ number1: an integer.
+ number2: another integer.
+ bits: the maximum number of bits to compare.
+
+ Returns:
+ The number of leading bits that are the same for two numbers.
+
+ """
+ for i in range(bits):
+ if number1 >> i == number2 >> i:
+ return bits - i
+ return 0
+
+def _count_righthand_zero_bits(number, bits):
+ """Count the number of zero bits on the right hand side.
+
+ Args:
+ number: an integer.
+ bits: maximum number of bits to count.
+
+ Returns:
+ The number of zero bits on the right hand side of the number.
+
+ """
+ if number == 0:
+ return bits
+ for i in range(bits):
+ if (number >> i) % 2:
+ return i
+
+def summarize_address_range(first, last):
+ """Summarize a network range given the first and last IP addresses.
+
+ Example:
+ >>> summarize_address_range(IPv4Address('1.1.1.0'),
+ IPv4Address('1.1.1.130'))
+ [IPv4Network('1.1.1.0/25'), IPv4Network('1.1.1.128/31'),
+ IPv4Network('1.1.1.130/32')]
+
+ Args:
+ first: the first IPv4Address or IPv6Address in the range.
+ last: the last IPv4Address or IPv6Address in the range.
+
+ Returns:
+ The address range collapsed to a list of IPv4Network's or
+ IPv6Network's.
+
+ Raise:
+ TypeError:
+ If the first and last objects are not IP addresses.
+ If the first and last objects are not the same version.
+ ValueError:
+ If the last object is not greater than the first.
+ If the version is not 4 or 6.
+
+ """
+ if not (isinstance(first, _BaseIP) and isinstance(last, _BaseIP)):
+ raise TypeError('first and last must be IP addresses, not networks')
+ if first.version != last.version:
+ raise TypeError("%s and %s are not of the same version" % (
+ str(first), str(last)))
+ if first > last:
+ raise ValueError('last IP address must be greater than first')
+
+ networks = []
+
+ if first.version == 4:
+ ip = IPv4Network
+ elif first.version == 6:
+ ip = IPv6Network
+ else:
+ raise ValueError('unknown IP version')
+
+ ip_bits = first._max_prefixlen
+ first_int = first._ip
+ last_int = last._ip
+ while first_int <= last_int:
+ nbits = _count_righthand_zero_bits(first_int, ip_bits)
+ current = None
+ while nbits >= 0:
+ addend = 2**nbits - 1
+ current = first_int + addend
+ nbits -= 1
+ if current <= last_int:
+ break
+ prefix = _get_prefix_length(first_int, current, ip_bits)
+ net = ip('%s/%d' % (str(first), prefix))
+ networks.append(net)
+ if current == ip._ALL_ONES:
+ break
+ first_int = current + 1
+ first = IPAddress(first_int, version=first._version)
+ return networks
+
+def _collapse_address_list_recursive(addresses):
+ """Loops through the addresses, collapsing concurrent netblocks.
+
+ Example:
+
+ ip1 = IPv4Network('1.1.0.0/24')
+ ip2 = IPv4Network('1.1.1.0/24')
+ ip3 = IPv4Network('1.1.2.0/24')
+ ip4 = IPv4Network('1.1.3.0/24')
+ ip5 = IPv4Network('1.1.4.0/24')
+ ip6 = IPv4Network('1.1.0.1/22')
+
+ _collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6]) ->
+ [IPv4Network('1.1.0.0/22'), IPv4Network('1.1.4.0/24')]
+
+ This shouldn't be called directly; it is called via
+ collapse_address_list([]).
+
+ Args:
+ addresses: A list of IPv4Network's or IPv6Network's
+
+ Returns:
+ A list of IPv4Network's or IPv6Network's depending on what we were
+ passed.
+
+ """
+ ret_array = []
+ optimized = False
+
+ for cur_addr in addresses:
+ if not ret_array:
+ ret_array.append(cur_addr)
+ continue
+ if cur_addr in ret_array[-1]:
+ optimized = True
+ elif cur_addr == ret_array[-1].supernet().subnet()[1]:
+ ret_array.append(ret_array.pop().supernet())
+ optimized = True
+ else:
+ ret_array.append(cur_addr)
+
+ if optimized:
+ return _collapse_address_list_recursive(ret_array)
+
+ return ret_array
+
+
+def collapse_address_list(addresses):
+ """Collapse a list of IP objects.
+
+ Example:
+ collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) ->
+ [IPv4('1.1.0.0/23')]
+
+ Args:
+ addresses: A list of IPv4Network or IPv6Network objects.
+
+ Returns:
+ A list of IPv4Network or IPv6Network objects depending on what we
+ were passed.
+
+ Raises:
+ TypeError: If passed a list of mixed version objects.
+
+ """
+ i = 0
+ addrs = []
+ ips = []
+ nets = []
+
+ # split IP addresses and networks
+ for ip in addresses:
+ if isinstance(ip, _BaseIP):
+ if ips and ips[-1]._version != ip._version:
+ raise TypeError("%s and %s are not of the same version" % (
+ str(ip), str(ips[-1])))
+ ips.append(ip)
+ elif ip._prefixlen == ip._max_prefixlen:
+ if ips and ips[-1]._version != ip._version:
+ raise TypeError("%s and %s are not of the same version" % (
+ str(ip), str(ips[-1])))
+ ips.append(ip.ip)
+ else:
+ if nets and nets[-1]._version != ip._version:
+ raise TypeError("%s and %s are not of the same version" % (
+ str(ip), str(ips[-1])))
+ nets.append(ip)
+
+ # sort and dedup
+ ips = sorted(set(ips))
+ nets = sorted(set(nets))
+
+ while i < len(ips):
+ (first, last) = _find_address_range(ips[i:])
+ i = ips.index(last) + 1
+ addrs.extend(summarize_address_range(first, last))
+
+ return _collapse_address_list_recursive(sorted(
+ addrs + nets, key=_BaseNet._get_networks_key))
+
+# backwards compatibility
+CollapseAddrList = collapse_address_list
+
+# Test whether this Python implementation supports byte objects that
+# are not identical to str ones.
+# We need to exclude platforms where bytes == str so that we can
+# distinguish between packed representations and strings, for example
+# b'12::' (the IPv4 address 49.50.58.58) and '12::' (an IPv6 address).
+try:
+ _compat_has_real_bytes = bytes is not str
+except NameError: # <Python2.6
+ _compat_has_real_bytes = False
+
+def get_mixed_type_key(obj):
+ """Return a key suitable for sorting between networks and addresses.
+
+ Address and Network objects are not sortable by default; they're
+ fundamentally different so the expression
+
+ IPv4Address('1.1.1.1') <= IPv4Network('1.1.1.1/24')
+
+ doesn't make any sense. There are some times however, where you may wish
+ to have ipaddr sort these for you anyway. If you need to do this, you
+ can use this function as the key= argument to sorted().
+
+ Args:
+ obj: either a Network or Address object.
+ Returns:
+ appropriate key.
+
+ """
+ if isinstance(obj, _BaseNet):
+ return obj._get_networks_key()
+ elif isinstance(obj, _BaseIP):
+ return obj._get_address_key()
+ return NotImplemented
+
+class _IPAddrBase(object):
+
+ """The mother class."""
+
+ def __index__(self):
+ return self._ip
+
+ def __int__(self):
+ return self._ip
+
+ def __hex__(self):
+ return hex(self._ip)
+
+ @property
+ def exploded(self):
+ """Return the longhand version of the IP address as a string."""
+ return self._explode_shorthand_ip_string()
+
+ @property
+ def compressed(self):
+ """Return the shorthand version of the IP address as a string."""
+ return str(self)
+
+
+class _BaseIP(_IPAddrBase):
+
+ """A generic IP object.
+
+ This IP class contains the version independent methods which are
+ used by single IP addresses.
+
+ """
+
+ def __init__(self, address):
+ if (not (_compat_has_real_bytes and isinstance(address, bytes))
+ and '/' in str(address)):
+ raise AddressValueError(address)
+
+ def __eq__(self, other):
+ try:
+ return (self._ip == other._ip
+ and self._version == other._version)
+ except AttributeError:
+ return NotImplemented
+
+ def __ne__(self, other):
+ eq = self.__eq__(other)
+ if eq is NotImplemented:
+ return NotImplemented
+ return not eq
+
+ def __le__(self, other):
+ gt = self.__gt__(other)
+ if gt is NotImplemented:
+ return NotImplemented
+ return not gt
+
+ def __ge__(self, other):
+ lt = self.__lt__(other)
+ if lt is NotImplemented:
+ return NotImplemented
+ return not lt
+
+ def __lt__(self, other):
+ if self._version != other._version:
+ raise TypeError('%s and %s are not of the same version' % (
+ str(self), str(other)))
+ if not isinstance(other, _BaseIP):
+ raise TypeError('%s and %s are not of the same type' % (
+ str(self), str(other)))
+ if self._ip != other._ip:
+ return self._ip < other._ip
+ return False
+
+ def __gt__(self, other):
+ if self._version != other._version:
+ raise TypeError('%s and %s are not of the same version' % (
+ str(self), str(other)))
+ if not isinstance(other, _BaseIP):
+ raise TypeError('%s and %s are not of the same type' % (
+ str(self), str(other)))
+ if self._ip != other._ip:
+ return self._ip > other._ip
+ return False
+
+ # Shorthand for Integer addition and subtraction. This is not
+ # meant to ever support addition/subtraction of addresses.
+ def __add__(self, other):
+ if not isinstance(other, int):
+ return NotImplemented
+ return IPAddress(int(self) + other, version=self._version)
+
+ def __sub__(self, other):
+ if not isinstance(other, int):
+ return NotImplemented
+ return IPAddress(int(self) - other, version=self._version)
+
+ def __repr__(self):
+ return '%s(%r)' % (self.__class__.__name__, str(self))
+
+ def __str__(self):
+ return '%s' % self._string_from_ip_int(self._ip)
+
+ def __hash__(self):
+ return hash(hex(long(self._ip)))
+
+ def _get_address_key(self):
+ return (self._version, self)
+
+ @property
+ def version(self):
+ raise NotImplementedError('BaseIP has no version')
+
+
+class _BaseNet(_IPAddrBase):
+
+ """A generic IP object.
+
+ This IP class contains the version independent methods which are
+ used by networks.
+
+ """
+
+ def __init__(self, address):
+ self._cache = {}
+
+ def __repr__(self):
+ return '%s(%r)' % (self.__class__.__name__, str(self))
+
+ def iterhosts(self):
+ """Generate Iterator over usable hosts in a network.
+
+ This is like __iter__ except it doesn't return the network
+ or broadcast addresses.
+
+ """
+ cur = int(self.network) + 1
+ bcast = int(self.broadcast) - 1
+ while cur <= bcast:
+ cur += 1
+ yield IPAddress(cur - 1, version=self._version)
+
+ def __iter__(self):
+ cur = int(self.network)
+ bcast = int(self.broadcast)
+ while cur <= bcast:
+ cur += 1
+ yield IPAddress(cur - 1, version=self._version)
+
+ def __getitem__(self, n):
+ network = int(self.network)
+ broadcast = int(self.broadcast)
+ if n >= 0:
+ if network + n > broadcast:
+ raise IndexError
+ return IPAddress(network + n, version=self._version)
+ else:
+ n += 1
+ if broadcast + n < network:
+ raise IndexError
+ return IPAddress(broadcast + n, version=self._version)
+
+ def __lt__(self, other):
+ if self._version != other._version:
+ raise TypeError('%s and %s are not of the same version' % (
+ str(self), str(other)))
+ if not isinstance(other, _BaseNet):
+ raise TypeError('%s and %s are not of the same type' % (
+ str(self), str(other)))
+ if self.network != other.network:
+ return self.network < other.network
+ if self.netmask != other.netmask:
+ return self.netmask < other.netmask
+ return False
+
+ def __gt__(self, other):
+ if self._version != other._version:
+ raise TypeError('%s and %s are not of the same version' % (
+ str(self), str(other)))
+ if not isinstance(other, _BaseNet):
+ raise TypeError('%s and %s are not of the same type' % (
+ str(self), str(other)))
+ if self.network != other.network:
+ return self.network > other.network
+ if self.netmask != other.netmask:
+ return self.netmask > other.netmask
+ return False
+
+ def __le__(self, other):
+ gt = self.__gt__(other)
+ if gt is NotImplemented:
+ return NotImplemented
+ return not gt
+
+ def __ge__(self, other):
+ lt = self.__lt__(other)
+ if lt is NotImplemented:
+ return NotImplemented
+ return not lt
+
+ def __eq__(self, other):
+ try:
+ return (self._version == other._version
+ and self.network == other.network
+ and int(self.netmask) == int(other.netmask))
+ except AttributeError:
+ if isinstance(other, _BaseIP):
+ return (self._version == other._version
+ and self._ip == other._ip)
+
+ def __ne__(self, other):
+ eq = self.__eq__(other)
+ if eq is NotImplemented:
+ return NotImplemented
+ return not eq
+
+ def __str__(self):
+ return '%s/%s' % (str(self.ip),
+ str(self._prefixlen))
+
+ def __hash__(self):
+ return hash(int(self.network) ^ int(self.netmask))
+
+ def __contains__(self, other):
+ # always false if one is v4 and the other is v6.
+ if self._version != other._version:
+ return False
+ # dealing with another network.
+ if isinstance(other, _BaseNet):
+ return (self.network <= other.network and
+ self.broadcast >= other.broadcast)
+ # dealing with another address
+ else:
+ return (int(self.network) <= int(other._ip) <=
+ int(self.broadcast))
+
+ def overlaps(self, other):
+ """Tell if self is partly contained in other."""
+ return self.network in other or self.broadcast in other or (
+ other.network in self or other.broadcast in self)
+
+ @property
+ def network(self):
+ x = self._cache.get('network')
+ if x is None:
+ x = IPAddress(self._ip & int(self.netmask), version=self._version)
+ self._cache['network'] = x
+ return x
+
+ @property
+ def broadcast(self):
+ x = self._cache.get('broadcast')
+ if x is None:
+ x = IPAddress(self._ip | int(self.hostmask), version=self._version)
+ self._cache['broadcast'] = x
+ return x
+
+ @property
+ def hostmask(self):
+ x = self._cache.get('hostmask')
+ if x is None:
+ x = IPAddress(int(self.netmask) ^ self._ALL_ONES,
+ version=self._version)
+ self._cache['hostmask'] = x
+ return x
+
+ @property
+ def with_prefixlen(self):
+ return '%s/%d' % (str(self.ip), self._prefixlen)
+
+ @property
+ def with_netmask(self):
+ return '%s/%s' % (str(self.ip), str(self.netmask))
+
+ @property
+ def with_hostmask(self):
+ return '%s/%s' % (str(self.ip), str(self.hostmask))
+
+ @property
+ def numhosts(self):
+ """Number of hosts in the current subnet."""
+ return int(self.broadcast) - int(self.network) + 1
+
+ @property
+ def version(self):
+ raise NotImplementedError('BaseNet has no version')
+
+ @property
+ def prefixlen(self):
+ return self._prefixlen
+
+ def address_exclude(self, other):
+ """Remove an address from a larger block.
+
+ For example:
+
+ addr1 = IPNetwork('10.1.1.0/24')
+ addr2 = IPNetwork('10.1.1.0/26')
+ addr1.address_exclude(addr2) =
+ [IPNetwork('10.1.1.64/26'), IPNetwork('10.1.1.128/25')]
+
+ or IPv6:
+
+ addr1 = IPNetwork('::1/32')
+ addr2 = IPNetwork('::1/128')
+ addr1.address_exclude(addr2) = [IPNetwork('::0/128'),
+ IPNetwork('::2/127'),
+ IPNetwork('::4/126'),
+ IPNetwork('::8/125'),
+ ...
+ IPNetwork('0:0:8000::/33')]
+
+ Args:
+ other: An IPvXNetwork object of the same type.
+
+ Returns:
+ A sorted list of IPvXNetwork objects addresses which is self
+ minus other.
+
+ Raises:
+ TypeError: If self and other are of difffering address
+ versions, or if other is not a network object.
+ ValueError: If other is not completely contained by self.
+
+ """
+ if not self._version == other._version:
+ raise TypeError("%s and %s are not of the same version" % (
+ str(self), str(other)))
+
+ if not isinstance(other, _BaseNet):
+ raise TypeError("%s is not a network object" % str(other))
+
+ if other not in self:
+ raise ValueError('%s not contained in %s' % (str(other),
+ str(self)))
+ if other == self:
+ return []
+
+ ret_addrs = []
+
+ # Make sure we're comparing the network of other.
+ other = IPNetwork('%s/%s' % (str(other.network), str(other.prefixlen)),
+ version=other._version)
+
+ s1, s2 = self.subnet()
+ while s1 != other and s2 != other:
+ if other in s1:
+ ret_addrs.append(s2)
+ s1, s2 = s1.subnet()
+ elif other in s2:
+ ret_addrs.append(s1)
+ s1, s2 = s2.subnet()
+ else:
+ # If we got here, there's a bug somewhere.
+ assert True == False, ('Error performing exclusion: '
+ 's1: %s s2: %s other: %s' %
+ (str(s1), str(s2), str(other)))
+ if s1 == other:
+ ret_addrs.append(s2)
+ elif s2 == other:
+ ret_addrs.append(s1)
+ else:
+ # If we got here, there's a bug somewhere.
+ assert True == False, ('Error performing exclusion: '
+ 's1: %s s2: %s other: %s' %
+ (str(s1), str(s2), str(other)))
+
+ return sorted(ret_addrs, key=_BaseNet._get_networks_key)
+
+ def compare_networks(self, other):
+ """Compare two IP objects.
+
+ This is only concerned about the comparison of the integer
+ representation of the network addresses. This means that the
+ host bits aren't considered at all in this method. If you want
+ to compare host bits, you can easily enough do a
+ 'HostA._ip < HostB._ip'
+
+ Args:
+ other: An IP object.
+
+ Returns:
+ If the IP versions of self and other are the same, returns:
+
+ -1 if self < other:
+ eg: IPv4('1.1.1.0/24') < IPv4('1.1.2.0/24')
+ IPv6('1080::200C:417A') < IPv6('1080::200B:417B')
+ 0 if self == other
+ eg: IPv4('1.1.1.1/24') == IPv4('1.1.1.2/24')
+ IPv6('1080::200C:417A/96') == IPv6('1080::200C:417B/96')
+ 1 if self > other
+ eg: IPv4('1.1.1.0/24') > IPv4('1.1.0.0/24')
+ IPv6('1080::1:200C:417A/112') >
+ IPv6('1080::0:200C:417A/112')
+
+ If the IP versions of self and other are different, returns:
+
+ -1 if self._version < other._version
+ eg: IPv4('10.0.0.1/24') < IPv6('::1/128')
+ 1 if self._version > other._version
+ eg: IPv6('::1/128') > IPv4('255.255.255.0/24')
+
+ """
+ if self._version < other._version:
+ return -1
+ if self._version > other._version:
+ return 1
+ # self._version == other._version below here:
+ if self.network < other.network:
+ return -1
+ if self.network > other.network:
+ return 1
+ # self.network == other.network below here:
+ if self.netmask < other.netmask:
+ return -1
+ if self.netmask > other.netmask:
+ return 1
+ # self.network == other.network and self.netmask == other.netmask
+ return 0
+
+ def _get_networks_key(self):
+ """Network-only key function.
+
+ Returns an object that identifies this address' network and
+ netmask. This function is a suitable "key" argument for sorted()
+ and list.sort().
+
+ """
+ return (self._version, self.network, self.netmask)
+
+ def _ip_int_from_prefix(self, prefixlen=None):
+ """Turn the prefix length netmask into a int for comparison.
+
+ Args:
+ prefixlen: An integer, the prefix length.
+
+ Returns:
+ An integer.
+
+ """
+ if not prefixlen and prefixlen != 0:
+ prefixlen = self._prefixlen
+ return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen)
+
+ def _prefix_from_ip_int(self, ip_int, mask=32):
+ """Return prefix length from the decimal netmask.
+
+ Args:
+ ip_int: An integer, the IP address.
+ mask: The netmask. Defaults to 32.
+
+ Returns:
+ An integer, the prefix length.
+
+ """
+ while mask:
+ if ip_int & 1 == 1:
+ break
+ ip_int >>= 1
+ mask -= 1
+
+ return mask
+
+ def _ip_string_from_prefix(self, prefixlen=None):
+ """Turn a prefix length into a dotted decimal string.
+
+ Args:
+ prefixlen: An integer, the netmask prefix length.
+
+ Returns:
+ A string, the dotted decimal netmask string.
+
+ """
+ if not prefixlen:
+ prefixlen = self._prefixlen
+ return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
+
+ def iter_subnets(self, prefixlen_diff=1, new_prefix=None):
+ """The subnets which join to make the current subnet.
+
+ In the case that self contains only one IP
+ (self._prefixlen == 32 for IPv4 or self._prefixlen == 128
+ for IPv6), return a list with just ourself.
+
+ Args:
+ prefixlen_diff: An integer, the amount the prefix length
+ should be increased by. This should not be set if
+ new_prefix is also set.
+ new_prefix: The desired new prefix length. This must be a
+ larger number (smaller prefix) than the existing prefix.
+ This should not be set if prefixlen_diff is also set.
+
+ Returns:
+ An iterator of IPv(4|6) objects.
+
+ Raises:
+ ValueError: The prefixlen_diff is too small or too large.
+ OR
+ prefixlen_diff and new_prefix are both set or new_prefix
+ is a smaller number than the current prefix (smaller
+ number means a larger network)
+
+ """
+ if self._prefixlen == self._max_prefixlen:
+ yield self
+ return
+
+ if new_prefix is not None:
+ if new_prefix < self._prefixlen:
+ raise ValueError('new prefix must be longer')
+ if prefixlen_diff != 1:
+ raise ValueError('cannot set prefixlen_diff and new_prefix')
+ prefixlen_diff = new_prefix - self._prefixlen
+
+ if prefixlen_diff < 0:
+ raise ValueError('prefix length diff must be > 0')
+ new_prefixlen = self._prefixlen + prefixlen_diff
+
+ if not self._is_valid_netmask(str(new_prefixlen)):
+ raise ValueError(
+ 'prefix length diff %d is invalid for netblock %s' % (
+ new_prefixlen, str(self)))
+
+ first = IPNetwork('%s/%s' % (str(self.network),
+ str(self._prefixlen + prefixlen_diff)),
+ version=self._version)
+
+ yield first
+ current = first
+ while True:
+ broadcast = current.broadcast
+ if broadcast == self.broadcast:
+ return
+ new_addr = IPAddress(int(broadcast) + 1, version=self._version)
+ current = IPNetwork('%s/%s' % (str(new_addr), str(new_prefixlen)),
+ version=self._version)
+
+ yield current
+
+ def masked(self):
+ """Return the network object with the host bits masked out."""
+ return IPNetwork('%s/%d' % (self.network, self._prefixlen),
+ version=self._version)
+
+ def subnet(self, prefixlen_diff=1, new_prefix=None):
+ """Return a list of subnets, rather than an iterator."""
+ return list(self.iter_subnets(prefixlen_diff, new_prefix))
+
+ def supernet(self, prefixlen_diff=1, new_prefix=None):
+ """The supernet containing the current network.
+
+ Args:
+ prefixlen_diff: An integer, the amount the prefix length of
+ the network should be decreased by. For example, given a
+ /24 network and a prefixlen_diff of 3, a supernet with a
+ /21 netmask is returned.
+
+ Returns:
+ An IPv4 network object.
+
+ Raises:
+ ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have a
+ negative prefix length.
+ OR
+ If prefixlen_diff and new_prefix are both set or new_prefix is a
+ larger number than the current prefix (larger number means a
+ smaller network)
+
+ """
+ if self._prefixlen == 0:
+ return self
+
+ if new_prefix is not None:
+ if new_prefix > self._prefixlen:
+ raise ValueError('new prefix must be shorter')
+ if prefixlen_diff != 1:
+ raise ValueError('cannot set prefixlen_diff and new_prefix')
+ prefixlen_diff = self._prefixlen - new_prefix
+
+
+ if self.prefixlen - prefixlen_diff < 0:
+ raise ValueError(
+ 'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
+ (self.prefixlen, prefixlen_diff))
+ return IPNetwork('%s/%s' % (str(self.network),
+ str(self.prefixlen - prefixlen_diff)),
+ version=self._version)
+
+ # backwards compatibility
+ Subnet = subnet
+ Supernet = supernet
+ AddressExclude = address_exclude
+ CompareNetworks = compare_networks
+ Contains = __contains__
+
+
+class _BaseV4(object):
+
+ """Base IPv4 object.
+
+ The following methods are used by IPv4 objects in both single IP
+ addresses and networks.
+
+ """
+
+ # Equivalent to 255.255.255.255 or 32 bits of 1's.
+ _ALL_ONES = (2**IPV4LENGTH) - 1
+ _DECIMAL_DIGITS = frozenset('0123456789')
+
+ def __init__(self, address):
+ self._version = 4
+ self._max_prefixlen = IPV4LENGTH
+
+ def _explode_shorthand_ip_string(self, ip_str=None):
+ if not ip_str:
+ ip_str = str(self)
+ return ip_str
+
+ def _ip_int_from_string(self, ip_str):
+ """Turn the given IP string into an integer for comparison.
+
+ Args:
+ ip_str: A string, the IP ip_str.
+
+ Returns:
+ The IP ip_str as an integer.
+
+ Raises:
+ AddressValueError: if ip_str isn't a valid IPv4 Address.
+
+ """
+ octets = ip_str.split('.')
+ if len(octets) != 4:
+ raise AddressValueError(ip_str)
+
+ packed_ip = 0
+ for oc in octets:
+ try:
+ packed_ip = (packed_ip << 8) | self._parse_octet(oc)
+ except ValueError:
+ raise AddressValueError(ip_str)
+ return packed_ip
+
+ def _parse_octet(self, octet_str):
+ """Convert a decimal octet into an integer.
+
+ Args:
+ octet_str: A string, the number to parse.
+
+ Returns:
+ The octet as an integer.
+
+ Raises:
+ ValueError: if the octet isn't strictly a decimal from [0..255].
+
+ """
+ # Whitelist the characters, since int() allows a lot of bizarre stuff.
+ if not self._DECIMAL_DIGITS.issuperset(octet_str):
+ raise ValueError
+ octet_int = int(octet_str, 10)
+ # Disallow leading zeroes, because no clear standard exists on
+ # whether these should be interpreted as decimal or octal.
+ if octet_int > 255 or (octet_str[0] == '0' and len(octet_str) > 1):
+ raise ValueError
+ return octet_int
+
+ def _string_from_ip_int(self, ip_int):
+ """Turns a 32-bit integer into dotted decimal notation.
+
+ Args:
+ ip_int: An integer, the IP address.
+
+ Returns:
+ The IP address as a string in dotted decimal notation.
+
+ """
+ octets = []
+ for _ in xrange(4):
+ octets.insert(0, str(ip_int & 0xFF))
+ ip_int >>= 8
+ return '.'.join(octets)
+
+ @property
+ def max_prefixlen(self):
+ return self._max_prefixlen
+
+ @property
+ def packed(self):
+ """The binary representation of this address."""
+ return v4_int_to_packed(self._ip)
+
+ @property
+ def version(self):
+ return self._version
+
+ @property
+ def is_reserved(self):
+ """Test if the address is otherwise IETF reserved.
+
+ Returns:
+ A boolean, True if the address is within the
+ reserved IPv4 Network range.
+
+ """
+ return self in IPv4Network('240.0.0.0/4')
+
+ @property
+ def is_private(self):
+ """Test if this address is allocated for private networks.
+
+ Returns:
+ A boolean, True if the address is reserved per RFC 1918.
+
+ """
+ return (self in IPv4Network('10.0.0.0/8') or
+ self in IPv4Network('172.16.0.0/12') or
+ self in IPv4Network('192.168.0.0/16'))
+
+ @property
+ def is_multicast(self):
+ """Test if the address is reserved for multicast use.
+
+ Returns:
+ A boolean, True if the address is multicast.
+ See RFC 3171 for details.
+
+ """
+ return self in IPv4Network('224.0.0.0/4')
+
+ @property
+ def is_unspecified(self):
+ """Test if the address is unspecified.
+
+ Returns:
+ A boolean, True if this is the unspecified address as defined in
+ RFC 5735 3.
+
+ """
+ return self in IPv4Network('0.0.0.0')
+
+ @property
+ def is_loopback(self):
+ """Test if the address is a loopback address.
+
+ Returns:
+ A boolean, True if the address is a loopback per RFC 3330.
+
+ """
+ return self in IPv4Network('127.0.0.0/8')
+
+ @property
+ def is_link_local(self):
+ """Test if the address is reserved for link-local.
+
+ Returns:
+ A boolean, True if the address is link-local per RFC 3927.
+
+ """
+ return self in IPv4Network('169.254.0.0/16')
+
+
+class IPv4Address(_BaseV4, _BaseIP):
+
+ """Represent and manipulate single IPv4 Addresses."""
+
+ def __init__(self, address):
+
+ """
+ Args:
+ address: A string or integer representing the IP
+ '192.168.1.1'
+
+ Additionally, an integer can be passed, so
+ IPv4Address('192.168.1.1') == IPv4Address(3232235777).
+ or, more generally
+ IPv4Address(int(IPv4Address('192.168.1.1'))) ==
+ IPv4Address('192.168.1.1')
+
+ Raises:
+ AddressValueError: If ipaddr isn't a valid IPv4 address.
+
+ """
+ _BaseIP.__init__(self, address)
+ _BaseV4.__init__(self, address)
+
+ # Efficient constructor from integer.
+ if isinstance(address, (int, long)):
+ self._ip = address
+ if address < 0 or address > self._ALL_ONES:
+ raise AddressValueError(address)
+ return
+
+ # Constructing from a packed address
+ if _compat_has_real_bytes:
+ if isinstance(address, bytes) and len(address) == 4:
+ self._ip = struct.unpack('!I', address)[0]
+ return
+
+ # Assume input argument to be string or any object representation
+ # which converts into a formatted IP string.
+ addr_str = str(address)
+ self._ip = self._ip_int_from_string(addr_str)
+
+
+class IPv4Network(_BaseV4, _BaseNet):
+
+ """This class represents and manipulates 32-bit IPv4 networks.
+
+ Attributes: [examples for IPv4Network('1.2.3.4/27')]
+ ._ip: 16909060
+ .ip: IPv4Address('1.2.3.4')
+ .network: IPv4Address('1.2.3.0')
+ .hostmask: IPv4Address('0.0.0.31')
+ .broadcast: IPv4Address('1.2.3.31')
+ .netmask: IPv4Address('255.255.255.224')
+ .prefixlen: 27
+
+ """
+
+ # the valid octets for host and netmasks. only useful for IPv4.
+ _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
+
+ def __init__(self, address, strict=False):
+ """Instantiate a new IPv4 network object.
+
+ Args:
+ address: A string or integer representing the IP [& network].
+ '192.168.1.1/24'
+ '192.168.1.1/255.255.255.0'
+ '192.168.1.1/0.0.0.255'
+ are all functionally the same in IPv4. Similarly,
+ '192.168.1.1'
+ '192.168.1.1/255.255.255.255'
+ '192.168.1.1/32'
+ are also functionaly equivalent. That is to say, failing to
+ provide a subnetmask will create an object with a mask of /32.
+
+ If the mask (portion after the / in the argument) is given in
+ dotted quad form, it is treated as a netmask if it starts with a
+ non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it
+ starts with a zero field (e.g. 0.255.255.255 == /8), with the
+ single exception of an all-zero mask which is treated as a
+ netmask == /0. If no mask is given, a default of /32 is used.
+
+ Additionally, an integer can be passed, so
+ IPv4Network('192.168.1.1') == IPv4Network(3232235777).
+ or, more generally
+ IPv4Network(int(IPv4Network('192.168.1.1'))) ==
+ IPv4Network('192.168.1.1')
+
+ strict: A boolean. If true, ensure that we have been passed
+ A true network address, eg, 192.168.1.0/24 and not an
+ IP address on a network, eg, 192.168.1.1/24.
+
+ Raises:
+ AddressValueError: If ipaddr isn't a valid IPv4 address.
+ NetmaskValueError: If the netmask isn't valid for
+ an IPv4 address.
+ ValueError: If strict was True and a network address was not
+ supplied.
+
+ """
+ _BaseNet.__init__(self, address)
+ _BaseV4.__init__(self, address)
+
+ # Efficient constructor from integer.
+ if isinstance(address, (int, long)):
+ self._ip = address
+ self.ip = IPv4Address(self._ip)
+ self._prefixlen = self._max_prefixlen
+ self.netmask = IPv4Address(self._ALL_ONES)
+ if address < 0 or address > self._ALL_ONES:
+ raise AddressValueError(address)
+ return
+
+ # Constructing from a packed address
+ if _compat_has_real_bytes:
+ if isinstance(address, bytes) and len(address) == 4:
+ self._ip = struct.unpack('!I', address)[0]
+ self.ip = IPv4Address(self._ip)
+ self._prefixlen = self._max_prefixlen
+ self.netmask = IPv4Address(self._ALL_ONES)
+ return
+
+ # Assume input argument to be string or any object representation
+ # which converts into a formatted IP prefix string.
+ addr = str(address).split('/')
+
+ if len(addr) > 2:
+ raise AddressValueError(address)
+
+ self._ip = self._ip_int_from_string(addr[0])
+ self.ip = IPv4Address(self._ip)
+
+ if len(addr) == 2:
+ mask = addr[1].split('.')
+ if len(mask) == 4:
+ # We have dotted decimal netmask.
+ if self._is_valid_netmask(addr[1]):
+ self.netmask = IPv4Address(self._ip_int_from_string(
+ addr[1]))
+ elif self._is_hostmask(addr[1]):
+ self.netmask = IPv4Address(
+ self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
+ else:
+ raise NetmaskValueError('%s is not a valid netmask'
+ % addr[1])
+
+ self._prefixlen = self._prefix_from_ip_int(int(self.netmask))
+ else:
+ # We have a netmask in prefix length form.
+ if not self._is_valid_netmask(addr[1]):
+ raise NetmaskValueError(addr[1])
+ self._prefixlen = int(addr[1])
+ self.netmask = IPv4Address(self._ip_int_from_prefix(
+ self._prefixlen))
+ else:
+ self._prefixlen = self._max_prefixlen
+ self.netmask = IPv4Address(self._ip_int_from_prefix(
+ self._prefixlen))
+ if strict:
+ if self.ip != self.network:
+ raise ValueError('%s has host bits set' %
+ self.ip)
+
+ def _is_hostmask(self, ip_str):
+ """Test if the IP string is a hostmask (rather than a netmask).
+
+ Args:
+ ip_str: A string, the potential hostmask.
+
+ Returns:
+ A boolean, True if the IP string is a hostmask.
+
+ """
+ bits = ip_str.split('.')
+ try:
+ parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
+ except ValueError:
+ return False
+ if len(parts) != len(bits):
+ return False
+ if parts[0] < parts[-1]:
+ return True
+ return False
+
+ def _is_valid_netmask(self, netmask):
+ """Verify that the netmask is valid.
+
+ Args:
+ netmask: A string, either a prefix or dotted decimal
+ netmask.
+
+ Returns:
+ A boolean, True if the prefix represents a valid IPv4
+ netmask.
+
+ """
+ mask = netmask.split('.')
+ if len(mask) == 4:
+ if [x for x in mask if int(x) not in self._valid_mask_octets]:
+ return False
+ if [y for idx, y in enumerate(mask) if idx > 0 and
+ y > mask[idx - 1]]:
+ return False
+ return True
+ try:
+ netmask = int(netmask)
+ except ValueError:
+ return False
+ return 0 <= netmask <= self._max_prefixlen
+
+ # backwards compatibility
+ IsRFC1918 = lambda self: self.is_private
+ IsMulticast = lambda self: self.is_multicast
+ IsLoopback = lambda self: self.is_loopback
+ IsLinkLocal = lambda self: self.is_link_local
+
+
+class _BaseV6(object):
+
+ """Base IPv6 object.
+
+ The following methods are used by IPv6 objects in both single IP
+ addresses and networks.
+
+ """
+
+ _ALL_ONES = (2**IPV6LENGTH) - 1
+ _HEXTET_COUNT = 8
+ _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef')
+
+ def __init__(self, address):
+ self._version = 6
+ self._max_prefixlen = IPV6LENGTH
+
+ def _ip_int_from_string(self, ip_str):
+ """Turn an IPv6 ip_str into an integer.
+
+ Args:
+ ip_str: A string, the IPv6 ip_str.
+
+ Returns:
+ A long, the IPv6 ip_str.
+
+ Raises:
+ AddressValueError: if ip_str isn't a valid IPv6 Address.
+
+ """
+ parts = ip_str.split(':')
+
+ # An IPv6 address needs at least 2 colons (3 parts).
+ if len(parts) < 3:
+ raise AddressValueError(ip_str)
+
+ # If the address has an IPv4-style suffix, convert it to hexadecimal.
+ if '.' in parts[-1]:
+ ipv4_int = IPv4Address(parts.pop())._ip
+ parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF))
+ parts.append('%x' % (ipv4_int & 0xFFFF))
+
+ # An IPv6 address can't have more than 8 colons (9 parts).
+ if len(parts) > self._HEXTET_COUNT + 1:
+ raise AddressValueError(ip_str)
+
+ # Disregarding the endpoints, find '::' with nothing in between.
+ # This indicates that a run of zeroes has been skipped.
+ try:
+ skip_index, = (
+ [i for i in xrange(1, len(parts) - 1) if not parts[i]] or
+ [None])
+ except ValueError:
+ # Can't have more than one '::'
+ raise AddressValueError(ip_str)
+
+ # parts_hi is the number of parts to copy from above/before the '::'
+ # parts_lo is the number of parts to copy from below/after the '::'
+ if skip_index is not None:
+ # If we found a '::', then check if it also covers the endpoints.
+ parts_hi = skip_index
+ parts_lo = len(parts) - skip_index - 1
+ if not parts[0]:
+ parts_hi -= 1
+ if parts_hi:
+ raise AddressValueError(ip_str) # ^: requires ^::
+ if not parts[-1]:
+ parts_lo -= 1
+ if parts_lo:
+ raise AddressValueError(ip_str) # :$ requires ::$
+ parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo)
+ if parts_skipped < 1:
+ raise AddressValueError(ip_str)
+ else:
+ # Otherwise, allocate the entire address to parts_hi. The endpoints
+ # could still be empty, but _parse_hextet() will check for that.
+ if len(parts) != self._HEXTET_COUNT:
+ raise AddressValueError(ip_str)
+ parts_hi = len(parts)
+ parts_lo = 0
+ parts_skipped = 0
+
+ try:
+ # Now, parse the hextets into a 128-bit integer.
+ ip_int = 0L
+ for i in xrange(parts_hi):
+ ip_int <<= 16
+ ip_int |= self._parse_hextet(parts[i])
+ ip_int <<= 16 * parts_skipped
+ for i in xrange(-parts_lo, 0):
+ ip_int <<= 16
+ ip_int |= self._parse_hextet(parts[i])
+ return ip_int
+ except ValueError:
+ raise AddressValueError(ip_str)
+
+ def _parse_hextet(self, hextet_str):
+ """Convert an IPv6 hextet string into an integer.
+
+ Args:
+ hextet_str: A string, the number to parse.
+
+ Returns:
+ The hextet as an integer.
+
+ Raises:
+ ValueError: if the input isn't strictly a hex number from [0..FFFF].
+
+ """
+ # Whitelist the characters, since int() allows a lot of bizarre stuff.
+ if not self._HEX_DIGITS.issuperset(hextet_str):
+ raise ValueError
+ hextet_int = int(hextet_str, 16)
+ if hextet_int > 0xFFFF:
+ raise ValueError
+ return hextet_int
+
+ def _compress_hextets(self, hextets):
+ """Compresses a list of hextets.
+
+ Compresses a list of strings, replacing the longest continuous
+ sequence of "0" in the list with "" and adding empty strings at
+ the beginning or at the end of the string such that subsequently
+ calling ":".join(hextets) will produce the compressed version of
+ the IPv6 address.
+
+ Args:
+ hextets: A list of strings, the hextets to compress.
+
+ Returns:
+ A list of strings.
+
+ """
+ best_doublecolon_start = -1
+ best_doublecolon_len = 0
+ doublecolon_start = -1
+ doublecolon_len = 0
+ for index in range(len(hextets)):
+ if hextets[index] == '0':
+ doublecolon_len += 1
+ if doublecolon_start == -1:
+ # Start of a sequence of zeros.
+ doublecolon_start = index
+ if doublecolon_len > best_doublecolon_len:
+ # This is the longest sequence of zeros so far.
+ best_doublecolon_len = doublecolon_len
+ best_doublecolon_start = doublecolon_start
+ else:
+ doublecolon_len = 0
+ doublecolon_start = -1
+
+ if best_doublecolon_len > 1:
+ best_doublecolon_end = (best_doublecolon_start +
+ best_doublecolon_len)
+ # For zeros at the end of the address.
+ if best_doublecolon_end == len(hextets):
+ hextets += ['']
+ hextets[best_doublecolon_start:best_doublecolon_end] = ['']
+ # For zeros at the beginning of the address.
+ if best_doublecolon_start == 0:
+ hextets = [''] + hextets
+
+ return hextets
+
+ def _string_from_ip_int(self, ip_int=None):
+ """Turns a 128-bit integer into hexadecimal notation.
+
+ Args:
+ ip_int: An integer, the IP address.
+
+ Returns:
+ A string, the hexadecimal representation of the address.
+
+ Raises:
+ ValueError: The address is bigger than 128 bits of all ones.
+
+ """
+ if not ip_int and ip_int != 0:
+ ip_int = int(self._ip)
+
+ if ip_int > self._ALL_ONES:
+ raise ValueError('IPv6 address is too large')
+
+ hex_str = '%032x' % ip_int
+ hextets = []
+ for x in range(0, 32, 4):
+ hextets.append('%x' % int(hex_str[x:x+4], 16))
+
+ hextets = self._compress_hextets(hextets)
+ return ':'.join(hextets)
+
+ def _explode_shorthand_ip_string(self, ip_str=None):
+ """Expand a shortened IPv6 address.
+
+ Args:
+ ip_str: A string, the IPv6 address.
+
+ Returns:
+ A string, the expanded IPv6 address.
+
+ """
+ if not ip_str:
+ ip_str = str(self)
+ if isinstance(self, _BaseNet):
+ ip_str = str(self.ip)
+
+ ip_int = self._ip_int_from_string(ip_str)
+ parts = []
+ for i in xrange(self._HEXTET_COUNT):
+ parts.append('%04x' % (ip_int & 0xFFFF))
+ ip_int >>= 16
+ parts.reverse()
+ return ':'.join(parts)
+
+ @property
+ def max_prefixlen(self):
+ return self._max_prefixlen
+
+ @property
+ def packed(self):
+ """The binary representation of this address."""
+ return v6_int_to_packed(self._ip)
+
+ @property
+ def version(self):
+ return self._version
+
+ @property
+ def is_multicast(self):
+ """Test if the address is reserved for multicast use.
+
+ Returns:
+ A boolean, True if the address is a multicast address.
+ See RFC 2373 2.7 for details.
+
+ """
+ return self in IPv6Network('ff00::/8')
+
+ @property
+ def is_reserved(self):
+ """Test if the address is otherwise IETF reserved.
+
+ Returns:
+ A boolean, True if the address is within one of the
+ reserved IPv6 Network ranges.
+
+ """
+ return (self in IPv6Network('::/8') or
+ self in IPv6Network('100::/8') or
+ self in IPv6Network('200::/7') or
+ self in IPv6Network('400::/6') or
+ self in IPv6Network('800::/5') or
+ self in IPv6Network('1000::/4') or
+ self in IPv6Network('4000::/3') or
+ self in IPv6Network('6000::/3') or
+ self in IPv6Network('8000::/3') or
+ self in IPv6Network('A000::/3') or
+ self in IPv6Network('C000::/3') or
+ self in IPv6Network('E000::/4') or
+ self in IPv6Network('F000::/5') or
+ self in IPv6Network('F800::/6') or
+ self in IPv6Network('FE00::/9'))
+
+ @property
+ def is_unspecified(self):
+ """Test if the address is unspecified.
+
+ Returns:
+ A boolean, True if this is the unspecified address as defined in
+ RFC 2373 2.5.2.
+
+ """
+ return self._ip == 0 and getattr(self, '_prefixlen', 128) == 128
+
+ @property
+ def is_loopback(self):
+ """Test if the address is a loopback address.
+
+ Returns:
+ A boolean, True if the address is a loopback address as defined in
+ RFC 2373 2.5.3.
+
+ """
+ return self._ip == 1 and getattr(self, '_prefixlen', 128) == 128
+
+ @property
+ def is_link_local(self):
+ """Test if the address is reserved for link-local.
+
+ Returns:
+ A boolean, True if the address is reserved per RFC 4291.
+
+ """
+ return self in IPv6Network('fe80::/10')
+
+ @property
+ def is_site_local(self):
+ """Test if the address is reserved for site-local.
+
+ Note that the site-local address space has been deprecated by RFC 3879.
+ Use is_private to test if this address is in the space of unique local
+ addresses as defined by RFC 4193.
+
+ Returns:
+ A boolean, True if the address is reserved per RFC 3513 2.5.6.
+
+ """
+ return self in IPv6Network('fec0::/10')
+
+ @property
+ def is_private(self):
+ """Test if this address is allocated for private networks.
+
+ Returns:
+ A boolean, True if the address is reserved per RFC 4193.
+
+ """
+ return self in IPv6Network('fc00::/7')
+
+ @property
+ def ipv4_mapped(self):
+ """Return the IPv4 mapped address.
+
+ Returns:
+ If the IPv6 address is a v4 mapped address, return the
+ IPv4 mapped address. Return None otherwise.
+
+ """
+ if (self._ip >> 32) != 0xFFFF:
+ return None
+ return IPv4Address(self._ip & 0xFFFFFFFF)
+
+ @property
+ def teredo(self):
+ """Tuple of embedded teredo IPs.
+
+ Returns:
+ Tuple of the (server, client) IPs or None if the address
+ doesn't appear to be a teredo address (doesn't start with
+ 2001::/32)
+
+ """
+ if (self._ip >> 96) != 0x20010000:
+ return None
+ return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
+ IPv4Address(~self._ip & 0xFFFFFFFF))
+
+ @property
+ def sixtofour(self):
+ """Return the IPv4 6to4 embedded address.
+
+ Returns:
+ The IPv4 6to4-embedded address if present or None if the
+ address doesn't appear to contain a 6to4 embedded address.
+
+ """
+ if (self._ip >> 112) != 0x2002:
+ return None
+ return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
+
+
+class IPv6Address(_BaseV6, _BaseIP):
+
+ """Represent and manipulate single IPv6 Addresses.
+ """
+
+ def __init__(self, address):
+ """Instantiate a new IPv6 address object.
+
+ Args:
+ address: A string or integer representing the IP
+
+ Additionally, an integer can be passed, so
+ IPv6Address('2001:4860::') ==
+ IPv6Address(42541956101370907050197289607612071936L).
+ or, more generally
+ IPv6Address(IPv6Address('2001:4860::')._ip) ==
+ IPv6Address('2001:4860::')
+
+ Raises:
+ AddressValueError: If address isn't a valid IPv6 address.
+
+ """
+ _BaseIP.__init__(self, address)
+ _BaseV6.__init__(self, address)
+
+ # Efficient constructor from integer.
+ if isinstance(address, (int, long)):
+ self._ip = address
+ if address < 0 or address > self._ALL_ONES:
+ raise AddressValueError(address)
+ return
+
+ # Constructing from a packed address
+ if _compat_has_real_bytes:
+ if isinstance(address, bytes) and len(address) == 16:
+ tmp = struct.unpack('!QQ', address)
+ self._ip = (tmp[0] << 64) | tmp[1]
+ return
+
+ # Assume input argument to be string or any object representation
+ # which converts into a formatted IP string.
+ addr_str = str(address)
+ if not addr_str:
+ raise AddressValueError('')
+
+ self._ip = self._ip_int_from_string(addr_str)
+
+
+class IPv6Network(_BaseV6, _BaseNet):
+
+ """This class represents and manipulates 128-bit IPv6 networks.
+
+ Attributes: [examples for IPv6('2001:658:22A:CAFE:200::1/64')]
+ .ip: IPv6Address('2001:658:22a:cafe:200::1')
+ .network: IPv6Address('2001:658:22a:cafe::')
+ .hostmask: IPv6Address('::ffff:ffff:ffff:ffff')
+ .broadcast: IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff')
+ .netmask: IPv6Address('ffff:ffff:ffff:ffff::')
+ .prefixlen: 64
+
+ """
+
+
+ def __init__(self, address, strict=False):
+ """Instantiate a new IPv6 Network object.
+
+ Args:
+ address: A string or integer representing the IPv6 network or the IP
+ and prefix/netmask.
+ '2001:4860::/128'
+ '2001:4860:0000:0000:0000:0000:0000:0000/128'
+ '2001:4860::'
+ are all functionally the same in IPv6. That is to say,
+ failing to provide a subnetmask will create an object with
+ a mask of /128.
+
+ Additionally, an integer can be passed, so
+ IPv6Network('2001:4860::') ==
+ IPv6Network(42541956101370907050197289607612071936L).
+ or, more generally
+ IPv6Network(IPv6Network('2001:4860::')._ip) ==
+ IPv6Network('2001:4860::')
+
+ strict: A boolean. If true, ensure that we have been passed
+ A true network address, eg, 192.168.1.0/24 and not an
+ IP address on a network, eg, 192.168.1.1/24.
+
+ Raises:
+ AddressValueError: If address isn't a valid IPv6 address.
+ NetmaskValueError: If the netmask isn't valid for
+ an IPv6 address.
+ ValueError: If strict was True and a network address was not
+ supplied.
+
+ """
+ _BaseNet.__init__(self, address)
+ _BaseV6.__init__(self, address)
+
+ # Efficient constructor from integer.
+ if isinstance(address, (int, long)):
+ self._ip = address
+ self.ip = IPv6Address(self._ip)
+ self._prefixlen = self._max_prefixlen
+ self.netmask = IPv6Address(self._ALL_ONES)
+ if address < 0 or address > self._ALL_ONES:
+ raise AddressValueError(address)
+ return
+
+ # Constructing from a packed address
+ if _compat_has_real_bytes:
+ if isinstance(address, bytes) and len(address) == 16:
+ tmp = struct.unpack('!QQ', address)
+ self._ip = (tmp[0] << 64) | tmp[1]
+ self.ip = IPv6Address(self._ip)
+ self._prefixlen = self._max_prefixlen
+ self.netmask = IPv6Address(self._ALL_ONES)
+ return
+
+ # Assume input argument to be string or any object representation
+ # which converts into a formatted IP prefix string.
+ addr = str(address).split('/')
+
+ if len(addr) > 2:
+ raise AddressValueError(address)
+
+ self._ip = self._ip_int_from_string(addr[0])
+ self.ip = IPv6Address(self._ip)
+
+ if len(addr) == 2:
+ if self._is_valid_netmask(addr[1]):
+ self._prefixlen = int(addr[1])
+ else:
+ raise NetmaskValueError(addr[1])
+ else:
+ self._prefixlen = self._max_prefixlen
+
+ self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen))
+
+ if strict:
+ if self.ip != self.network:
+ raise ValueError('%s has host bits set' %
+ self.ip)
+
+ def _is_valid_netmask(self, prefixlen):
+ """Verify that the netmask/prefixlen is valid.
+
+ Args:
+ prefixlen: A string, the netmask in prefix length format.
+
+ Returns:
+ A boolean, True if the prefix represents a valid IPv6
+ netmask.
+
+ """
+ try:
+ prefixlen = int(prefixlen)
+ except ValueError:
+ return False
+ return 0 <= prefixlen <= self._max_prefixlen
+
+ @property
+ def with_netmask(self):
+ return self.with_prefixlen
diff --git a/contrib/ipaddr-py/ipaddr_test.py b/contrib/ipaddr-py/ipaddr_test.py
new file mode 100755
index 000000000..09bece0e7
--- /dev/null
+++ b/contrib/ipaddr-py/ipaddr_test.py
@@ -0,0 +1,1099 @@
+#!/usr/bin/python
+#
+# Copyright 2007 Google Inc.
+# Licensed to PSF under a Contributor Agreement.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Unittest for ipaddr module."""
+
+
+import unittest
+import time
+import ipaddr
+
+# Compatibility function to cast str to bytes objects
+if ipaddr._compat_has_real_bytes:
+ _cb = lambda bytestr: bytes(bytestr, 'charmap')
+else:
+ _cb = str
+
+class IpaddrUnitTest(unittest.TestCase):
+
+ def setUp(self):
+ self.ipv4 = ipaddr.IPv4Network('1.2.3.4/24')
+ self.ipv4_hostmask = ipaddr.IPv4Network('10.0.0.1/0.255.255.255')
+ self.ipv6 = ipaddr.IPv6Network('2001:658:22a:cafe:200:0:0:1/64')
+
+ def tearDown(self):
+ del(self.ipv4)
+ del(self.ipv4_hostmask)
+ del(self.ipv6)
+ del(self)
+
+ def testRepr(self):
+ self.assertEqual("IPv4Network('1.2.3.4/32')",
+ repr(ipaddr.IPv4Network('1.2.3.4')))
+ self.assertEqual("IPv6Network('::1/128')",
+ repr(ipaddr.IPv6Network('::1')))
+
+ def testAutoMasking(self):
+ addr1 = ipaddr.IPv4Network('1.1.1.255/24')
+ addr1_masked = ipaddr.IPv4Network('1.1.1.0/24')
+ self.assertEqual(addr1_masked, addr1.masked())
+
+ addr2 = ipaddr.IPv6Network('2000:cafe::efac:100/96')
+ addr2_masked = ipaddr.IPv6Network('2000:cafe::/96')
+ self.assertEqual(addr2_masked, addr2.masked())
+
+ # issue57
+ def testAddressIntMath(self):
+ self.assertEqual(ipaddr.IPv4Address('1.1.1.1') + 255,
+ ipaddr.IPv4Address('1.1.2.0'))
+ self.assertEqual(ipaddr.IPv4Address('1.1.1.1') - 256,
+ ipaddr.IPv4Address('1.1.0.1'))
+ self.assertEqual(ipaddr.IPv6Address('::1') + (2**16 - 2),
+ ipaddr.IPv6Address('::ffff'))
+ self.assertEqual(ipaddr.IPv6Address('::ffff') - (2**16 - 2),
+ ipaddr.IPv6Address('::1'))
+
+ def testInvalidStrings(self):
+ def AssertInvalidIP(ip_str):
+ self.assertRaises(ValueError, ipaddr.IPAddress, ip_str)
+ AssertInvalidIP("")
+ AssertInvalidIP("016.016.016.016")
+ AssertInvalidIP("016.016.016")
+ AssertInvalidIP("016.016")
+ AssertInvalidIP("016")
+ AssertInvalidIP("000.000.000.000")
+ AssertInvalidIP("000")
+ AssertInvalidIP("0x0a.0x0a.0x0a.0x0a")
+ AssertInvalidIP("0x0a.0x0a.0x0a")
+ AssertInvalidIP("0x0a.0x0a")
+ AssertInvalidIP("0x0a")
+ AssertInvalidIP("42.42.42.42.42")
+ AssertInvalidIP("42.42.42")
+ AssertInvalidIP("42.42")
+ AssertInvalidIP("42")
+ AssertInvalidIP("42..42.42")
+ AssertInvalidIP("42..42.42.42")
+ AssertInvalidIP("42.42.42.42.")
+ AssertInvalidIP("42.42.42.42...")
+ AssertInvalidIP(".42.42.42.42")
+ AssertInvalidIP("...42.42.42.42")
+ AssertInvalidIP("42.42.42.-0")
+ AssertInvalidIP("42.42.42.+0")
+ AssertInvalidIP(".")
+ AssertInvalidIP("...")
+ AssertInvalidIP("bogus")
+ AssertInvalidIP("bogus.com")
+ AssertInvalidIP("192.168.0.1.com")
+ AssertInvalidIP("12345.67899.-54321.-98765")
+ AssertInvalidIP("257.0.0.0")
+ AssertInvalidIP("42.42.42.-42")
+ AssertInvalidIP("3ffe::1.net")
+ AssertInvalidIP("3ffe::1::1")
+ AssertInvalidIP("1::2::3::4:5")
+ AssertInvalidIP("::7:6:5:4:3:2:")
+ AssertInvalidIP(":6:5:4:3:2:1::")
+ AssertInvalidIP("2001::db:::1")
+ AssertInvalidIP("FEDC:9878")
+ AssertInvalidIP("+1.+2.+3.4")
+ AssertInvalidIP("1.2.3.4e0")
+ AssertInvalidIP("::7:6:5:4:3:2:1:0")
+ AssertInvalidIP("7:6:5:4:3:2:1:0::")
+ AssertInvalidIP("9:8:7:6:5:4:3::2:1")
+ AssertInvalidIP("0:1:2:3::4:5:6:7")
+ AssertInvalidIP("3ffe:0:0:0:0:0:0:0:1")
+ AssertInvalidIP("3ffe::10000")
+ AssertInvalidIP("3ffe::goog")
+ AssertInvalidIP("3ffe::-0")
+ AssertInvalidIP("3ffe::+0")
+ AssertInvalidIP("3ffe::-1")
+ AssertInvalidIP(":")
+ AssertInvalidIP(":::")
+ AssertInvalidIP("::1.2.3")
+ AssertInvalidIP("::1.2.3.4.5")
+ AssertInvalidIP("::1.2.3.4:")
+ AssertInvalidIP("1.2.3.4::")
+ AssertInvalidIP("2001:db8::1:")
+ AssertInvalidIP(":2001:db8::1")
+ AssertInvalidIP(":1:2:3:4:5:6:7")
+ AssertInvalidIP("1:2:3:4:5:6:7:")
+ AssertInvalidIP(":1:2:3:4:5:6:")
+
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network, '')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network,
+ 'google.com')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network,
+ '::1.2.3.4')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network, '')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
+ 'google.com')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
+ '1.2.3.4')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
+ 'cafe:cafe::/128/190')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
+ '1234:axy::b')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Address,
+ '1234:axy::b')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Address,
+ '2001:db8:::1')
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Address,
+ '2001:888888::1')
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv4Address(1)._ip_int_from_string,
+ '1.a.2.3')
+ self.assertEqual(False, ipaddr.IPv4Network(1)._is_hostmask('1.a.2.3'))
+
+ def testGetNetwork(self):
+ self.assertEqual(int(self.ipv4.network), 16909056)
+ self.assertEqual(str(self.ipv4.network), '1.2.3.0')
+ self.assertEqual(str(self.ipv4_hostmask.network), '10.0.0.0')
+
+ self.assertEqual(int(self.ipv6.network),
+ 42540616829182469433403647294022090752)
+ self.assertEqual(str(self.ipv6.network),
+ '2001:658:22a:cafe::')
+ self.assertEqual(str(self.ipv6.hostmask),
+ '::ffff:ffff:ffff:ffff')
+
+ def testBadVersionComparison(self):
+ # These should always raise TypeError
+ v4addr = ipaddr.IPAddress('1.1.1.1')
+ v4net = ipaddr.IPNetwork('1.1.1.1')
+ v6addr = ipaddr.IPAddress('::1')
+ v6net = ipaddr.IPAddress('::1')
+
+ self.assertRaises(TypeError, v4addr.__lt__, v6addr)
+ self.assertRaises(TypeError, v4addr.__gt__, v6addr)
+ self.assertRaises(TypeError, v4net.__lt__, v6net)
+ self.assertRaises(TypeError, v4net.__gt__, v6net)
+
+ self.assertRaises(TypeError, v6addr.__lt__, v4addr)
+ self.assertRaises(TypeError, v6addr.__gt__, v4addr)
+ self.assertRaises(TypeError, v6net.__lt__, v4net)
+ self.assertRaises(TypeError, v6net.__gt__, v4net)
+
+ def testMixedTypeComparison(self):
+ v4addr = ipaddr.IPAddress('1.1.1.1')
+ v4net = ipaddr.IPNetwork('1.1.1.1/32')
+ v6addr = ipaddr.IPAddress('::1')
+ v6net = ipaddr.IPNetwork('::1/128')
+
+ self.assertFalse(v4net.__contains__(v6net))
+ self.assertFalse(v6net.__contains__(v4net))
+
+ self.assertRaises(TypeError, lambda: v4addr < v4net)
+ self.assertRaises(TypeError, lambda: v4addr > v4net)
+ self.assertRaises(TypeError, lambda: v4net < v4addr)
+ self.assertRaises(TypeError, lambda: v4net > v4addr)
+
+ self.assertRaises(TypeError, lambda: v6addr < v6net)
+ self.assertRaises(TypeError, lambda: v6addr > v6net)
+ self.assertRaises(TypeError, lambda: v6net < v6addr)
+ self.assertRaises(TypeError, lambda: v6net > v6addr)
+
+ # with get_mixed_type_key, you can sort addresses and network.
+ self.assertEqual([v4addr, v4net], sorted([v4net, v4addr],
+ key=ipaddr.get_mixed_type_key))
+ self.assertEqual([v6addr, v6net], sorted([v6net, v6addr],
+ key=ipaddr.get_mixed_type_key))
+
+ def testIpFromInt(self):
+ self.assertEqual(self.ipv4.ip, ipaddr.IPv4Network(16909060).ip)
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv4Network, 2**32)
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv4Network, -1)
+
+ ipv4 = ipaddr.IPNetwork('1.2.3.4')
+ ipv6 = ipaddr.IPNetwork('2001:658:22a:cafe:200:0:0:1')
+ self.assertEqual(ipv4, ipaddr.IPNetwork(int(ipv4)))
+ self.assertEqual(ipv6, ipaddr.IPNetwork(int(ipv6)))
+
+ v6_int = 42540616829182469433547762482097946625
+ self.assertEqual(self.ipv6.ip, ipaddr.IPv6Network(v6_int).ip)
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv6Network, 2**128)
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv6Network, -1)
+
+ self.assertEqual(ipaddr.IPNetwork(self.ipv4.ip).version, 4)
+ self.assertEqual(ipaddr.IPNetwork(self.ipv6.ip).version, 6)
+
+ if ipaddr._compat_has_real_bytes: # on python3+
+ def testIpFromPacked(self):
+ ip = ipaddr.IPNetwork
+
+ self.assertEqual(self.ipv4.ip,
+ ip(_cb('\x01\x02\x03\x04')).ip)
+ self.assertEqual(ip('255.254.253.252'),
+ ip(_cb('\xff\xfe\xfd\xfc')))
+ self.assertRaises(ValueError, ipaddr.IPNetwork, _cb('\x00' * 3))
+ self.assertRaises(ValueError, ipaddr.IPNetwork, _cb('\x00' * 5))
+ self.assertEqual(self.ipv6.ip,
+ ip(_cb('\x20\x01\x06\x58\x02\x2a\xca\xfe'
+ '\x02\x00\x00\x00\x00\x00\x00\x01')).ip)
+ self.assertEqual(ip('ffff:2:3:4:ffff::'),
+ ip(_cb('\xff\xff\x00\x02\x00\x03\x00\x04' +
+ '\xff\xff' + '\x00' * 6)))
+ self.assertEqual(ip('::'),
+ ip(_cb('\x00' * 16)))
+ self.assertRaises(ValueError, ip, _cb('\x00' * 15))
+ self.assertRaises(ValueError, ip, _cb('\x00' * 17))
+
+ def testGetIp(self):
+ self.assertEqual(int(self.ipv4.ip), 16909060)
+ self.assertEqual(str(self.ipv4.ip), '1.2.3.4')
+ self.assertEqual(str(self.ipv4_hostmask.ip), '10.0.0.1')
+
+ self.assertEqual(int(self.ipv6.ip),
+ 42540616829182469433547762482097946625)
+ self.assertEqual(str(self.ipv6.ip),
+ '2001:658:22a:cafe:200::1')
+
+ def testGetNetmask(self):
+ self.assertEqual(int(self.ipv4.netmask), 4294967040L)
+ self.assertEqual(str(self.ipv4.netmask), '255.255.255.0')
+ self.assertEqual(str(self.ipv4_hostmask.netmask), '255.0.0.0')
+ self.assertEqual(int(self.ipv6.netmask),
+ 340282366920938463444927863358058659840)
+ self.assertEqual(self.ipv6.prefixlen, 64)
+
+ def testZeroNetmask(self):
+ ipv4_zero_netmask = ipaddr.IPv4Network('1.2.3.4/0')
+ self.assertEqual(int(ipv4_zero_netmask.netmask), 0)
+ self.assertTrue(ipv4_zero_netmask._is_valid_netmask(str(0)))
+
+ ipv6_zero_netmask = ipaddr.IPv6Network('::1/0')
+ self.assertEqual(int(ipv6_zero_netmask.netmask), 0)
+ self.assertTrue(ipv6_zero_netmask._is_valid_netmask(str(0)))
+
+ def testGetBroadcast(self):
+ self.assertEqual(int(self.ipv4.broadcast), 16909311L)
+ self.assertEqual(str(self.ipv4.broadcast), '1.2.3.255')
+
+ self.assertEqual(int(self.ipv6.broadcast),
+ 42540616829182469451850391367731642367)
+ self.assertEqual(str(self.ipv6.broadcast),
+ '2001:658:22a:cafe:ffff:ffff:ffff:ffff')
+
+ def testGetPrefixlen(self):
+ self.assertEqual(self.ipv4.prefixlen, 24)
+
+ self.assertEqual(self.ipv6.prefixlen, 64)
+
+ def testGetSupernet(self):
+ self.assertEqual(self.ipv4.supernet().prefixlen, 23)
+ self.assertEqual(str(self.ipv4.supernet().network), '1.2.2.0')
+ self.assertEqual(ipaddr.IPv4Network('0.0.0.0/0').supernet(),
+ ipaddr.IPv4Network('0.0.0.0/0'))
+
+ self.assertEqual(self.ipv6.supernet().prefixlen, 63)
+ self.assertEqual(str(self.ipv6.supernet().network),
+ '2001:658:22a:cafe::')
+ self.assertEqual(ipaddr.IPv6Network('::0/0').supernet(),
+ ipaddr.IPv6Network('::0/0'))
+
+ def testGetSupernet3(self):
+ self.assertEqual(self.ipv4.supernet(3).prefixlen, 21)
+ self.assertEqual(str(self.ipv4.supernet(3).network), '1.2.0.0')
+
+ self.assertEqual(self.ipv6.supernet(3).prefixlen, 61)
+ self.assertEqual(str(self.ipv6.supernet(3).network),
+ '2001:658:22a:caf8::')
+
+ def testGetSupernet4(self):
+ self.assertRaises(ValueError, self.ipv4.supernet, prefixlen_diff=2,
+ new_prefix=1)
+ self.assertRaises(ValueError, self.ipv4.supernet, new_prefix=25)
+ self.assertEqual(self.ipv4.supernet(prefixlen_diff=2),
+ self.ipv4.supernet(new_prefix=22))
+
+ self.assertRaises(ValueError, self.ipv6.supernet, prefixlen_diff=2,
+ new_prefix=1)
+ self.assertRaises(ValueError, self.ipv6.supernet, new_prefix=65)
+ self.assertEqual(self.ipv6.supernet(prefixlen_diff=2),
+ self.ipv6.supernet(new_prefix=62))
+
+ def testIterSubnets(self):
+ self.assertEqual(self.ipv4.subnet(), list(self.ipv4.iter_subnets()))
+ self.assertEqual(self.ipv6.subnet(), list(self.ipv6.iter_subnets()))
+
+ def testFancySubnetting(self):
+ self.assertEqual(sorted(self.ipv4.subnet(prefixlen_diff=3)),
+ sorted(self.ipv4.subnet(new_prefix=27)))
+ self.assertRaises(ValueError, self.ipv4.subnet, new_prefix=23)
+ self.assertRaises(ValueError, self.ipv4.subnet,
+ prefixlen_diff=3, new_prefix=27)
+ self.assertEqual(sorted(self.ipv6.subnet(prefixlen_diff=4)),
+ sorted(self.ipv6.subnet(new_prefix=68)))
+ self.assertRaises(ValueError, self.ipv6.subnet, new_prefix=63)
+ self.assertRaises(ValueError, self.ipv6.subnet,
+ prefixlen_diff=4, new_prefix=68)
+
+ def testGetSubnet(self):
+ self.assertEqual(self.ipv4.subnet()[0].prefixlen, 25)
+ self.assertEqual(str(self.ipv4.subnet()[0].network), '1.2.3.0')
+ self.assertEqual(str(self.ipv4.subnet()[1].network), '1.2.3.128')
+
+ self.assertEqual(self.ipv6.subnet()[0].prefixlen, 65)
+
+ def testGetSubnetForSingle32(self):
+ ip = ipaddr.IPv4Network('1.2.3.4/32')
+ subnets1 = [str(x) for x in ip.subnet()]
+ subnets2 = [str(x) for x in ip.subnet(2)]
+ self.assertEqual(subnets1, ['1.2.3.4/32'])
+ self.assertEqual(subnets1, subnets2)
+
+ def testGetSubnetForSingle128(self):
+ ip = ipaddr.IPv6Network('::1/128')
+ subnets1 = [str(x) for x in ip.subnet()]
+ subnets2 = [str(x) for x in ip.subnet(2)]
+ self.assertEqual(subnets1, ['::1/128'])
+ self.assertEqual(subnets1, subnets2)
+
+ def testSubnet2(self):
+ ips = [str(x) for x in self.ipv4.subnet(2)]
+ self.assertEqual(
+ ips,
+ ['1.2.3.0/26', '1.2.3.64/26', '1.2.3.128/26', '1.2.3.192/26'])
+
+ ipsv6 = [str(x) for x in self.ipv6.subnet(2)]
+ self.assertEqual(
+ ipsv6,
+ ['2001:658:22a:cafe::/66',
+ '2001:658:22a:cafe:4000::/66',
+ '2001:658:22a:cafe:8000::/66',
+ '2001:658:22a:cafe:c000::/66'])
+
+ def testSubnetFailsForLargeCidrDiff(self):
+ self.assertRaises(ValueError, self.ipv4.subnet, 9)
+ self.assertRaises(ValueError, self.ipv6.subnet, 65)
+
+ def testSupernetFailsForLargeCidrDiff(self):
+ self.assertRaises(ValueError, self.ipv4.supernet, 25)
+ self.assertRaises(ValueError, self.ipv6.supernet, 65)
+
+ def testSubnetFailsForNegativeCidrDiff(self):
+ self.assertRaises(ValueError, self.ipv4.subnet, -1)
+ self.assertRaises(ValueError, self.ipv6.subnet, -1)
+
+ def testGetNumHosts(self):
+ self.assertEqual(self.ipv4.numhosts, 256)
+ self.assertEqual(self.ipv4.subnet()[0].numhosts, 128)
+ self.assertEqual(self.ipv4.supernet().numhosts, 512)
+
+ self.assertEqual(self.ipv6.numhosts, 18446744073709551616)
+ self.assertEqual(self.ipv6.subnet()[0].numhosts, 9223372036854775808)
+ self.assertEqual(self.ipv6.supernet().numhosts, 36893488147419103232)
+
+ def testContains(self):
+ self.assertTrue(ipaddr.IPv4Network('1.2.3.128/25') in self.ipv4)
+ self.assertFalse(ipaddr.IPv4Network('1.2.4.1/24') in self.ipv4)
+ self.assertTrue(self.ipv4 in self.ipv4)
+ self.assertTrue(self.ipv6 in self.ipv6)
+ # We can test addresses and string as well.
+ addr1 = ipaddr.IPv4Address('1.2.3.37')
+ self.assertTrue(addr1 in self.ipv4)
+ # issue 61, bad network comparison on like-ip'd network objects
+ # with identical broadcast addresses.
+ self.assertFalse(ipaddr.IPv4Network('1.1.0.0/16').__contains__(
+ ipaddr.IPv4Network('1.0.0.0/15')))
+
+ def testBadAddress(self):
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network,
+ 'poop')
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv4Network, '1.2.3.256')
+
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
+ 'poopv6')
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv4Network, '1.2.3.4/32/24')
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv4Network, '10/8')
+ self.assertRaises(ipaddr.AddressValueError,
+ ipaddr.IPv6Network, '10/8')
+
+
+ def testBadNetMask(self):
+ self.assertRaises(ipaddr.NetmaskValueError,
+ ipaddr.IPv4Network, '1.2.3.4/')
+ self.assertRaises(ipaddr.NetmaskValueError,
+ ipaddr.IPv4Network, '1.2.3.4/33')
+ self.assertRaises(ipaddr.NetmaskValueError,
+ ipaddr.IPv4Network, '1.2.3.4/254.254.255.256')
+ self.assertRaises(ipaddr.NetmaskValueError,
+ ipaddr.IPv4Network, '1.1.1.1/240.255.0.0')
+ self.assertRaises(ipaddr.NetmaskValueError,
+ ipaddr.IPv6Network, '::1/')
+ self.assertRaises(ipaddr.NetmaskValueError,
+ ipaddr.IPv6Network, '::1/129')
+
+ def testNth(self):
+ self.assertEqual(str(self.ipv4[5]), '1.2.3.5')
+ self.assertRaises(IndexError, self.ipv4.__getitem__, 256)
+
+ self.assertEqual(str(self.ipv6[5]),
+ '2001:658:22a:cafe::5')
+
+ def testGetitem(self):
+ # http://code.google.com/p/ipaddr-py/issues/detail?id=15
+ addr = ipaddr.IPv4Network('172.31.255.128/255.255.255.240')
+ self.assertEqual(28, addr.prefixlen)
+ addr_list = list(addr)
+ self.assertEqual('172.31.255.128', str(addr_list[0]))
+ self.assertEqual('172.31.255.128', str(addr[0]))
+ self.assertEqual('172.31.255.143', str(addr_list[-1]))
+ self.assertEqual('172.31.255.143', str(addr[-1]))
+ self.assertEqual(addr_list[-1], addr[-1])
+
+ def testEqual(self):
+ self.assertTrue(self.ipv4 == ipaddr.IPv4Network('1.2.3.4/24'))
+ self.assertFalse(self.ipv4 == ipaddr.IPv4Network('1.2.3.4/23'))
+ self.assertFalse(self.ipv4 == ipaddr.IPv6Network('::1.2.3.4/24'))
+ self.assertFalse(self.ipv4 == '')
+ self.assertFalse(self.ipv4 == [])
+ self.assertFalse(self.ipv4 == 2)
+ self.assertTrue(ipaddr.IPNetwork('1.1.1.1/32') ==
+ ipaddr.IPAddress('1.1.1.1'))
+ self.assertTrue(ipaddr.IPNetwork('1.1.1.1/24') ==
+ ipaddr.IPAddress('1.1.1.1'))
+ self.assertFalse(ipaddr.IPNetwork('1.1.1.0/24') ==
+ ipaddr.IPAddress('1.1.1.1'))
+
+ self.assertTrue(self.ipv6 ==
+ ipaddr.IPv6Network('2001:658:22a:cafe:200::1/64'))
+ self.assertTrue(ipaddr.IPNetwork('::1/128') ==
+ ipaddr.IPAddress('::1'))
+ self.assertTrue(ipaddr.IPNetwork('::1/127') ==
+ ipaddr.IPAddress('::1'))
+ self.assertFalse(ipaddr.IPNetwork('::0/127') ==
+ ipaddr.IPAddress('::1'))
+ self.assertFalse(self.ipv6 ==
+ ipaddr.IPv6Network('2001:658:22a:cafe:200::1/63'))
+ self.assertFalse(self.ipv6 == ipaddr.IPv4Network('1.2.3.4/23'))
+ self.assertFalse(self.ipv6 == '')
+ self.assertFalse(self.ipv6 == [])
+ self.assertFalse(self.ipv6 == 2)
+
+ def testNotEqual(self):
+ self.assertFalse(self.ipv4 != ipaddr.IPv4Network('1.2.3.4/24'))
+ self.assertTrue(self.ipv4 != ipaddr.IPv4Network('1.2.3.4/23'))
+ self.assertTrue(self.ipv4 != ipaddr.IPv6Network('::1.2.3.4/24'))
+ self.assertTrue(self.ipv4 != '')
+ self.assertTrue(self.ipv4 != [])
+ self.assertTrue(self.ipv4 != 2)
+
+ addr2 = ipaddr.IPAddress('2001:658:22a:cafe:200::1')
+ self.assertFalse(self.ipv6 !=
+ ipaddr.IPv6Network('2001:658:22a:cafe:200::1/64'))
+ self.assertTrue(self.ipv6 !=
+ ipaddr.IPv6Network('2001:658:22a:cafe:200::1/63'))
+ self.assertTrue(self.ipv6 != ipaddr.IPv4Network('1.2.3.4/23'))
+ self.assertTrue(self.ipv6 != '')
+ self.assertTrue(self.ipv6 != [])
+ self.assertTrue(self.ipv6 != 2)
+
+ def testSlash32Constructor(self):
+ self.assertEqual(str(ipaddr.IPv4Network('1.2.3.4/255.255.255.255')),
+ '1.2.3.4/32')
+
+ def testSlash128Constructor(self):
+ self.assertEqual(str(ipaddr.IPv6Network('::1/128')),
+ '::1/128')
+
+ def testSlash0Constructor(self):
+ self.assertEqual(str(ipaddr.IPv4Network('1.2.3.4/0.0.0.0')),
+ '1.2.3.4/0')
+
+ def testCollapsing(self):
+ # test only IP addresses including some duplicates
+ ip1 = ipaddr.IPv4Address('1.1.1.0')
+ ip2 = ipaddr.IPv4Address('1.1.1.1')
+ ip3 = ipaddr.IPv4Address('1.1.1.2')
+ ip4 = ipaddr.IPv4Address('1.1.1.3')
+ ip5 = ipaddr.IPv4Address('1.1.1.4')
+ ip6 = ipaddr.IPv4Address('1.1.1.0')
+ # check that addreses are subsumed properly.
+ collapsed = ipaddr.collapse_address_list([ip1, ip2, ip3, ip4, ip5, ip6])
+ self.assertEqual(collapsed, [ipaddr.IPv4Network('1.1.1.0/30'),
+ ipaddr.IPv4Network('1.1.1.4/32')])
+
+ # test a mix of IP addresses and networks including some duplicates
+ ip1 = ipaddr.IPv4Address('1.1.1.0')
+ ip2 = ipaddr.IPv4Address('1.1.1.1')
+ ip3 = ipaddr.IPv4Address('1.1.1.2')
+ ip4 = ipaddr.IPv4Address('1.1.1.3')
+ ip5 = ipaddr.IPv4Network('1.1.1.4/30')
+ ip6 = ipaddr.IPv4Network('1.1.1.4/30')
+ # check that addreses are subsumed properly.
+ collapsed = ipaddr.collapse_address_list([ip5, ip1, ip2, ip3, ip4, ip6])
+ self.assertEqual(collapsed, [ipaddr.IPv4Network('1.1.1.0/29')])
+
+ # test only IP networks
+ ip1 = ipaddr.IPv4Network('1.1.0.0/24')
+ ip2 = ipaddr.IPv4Network('1.1.1.0/24')
+ ip3 = ipaddr.IPv4Network('1.1.2.0/24')
+ ip4 = ipaddr.IPv4Network('1.1.3.0/24')
+ ip5 = ipaddr.IPv4Network('1.1.4.0/24')
+ # stored in no particular order b/c we want CollapseAddr to call [].sort
+ ip6 = ipaddr.IPv4Network('1.1.0.0/22')
+ # check that addreses are subsumed properly.
+ collapsed = ipaddr.collapse_address_list([ip1, ip2, ip3, ip4, ip5, ip6])
+ self.assertEqual(collapsed, [ipaddr.IPv4Network('1.1.0.0/22'),
+ ipaddr.IPv4Network('1.1.4.0/24')])
+
+ # test that two addresses are supernet'ed properly
+ collapsed = ipaddr.collapse_address_list([ip1, ip2])
+ self.assertEqual(collapsed, [ipaddr.IPv4Network('1.1.0.0/23')])
+
+ # test same IP networks
+ ip_same1 = ip_same2 = ipaddr.IPv4Network('1.1.1.1/32')
+ self.assertEqual(ipaddr.collapse_address_list([ip_same1, ip_same2]),
+ [ip_same1])
+
+ # test same IP addresses
+ ip_same1 = ip_same2 = ipaddr.IPv4Address('1.1.1.1')
+ self.assertEqual(ipaddr.collapse_address_list([ip_same1, ip_same2]),
+ [ipaddr.IPNetwork('1.1.1.1/32')])
+ ip1 = ipaddr.IPv6Network('::2001:1/100')
+ ip2 = ipaddr.IPv6Network('::2002:1/120')
+ ip3 = ipaddr.IPv6Network('::2001:1/96')
+ # test that ipv6 addresses are subsumed properly.
+ collapsed = ipaddr.collapse_address_list([ip1, ip2, ip3])
+ self.assertEqual(collapsed, [ip3])
+
+ # the toejam test
+ ip1 = ipaddr.IPAddress('1.1.1.1')
+ ip2 = ipaddr.IPAddress('::1')
+ self.assertRaises(TypeError, ipaddr.collapse_address_list,
+ [ip1, ip2])
+
+ def testSummarizing(self):
+ #ip = ipaddr.IPAddress
+ #ipnet = ipaddr.IPNetwork
+ summarize = ipaddr.summarize_address_range
+ ip1 = ipaddr.IPAddress('1.1.1.0')
+ ip2 = ipaddr.IPAddress('1.1.1.255')
+ # test a /24 is sumamrized properly
+ self.assertEqual(summarize(ip1, ip2)[0], ipaddr.IPNetwork('1.1.1.0/24'))
+ # test an IPv4 range that isn't on a network byte boundary
+ ip2 = ipaddr.IPAddress('1.1.1.8')
+ self.assertEqual(summarize(ip1, ip2), [ipaddr.IPNetwork('1.1.1.0/29'),
+ ipaddr.IPNetwork('1.1.1.8')])
+
+ ip1 = ipaddr.IPAddress('1::')
+ ip2 = ipaddr.IPAddress('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
+ # test a IPv6 is sumamrized properly
+ self.assertEqual(summarize(ip1, ip2)[0], ipaddr.IPNetwork('1::/16'))
+ # test an IPv6 range that isn't on a network byte boundary
+ ip2 = ipaddr.IPAddress('2::')
+ self.assertEqual(summarize(ip1, ip2), [ipaddr.IPNetwork('1::/16'),
+ ipaddr.IPNetwork('2::/128')])
+
+ # test exception raised when first is greater than last
+ self.assertRaises(ValueError, summarize, ipaddr.IPAddress('1.1.1.0'),
+ ipaddr.IPAddress('1.1.0.0'))
+ # test exception raised when first and last aren't IP addresses
+ self.assertRaises(TypeError, summarize,
+ ipaddr.IPNetwork('1.1.1.0'),
+ ipaddr.IPNetwork('1.1.0.0'))
+ self.assertRaises(TypeError, summarize,
+ ipaddr.IPNetwork('1.1.1.0'), ipaddr.IPNetwork('1.1.0.0'))
+ # test exception raised when first and last are not same version
+ self.assertRaises(TypeError, summarize, ipaddr.IPAddress('::'),
+ ipaddr.IPNetwork('1.1.0.0'))
+
+ def testAddressComparison(self):
+ self.assertTrue(ipaddr.IPAddress('1.1.1.1') <=
+ ipaddr.IPAddress('1.1.1.1'))
+ self.assertTrue(ipaddr.IPAddress('1.1.1.1') <=
+ ipaddr.IPAddress('1.1.1.2'))
+ self.assertTrue(ipaddr.IPAddress('::1') <= ipaddr.IPAddress('::1'))
+ self.assertTrue(ipaddr.IPAddress('::1') <= ipaddr.IPAddress('::2'))
+
+ def testNetworkComparison(self):
+ # ip1 and ip2 have the same network address
+ ip1 = ipaddr.IPv4Network('1.1.1.0/24')
+ ip2 = ipaddr.IPv4Network('1.1.1.1/24')
+ ip3 = ipaddr.IPv4Network('1.1.2.0/24')
+
+ self.assertTrue(ip1 < ip3)
+ self.assertTrue(ip3 > ip2)
+
+ self.assertEqual(ip1.compare_networks(ip2), 0)
+ self.assertTrue(ip1._get_networks_key() == ip2._get_networks_key())
+ self.assertEqual(ip1.compare_networks(ip3), -1)
+ self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
+
+ ip1 = ipaddr.IPv6Network('2001::2000/96')
+ ip2 = ipaddr.IPv6Network('2001::2001/96')
+ ip3 = ipaddr.IPv6Network('2001:ffff::2000/96')
+
+ self.assertTrue(ip1 < ip3)
+ self.assertTrue(ip3 > ip2)
+ self.assertEqual(ip1.compare_networks(ip2), 0)
+ self.assertTrue(ip1._get_networks_key() == ip2._get_networks_key())
+ self.assertEqual(ip1.compare_networks(ip3), -1)
+ self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
+
+ # Test comparing different protocols.
+ # Should always raise a TypeError.
+ ipv6 = ipaddr.IPv6Network('::/0')
+ ipv4 = ipaddr.IPv4Network('0.0.0.0/0')
+ self.assertRaises(TypeError, ipv4.__lt__, ipv6)
+ self.assertRaises(TypeError, ipv4.__gt__, ipv6)
+ self.assertRaises(TypeError, ipv6.__lt__, ipv4)
+ self.assertRaises(TypeError, ipv6.__gt__, ipv4)
+
+ # Regression test for issue 19.
+ ip1 = ipaddr.IPNetwork('10.1.2.128/25')
+ self.assertFalse(ip1 < ip1)
+ self.assertFalse(ip1 > ip1)
+ ip2 = ipaddr.IPNetwork('10.1.3.0/24')
+ self.assertTrue(ip1 < ip2)
+ self.assertFalse(ip2 < ip1)
+ self.assertFalse(ip1 > ip2)
+ self.assertTrue(ip2 > ip1)
+ ip3 = ipaddr.IPNetwork('10.1.3.0/25')
+ self.assertTrue(ip2 < ip3)
+ self.assertFalse(ip3 < ip2)
+ self.assertFalse(ip2 > ip3)
+ self.assertTrue(ip3 > ip2)
+
+ # Regression test for issue 28.
+ ip1 = ipaddr.IPNetwork('10.10.10.0/31')
+ ip2 = ipaddr.IPNetwork('10.10.10.0')
+ ip3 = ipaddr.IPNetwork('10.10.10.2/31')
+ ip4 = ipaddr.IPNetwork('10.10.10.2')
+ sorted = [ip1, ip2, ip3, ip4]
+ unsorted = [ip2, ip4, ip1, ip3]
+ unsorted.sort()
+ self.assertEqual(sorted, unsorted)
+ unsorted = [ip4, ip1, ip3, ip2]
+ unsorted.sort()
+ self.assertEqual(sorted, unsorted)
+ self.assertRaises(TypeError, ip1.__lt__, ipaddr.IPAddress('10.10.10.0'))
+ self.assertRaises(TypeError, ip2.__lt__, ipaddr.IPAddress('10.10.10.0'))
+
+ # <=, >=
+ self.assertTrue(ipaddr.IPNetwork('1.1.1.1') <=
+ ipaddr.IPNetwork('1.1.1.1'))
+ self.assertTrue(ipaddr.IPNetwork('1.1.1.1') <=
+ ipaddr.IPNetwork('1.1.1.2'))
+ self.assertFalse(ipaddr.IPNetwork('1.1.1.2') <=
+ ipaddr.IPNetwork('1.1.1.1'))
+ self.assertTrue(ipaddr.IPNetwork('::1') <= ipaddr.IPNetwork('::1'))
+ self.assertTrue(ipaddr.IPNetwork('::1') <= ipaddr.IPNetwork('::2'))
+ self.assertFalse(ipaddr.IPNetwork('::2') <= ipaddr.IPNetwork('::1'))
+
+ def testStrictNetworks(self):
+ self.assertRaises(ValueError, ipaddr.IPNetwork, '192.168.1.1/24',
+ strict=True)
+ self.assertRaises(ValueError, ipaddr.IPNetwork, '::1/120', strict=True)
+
+ def testOverlaps(self):
+ other = ipaddr.IPv4Network('1.2.3.0/30')
+ other2 = ipaddr.IPv4Network('1.2.2.0/24')
+ other3 = ipaddr.IPv4Network('1.2.2.64/26')
+ self.assertTrue(self.ipv4.overlaps(other))
+ self.assertFalse(self.ipv4.overlaps(other2))
+ self.assertTrue(other2.overlaps(other3))
+
+ def testEmbeddedIpv4(self):
+ ipv4_string = '192.168.0.1'
+ ipv4 = ipaddr.IPv4Network(ipv4_string)
+ v4compat_ipv6 = ipaddr.IPv6Network('::%s' % ipv4_string)
+ self.assertEqual(int(v4compat_ipv6.ip), int(ipv4.ip))
+ v4mapped_ipv6 = ipaddr.IPv6Network('::ffff:%s' % ipv4_string)
+ self.assertNotEqual(v4mapped_ipv6.ip, ipv4.ip)
+ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
+ '2001:1.1.1.1:1.1.1.1')
+
+ # Issue 67: IPv6 with embedded IPv4 address not recognized.
+ def testIPv6AddressTooLarge(self):
+ # RFC4291 2.5.5.2
+ self.assertEqual(ipaddr.IPAddress('::FFFF:192.0.2.1'),
+ ipaddr.IPAddress('::FFFF:c000:201'))
+ # RFC4291 2.2 (part 3) x::d.d.d.d
+ self.assertEqual(ipaddr.IPAddress('FFFF::192.0.2.1'),
+ ipaddr.IPAddress('FFFF::c000:201'))
+
+ def testIPVersion(self):
+ self.assertEqual(self.ipv4.version, 4)
+ self.assertEqual(self.ipv6.version, 6)
+
+ def testMaxPrefixLength(self):
+ self.assertEqual(self.ipv4.max_prefixlen, 32)
+ self.assertEqual(self.ipv6.max_prefixlen, 128)
+
+ def testPacked(self):
+ self.assertEqual(self.ipv4.packed,
+ _cb('\x01\x02\x03\x04'))
+ self.assertEqual(ipaddr.IPv4Network('255.254.253.252').packed,
+ _cb('\xff\xfe\xfd\xfc'))
+ self.assertEqual(self.ipv6.packed,
+ _cb('\x20\x01\x06\x58\x02\x2a\xca\xfe'
+ '\x02\x00\x00\x00\x00\x00\x00\x01'))
+ self.assertEqual(ipaddr.IPv6Network('ffff:2:3:4:ffff::').packed,
+ _cb('\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff'
+ + '\x00' * 6))
+ self.assertEqual(ipaddr.IPv6Network('::1:0:0:0:0').packed,
+ _cb('\x00' * 6 + '\x00\x01' + '\x00' * 8))
+
+ def testIpStrFromPrefixlen(self):
+ ipv4 = ipaddr.IPv4Network('1.2.3.4/24')
+ self.assertEqual(ipv4._ip_string_from_prefix(), '255.255.255.0')
+ self.assertEqual(ipv4._ip_string_from_prefix(28), '255.255.255.240')
+
+ def testIpType(self):
+ ipv4net = ipaddr.IPNetwork('1.2.3.4')
+ ipv4addr = ipaddr.IPAddress('1.2.3.4')
+ ipv6net = ipaddr.IPNetwork('::1.2.3.4')
+ ipv6addr = ipaddr.IPAddress('::1.2.3.4')
+ self.assertEqual(ipaddr.IPv4Network, type(ipv4net))
+ self.assertEqual(ipaddr.IPv4Address, type(ipv4addr))
+ self.assertEqual(ipaddr.IPv6Network, type(ipv6net))
+ self.assertEqual(ipaddr.IPv6Address, type(ipv6addr))
+
+ def testReservedIpv4(self):
+ # test networks
+ self.assertEqual(True, ipaddr.IPNetwork('224.1.1.1/31').is_multicast)
+ self.assertEqual(False, ipaddr.IPNetwork('240.0.0.0').is_multicast)
+
+ self.assertEqual(True, ipaddr.IPNetwork('192.168.1.1/17').is_private)
+ self.assertEqual(False, ipaddr.IPNetwork('192.169.0.0').is_private)
+ self.assertEqual(True, ipaddr.IPNetwork('10.255.255.255').is_private)
+ self.assertEqual(False, ipaddr.IPNetwork('11.0.0.0').is_private)
+ self.assertEqual(True, ipaddr.IPNetwork('172.31.255.255').is_private)
+ self.assertEqual(False, ipaddr.IPNetwork('172.32.0.0').is_private)
+
+ self.assertEqual(True,
+ ipaddr.IPNetwork('169.254.100.200/24').is_link_local)
+ self.assertEqual(False,
+ ipaddr.IPNetwork('169.255.100.200/24').is_link_local)
+
+ self.assertEqual(True,
+ ipaddr.IPNetwork('127.100.200.254/32').is_loopback)
+ self.assertEqual(True, ipaddr.IPNetwork('127.42.0.0/16').is_loopback)
+ self.assertEqual(False, ipaddr.IPNetwork('128.0.0.0').is_loopback)
+
+ # test addresses
+ self.assertEqual(True, ipaddr.IPAddress('224.1.1.1').is_multicast)
+ self.assertEqual(False, ipaddr.IPAddress('240.0.0.0').is_multicast)
+
+ self.assertEqual(True, ipaddr.IPAddress('192.168.1.1').is_private)
+ self.assertEqual(False, ipaddr.IPAddress('192.169.0.0').is_private)
+ self.assertEqual(True, ipaddr.IPAddress('10.255.255.255').is_private)
+ self.assertEqual(False, ipaddr.IPAddress('11.0.0.0').is_private)
+ self.assertEqual(True, ipaddr.IPAddress('172.31.255.255').is_private)
+ self.assertEqual(False, ipaddr.IPAddress('172.32.0.0').is_private)
+
+ self.assertEqual(True,
+ ipaddr.IPAddress('169.254.100.200').is_link_local)
+ self.assertEqual(False,
+ ipaddr.IPAddress('169.255.100.200').is_link_local)
+
+ self.assertEqual(True,
+ ipaddr.IPAddress('127.100.200.254').is_loopback)
+ self.assertEqual(True, ipaddr.IPAddress('127.42.0.0').is_loopback)
+ self.assertEqual(False, ipaddr.IPAddress('128.0.0.0').is_loopback)
+ self.assertEqual(True, ipaddr.IPNetwork('0.0.0.0').is_unspecified)
+
+ def testReservedIpv6(self):
+
+ self.assertEqual(True, ipaddr.IPNetwork('ffff::').is_multicast)
+ self.assertEqual(True, ipaddr.IPNetwork(2**128-1).is_multicast)
+ self.assertEqual(True, ipaddr.IPNetwork('ff00::').is_multicast)
+ self.assertEqual(False, ipaddr.IPNetwork('fdff::').is_multicast)
+
+ self.assertEqual(True, ipaddr.IPNetwork('fecf::').is_site_local)
+ self.assertEqual(True, ipaddr.IPNetwork(
+ 'feff:ffff:ffff:ffff::').is_site_local)
+ self.assertEqual(False, ipaddr.IPNetwork('fbf:ffff::').is_site_local)
+ self.assertEqual(False, ipaddr.IPNetwork('ff00::').is_site_local)
+
+ self.assertEqual(True, ipaddr.IPNetwork('fc00::').is_private)
+ self.assertEqual(True, ipaddr.IPNetwork(
+ 'fc00:ffff:ffff:ffff::').is_private)
+ self.assertEqual(False, ipaddr.IPNetwork('fbff:ffff::').is_private)
+ self.assertEqual(False, ipaddr.IPNetwork('fe00::').is_private)
+
+ self.assertEqual(True, ipaddr.IPNetwork('fea0::').is_link_local)
+ self.assertEqual(True, ipaddr.IPNetwork('febf:ffff::').is_link_local)
+ self.assertEqual(False, ipaddr.IPNetwork('fe7f:ffff::').is_link_local)
+ self.assertEqual(False, ipaddr.IPNetwork('fec0::').is_link_local)
+
+ self.assertEqual(True, ipaddr.IPNetwork('0:0::0:01').is_loopback)
+ self.assertEqual(False, ipaddr.IPNetwork('::1/127').is_loopback)
+ self.assertEqual(False, ipaddr.IPNetwork('::').is_loopback)
+ self.assertEqual(False, ipaddr.IPNetwork('::2').is_loopback)
+
+ self.assertEqual(True, ipaddr.IPNetwork('0::0').is_unspecified)
+ self.assertEqual(False, ipaddr.IPNetwork('::1').is_unspecified)
+ self.assertEqual(False, ipaddr.IPNetwork('::/127').is_unspecified)
+
+ # test addresses
+ self.assertEqual(True, ipaddr.IPAddress('ffff::').is_multicast)
+ self.assertEqual(True, ipaddr.IPAddress(2**128-1).is_multicast)
+ self.assertEqual(True, ipaddr.IPAddress('ff00::').is_multicast)
+ self.assertEqual(False, ipaddr.IPAddress('fdff::').is_multicast)
+
+ self.assertEqual(True, ipaddr.IPAddress('fecf::').is_site_local)
+ self.assertEqual(True, ipaddr.IPAddress(
+ 'feff:ffff:ffff:ffff::').is_site_local)
+ self.assertEqual(False, ipaddr.IPAddress('fbf:ffff::').is_site_local)
+ self.assertEqual(False, ipaddr.IPAddress('ff00::').is_site_local)
+
+ self.assertEqual(True, ipaddr.IPAddress('fc00::').is_private)
+ self.assertEqual(True, ipaddr.IPAddress(
+ 'fc00:ffff:ffff:ffff::').is_private)
+ self.assertEqual(False, ipaddr.IPAddress('fbff:ffff::').is_private)
+ self.assertEqual(False, ipaddr.IPAddress('fe00::').is_private)
+
+ self.assertEqual(True, ipaddr.IPAddress('fea0::').is_link_local)
+ self.assertEqual(True, ipaddr.IPAddress('febf:ffff::').is_link_local)
+ self.assertEqual(False, ipaddr.IPAddress('fe7f:ffff::').is_link_local)
+ self.assertEqual(False, ipaddr.IPAddress('fec0::').is_link_local)
+
+ self.assertEqual(True, ipaddr.IPAddress('0:0::0:01').is_loopback)
+ self.assertEqual(True, ipaddr.IPAddress('::1').is_loopback)
+ self.assertEqual(False, ipaddr.IPAddress('::2').is_loopback)
+
+ self.assertEqual(True, ipaddr.IPAddress('0::0').is_unspecified)
+ self.assertEqual(False, ipaddr.IPAddress('::1').is_unspecified)
+
+ # some generic IETF reserved addresses
+ self.assertEqual(True, ipaddr.IPAddress('100::').is_reserved)
+ self.assertEqual(True, ipaddr.IPNetwork('4000::1/128').is_reserved)
+
+ def testIpv4Mapped(self):
+ self.assertEqual(ipaddr.IPAddress('::ffff:192.168.1.1').ipv4_mapped,
+ ipaddr.IPAddress('192.168.1.1'))
+ self.assertEqual(ipaddr.IPAddress('::c0a8:101').ipv4_mapped, None)
+ self.assertEqual(ipaddr.IPAddress('::ffff:c0a8:101').ipv4_mapped,
+ ipaddr.IPAddress('192.168.1.1'))
+
+ def testAddrExclude(self):
+ addr1 = ipaddr.IPNetwork('10.1.1.0/24')
+ addr2 = ipaddr.IPNetwork('10.1.1.0/26')
+ addr3 = ipaddr.IPNetwork('10.2.1.0/24')
+ addr4 = ipaddr.IPAddress('10.1.1.0')
+ self.assertEqual(addr1.address_exclude(addr2),
+ [ipaddr.IPNetwork('10.1.1.64/26'),
+ ipaddr.IPNetwork('10.1.1.128/25')])
+ self.assertRaises(ValueError, addr1.address_exclude, addr3)
+ self.assertRaises(TypeError, addr1.address_exclude, addr4)
+ self.assertEqual(addr1.address_exclude(addr1), [])
+
+ def testHash(self):
+ self.assertEqual(hash(ipaddr.IPNetwork('10.1.1.0/24')),
+ hash(ipaddr.IPNetwork('10.1.1.0/24')))
+ self.assertEqual(hash(ipaddr.IPAddress('10.1.1.0')),
+ hash(ipaddr.IPAddress('10.1.1.0')))
+ # i70
+ self.assertEqual(hash(ipaddr.IPAddress('1.2.3.4')),
+ hash(ipaddr.IPAddress(
+ long(ipaddr.IPAddress('1.2.3.4')._ip))))
+ ip1 = ipaddr.IPAddress('10.1.1.0')
+ ip2 = ipaddr.IPAddress('1::')
+ dummy = {}
+ dummy[self.ipv4] = None
+ dummy[self.ipv6] = None
+ dummy[ip1] = None
+ dummy[ip2] = None
+ self.assertTrue(self.ipv4 in dummy)
+ self.assertTrue(ip2 in dummy)
+
+ def testCopyConstructor(self):
+ addr1 = ipaddr.IPNetwork('10.1.1.0/24')
+ addr2 = ipaddr.IPNetwork(addr1)
+ addr3 = ipaddr.IPNetwork('2001:658:22a:cafe:200::1/64')
+ addr4 = ipaddr.IPNetwork(addr3)
+ addr5 = ipaddr.IPv4Address('1.1.1.1')
+ addr6 = ipaddr.IPv6Address('2001:658:22a:cafe:200::1')
+
+ self.assertEqual(addr1, addr2)
+ self.assertEqual(addr3, addr4)
+ self.assertEqual(addr5, ipaddr.IPv4Address(addr5))
+ self.assertEqual(addr6, ipaddr.IPv6Address(addr6))
+
+ def testCompressIPv6Address(self):
+ test_addresses = {
+ '1:2:3:4:5:6:7:8': '1:2:3:4:5:6:7:8/128',
+ '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128',
+ '2001:0:0:4:5:6:7:8': '2001::4:5:6:7:8/128',
+ '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
+ '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
+ '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128',
+ '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128',
+ '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128',
+ '1:0:0:4:0:0:7:8': '1::4:0:0:7:8/128',
+ '0:0:0:0:0:0:0:0': '::/128',
+ '0:0:0:0:0:0:0:0/0': '::/0',
+ '0:0:0:0:0:0:0:1': '::1/128',
+ '2001:0658:022a:cafe:0000:0000:0000:0000/66':
+ '2001:658:22a:cafe::/66',
+ '::1.2.3.4': '::102:304/128',
+ '1:2:3:4:5:ffff:1.2.3.4': '1:2:3:4:5:ffff:102:304/128',
+ '::7:6:5:4:3:2:1': '0:7:6:5:4:3:2:1/128',
+ '::7:6:5:4:3:2:0': '0:7:6:5:4:3:2:0/128',
+ '7:6:5:4:3:2:1::': '7:6:5:4:3:2:1:0/128',
+ '0:6:5:4:3:2:1::': '0:6:5:4:3:2:1:0/128',
+ }
+ for uncompressed, compressed in test_addresses.items():
+ self.assertEqual(compressed, str(ipaddr.IPv6Network(uncompressed)))
+
+ def testExplodeShortHandIpStr(self):
+ addr1 = ipaddr.IPv6Network('2001::1')
+ addr2 = ipaddr.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
+ self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0001',
+ addr1._explode_shorthand_ip_string(str(addr1.ip)))
+ self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001',
+ ipaddr.IPv6Network('::1/128').exploded)
+ # issue 77
+ self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1',
+ addr2.exploded)
+
+ def testIntRepresentation(self):
+ self.assertEqual(16909060, int(self.ipv4))
+ self.assertEqual(42540616829182469433547762482097946625, int(self.ipv6))
+
+ def testHexRepresentation(self):
+ self.assertEqual(hex(0x1020304),
+ hex(self.ipv4))
+
+ self.assertEqual(hex(0x20010658022ACAFE0200000000000001),
+ hex(self.ipv6))
+
+ # backwards compatibility
+ def testBackwardsCompability(self):
+ self.assertEqual(ipaddr.CollapseAddrList(
+ [ipaddr.IPNetwork('1.1.0.0/24'), ipaddr.IPNetwork('1.1.1.0/24')]),
+ [ipaddr.IPNetwork('1.1.0.0/23')])
+
+ self.assertEqual(ipaddr.IPNetwork('::42:0/112').AddressExclude(
+ ipaddr.IPNetwork('::42:8000/113')),
+ [ipaddr.IPNetwork('::42:0/113')])
+
+ self.assertTrue(ipaddr.IPNetwork('1::/8').CompareNetworks(
+ ipaddr.IPNetwork('2::/9')) < 0)
+
+ self.assertEqual(ipaddr.IPNetwork('1::/16').Contains(
+ ipaddr.IPNetwork('2::/16')), False)
+
+ self.assertEqual(ipaddr.IPNetwork('0.0.0.0/0').Subnet(),
+ [ipaddr.IPNetwork('0.0.0.0/1'),
+ ipaddr.IPNetwork('128.0.0.0/1')])
+ self.assertEqual(ipaddr.IPNetwork('::/127').Subnet(),
+ [ipaddr.IPNetwork('::/128'),
+ ipaddr.IPNetwork('::1/128')])
+
+ self.assertEqual(ipaddr.IPNetwork('1.0.0.0/32').Supernet(),
+ ipaddr.IPNetwork('1.0.0.0/31'))
+ self.assertEqual(ipaddr.IPNetwork('::/121').Supernet(),
+ ipaddr.IPNetwork('::/120'))
+
+ self.assertEqual(ipaddr.IPNetwork('10.0.0.2').IsRFC1918(), True)
+ self.assertEqual(ipaddr.IPNetwork('10.0.0.0').IsMulticast(), False)
+ self.assertEqual(ipaddr.IPNetwork('127.255.255.255').IsLoopback(), True)
+ self.assertEqual(ipaddr.IPNetwork('169.255.255.255').IsLinkLocal(),
+ False)
+
+ def testForceVersion(self):
+ self.assertEqual(ipaddr.IPNetwork(1).version, 4)
+ self.assertEqual(ipaddr.IPNetwork(1, version=6).version, 6)
+
+ def testWithStar(self):
+ self.assertEqual(str(self.ipv4.with_prefixlen), "1.2.3.4/24")
+ self.assertEqual(str(self.ipv4.with_netmask), "1.2.3.4/255.255.255.0")
+ self.assertEqual(str(self.ipv4.with_hostmask), "1.2.3.4/0.0.0.255")
+
+ self.assertEqual(str(self.ipv6.with_prefixlen),
+ '2001:658:22a:cafe:200::1/64')
+ # rfc3513 sec 2.3 says that ipv6 only uses cidr notation for
+ # subnets
+ self.assertEqual(str(self.ipv6.with_netmask),
+ '2001:658:22a:cafe:200::1/64')
+ # this probably don't make much sense, but it's included for
+ # compatibility with ipv4
+ self.assertEqual(str(self.ipv6.with_hostmask),
+ '2001:658:22a:cafe:200::1/::ffff:ffff:ffff:ffff')
+
+ def testNetworkElementCaching(self):
+ # V4 - make sure we're empty
+ self.assertFalse(self.ipv4._cache.has_key('network'))
+ self.assertFalse(self.ipv4._cache.has_key('broadcast'))
+ self.assertFalse(self.ipv4._cache.has_key('hostmask'))
+
+ # V4 - populate and test
+ self.assertEqual(self.ipv4.network, ipaddr.IPv4Address('1.2.3.0'))
+ self.assertEqual(self.ipv4.broadcast, ipaddr.IPv4Address('1.2.3.255'))
+ self.assertEqual(self.ipv4.hostmask, ipaddr.IPv4Address('0.0.0.255'))
+
+ # V4 - check we're cached
+ self.assertTrue(self.ipv4._cache.has_key('network'))
+ self.assertTrue(self.ipv4._cache.has_key('broadcast'))
+ self.assertTrue(self.ipv4._cache.has_key('hostmask'))
+
+ # V6 - make sure we're empty
+ self.assertFalse(self.ipv6._cache.has_key('network'))
+ self.assertFalse(self.ipv6._cache.has_key('broadcast'))
+ self.assertFalse(self.ipv6._cache.has_key('hostmask'))
+
+ # V6 - populate and test
+ self.assertEqual(self.ipv6.network,
+ ipaddr.IPv6Address('2001:658:22a:cafe::'))
+ self.assertEqual(self.ipv6.broadcast, ipaddr.IPv6Address(
+ '2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
+ self.assertEqual(self.ipv6.hostmask,
+ ipaddr.IPv6Address('::ffff:ffff:ffff:ffff'))
+
+ # V6 - check we're cached
+ self.assertTrue(self.ipv6._cache.has_key('network'))
+ self.assertTrue(self.ipv6._cache.has_key('broadcast'))
+ self.assertTrue(self.ipv6._cache.has_key('hostmask'))
+
+ def testTeredo(self):
+ # stolen from wikipedia
+ server = ipaddr.IPv4Address('65.54.227.120')
+ client = ipaddr.IPv4Address('192.0.2.45')
+ teredo_addr = '2001:0000:4136:e378:8000:63bf:3fff:fdd2'
+ self.assertEqual((server, client),
+ ipaddr.IPAddress(teredo_addr).teredo)
+ bad_addr = '2000::4136:e378:8000:63bf:3fff:fdd2'
+ self.assertFalse(ipaddr.IPAddress(bad_addr).teredo)
+ bad_addr = '2001:0001:4136:e378:8000:63bf:3fff:fdd2'
+ self.assertFalse(ipaddr.IPAddress(bad_addr).teredo)
+
+ # i77
+ teredo_addr = ipaddr.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
+ self.assertEqual((ipaddr.IPv4Address('94.245.121.253'),
+ ipaddr.IPv4Address('95.26.244.94')),
+ teredo_addr.teredo)
+
+
+ def testsixtofour(self):
+ sixtofouraddr = ipaddr.IPAddress('2002:ac1d:2d64::1')
+ bad_addr = ipaddr.IPAddress('2000:ac1d:2d64::1')
+ self.assertEqual(ipaddr.IPv4Address('172.29.45.100'),
+ sixtofouraddr.sixtofour)
+ self.assertFalse(bad_addr.sixtofour)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/contrib/ipaddr-py/setup.py b/contrib/ipaddr-py/setup.py
new file mode 100755
index 000000000..33564320e
--- /dev/null
+++ b/contrib/ipaddr-py/setup.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+#
+# Copyright 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from distutils.core import setup
+
+import ipaddr
+
+
+setup(name='ipaddr',
+ maintainer='Google',
+ maintainer_email='ipaddr-py-dev@googlegroups.com',
+ version=ipaddr.__version__,
+ url='http://code.google.com/p/ipaddr-py/',
+ license='Apache License, Version 2.0',
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Apache Software License',
+ 'Operating System :: OS Independent',
+ 'Topic :: Internet',
+ 'Topic :: Software Development :: Libraries',
+ 'Topic :: System :: Networking'],
+ py_modules=['ipaddr'])
diff --git a/contrib/ipaddr-py/test-2to3.sh b/contrib/ipaddr-py/test-2to3.sh
new file mode 100755
index 000000000..408d665bc
--- /dev/null
+++ b/contrib/ipaddr-py/test-2to3.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Converts the python2 ipaddr files to python3 and runs the unit tests
+# with both python versions.
+
+mkdir -p 2to3output && \
+cp -f *.py 2to3output && \
+( cd 2to3output && 2to3 . | patch -p0 ) && \
+py3version=$(python3 --version 2>&1) && \
+echo -e "\nTesting with ${py3version}" && \
+python3 2to3output/ipaddr_test.py && \
+rm -r 2to3output && \
+pyversion=$(python --version 2>&1) && \
+echo -e "\nTesting with ${pyversion}" && \
+./ipaddr_test.py
diff --git a/contrib/libgen/basename_r.c b/contrib/libgen/basename_r.c
new file mode 100644
index 000000000..d63bce4e5
--- /dev/null
+++ b/contrib/libgen/basename_r.c
@@ -0,0 +1,40 @@
+#ifdef THREAD_UNSAFE_BASENAME
+/*
+ * borrowed from glibc-2.12.1/string/basename.c
+ * Modified to return "." for NULL or "", as required for SUSv2.
+ */
+#include <string.h>
+#include <stdlib.h>
+
+/* Return the name-within-directory of a file name.
+ Copyright (C) 1996,97,98,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+char *
+basename_r (filename)
+ const char *filename;
+{
+ char *p;
+
+ if ((filename == NULL) || (*filename == '\0'))
+ return ".";
+
+ p = strrchr (filename, '/');
+ return p ? p + 1 : (char *) filename;
+}
+#endif /* THREAD_UNSAFE_BASENAME */
diff --git a/contrib/libgen/dirname_r.c b/contrib/libgen/dirname_r.c
new file mode 100644
index 000000000..02981f5ec
--- /dev/null
+++ b/contrib/libgen/dirname_r.c
@@ -0,0 +1,243 @@
+#ifdef THREAD_UNSAFE_DIRNAME
+/*
+ * Borrowed from glibc-2.12.1/string/memrchr.c
+ * Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ * Removed code for long bigger than 32 bytes, renamed __ptr_t as void *
+ * changed reg_char type to char.
+ */
+#include <string.h>
+#include <stdlib.h>
+
+/* memrchr -- find the last occurrence of a byte in a memory block
+ Copyright (C) 1991, 93, 96, 97, 99, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se) and
+ commentary by Jim Blandy (jimb@ai.mit.edu);
+ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+ and implemented by Roland McGrath (roland@ai.mit.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+void *
+__memrchr (s, c_in, n)
+ const void * s;
+ int c_in;
+ size_t n;
+{
+ const unsigned char *char_ptr;
+ const unsigned long int *longword_ptr;
+ unsigned long int longword, magic_bits, charmask;
+ unsigned char c;
+
+ c = (unsigned char) c_in;
+
+ /* Handle the last few characters by reading one character at a time.
+ Do this until CHAR_PTR is aligned on a longword boundary. */
+ for (char_ptr = (const unsigned char *) s + n;
+ n > 0 && ((unsigned long int) char_ptr
+ & (sizeof (longword) - 1)) != 0;
+ --n)
+ if (*--char_ptr == c)
+ return (void *) char_ptr;
+
+ /* All these elucidatory comments refer to 4-byte longwords,
+ but the theory applies equally well to 8-byte longwords. */
+
+ longword_ptr = (const unsigned long int *) char_ptr;
+
+ /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
+ the "holes." Note that there is a hole just to the left of
+ each byte, with an extra at the end:
+
+ bits: 01111110 11111110 11111110 11111111
+ bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+ The 1-bits make sure that carries propagate to the next 0-bit.
+ The 0-bits provide holes for carries to fall into. */
+
+ if (sizeof (longword) != 4 && sizeof (longword) != 8)
+ abort ();
+
+ magic_bits = 0x7efefeff;
+
+ /* Set up a longword, each of whose bytes is C. */
+ charmask = c | (c << 8);
+ charmask |= charmask << 16;
+
+ /* Instead of the traditional loop which tests each character,
+ we will test a longword at a time. The tricky part is testing
+ if *any of the four* bytes in the longword in question are zero. */
+ while (n >= sizeof (longword))
+ {
+ /* We tentatively exit the loop if adding MAGIC_BITS to
+ LONGWORD fails to change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-30 is set, there will be a carry
+ into bit 31, so all of the hole bits will be changed.
+
+ The one misfire occurs when bits 24-30 are clear and bit
+ 31 is set; in this case, the hole at bit 31 is not
+ changed. If we had access to the processor carry flag,
+ we could close this loophole by putting the fourth hole
+ at bit 32!
+
+ So it ignores everything except 128's, when they're aligned
+ properly.
+
+ 3) But wait! Aren't we looking for C, not zero?
+ Good point. So what we do is XOR LONGWORD with a longword,
+ each of whose bytes is C. This turns each byte that is C
+ into a zero. */
+
+ longword = *--longword_ptr ^ charmask;
+
+ /* Add MAGIC_BITS to LONGWORD. */
+ if ((((longword + magic_bits)
+
+ /* Set those bits that were unchanged by the addition. */
+ ^ ~longword)
+
+ /* Look at only the hole bits. If any of the hole bits
+ are unchanged, most likely one of the bytes was a
+ zero. */
+ & ~magic_bits) != 0)
+ {
+ /* Which of the bytes was C? If none of them were, it was
+ a misfire; continue the search. */
+
+ const unsigned char *cp = (const unsigned char *) longword_ptr;
+
+ if (cp[3] == c)
+ return (void *) &cp[3];
+ if (cp[2] == c)
+ return (void *) &cp[2];
+ if (cp[1] == c)
+ return (void *) &cp[1];
+ if (cp[0] == c)
+ return (void *) cp;
+ }
+
+ n -= sizeof (longword);
+ }
+
+ char_ptr = (const unsigned char *) longword_ptr;
+
+ while (n-- > 0)
+ {
+ if (*--char_ptr == c)
+ return (void *) char_ptr;
+ }
+
+ return 0;
+}
+
+/*
+ * Borrowed from glibc-2.12.1/misc/dirname.c
+ */
+
+/* dirname - return directory part of PATH.
+ Copyright (C) 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+char *
+dirname_r (char *path)
+{
+ static const char dot[] = ".";
+ char *last_slash;
+
+ /* Find last '/'. */
+ last_slash = path != NULL ? strrchr (path, '/') : NULL;
+
+ if (last_slash != NULL && last_slash != path && last_slash[1] == '\0')
+ {
+ /* Determine whether all remaining characters are slashes. */
+ char *runp;
+
+ for (runp = last_slash; runp != path; --runp)
+ if (runp[-1] != '/')
+ break;
+
+ /* The '/' is the last character, we have to look further. */
+ if (runp != path)
+ last_slash = __memrchr (path, '/', runp - path);
+ }
+
+ if (last_slash != NULL)
+ {
+ /* Determine whether all remaining characters are slashes. */
+ char *runp;
+
+ for (runp = last_slash; runp != path; --runp)
+ if (runp[-1] != '/')
+ break;
+
+ /* Terminate the path. */
+ if (runp == path)
+ {
+ /* The last slash is the first character in the string. We have to
+ return "/". As a special case we have to return "//" if there
+ are exactly two slashes at the beginning of the string. See
+ XBD 4.10 Path Name Resolution for more information. */
+ if (last_slash == path + 1)
+ ++last_slash;
+ else
+ last_slash = path + 1;
+ }
+ else
+ last_slash = runp;
+
+ last_slash[0] = '\0';
+ }
+ else
+ /* This assignment is ill-designed but the XPG specs require to
+ return a string containing "." in any case no directory part is
+ found and so a static and constant string is required. */
+ path = (char *) dot;
+
+ return path;
+}
+#endif /* THREAD_UNSAFE_DIRNAME */
diff --git a/contrib/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c
index 9d87fca35..c485583e9 100644
--- a/contrib/macfuse/mount_darwin.c
+++ b/contrib/macfuse/mount_darwin.c
@@ -133,7 +133,8 @@ Return:
}
int
-gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param)
+gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
+ pid_t *mtab_pid /* not used on OS X */)
{
int fd, pid;
int result;
diff --git a/contrib/md5/md5.c b/contrib/md5/md5.c
deleted file mode 100644
index 5f0d0d157..000000000
--- a/contrib/md5/md5.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * RFC 1321 compliant MD5 implementation
- *
- * Copyright (C) 2001-2003 Christophe Devine
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, visit the http://fsf.org website.
- */
-
-
-#include <inttypes.h>
-#include <string.h>
-
-#include "md5.h"
-
-void md5_begin(md_context *ctx)
-{
- ctx->A = 0x67452301;
- ctx->B = 0xEFCDAB89;
- ctx->C = 0x98BADCFE;
- ctx->D = 0x10325476;
-
- ctx->totalN = ctx->totalN2 = 0;
-}
-
-static void md5_process(md_context *ctx, const uint8_t data[CSUM_CHUNK])
-{
- uint32_t X[16], A, B, C, D;
-
- A = ctx->A;
- B = ctx->B;
- C = ctx->C;
- D = ctx->D;
-
- X[0] = IVAL(data, 0);
- X[1] = IVAL(data, 4);
- X[2] = IVAL(data, 8);
- X[3] = IVAL(data, 12);
- X[4] = IVAL(data, 16);
- X[5] = IVAL(data, 20);
- X[6] = IVAL(data, 24);
- X[7] = IVAL(data, 28);
- X[8] = IVAL(data, 32);
- X[9] = IVAL(data, 36);
- X[10] = IVAL(data, 40);
- X[11] = IVAL(data, 44);
- X[12] = IVAL(data, 48);
- X[13] = IVAL(data, 52);
- X[14] = IVAL(data, 56);
- X[15] = IVAL(data, 60);
-
-#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
-
-#define P(a,b,c,d,k,s,t) a += F(b,c,d) + X[k] + t, a = S(a,s) + b
-
-#define F(x,y,z) (z ^ (x & (y ^ z)))
-
- P(A, B, C, D, 0, 7, 0xD76AA478);
- P(D, A, B, C, 1, 12, 0xE8C7B756);
- P(C, D, A, B, 2, 17, 0x242070DB);
- P(B, C, D, A, 3, 22, 0xC1BDCEEE);
- P(A, B, C, D, 4, 7, 0xF57C0FAF);
- P(D, A, B, C, 5, 12, 0x4787C62A);
- P(C, D, A, B, 6, 17, 0xA8304613);
- P(B, C, D, A, 7, 22, 0xFD469501);
- P(A, B, C, D, 8, 7, 0x698098D8);
- P(D, A, B, C, 9, 12, 0x8B44F7AF);
- P(C, D, A, B, 10, 17, 0xFFFF5BB1);
- P(B, C, D, A, 11, 22, 0x895CD7BE);
- P(A, B, C, D, 12, 7, 0x6B901122);
- P(D, A, B, C, 13, 12, 0xFD987193);
- P(C, D, A, B, 14, 17, 0xA679438E);
- P(B, C, D, A, 15, 22, 0x49B40821);
-
-#undef F
-#define F(x,y,z) (y ^ (z & (x ^ y)))
-
- P(A, B, C, D, 1, 5, 0xF61E2562);
- P(D, A, B, C, 6, 9, 0xC040B340);
- P(C, D, A, B, 11, 14, 0x265E5A51);
- P(B, C, D, A, 0, 20, 0xE9B6C7AA);
- P(A, B, C, D, 5, 5, 0xD62F105D);
- P(D, A, B, C, 10, 9, 0x02441453);
- P(C, D, A, B, 15, 14, 0xD8A1E681);
- P(B, C, D, A, 4, 20, 0xE7D3FBC8);
- P(A, B, C, D, 9, 5, 0x21E1CDE6);
- P(D, A, B, C, 14, 9, 0xC33707D6);
- P(C, D, A, B, 3, 14, 0xF4D50D87);
- P(B, C, D, A, 8, 20, 0x455A14ED);
- P(A, B, C, D, 13, 5, 0xA9E3E905);
- P(D, A, B, C, 2, 9, 0xFCEFA3F8);
- P(C, D, A, B, 7, 14, 0x676F02D9);
- P(B, C, D, A, 12, 20, 0x8D2A4C8A);
-
-#undef F
-#define F(x,y,z) (x ^ y ^ z)
-
- P(A, B, C, D, 5, 4, 0xFFFA3942);
- P(D, A, B, C, 8, 11, 0x8771F681);
- P(C, D, A, B, 11, 16, 0x6D9D6122);
- P(B, C, D, A, 14, 23, 0xFDE5380C);
- P(A, B, C, D, 1, 4, 0xA4BEEA44);
- P(D, A, B, C, 4, 11, 0x4BDECFA9);
- P(C, D, A, B, 7, 16, 0xF6BB4B60);
- P(B, C, D, A, 10, 23, 0xBEBFBC70);
- P(A, B, C, D, 13, 4, 0x289B7EC6);
- P(D, A, B, C, 0, 11, 0xEAA127FA);
- P(C, D, A, B, 3, 16, 0xD4EF3085);
- P(B, C, D, A, 6, 23, 0x04881D05);
- P(A, B, C, D, 9, 4, 0xD9D4D039);
- P(D, A, B, C, 12, 11, 0xE6DB99E5);
- P(C, D, A, B, 15, 16, 0x1FA27CF8);
- P(B, C, D, A, 2, 23, 0xC4AC5665);
-
-#undef F
-#define F(x,y,z) (y ^ (x | ~z))
-
- P(A, B, C, D, 0, 6, 0xF4292244);
- P(D, A, B, C, 7, 10, 0x432AFF97);
- P(C, D, A, B, 14, 15, 0xAB9423A7);
- P(B, C, D, A, 5, 21, 0xFC93A039);
- P(A, B, C, D, 12, 6, 0x655B59C3);
- P(D, A, B, C, 3, 10, 0x8F0CCC92);
- P(C, D, A, B, 10, 15, 0xFFEFF47D);
- P(B, C, D, A, 1, 21, 0x85845DD1);
- P(A, B, C, D, 8, 6, 0x6FA87E4F);
- P(D, A, B, C, 15, 10, 0xFE2CE6E0);
- P(C, D, A, B, 6, 15, 0xA3014314);
- P(B, C, D, A, 13, 21, 0x4E0811A1);
- P(A, B, C, D, 4, 6, 0xF7537E82);
- P(D, A, B, C, 11, 10, 0xBD3AF235);
- P(C, D, A, B, 2, 15, 0x2AD7D2BB);
- P(B, C, D, A, 9, 21, 0xEB86D391);
-
-#undef F
-
- ctx->A += A;
- ctx->B += B;
- ctx->C += C;
- ctx->D += D;
-}
-
-void md5_update(md_context *ctx, const uint8_t *input, uint32_t length)
-{
- uint32_t left, fill;
-
- if (!length)
- return;
-
- left = ctx->totalN & 0x3F;
- fill = CSUM_CHUNK - left;
-
- ctx->totalN += length;
- ctx->totalN &= 0xFFFFFFFF;
-
- if (ctx->totalN < length)
- ctx->totalN2++;
-
- if (left && length >= fill) {
- memcpy(ctx->buffer + left, input, fill);
- md5_process(ctx, ctx->buffer);
- length -= fill;
- input += fill;
- left = 0;
- }
-
- while (length >= CSUM_CHUNK) {
- md5_process(ctx, input);
- length -= CSUM_CHUNK;
- input += CSUM_CHUNK;
- }
-
- if (length)
- memcpy(ctx->buffer + left, input, length);
-}
-
-static uint8_t md5_padding[CSUM_CHUNK] = { 0x80 };
-
-void md5_result(md_context *ctx, uint8_t digest[MD5_DIGEST_LEN])
-{
- uint32_t last, padn;
- uint32_t high, low;
- uint8_t msglen[8];
-
- high = (ctx->totalN >> 29)
- | (ctx->totalN2 << 3);
- low = (ctx->totalN << 3);
-
- SIVAL(msglen, 0, low);
- SIVAL(msglen, 4, high);
-
- last = ctx->totalN & 0x3F;
- padn = last < 56 ? 56 - last : 120 - last;
-
- md5_update(ctx, md5_padding, padn);
- md5_update(ctx, msglen, 8);
-
- SIVAL(digest, 0, ctx->A);
- SIVAL(digest, 4, ctx->B);
- SIVAL(digest, 8, ctx->C);
- SIVAL(digest, 12, ctx->D);
-}
-
-void get_md5(uint8_t *out, const uint8_t *input, int n)
-{
- md_context ctx;
- md5_begin(&ctx);
- md5_update(&ctx, input, n);
- md5_result(&ctx, out);
-}
-
-#ifdef TEST_MD5
-
-#include <stdlib.h>
-#include <stdio.h>
-
-/*
- * those are the standard RFC 1321 test vectors
- */
-
-static struct {
- char *str, *md5;
-} tests[] = {
- { "",
- "d41d8cd98f00b204e9800998ecf8427e" },
- { "a",
- "0cc175b9c0f1b6a831c399e269772661" },
- { "abc",
- "900150983cd24fb0d6963f7d28e17f72" },
- { "message digest",
- "f96b697d7cb7938d525a2f31aaf161d0" },
- { "abcdefghijklmnopqrstuvwxyz",
- "c3fcd3d76192e4007dfb496cca67e13b" },
- { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
- "d174ab98d277d9f5a5611c2c9f419d9f" },
- { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
- "57edf4a22be3c955ac49da2e2107b67a" },
- { NULL, NULL }
-};
-
-int main(int argc, char *argv[])
-{
- FILE *f;
- int i, j;
- char output[33];
- md_context ctx;
- uint8_t buf[1000];
- uint8_t md5sum[MD5_DIGEST_LEN];
-
- if (argc < 2) {
- printf("\nMD5 Validation Tests:\n\n");
-
- for (i = 0; tests[i].str; i++) {
- char *str = tests[i].str;
- char *chk = tests[i].md5;
-
- printf(" Test %d ", i + 1);
-
- get_md5(md5sum, str, strlen(str));
-
- for (j = 0; j < MD5_DIGEST_LEN; j++)
- sprintf(output + j * 2, "%02x", md5sum[j]);
-
- if (memcmp(output, chk, 32)) {
- printf("failed!\n");
- return 1;
- }
-
- printf("passed.\n");
- }
-
- printf("\n");
- return 0;
- }
-
- while (--argc) {
- if (!(f = fopen(*++argv, "rb"))) {
- perror("fopen");
- return 1;
- }
-
- md5_begin(&ctx);
-
- while ((i = fread(buf, 1, sizeof buf, f)) > 0)
- md5_update(&ctx, buf, i);
-
- fclose(f);
-
- md5_result(&ctx, md5sum);
-
- for (j = 0; j < MD5_DIGEST_LEN; j++)
- printf("%02x", md5sum[j]);
-
- printf(" %s\n", *argv);
- }
-
- return 0;
-}
-
-#endif
diff --git a/contrib/md5/md5.h b/contrib/md5/md5.h
deleted file mode 100644
index ba8f08dbc..000000000
--- a/contrib/md5/md5.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* rsync-3.0.6/byteorder.h */
-
-/*
- * Simple byteorder handling.
- *
- * Copyright (C) 1992-1995 Andrew Tridgell
- * Copyright (C) 2007-2008 Wayne Davison
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, visit the http://fsf.org website.
- */
-
-#undef CAREFUL_ALIGNMENT
-
-/* We know that the x86 can handle misalignment and has the same
- * byte order (LSB-first) as the 32-bit numbers we transmit. */
-
-#ifdef __i386__
-#define CAREFUL_ALIGNMENT 0
-#endif
-
-#ifndef CAREFUL_ALIGNMENT
-#define CAREFUL_ALIGNMENT 1
-#endif
-
-#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
-#define UVAL(buf,pos) ((uint32_t)CVAL(buf,pos))
-#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
-
-#if CAREFUL_ALIGNMENT
-#define PVAL(buf,pos) (UVAL(buf,pos)|UVAL(buf,(pos)+1)<<8)
-#define IVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+2)<<16)
-#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
-#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
-#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32_t)(val)))
-#else
-
-/* this handles things for architectures like the 386 that can handle
- alignment errors */
-
-/*
- WARNING: This section is dependent on the length of int32
- being correct. set CAREFUL_ALIGNMENT if it is not.
-*/
-
-#define IVAL(buf,pos) (*(uint32_t *)((char *)(buf) + (pos)))
-#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32_t)(val))
-#endif
-
-/* The include file for both the MD4 and MD5 routines. */
-
-#define MD5_DIGEST_LEN 16
-#define MAX_DIGEST_LEN MD5_DIGEST_LEN
-
-#define CSUM_CHUNK 64
-
-typedef struct {
- uint32_t A, B, C, D;
- uint32_t totalN; /* bit count, lower 32 bits */
- uint32_t totalN2; /* bit count, upper 32 bits */
- uint8_t buffer[CSUM_CHUNK];
-} md_context;
-
-void md5_begin(md_context *ctx);
-void md5_update(md_context *ctx, const uint8_t *input, uint32_t length);
-void md5_result(md_context *ctx, uint8_t digest[MD5_DIGEST_LEN]);
-
-void get_md5(uint8_t digest[MD5_DIGEST_LEN], const uint8_t *input, int n);
diff --git a/contrib/rbtree/rb.c b/contrib/rbtree/rb.c
index d1339b97d..6184c507e 100644
--- a/contrib/rbtree/rb.c
+++ b/contrib/rbtree/rb.c
@@ -1,26 +1,30 @@
/* Produced by texiweb from libavl.w. */
/* libavl - library for manipulation of binary trees.
- Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
+ Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ This code is also covered by the following earlier license notice:
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-
- The author may be contacted at <blp@gnu.org> on the Internet, or
- write to Ben Pfaff, Stanford University, Computer Science Dept., 353
- Serra Mall, Stanford CA 94305, USA.
*/
#include <assert.h>
diff --git a/contrib/rbtree/rb.h b/contrib/rbtree/rb.h
index c8858b556..97b44cfd4 100644
--- a/contrib/rbtree/rb.h
+++ b/contrib/rbtree/rb.h
@@ -1,26 +1,30 @@
/* Produced by texiweb from libavl.w. */
/* libavl - library for manipulation of binary trees.
- Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
+ Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ This code is also covered by the following earlier license notice:
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-
- The author may be contacted at <blp@gnu.org> on the Internet, or
- write to Ben Pfaff, Stanford University, Computer Science Dept., 353
- Serra Mall, Stanford CA 94305, USA.
*/
#ifndef RB_H
@@ -51,7 +55,7 @@ void rb_free (struct libavl_allocator *, void *);
/* Maximum RB height. */
#ifndef RB_MAX_HEIGHT
-#define RB_MAX_HEIGHT 48
+#define RB_MAX_HEIGHT 128
#endif
/* Tree data structure. */
diff --git a/contrib/stdlib/gf_mkostemp.c b/contrib/stdlib/gf_mkostemp.c
new file mode 100644
index 000000000..931249a45
--- /dev/null
+++ b/contrib/stdlib/gf_mkostemp.c
@@ -0,0 +1,107 @@
+/* Borrowed from glibc-2.16/sysdeps/posix/tempname.c */
+
+/* Copyright (C) 1991-2001, 2006, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <time.h>
+#include <inttypes.h>
+
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary file name based on TMPL. TMPL must match the
+ rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
+*/
+
+#if !defined(TMP_MAX)
+#define TMP_MAX 238328
+#endif
+
+int
+gf_mkostemp (char *tmpl, int suffixlen, int flags)
+{
+ int len;
+ char *XXXXXX;
+ static uint64_t value;
+ uint64_t random_time_bits;
+ unsigned int count;
+ int fd = -1;
+
+ /* A lower bound on the number of temporary files to attempt to
+ generate. The maximum total number of temporary file names that
+ can exist for a given template is 62**6. It should never be
+ necessary to try all these combinations. Instead if a reasonable
+ number of names is tried (we define reasonable as 62**3) fail to
+ give the system administrator the chance to remove the problems. */
+
+ unsigned int attempts = TMP_MAX; /* TMP_MAX == 62³ */
+
+ len = strlen (tmpl);
+ if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen],
+ "XXXXXX", 6))
+ return -1;
+
+ /* This is where the Xs start. */
+ XXXXXX = &tmpl[len - 6 - suffixlen];
+
+ /* Get some more or less random data. */
+# if HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+# else
+ random_time_bits = time (NULL);
+# endif
+
+ value += random_time_bits ^ getpid ();
+
+ for (count = 0; count < attempts; value += 7777, ++count) {
+ uint64_t v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = open (tmpl, (flags & ~O_ACCMODE)
+ | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+
+ if (fd >= 0)
+ return fd;
+ else if (errno != EEXIST)
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ return -1;
+}
diff --git a/contrib/uuid/uuid_types.h b/contrib/uuid/uuid_types.h.in
index 3e2290b46..f21ff4ee1 100644
--- a/contrib/uuid/uuid_types.h
+++ b/contrib/uuid/uuid_types.h.in
@@ -9,13 +9,13 @@
typedef unsigned char uint8_t;
typedef signed char int8_t;
-#if (4 == 8)
+#if (@SIZEOF_INT@ == 8)
typedef int int64_t;
typedef unsigned int uint64_t;
-#elif (8 == 8)
+#elif (@SIZEOF_LONG@ == 8)
typedef long int64_t;
typedef unsigned long uint64_t;
-#elif (8 == 8)
+#elif (@SIZEOF_LONG_LONG@ == 8)
#if defined(__GNUC__)
typedef __signed__ long long int64_t;
#else
@@ -24,23 +24,23 @@ typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#endif
-#if (4 == 2)
+#if (@SIZEOF_INT@ == 2)
typedef int int16_t;
typedef unsigned int uint16_t;
-#elif (2 == 2)
+#elif (@SIZEOF_SHORT@ == 2)
typedef short int16_t;
typedef unsigned short uint16_t;
#else
?==error: undefined 16 bit type
#endif
-#if (4 == 4)
+#if (@SIZEOF_INT@ == 4)
typedef int int32_t;
typedef unsigned int uint32_t;
-#elif (8 == 4)
+#elif (@SIZEOF_LONG@ == 4)
typedef long int32_t;
typedef unsigned long uint32_t;
-#elif (2 == 4)
+#elif (@SIZEOF_SHORT@ == 4)
typedef short int32_t;
typedef unsigned short uint32_t;
#else
diff --git a/doc/Makefile.am b/doc/Makefile.am
index c5fd2b81a..9847f0ac0 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,13 +1,11 @@
EXTRA_DIST = glusterfs.vol.sample glusterfsd.vol.sample glusterfs.8 mount.glusterfs.8\
- porting_guide.txt authentication.txt coding-standard.pdf get_put_api_using_xattr.txt \
- translator-options.txt mac-related-xattrs.txt replicate.pdf glusterd.vol gluster.8 \
- glusterd.8 glusterfsd.8
-
-SUBDIRS = examples hacker-guide
+ glusterd.vol gluster.8 glusterd.8 glusterfsd.8
voldir = $(sysconfdir)/glusterfs
-vol_DATA = glusterfs.vol.sample glusterfsd.vol.sample glusterd.vol
+vol_DATA = glusterd.vol
-man8_MANS = glusterfs.8 mount.glusterfs.8 gluster.8 glusterd.8 glusterfsd.8
+man8_MANS = gluster.8 glusterfs.8
+# TODO: update the following man pages and readd them
+# glusterfs.8 mount.glusterfs.8 gluster.8 glusterd.8 glusterfsd.8
-CLEANFILES =
+CLEANFILES =
diff --git a/doc/admin-guide/en-US/Administration_Guide.ent b/doc/admin-guide/en-US/Administration_Guide.ent
new file mode 100644
index 000000000..3381b2bfe
--- /dev/null
+++ b/doc/admin-guide/en-US/Administration_Guide.ent
@@ -0,0 +1,4 @@
+<!ENTITY PRODUCT "Documentation">
+<!ENTITY BOOKID "Administration_Guide">
+<!ENTITY YEAR "2012">
+<!ENTITY HOLDER "Red Hat Inc">
diff --git a/doc/admin-guide/en-US/Administration_Guide.xml b/doc/admin-guide/en-US/Administration_Guide.xml
new file mode 100644
index 000000000..483855b1a
--- /dev/null
+++ b/doc/admin-guide/en-US/Administration_Guide.xml
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<book>
+ <xi:include href="Book_Info.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="gfs_introduction.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_start_stop_daemon.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_console.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_storage_pools.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_setting_volumes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_settingup_clients.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_managing_volumes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_geo-replication.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_directory_Quota.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_monitoring_workload.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_ACLs.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_UFO.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_Hadoop.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_troubleshooting.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="admin_commandref.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="glossary.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Revision_History.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+</book>
+
diff --git a/doc/admin-guide/en-US/Author_Group.xml b/doc/admin-guide/en-US/Author_Group.xml
new file mode 100644
index 000000000..f3fa31740
--- /dev/null
+++ b/doc/admin-guide/en-US/Author_Group.xml
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<authorgroup>
+ <author>
+ <firstname>Divya</firstname>
+ <surname>Muntimadugu</surname>
+ <affiliation>
+ <orgname>Red Hat</orgname>
+ <orgdiv>Engineering Content Services</orgdiv>
+ </affiliation>
+ <email>divya@redhat.com</email>
+ </author>
+</authorgroup>
+
diff --git a/doc/admin-guide/en-US/Book_Info.xml b/doc/admin-guide/en-US/Book_Info.xml
new file mode 100644
index 000000000..19fb40a2f
--- /dev/null
+++ b/doc/admin-guide/en-US/Book_Info.xml
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<bookinfo id="book-Administration_Guide-Administration_Guide">
+ <title>Administration Guide</title>
+ <subtitle>Using Gluster File System </subtitle>
+ <productname>Gluster File System</productname>
+ <productnumber>3.3.0</productnumber>
+ <edition>1</edition>
+ <pubsnumber>1</pubsnumber>
+ <abstract>
+ <para>
+ This guide describes Gluster File System (GlusterFS) and provides information on how to configure, operate, and manage GlusterFS.
+ </para>
+ </abstract>
+ <corpauthor>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="Common_Content/images/title_logo.svg" format="SVG" />
+ </imageobject>
+ </inlinemediaobject>
+ </corpauthor>
+ <xi:include href="Common_Content/Legal_Notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Author_Group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+</bookinfo>
+
diff --git a/doc/admin-guide/en-US/Chapter.xml b/doc/admin-guide/en-US/Chapter.xml
new file mode 100644
index 000000000..4a1cef872
--- /dev/null
+++ b/doc/admin-guide/en-US/Chapter.xml
@@ -0,0 +1,33 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Administration_Guide-Test_Chapter">
+ <title>Test Chapter</title>
+ <para>
+ This is a test paragraph
+ </para>
+ <section id="sect-Administration_Guide-Test_Chapter-Test_Section_1">
+ <title>Test Section 1</title>
+ <para>
+ This is a test paragraph in a section
+ </para>
+ </section>
+
+ <section id="sect-Administration_Guide-Test_Chapter-Test_Section_2">
+ <title>Test Section 2</title>
+ <para>
+ This is a test paragraph in Section 2
+ <orderedlist>
+ <listitem>
+ <para>
+ listitem text
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </section>
+
+</chapter>
+
diff --git a/doc/admin-guide/en-US/Preface.xml b/doc/admin-guide/en-US/Preface.xml
new file mode 100644
index 000000000..320311906
--- /dev/null
+++ b/doc/admin-guide/en-US/Preface.xml
@@ -0,0 +1,24 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. -->
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<preface id="pref-Administration_Guide-Preface">
+ <title>Preface</title>
+ <para>This guide describes how to configure, operate, and manage Gluster File System (GlusterFS).</para>
+ <section>
+ <title>Audience</title>
+ <para>This guide is intended for Systems Administrators interested in configuring and managing GlusterFS.</para>
+ <para>This guide assumes that you are familiar with the Linux operating system, concepts of File System, GlusterFS concepts, and GlusterFS Installation</para>
+ </section>
+ <section>
+ <title>License</title>
+ <para>The License information is available at <ulink url="http://www.redhat.com/licenses/rhel_rha_eula.html"/>.</para>
+ </section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Common_Content/Conventions.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Feedback.xml">
+ <xi:fallback xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Common_Content/Feedback.xml"/>
+ </xi:fallback>
+ </xi:include>
+</preface>
diff --git a/doc/admin-guide/en-US/Revision_History.xml b/doc/admin-guide/en-US/Revision_History.xml
new file mode 100644
index 000000000..09320821f
--- /dev/null
+++ b/doc/admin-guide/en-US/Revision_History.xml
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<appendix id="appe-Administration_Guide-Revision_History">
+ <title>Revision History</title>
+ <simpara>
+ <revhistory>
+ <revision>
+ <revnumber>1-0</revnumber>
+ <date>Thu Apr 5 2012</date>
+ <author>
+ <firstname>Divya</firstname>
+ <surname>Muntimadugu</surname>
+ <email>divya@redhat.com</email>
+ </author>
+ <revdescription>
+ <simplelist>
+ <member>Draft </member>
+ </simplelist>
+ </revdescription>
+ </revision>
+ </revhistory>
+ </simpara>
+</appendix>
+
diff --git a/doc/admin-guide/en-US/admin_ACLs.xml b/doc/admin-guide/en-US/admin_ACLs.xml
new file mode 100644
index 000000000..edad2d67d
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_ACLs.xml
@@ -0,0 +1,211 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter id="chap-Administration_Guide-ACLs">
+ <title>POSIX Access Control Lists </title>
+ <para>POSIX Access Control Lists (ACLs) allows you to assign different permissions for different users or
+groups even though they do not correspond to the original owner or the owning group.
+ </para>
+ <para>For example: User john creates a file but does not want to allow anyone to do anything with this
+file, except another user, antony (even though there are other users that belong to the group john).
+</para>
+ <para>This means, in addition to the file owner, the file group, and others, additional users and groups can
+be granted or denied access by using POSIX ACLs.
+</para>
+ <section id="sect-Administration_Guide-ACLs-Activating_ACLs">
+ <title>Activating POSIX ACLs Support </title>
+ <para>To use POSIX ACLs for a file or directory, the mount point where the file or directory exists, must be mounted with
+POSIX ACLs support.
+</para>
+ <section id="sect-Administration_Guide-ACLs-Activating_ACLs-Server">
+ <title>Activating POSIX ACLs Support on Sever </title>
+ <para>To mount the backend export directories for POSIX ACLs support, use the following command:
+</para>
+ <para><command># mount -o acl <replaceable>device-name</replaceable><replaceable>partition</replaceable></command>
+</para>
+ <para>If the backend export directory is already mounted, use the following command:
+</para>
+ <para><command># mount -oremount,acl <replaceable>device-name</replaceable><replaceable>partition</replaceable></command>
+</para>
+
+ <para>For example:
+</para>
+ <para><command># mount -o acl /dev/sda1 /export1 </command></para>
+ <para>Alternatively, if the partition is listed in the /etc/fstab file, add the following entry for the partition
+to include the POSIX ACLs option:
+</para>
+ <para><command>LABEL=/work /export1 xfs rw,acl 1 4 </command></para>
+ </section>
+ <section>
+ <title>Activating POSIX ACLs Support on Client </title>
+ <para>To mount the glusterfs volume with POSIX ACLs support, use the following command:
+</para>
+ <para><command># mount –t glusterfs -o acl <replaceable>severname:/volume-id</replaceable><replaceable>mount point</replaceable></command>
+</para>
+ <para>For example:
+</para>
+ <para><command># mount -t glusterfs -o acl 198.192.198.234:/glustervolume /mnt/gluster</command>
+</para>
+ </section>
+ </section>
+ <section>
+ <title>Setting POSIX ACLs </title>
+ <para>You can set two types of POSIX ACLs, that is, access ACLs and default ACLs. You can use
+access ACLs to grant permission for a specific file or directory. You can use default ACLs only
+on a directory but if a file inside that directory does not have an ACLs, it inherits the permissions of
+the default ACLs of the directory.
+</para>
+ <para>You can set ACLs for per user, per group, for users not in the user group for the file, and via the
+effective right mask.
+</para>
+ <section>
+ <title>Setting Access ACLs </title>
+ <para>You can apply access ACLs to grant permission for both files and directories.
+</para>
+ <para><emphasis role="bold">To set or modify Access ACLs</emphasis>
+</para>
+ <para>You can set or modify access ACLs use the following command:
+</para>
+ <para><command># setfacl –m <replaceable>entry type</replaceable> file </command></para>
+ <para>The ACL entry types are the POSIX ACLs representations of owner, group, and other.
+</para>
+ <para>Permissions must be a combination of the characters <command>r</command> (read), <command>w</command> (write), and <command>x</command> (execute). You must
+specify the ACL entry in the following format and can specify multiple entry types separated by
+commas.
+</para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>ACL Entry</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>u:uid:&lt;permission&gt; </entry>
+ <entry>Sets the access ACLs for a user. You can specify user name or UID </entry>
+ </row>
+ <row>
+ <entry>g:gid:&lt;permission&gt; </entry>
+ <entry>Sets the access ACLs for a group. You can specify group name or GID. </entry>
+ </row>
+ <row>
+ <entry>m:&lt;permission&gt; </entry>
+ <entry>Sets the effective rights mask. The mask is the combination of all access permissions of the owning group and all of the user and group entries. </entry>
+ </row>
+ <row>
+ <entry>o:&lt;permission&gt; </entry>
+ <entry>Sets the access ACLs for users other than the ones in the group for the file. </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ <para>If a file or directory already has an POSIX ACLs, and the setfacl command is used, the additional
+permissions are added to the existing POSIX ACLs or the existing rule is modified.
+</para>
+ <para>For example, to give read and write permissions to user antony:
+</para>
+ <para><command># setfacl -m u:antony:rw /mnt/gluster/data/testfile </command></para>
+ </section>
+ <section>
+ <title>Setting Default ACLs </title>
+ <para>You can apply default ACLs only to directories. They determine the permissions of a file system
+objects that inherits from its parent directory when it is created.
+</para>
+ <para>To set default ACLs
+</para>
+ <para>You can set default ACLs for files and directories using the following command:
+</para>
+ <para><command># setfacl –m –-set <replaceable>entry type directory</replaceable></command>
+</para>
+ <para>For example, to set the default ACLs for the /data directory to read for users not in the user group:
+</para>
+ <para><command># setfacl –m --set o::r /mnt/gluster/data </command></para>
+ <para><note>
+ <para>An access ACLs set for an individual file can override the default ACLs permissions.
+</para>
+ </note></para>
+ <para><emphasis role="bold">Effects of a Default ACLs </emphasis></para>
+ <para>The following are the ways in which the permissions of a directory&apos;s default ACLs are passed to the
+files and subdirectories in it:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>A subdirectory inherits the default ACLs of the parent directory both as its default ACLs and as an
+access ACLs.
+</para>
+ </listitem>
+ <listitem>
+ <para>A file inherits the default ACLs as its access ACLs.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section>
+ <title>Retrieving POSIX ACLs </title>
+ <para>You can view the existing POSIX ACLs for a file or directory.
+</para>
+ <para><emphasis role="bold">To view existing POSIX ACLs </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>View the existing access ACLs of a file using the following command:
+</para>
+ <para><command># getfacl <replaceable>path/filename</replaceable></command>
+</para>
+ <para>For example, to view the existing POSIX ACLs for sample.jpg
+</para>
+ <programlisting># getfacl /mnt/gluster/data/test/sample.jpg
+# owner: antony
+# group: antony
+user::rw-
+group::rw-
+other::r--</programlisting>
+ </listitem>
+ <listitem>
+ <para>View the default ACLs of a directory using the following command:
+</para>
+ <para><command># getfacl <replaceable>directory name</replaceable></command></para>
+ <para>For example, to view the existing ACLs for /data/doc
+</para>
+ <programlisting># getfacl /mnt/gluster/data/doc
+# owner: antony
+# group: antony
+user::rw-
+user:john:r--
+group::r--
+mask::r--
+other::r--
+default:user::rwx
+default:user:antony:rwx
+default:group::r-x
+default:mask::rwx
+default:other::r-x</programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Removing POSIX ACLs </title>
+ <para>To remove all the permissions for a user, groups, or others, use the following command:
+</para>
+ <para><command># setfacl -x <replaceable>ACL entry type file</replaceable></command></para>
+ <para>For example, to remove all permissions from the user antony:
+</para>
+ <para><command># setfacl -x u:antony /mnt/gluster/data/test-file</command></para>
+ </section>
+ <section>
+ <title>Samba and ACLs </title>
+ <para>If you are using Samba to access GlusterFS FUSE mount, then POSIX ACLs are enabled by default.
+Samba has been compiled with the <command>--with-acl-support</command> option, so no special flags are required
+when accessing or mounting a Samba share.
+</para>
+ </section>
+ <section>
+ <title>NFS and ACLs </title>
+ <para>Currently we do not support ACLs configuration through NFS, i.e. setfacl and getfacl commands do
+not work. However, ACLs permissions set using Gluster Native Client applies on NFS mounts.
+</para>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_Hadoop.xml b/doc/admin-guide/en-US/admin_Hadoop.xml
new file mode 100644
index 000000000..31eaaa84f
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_Hadoop.xml
@@ -0,0 +1,248 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Administration_Guide-Hadoop">
+ <title>Managing Hadoop Compatible Storage </title>
+ <para>GlusterFS provides compatibility for Apache Hadoop and it uses the standard file system
+APIs available in Hadoop to provide a new storage option for Hadoop deployments. Existing
+MapReduce based applications can use GlusterFS seamlessly. This new functionality opens up data
+within Hadoop deployments to any file-based or object-based application.
+
+ </para>
+ <section id="sect-Administration_Guide-Hadoop-Introduction-Architecture_Overview">
+ <title>Architecture Overview </title>
+ <para>The following diagram illustrates Hadoop integration with GlusterFS:
+<mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Hadoop_Architecture.png"/>
+ </imageobject>
+ </mediaobject>
+ </para>
+ </section>
+ <section id="sect-Administration_Guide-Hadoop-Introduction-Advantages">
+ <title>Advantages </title>
+ <para>
+The following are the advantages of Hadoop Compatible Storage with GlusterFS:
+
+
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Provides simultaneous file-based and object-based access within Hadoop.
+</para>
+ </listitem>
+ <listitem>
+ <para>Eliminates the centralized metadata server.
+</para>
+ </listitem>
+ <listitem>
+ <para>Provides compatibility with MapReduce applications and rewrite is not required.
+</para>
+ </listitem>
+ <listitem>
+ <para>Provides a fault tolerant file system.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Preparing to Install Hadoop Compatible Storage</title>
+ <para>This section provides information on pre-requisites and list of dependencies that will be installed
+during installation of Hadoop compatible storage.
+
+</para>
+ <section id="sect-Administration_Guide-Hadoop-Preparation">
+ <title>Pre-requisites </title>
+ <para>The following are the pre-requisites to install Hadoop Compatible
+Storage :
+
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Hadoop 0.20.2 is installed, configured, and is running on all the machines in the cluster.
+</para>
+ </listitem>
+ <listitem>
+ <para>Java Runtime Environment
+</para>
+ </listitem>
+ <listitem>
+ <para>Maven (mandatory only if you are building the plugin from the source)
+</para>
+ </listitem>
+ <listitem>
+ <para>JDK (mandatory only if you are building the plugin from the source)
+</para>
+ </listitem>
+ <listitem>
+ <para>getfattr
+- command line utility</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section>
+ <title>Installing, and Configuring Hadoop Compatible Storage</title>
+ <para>This section describes how to install and configure Hadoop Compatible Storage in your storage
+environment and verify that it is functioning correctly.
+
+</para>
+ <orderedlist>
+ <para>To install and configure Hadoop compatible storage:</para>
+ <listitem>
+ <para>Download
+ <filename>glusterfs-hadoop-plugin-0.20.2-0.1.x86_64.rpm</filename>
+ file to each server on your cluster. You can download the file from
+ <ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/Hadoop/glusterfs-hadoop-plugin-0.20.2_0.1-beta.noarch.rpm"/>.
+
+</para>
+ </listitem>
+ <listitem>
+ <para>To install Hadoop Compatible Storage on all servers in your cluster, run the following command:
+</para>
+ <para><command># rpm –ivh --nodeps glusterfs-hadoop-plugin-0.20.2-0.1.x86_64.rpm</command>
+</para>
+ <para>The following files will be extracted:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>/usr/local/lib/glusterfs-<replaceable>Hadoop-version-gluster_plugin_version</replaceable>.jar </para>
+ </listitem>
+ <listitem>
+ <para> /usr/local/lib/conf/core-site.xml</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>(Optional) To install Hadoop Compatible Storage in a different location, run the following
+command:
+</para>
+ <para><command># rpm –ivh --nodeps –prefix /usr/local/glusterfs/hadoop
+ glusterfs-hadoop-plugin-0.20.2-0.1.x86_64.rpm</command>
+</para>
+ </listitem>
+ <listitem>
+ <para>Edit the <filename>conf/core-site.xml</filename> file. The following is the sample <filename>conf/core-site.xml</filename> file:
+</para>
+ <para><programlisting>&lt;configuration&gt;
+ &lt;property&gt;
+ &lt;name&gt;fs.glusterfs.impl&lt;/name&gt;
+ &lt;value&gt;org.apache.hadoop.fs.glusterfs.Gluster FileSystem&lt;/value&gt;
+&lt;/property&gt;
+
+&lt;property&gt;
+ &lt;name&gt;fs.default.name&lt;/name&gt;
+ &lt;value&gt;glusterfs://fedora1:9000&lt;/value&gt;
+&lt;/property&gt;
+
+&lt;property&gt;
+ &lt;name&gt;fs.glusterfs.volname&lt;/name&gt;
+ &lt;value&gt;hadoopvol&lt;/value&gt;
+&lt;/property&gt;
+
+&lt;property&gt;
+ &lt;name&gt;fs.glusterfs.mount&lt;/name&gt;
+ &lt;value&gt;/mnt/glusterfs&lt;/value&gt;
+&lt;/property&gt;
+
+&lt;property&gt;
+ &lt;name&gt;fs.glusterfs.server&lt;/name&gt;
+ &lt;value&gt;fedora2&lt;/value&gt;
+&lt;/property&gt;
+
+&lt;property&gt;
+ &lt;name&gt;quick.slave.io&lt;/name&gt;
+ &lt;value&gt;Off&lt;/value&gt;
+&lt;/property&gt;
+&lt;/configuration&gt;
+</programlisting></para>
+ <para>The following are the configurable fields:
+</para>
+ <para><informaltable frame="none">
+ <tgroup cols="3">
+ <colspec colnum="1" colname="c0" colsep="0"/>
+ <colspec colnum="2" colname="c1" colsep="0"/>
+ <colspec colnum="3" colname="c2" colsep="0"/>
+ <thead>
+ <row>
+ <entry>Property Name </entry>
+ <entry>Default Value </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>fs.default.name </entry>
+ <entry>glusterfs://fedora1:9000</entry>
+ <entry>Any hostname in the cluster as the server and any port number. </entry>
+ </row>
+ <row>
+ <entry>fs.glusterfs.volname </entry>
+ <entry>hadoopvol </entry>
+ <entry>GlusterFS volume to mount. </entry>
+ </row>
+ <row>
+ <entry>fs.glusterfs.mount </entry>
+ <entry>/mnt/glusterfs</entry>
+ <entry>The directory used to fuse mount the volume.</entry>
+ </row>
+ <row>
+ <entry>fs.glusterfs.server </entry>
+ <entry>fedora2</entry>
+ <entry>Any hostname or IP address on the cluster except the client/master. </entry>
+ </row>
+ <row>
+ <entry>quick.slave.io </entry>
+ <entry>Off </entry>
+ <entry>Performance tunable option. If this option is set to On, the plugin will try to perform I/O directly from the disk file system (like ext3 or ext4) the file resides on. Hence read performance will improve and job would run faster. <note>
+ <para>This option is not tested widely</para>
+ </note></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+ </listitem>
+ <listitem>
+ <para>Create a soft link in Hadoop’s library and configuration directory for the downloaded files (in
+Step 3) using the following commands:
+</para>
+ <para><command># ln -s <replaceable>&lt;target location&gt; &lt;source location</replaceable>&gt;</command>
+</para>
+ <para>For example,
+</para>
+ <para><command># ln –s /usr/local/lib/glusterfs-0.20.2-0.1.jar <replaceable>$HADOOP_HOME</replaceable>/lib/glusterfs-0.20.2-0.1.jar</command>
+</para>
+ <para><command># ln –s /usr/local/lib/conf/core-site.xml <replaceable>$HADOOP_HOME</replaceable>/conf/core-site.xml </command></para>
+ </listitem>
+ <listitem>
+ <para> (Optional) You can run the following command on Hadoop master to build the plugin and deploy
+it along with core-site.xml file, instead of repeating the above steps:
+</para>
+ <para><command># build-deploy-jar.py -d <replaceable>$HADOOP_HOME</replaceable> -c </command></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>Starting and Stopping the Hadoop MapReduce Daemon</title>
+ <para>To start and stop MapReduce daemon</para>
+ <itemizedlist>
+ <listitem>
+ <para>To start MapReduce daemon manually, enter the following command:
+</para>
+ <para><command># <replaceable>$HADOOP_HOME</replaceable>/bin/start-mapred.sh</command>
+</para>
+ </listitem>
+ <listitem>
+ <para>To stop MapReduce daemon manually, enter the following command:
+</para>
+ <para><command># <replaceable>$HADOOP_HOME</replaceable>/bin/stop-mapred.sh </command></para>
+ </listitem>
+ </itemizedlist>
+ <para><note>
+ <para>You must start Hadoop MapReduce daemon on all servers.
+</para>
+ </note></para>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_UFO.xml b/doc/admin-guide/en-US/admin_UFO.xml
new file mode 100644
index 000000000..9669c59f8
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_UFO.xml
@@ -0,0 +1,1580 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Administration_Guide-UFO">
+ <title>Managing Unified File and Object Storage</title>
+ <para>Unified File and Object Storage (UFO) unifies NAS and object storage technology. It
+provides a system for data storage that enables users to access the same data, both as an object and as a
+file, thus simplifying management and controlling storage costs.
+
+</para>
+ <para>Unified File and Object Storage is built upon Openstack&apos;s Object Storage Swift. Open Stack Object Storage allows users to store and retrieve files and content through a simple Web Service (REST: Representational State Transfer) interface as objects and GlusterFS, allows users to store and retrieve files using Native Fuse and NFS mounts. It uses GlusterFS as a backend file system for Open Stack Swift. It also leverages on Open Stack Swift&apos;s web interface for storing and retrieving files over the web combined with GlusterFS features like scalability and high availability, replication, elastic volume management for data management at disk level.</para>
+ <para>Unified File and Object Storage technology enables enterprises to adopt and deploy
+cloud storage solutions. It allows users to access and modify data as objects from a
+REST interface along with the ability to access and modify files from NAS interfaces including NFS
+and CIFS. In addition to decreasing cost and making it faster and easier to access object data,
+it also delivers massive scalability, high availability and replication of object storage.
+Infrastructure as a Service (IaaS) providers can utilize GlusterFS Unified File and Object Storage technology to enable their own cloud
+storage service. Enterprises can use this technology to accelerate the process of preparing file-based
+applications for the cloud and simplify new application development for cloud computing
+environments.
+
+</para>
+ <para>OpenStack Object Storage is scalable object storage system and it is not a traditional file system. You will not be able to mount this system like traditional SAN or NAS
+volumes and perform POSIX compliant operations. </para>
+ <para><figure>
+ <title>Unified File and Object Storage Architecture</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/UFO_Architecture.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure></para>
+ <section>
+ <title>Components of Object Storage</title>
+ <para>The major components of Object Storage are:
+ </para>
+ <para><emphasis role="bold">Proxy Server</emphasis>
+
+</para>
+ <para>All REST requests to the UFO are routed through the Proxy Server.
+
+
+</para>
+ <para><emphasis role="bold">Objects and Containers </emphasis></para>
+ <para>An object is the basic storage entity and any optional metadata that represents the data
+you store. When you upload data, the data is stored as-is (with no compression or encryption).
+
+</para>
+ <para>A container is a storage compartment for your data and provides a way for you to organize
+your data. Containers can be visualized as directories in a Linux system. Data must be stored in a container and hence objects are created within a container.
+
+</para>
+ <para>It implements objects as files and directories under the container. The object name is a &apos;/&apos; separated path and UFO maps it to directories until the last name in the path, which is marked as a file. With this approach, objects can be accessed as files and directories from native GlusterFS (FUSE) or NFS mounts by providing the &apos;/&apos; separated path.</para>
+ <para><emphasis role="bold">Accounts and Account Servers</emphasis></para>
+ <para>The OpenStack Object Storage system is designed to be used by many different storage
+consumers. Each user is associated with one or more accounts and must identify themselves using an authentication system. While authenticating, users must provide the name of the account for which the authentication is requested.
+
+</para>
+ <para>UFO implements accounts as GlusterFS volumes. So, when a user is granted read/write permission on an account, it means that that user has access to all the data available on that GlusterFS volume.
+
+
+
+
+</para>
+ <para><emphasis role="bold">Authentication and Access Permissions</emphasis>
+
+</para>
+ <para>You must authenticate against an authentication service to receive OpenStack Object
+Storage connection parameters and an authentication token. The token must be passed
+in for all subsequent container or object operations. One authentication service that you
+can use as a middleware example is called <literal>tempauth</literal>.</para>
+ <para>By default, each user has their own storage account and has full access to that
+account. Users must authenticate with their credentials as described above, but once
+authenticated they can manage containers and objects within that account. If a user wants to access the content from another account, they must have API access key or a session token provided by their authentication system.</para>
+ </section>
+ <section>
+ <title>Advantages of using GlusterFS Unified File and Object Storage</title>
+ <para>The following are the advantages of using GlusterFS UFO:</para>
+ <itemizedlist>
+ <listitem>
+ <para>No limit on upload and download files sizes as compared to Open Stack Swift which limits the object size to 5GB.</para>
+ </listitem>
+ <listitem>
+ <para>A unified view of data across NAS and Object Storage technologies.</para>
+ </listitem>
+ <listitem>
+ <para>Using GlusterFS&apos;s UFO has other advantages like the following: </para>
+ <para><itemizedlist>
+ <listitem>
+ <para>High availability</para>
+ </listitem>
+ <listitem>
+ <para>Scalability</para>
+ </listitem>
+ <listitem>
+ <para>Replication</para>
+ </listitem>
+ <listitem>
+ <para>Elastic Volume management</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Preparing to Deploy Unified File and Object Storage</title>
+ <para>This section provides information on pre-requisites and list of dependencies that will be installed
+during the installation of Unified File and Object Storage.
+</para>
+ <section>
+ <title>Pre-requisites </title>
+ <para>GlusterFS&apos;s Unified File and Object Storage needs <literal>user_xattr</literal> support from the underlying disk file system.
+Use the following command to enable <literal>user_xattr</literal> for GlusterFS bricks backend:
+</para>
+ <para><command># mount –o remount,user_xattr <replaceable>device name</replaceable></command></para>
+ <para>For example,
+</para>
+ <para><command># mount –o remount,user_xattr /dev/hda1 </command>
+</para>
+ </section>
+ <section>
+ <title>Dependencies </title>
+ <para>The following packages are installed on GlusterFS when you install Unified File and Object
+Storage:
+
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>curl
+
+
+
+
+
+
+
+
+
+
+
+
+
+</para>
+ </listitem>
+ <listitem>
+ <para>memcached</para>
+ </listitem>
+ <listitem>
+ <para>openssl</para>
+ </listitem>
+ <listitem>
+ <para>xfsprogs</para>
+ </listitem>
+ <listitem>
+ <para>python2.6</para>
+ </listitem>
+ <listitem>
+ <para>pyxattr</para>
+ </listitem>
+ <listitem>
+ <para>python-configobj
+</para>
+ </listitem>
+ <listitem>
+ <para>python-setuptools
+
+</para>
+ </listitem>
+ <listitem>
+ <para>python-simplejson
+
+</para>
+ </listitem>
+ <listitem>
+ <para>python-webob
+
+</para>
+ </listitem>
+ <listitem>
+ <para>python-eventlet
+
+</para>
+ </listitem>
+ <listitem>
+ <para>python-greenlet
+
+</para>
+ </listitem>
+ <listitem>
+ <para>python-pastedeploy
+
+</para>
+ </listitem>
+ <listitem>
+ <para>python-netifaces
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section>
+ <title>Installing and Configuring Unified File and Object Storage</title>
+ <para>This section provides instructions on how to install and configure Unified File and Object Storage in your storage
+environment.</para>
+ <section id="chap-ation_Guide-Dir_Quota-Enable">
+ <title>Installing Unified File and Object Storage</title>
+ <para>To install Unified File and Object Storage:</para>
+ <orderedlist>
+ <listitem>
+ <para>Download <filename>rhel_install.sh</filename> install script from <ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/UFO/"/> .
+</para>
+ </listitem>
+ <listitem>
+ <para>Run
+ <filename>rhel_install.sh</filename> script using the following command:
+</para>
+ <para><command># sh rhel_install.sh</command></para>
+ </listitem>
+ <para><note>
+ <para>You must repeat the above steps on all the machines on which you want to install Unified File and Object Storage. If you install the Unified File and Object Storage on multiple servers, you can use a load balancer like pound, nginx, and so on to distribute the request across the machines.</para>
+ </note></para>
+ </orderedlist>
+ </section>
+ <section>
+ <title>Adding Users</title>
+ <para>The authentication system allows the administrator to grant different levels of access to different users based on the requirement. The following are the types of user permissions:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>admin user
+ </para>
+ </listitem>
+ <listitem>
+ <para>normal user</para>
+ </listitem>
+ </itemizedlist>
+ <para>Admin user has read and write permissions on the account. By default, a normal user has no read or write permissions. A normal user can only authenticate itself to get a Auth-Token. Read or write permission are provided through ACLs by the admin users.</para>
+ <para>Add a new user by adding the following entry in <filename>/etc/swift/proxy-server.conf</filename> file:</para>
+ <para><command>user_&lt;account-name&gt;_&lt;user-name&gt; = &lt;password&gt; [.admin]</command></para>
+ <para>For example, </para>
+ <para><command>user_test_tester = testing .admin</command>
+</para>
+ <note>
+ <para>During installation, the installation script adds few sample users to the <filename>proxy-server.conf</filename> file. It is highly recommended that you remove all the default sample user entries from the configuration file.
+</para>
+ </note>
+ <para>For more information on setting ACLs, see <xref linkend="chap-Administration_Guide-Working_UFO-Setting_ACLs"/>.</para>
+ </section>
+ <section>
+ <title>Configuring Proxy Server</title>
+ <para>The Proxy Server is responsible for connecting to the rest of the OpenStack Object Storage architecture. For each request, it looks up the location of the account, container, or object in the ring and route the request accordingly. The public API is also exposed through the proxy server. When objects are streamed to or from an object server, they are streamed directly through the proxy server to or from the user – the proxy server does not spool them.
+</para>
+ <para>The configurable options pertaining to proxy server are stored in <filename>/etc/swift/proxy-server.conf</filename>. The following is the sample <filename>proxy-server.conf</filename> file:</para>
+ <para><programlisting>[app:proxy-server]
+use = egg:swift#proxy
+allow_account_management=true
+account_autocreate=true
+
+[filter:tempauth]
+use = egg:swift#tempauth user_admin_admin=admin.admin.reseller_admin
+user_test_tester=testing.admin
+user_test2_tester2=testing2.admin
+user_test_tester3=testing3
+
+[filter:healthcheck]
+use = egg:swift#healthcheck
+
+[filter:cache]
+use = egg:swift#memcache</programlisting></para>
+ <para>By default, GlusterFS&apos;s Unified File and Object Storage is configured to support HTTP protocol and uses temporary authentication to authenticate the HTTP requests.</para>
+ </section>
+ <section>
+ <title>Configuring Authentication System</title>
+ <para>Proxy server must be configured to authenticate using <literal>
+ <literal>tempauth</literal>
+ </literal>. </para>
+ </section>
+ <section>
+ <title>Configuring Proxy Server for HTTPS</title>
+ <para>By default, proxy server only handles HTTP request. To configure the proxy server to process HTTPS requests, perform the following steps:</para>
+ <orderedlist>
+ <listitem>
+ <para>Create self-signed cert for SSL using the following commands:</para>
+ <para><programlisting>cd /etc/swift
+openssl req -new -x509 -nodes -out cert.crt -keyout cert.key</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Add the following lines to <filename>/etc/swift/proxy-server.conf </filename>under <replaceable>[DEFAULT]</replaceable></para>
+ <para><programlisting>bind_port = 443
+ cert_file = /etc/swift/cert.crt
+ key_file = /etc/swift/cert.key</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Restart the servers using the following commands:</para>
+ <para><programlisting>swift-init main stop
+swift-init main start</programlisting></para>
+ </listitem>
+ </orderedlist>
+ <para>The following are the configurable options:
+</para>
+ <table frame="all">
+ <title>proxy-server.conf Default Options in the [DEFAULT] section </title>
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Option </entry>
+ <entry>Default </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>bind_ip </entry>
+ <entry>0.0.0.0 </entry>
+ <entry>IP Address for server to bind</entry>
+ </row>
+ <row>
+ <entry>bind_port </entry>
+ <entry>80 </entry>
+ <entry>Port for server to bind </entry>
+ </row>
+ <row>
+ <entry>swift_dir </entry>
+ <entry>/etc/swift </entry>
+ <entry>Swift configuration directory </entry>
+ </row>
+ <row>
+ <entry>workers </entry>
+ <entry>1</entry>
+ <entry>Number of workers to fork </entry>
+ </row>
+ <row>
+ <entry>user </entry>
+ <entry>swift </entry>
+ <entry>swift user</entry>
+ </row>
+ <row>
+ <entry>cert_file </entry>
+ <entry/>
+ <entry>Path to the ssl .crt </entry>
+ </row>
+ <row>
+ <entry>key_file </entry>
+ <entry/>
+ <entry>Path to the ssl .key </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table frame="all">
+ <title>proxy-server.conf Server Options in the [proxy-server] section </title>
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Option </entry>
+ <entry>Default </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>use </entry>
+ <entry/>
+ <entry>paste.deploy entry point for the container server. For most cases, this should be <literal>egg:swift#container</literal>. </entry>
+ </row>
+ <row>
+ <entry>log_name </entry>
+ <entry>proxy-server </entry>
+ <entry>Label used when logging </entry>
+ </row>
+ <row>
+ <entry>log_facility </entry>
+ <entry>LOG_LOCAL0 </entry>
+ <entry>Syslog log facility </entry>
+ </row>
+ <row>
+ <entry>log_level </entry>
+ <entry>INFO </entry>
+ <entry>Log level </entry>
+ </row>
+ <row>
+ <entry>log_headers </entry>
+ <entry>True </entry>
+ <entry>If True, log headers in each request </entry>
+ </row>
+ <row>
+ <entry>recheck_account_existence </entry>
+ <entry>60 </entry>
+ <entry>Cache timeout in seconds to send memcached for account existence </entry>
+ </row>
+ <row>
+ <entry>recheck_container_existence </entry>
+ <entry>60 </entry>
+ <entry>Cache timeout in seconds to send memcached for container existence </entry>
+ </row>
+ <row>
+ <entry>object_chunk_size </entry>
+ <entry>65536 </entry>
+ <entry>Chunk size to read from object servers </entry>
+ </row>
+ <row>
+ <entry>client_chunk_size </entry>
+ <entry>65536 </entry>
+ <entry>Chunk size to read from clients </entry>
+ </row>
+ <row>
+ <entry>memcache_servers </entry>
+ <entry>127.0.0.1:11211 </entry>
+ <entry>Comma separated list of memcached servers ip:port </entry>
+ </row>
+ <row>
+ <entry>node_timeout </entry>
+ <entry>10 </entry>
+ <entry>Request timeout to external services </entry>
+ </row>
+ <row>
+ <entry>client_timeout </entry>
+ <entry>60 </entry>
+ <entry>Timeout to read one chunk from a client </entry>
+ </row>
+ <row>
+ <entry>conn_timeout </entry>
+ <entry>0.5 </entry>
+ <entry>Connection timeout to external services </entry>
+ </row>
+ <row>
+ <entry>error_suppression_interval </entry>
+ <entry>60 </entry>
+ <entry>Time in seconds that must elapse since the last error for a node to be considered no longer error limited </entry>
+ </row>
+ <row>
+ <entry>error_suppression_limit </entry>
+ <entry>10 </entry>
+ <entry>Error count to consider a node error limited </entry>
+ </row>
+ <row>
+ <entry>allow_account_management </entry>
+ <entry>false </entry>
+ <entry>Whether account <literal>PUT</literal>s and <literal>DELETE</literal>s are even callable </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>Configuring Object Server</title>
+ <para>The Object Server is a very simple blob storage server that can store, retrieve, and delete objects stored on local devices. Objects are stored as binary files on the file system with metadata stored in the file’s extended attributes (xattrs). This requires that the underlying file system choice for object servers support xattrs on files.
+
+</para>
+ <para>The configurable options pertaining Object Server are stored in the file <filename>/etc/swift/object-server/1.conf</filename>. The following is the sample <filename>object-server/1.conf</filename> file:</para>
+ <para><programlisting>[DEFAULT]
+devices = /srv/1/node
+mount_check = false
+bind_port = 6010
+user = root
+log_facility = LOG_LOCAL2
+
+[pipeline:main]
+pipeline = gluster object-server
+
+[app:object-server]
+use = egg:swift#object
+
+[filter:gluster]
+use = egg:swift#gluster
+
+[object-replicator]
+vm_test_mode = yes
+
+[object-updater]
+[object-auditor]</programlisting></para>
+ <para>The following are the configurable options:
+</para>
+ <table frame="all">
+ <title>object-server.conf Default Options in the [DEFAULT] section </title>
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Option </entry>
+ <entry>Default </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>swift_dir </entry>
+ <entry>/etc/swift </entry>
+ <entry>Swift configuration directory </entry>
+ </row>
+ <row>
+ <entry>devices </entry>
+ <entry>/srv/node </entry>
+ <entry>Mount parent directory where devices are mounted </entry>
+ </row>
+ <row>
+ <entry>mount_check </entry>
+ <entry>true </entry>
+ <entry>Whether or not check if the devices are mounted to prevent accidentally writing to the root device </entry>
+ </row>
+ <row>
+ <entry>bind_ip </entry>
+ <entry>0.0.0.0 </entry>
+ <entry>IP Address for server to bind</entry>
+ </row>
+ <row>
+ <entry>bind_port </entry>
+ <entry>6000 </entry>
+ <entry>Port for server to bind</entry>
+ </row>
+ <row>
+ <entry>workers </entry>
+ <entry>1 </entry>
+ <entry>Number of workers to fork </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table frame="all">
+ <title>object-server.conf Server Options in the [object-server] section </title>
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Option </entry>
+ <entry>Default </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>use </entry>
+ <entry/>
+ <entry>paste.deploy entry point for the object server. For most cases, this should be <literal>egg:swift#object</literal>. </entry>
+ </row>
+ <row>
+ <entry>log_name </entry>
+ <entry>object-server </entry>
+ <entry>log name used when logging </entry>
+ </row>
+ <row>
+ <entry>log_facility </entry>
+ <entry>LOG_LOCAL0 </entry>
+ <entry>Syslog log facility </entry>
+ </row>
+ <row>
+ <entry>log_level </entry>
+ <entry>INFO </entry>
+ <entry>Logging level </entry>
+ </row>
+ <row>
+ <entry>log_requests </entry>
+ <entry>True </entry>
+ <entry>Whether or not to log each request </entry>
+ </row>
+ <row>
+ <entry>user </entry>
+ <entry>swift </entry>
+ <entry>swift user</entry>
+ </row>
+ <row>
+ <entry>node_timeout </entry>
+ <entry>3</entry>
+ <entry>Request timeout to external services </entry>
+ </row>
+ <row>
+ <entry>conn_timeout </entry>
+ <entry>0.5</entry>
+ <entry>Connection timeout to external services </entry>
+ </row>
+ <row>
+ <entry>network_chunk_size </entry>
+ <entry>65536 </entry>
+ <entry>Size of chunks to read or write over the network </entry>
+ </row>
+ <row>
+ <entry>disk_chunk_size </entry>
+ <entry>65536 </entry>
+ <entry>Size of chunks to read or write to disk </entry>
+ </row>
+ <row>
+ <entry>max_upload_time </entry>
+ <entry>65536 </entry>
+ <entry>Maximum time allowed to upload an object </entry>
+ </row>
+ <row>
+ <entry>slow </entry>
+ <entry>0</entry>
+ <entry>If &gt; 0, Minimum time in seconds for a <literal>PUT</literal> or <literal>DELETE</literal> request to complete </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>Configuring Container Server</title>
+ <para>The Container Server’s primary job is to handle listings of objects. The listing is done by querying the GlusterFS mount point with path. This query returns a list of all files and directories present under that container.
+</para>
+ <para>The configurable options pertaining to container server are stored in <filename>/etc/swift/container-server/1.conf</filename> file. The following is the sample <filename>container-server/1.conf</filename> file:</para>
+ <para><programlisting>[DEFAULT]
+devices = /srv/1/node
+mount_check = false
+bind_port = 6011
+user = root
+log_facility = LOG_LOCAL2
+
+[pipeline:main]
+pipeline = gluster container-server
+
+[app:container-server]
+use = egg:swift#container
+
+[filter:gluster]
+use = egg:swift#gluster
+
+[container-replicator]
+[container-updater]
+[container-auditor]</programlisting></para>
+ <para>The following are the configurable options:</para>
+ <table frame="all">
+ <title>container-server.conf Default Options in the [DEFAULT] section </title>
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Option </entry>
+ <entry>Default </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>swift_dir </entry>
+ <entry>/etc/swift </entry>
+ <entry>Swift configuration directory </entry>
+ </row>
+ <row>
+ <entry>devices </entry>
+ <entry>/srv/node </entry>
+ <entry>Mount parent directory where devices are mounted </entry>
+ </row>
+ <row>
+ <entry>mount_check </entry>
+ <entry>true </entry>
+ <entry>Whether or not check if the devices are mounted to prevent accidentally writing to the root device </entry>
+ </row>
+ <row>
+ <entry>bind_ip </entry>
+ <entry>0.0.0.0 </entry>
+ <entry>IP Address for server to bind</entry>
+ </row>
+ <row>
+ <entry>bind_port </entry>
+ <entry>6001 </entry>
+ <entry>Port for server to bind</entry>
+ </row>
+ <row>
+ <entry>workers </entry>
+ <entry>1 </entry>
+ <entry>Number of workers to fork </entry>
+ </row>
+ <row>
+ <entry>user </entry>
+ <entry>swift </entry>
+ <entry>Swift user</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table frame="all">
+ <title>container-server.conf Server Options in the [container-server] section </title>
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Option </entry>
+ <entry>Default </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>use </entry>
+ <entry/>
+ <entry>paste.deploy entry point for the container server. For most cases, this should be <literal>egg:swift#container</literal>. </entry>
+ </row>
+ <row>
+ <entry>log_name </entry>
+ <entry>container-server </entry>
+ <entry>Label used when logging </entry>
+ </row>
+ <row>
+ <entry>log_facility </entry>
+ <entry>LOG_LOCAL0 </entry>
+ <entry>Syslog log facility </entry>
+ </row>
+ <row>
+ <entry>log_level </entry>
+ <entry>INFO </entry>
+ <entry>Logging level </entry>
+ </row>
+ <row>
+ <entry>node_timeout </entry>
+ <entry>3 </entry>
+ <entry>Request timeout to external services </entry>
+ </row>
+ <row>
+ <entry>conn_timeout </entry>
+ <entry>0.5 </entry>
+ <entry>Connection timeout to external services </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>Configuring Account Server</title>
+ <para>The Account Server is very similar to the Container Server, except that it is responsible for listing of containers rather than objects. In UFO, each gluster volume is an account.
+</para>
+ <para>The configurable options pertaining to account server are stored in <filename>/etc/swift/account-server/1.conf</filename> file. The following is the sample <filename>account-server/1.conf</filename> file: </para>
+ <para><programlisting>[DEFAULT]
+devices = /srv/1/node
+mount_check = false
+bind_port = 6012
+user = root
+log_facility = LOG_LOCAL2
+
+[pipeline:main]
+pipeline = gluster account-server
+
+[app:account-server]
+use = egg:swift#account
+
+[filter:gluster]
+use = egg:swift#gluster
+
+[account-replicator]
+vm_test_mode = yes
+
+[account-auditor]
+[account-reaper]</programlisting></para>
+ <para>The following are the configurable options:</para>
+ <table frame="all">
+ <title>account-server.conf Default Options in the [DEFAULT] section </title>
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Option </entry>
+ <entry>Default </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>swift_dir </entry>
+ <entry>/etc/swift </entry>
+ <entry>Swift configuration directory </entry>
+ </row>
+ <row>
+ <entry>devices </entry>
+ <entry>/srv/node </entry>
+ <entry>mount parent directory where devices are mounted </entry>
+ </row>
+ <row>
+ <entry>mount_check </entry>
+ <entry>true </entry>
+ <entry>Whether or not check if the devices are mounted to prevent accidentally writing to the root device </entry>
+ </row>
+ <row>
+ <entry>bind_ip </entry>
+ <entry>0.0.0.0 </entry>
+ <entry>IP Address for server to bind</entry>
+ </row>
+ <row>
+ <entry>bind_port </entry>
+ <entry>6002 </entry>
+ <entry>Port for server to bind</entry>
+ </row>
+ <row>
+ <entry>workers </entry>
+ <entry>1 </entry>
+ <entry>Number of workers to fork </entry>
+ </row>
+ <row>
+ <entry>user </entry>
+ <entry>swift </entry>
+ <entry>Swift user</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table frame="all">
+ <title>account-server.conf Server Options in the [account-server] section </title>
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Option </entry>
+ <entry>Default </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>use </entry>
+ <entry/>
+ <entry>paste.deploy entry point for the container server. For most cases, this should be <literal>egg:swift#container</literal>. </entry>
+ </row>
+ <row>
+ <entry>log_name </entry>
+ <entry>account-server </entry>
+ <entry>Label used when logging </entry>
+ </row>
+ <row>
+ <entry>log_facility </entry>
+ <entry>LOG_LOCAL0 </entry>
+ <entry>Syslog log facility </entry>
+ </row>
+ <row>
+ <entry>log_level </entry>
+ <entry>INFO </entry>
+ <entry>Logging level </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>Starting and Stopping Server</title>
+ <para>You must start the server manually when system reboots and whenever you update/modify the configuration files.</para>
+ <itemizedlist>
+ <listitem>
+ <para>To start the server, enter the following command:</para>
+ <para><command># swift_init main start</command></para>
+ </listitem>
+ <listitem>
+ <para>To stop the server, enter the following command:</para>
+ <para><command># swift_init main stop</command></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section>
+ <title>Working with Unified File and Object Storage</title>
+ <para>This section describes the REST API for administering and managing Object Storage. All requests will
+be directed to the host and URL described in the <filename>X-Storage-URL HTTP</filename> header obtained during
+successful authentication.
+</para>
+ <section>
+ <title>Configuring Authenticated Access </title>
+ <para>Authentication is the process of proving identity to the system. To use the REST interface, you must
+obtain an authorization token using GET method and supply it with v1.0 as the path.
+</para>
+ <para>Each REST request against the Object Storage system requires the addition of a specific authorization
+token HTTP x-header, defined as X-Auth-Token. The storage URL and authentication token are
+returned in the headers of the response.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To authenticate, run the following command:
+</para>
+ <programlisting>GET auth/v1.0 HTTP/1.1
+Host: &lt;auth URL&gt;
+X-Auth-User: &lt;account name&gt;:&lt;user name&gt;
+X-Auth-Key: &lt;user-Password&gt;</programlisting>
+ <para>For example,
+</para>
+ <programlisting>GET auth/v1.0 HTTP/1.1
+Host: auth.example.com
+X-Auth-User: test:tester
+X-Auth-Key: testing
+
+HTTP/1.1 200 OK
+X-Storage-Url: https:/example.storage.com:443/v1/AUTH_test
+X-Storage-Token: AUTH_tkde3ad38b087b49bbbac0494f7600a554
+X-Auth-Token: AUTH_tkde3ad38b087b49bbbac0494f7600a554
+Content-Length: 0
+Date: Wed, 10 jul 2011 06:11:51 GMT</programlisting>
+ <para>To authenticate access using cURL (for the above example), run the following
+command:
+</para>
+ <programlisting>curl -v -H &apos;X-Storage-User: test:tester&apos; -H &apos;X-Storage-Pass:testing&apos; -k
+https://auth.example.com:443/auth/v1.0</programlisting>
+ <para>The X-Auth-Url has to be parsed and used in the connection and request line of all subsequent
+requests to the server. In the example output, users connecting to server will send most
+container/object requests with a host header of example.storage.com and the request line&apos;s version
+and account as v1/AUTH_test.
+
+</para>
+ </listitem>
+ </itemizedlist>
+ <note>
+ <para>The authentication tokens are valid for a 24 hour period.
+</para>
+ </note>
+ </section>
+ <section>
+ <title>Working with Accounts </title>
+ <para>This section describes the list of operations you can perform at the account level of the URL.
+</para>
+ <section>
+ <title>Displaying Container Information </title>
+ <para>You can list the objects of a specific container, or all containers, as needed using GET command. You
+can use the following optional parameters with GET request to refine the results:
+</para>
+ <para><informaltable frame="none">
+ <tgroup cols="2">
+ <colspec colnum="1" colname="c0" colsep="0"/>
+ <colspec colnum="2" colname="c1" colsep="0"/>
+ <thead>
+ <row>
+ <entry>Parameter </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>limit </entry>
+ <entry>Limits the number of results to at most <emphasis role="italic">n</emphasis> value. </entry>
+ </row>
+ <row>
+ <entry>marker </entry>
+ <entry>Returns object names greater in value than the specified marker. </entry>
+ </row>
+ <row>
+ <entry>format </entry>
+ <entry>Specify either json or xml to return the respective serialized response. </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+ <para><emphasis role="bold">To display container information </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>List all the containers of an account using the following command:
+</para>
+ <para><programlisting>GET /&lt;apiversion&gt;/&lt;account&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;authentication-token-key&gt;</programlisting></para>
+ <para>For example,
+</para>
+ <programlisting>GET /v1/AUTH_test HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+
+HTTP/1.1 200 Ok
+Date: Wed, 13 Jul 2011 16:32:21 GMT
+Server: Apache
+Content-Type: text/plain; charset=UTF-8
+Content-Length: 39
+
+songs
+movies
+documents
+reports</programlisting>
+ </listitem>
+ </itemizedlist>
+ <para>To display container information using cURL (for the above example), run the following
+command:
+</para>
+ <para><programlisting>curl -v -X GET -H &apos;X-Auth-Token: AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test -k</programlisting></para>
+ </section>
+ <section>
+ <title>Displaying Account Metadata Information </title>
+ <para>You can issue HEAD command to the storage service to view the number of containers and the total
+bytes stored in the account.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To display containers and storage used, run the following command:
+</para>
+ <programlisting>HEAD /&lt;apiversion&gt;/&lt;account&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;authentication-token-key&gt;</programlisting>
+ <para>For example,
+</para>
+ <programlisting>HEAD /v1/AUTH_test HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+
+HTTP/1.1 204 No Content
+Date: Wed, 13 Jul 2011 16:52:21 GMT
+Server: Apache
+X-Account-Container-Count: 4
+X-Account-Total-Bytes-Used: 394792</programlisting>
+ <para>To display account metadata information using cURL (for the above example), run the following
+command:
+</para>
+ <programlisting>curl -v -X HEAD -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test -k</programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section>
+ <title>Working with Containers </title>
+ <para>This section describes the list of operations you can perform at the container level of the URL.
+</para>
+ <section>
+ <title> Creating Containers </title>
+ <para>You can use PUT command to create containers. Containers are the storage folders for your data.
+The URL encoded name must be less than 256 bytes and cannot contain a forward slash &apos;/&apos; character.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To create a container, run the following command:
+</para>
+ <programlisting>PUT /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/ HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;authentication-token-key&gt;</programlisting>
+ <para>For example,
+</para>
+ <programlisting>PUT /v1/AUTH_test/pictures/ HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+HTTP/1.1 201 Created
+
+Date: Wed, 13 Jul 2011 17:32:21 GMT
+Server: Apache
+Content-Type: text/plain; charset=UTF-8</programlisting>
+ <para>To create container using cURL (for the above example), run the following command:
+</para>
+ <programlisting>curl -v -X PUT -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/pictures -k</programlisting>
+ <para>The status code of 201 (Created) indicates that you have successfully created the container. If a
+container with same is already existed, the status code of 202 is displayed.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Displaying Objects of a Container </title>
+ <para>You can list the objects of a container using GET command. You can use the following optional
+parameters with GET request to refine the results:
+</para>
+ <para><informaltable frame="none">
+ <tgroup cols="2">
+ <colspec colnum="1" colname="c0" colsep="0"/>
+ <colspec colnum="2" colname="c1" colsep="0"/>
+ <thead>
+ <row>
+ <entry>Parameter </entry>
+ <entry>Description </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>limit </entry>
+ <entry>Limits the number of results to at most <emphasis role="italic">n</emphasis> value. </entry>
+ </row>
+ <row>
+ <entry>marker </entry>
+ <entry>Returns object names greater in value than the specified marker. </entry>
+ </row>
+ <row>
+ <entry>prefix </entry>
+ <entry>Displays the results limited to object names beginning with the substring x. beginning with the substring x. </entry>
+ </row>
+ <row>
+ <entry>path </entry>
+ <entry>Returns the object names nested in the pseudo path. </entry>
+ </row>
+ <row>
+ <entry>format </entry>
+ <entry>Specify either json or xml to return the respective serialized response. </entry>
+ </row>
+ <row>
+ <entry>delimiter </entry>
+ <entry>Returns all the object names nested in the container. </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+ <para>To display objects of a container
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>List objects of a specific container using the following command:
+</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>GET /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;[parm=value] HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;authentication-token-key&gt;</programlisting>
+ <para>For example,
+</para>
+ <programlisting>GET /v1/AUTH_test/images HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+
+HTTP/1.1 200 Ok
+Date: Wed, 13 Jul 2011 15:42:21 GMT
+Server: Apache
+Content-Type: text/plain; charset=UTF-8
+Content-Length: 139
+
+sample file.jpg
+test-file.pdf
+You and Me.pdf
+Puddle of Mudd.mp3
+Test Reports.doc</programlisting>
+ <para>To display objects of a container using cURL (for the above example), run the following
+command:
+</para>
+ <programlisting>curl -v -X GET-H &apos;X-Auth-Token: AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/images -k</programlisting>
+ </section>
+ <section>
+ <title>Displaying Container Metadata Information </title>
+ <para>You can issue HEAD command to the storage service to view the number of objects in a container and
+the total bytes of all the objects stored in the container.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To display list of objects and storage used, run the following command:
+</para>
+ <programlisting>HEAD /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;authentication-token-key&gt;</programlisting>
+ <para>For example,</para>
+ <programlisting>HEAD /v1/AUTH_test/images HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+
+HTTP/1.1 204 No Content
+Date: Wed, 13 Jul 2011 19:52:21 GMT
+Server: Apache
+X-Account-Object-Count: 8
+X-Container-Bytes-Used: 472</programlisting>
+ <para>To display list of objects and storage used in a container using cURL (for the above example), run
+the following command:
+</para>
+ <programlisting>curl -v -X HEAD -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/images -k</programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Deleting Container </title>
+ <para>You can use DELETE command to permanently delete containers. The container must be empty
+before it can be deleted.
+</para>
+ <para>You can issue HEAD command to determine if it contains any objects.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To delete a container, run the following command:
+</para>
+ <programlisting>DELETE /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/ HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;authentication-token-key&gt;</programlisting>
+ <para>For example,</para>
+ <programlisting>DELETE /v1/AUTH_test/pictures HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+
+HTTP/1.1 204 No Content
+Date: Wed, 13 Jul 2011 17:52:21 GMT
+Server: Apache
+Content-Length: 0
+Content-Type: text/plain; charset=UTF-8</programlisting>
+ <para>To delete a container using cURL (for the above example), run the following command:
+</para>
+ <programlisting>curl -v -X DELETE -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/pictures -k</programlisting>
+ <para>The status code of 204 (No Content) indicates that you have successfully deleted the container. If
+that container does not exist, the status code 404 (Not Found) is displayed, and if the container is
+not empty, the status code 409 (Conflict) is displayed.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Updating Container Metadata </title>
+ <para>You can update the metadata of container using POST operation, metadata keys should be prefixed
+with &apos;x-container-meta&apos;.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To update the metadata of the object, run the following command:
+</para>
+ <programlisting>POST /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;Authentication-token-key&gt;
+X-Container-Meta-&lt;key&gt;: &lt;new value&gt;
+X-Container-Meta-&lt;key&gt;: &lt;new value&gt;</programlisting>
+ <para>For example,
+</para>
+ <para><programlisting>POST /v1/AUTH_test/images HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+X-Container-Meta-Zoo: Lion
+X-Container-Meta-Home: Dog
+
+HTTP/1.1 204 No Content
+Date: Wed, 13 Jul 2011 20:52:21 GMT
+Server: Apache
+Content-Type: text/plain; charset=UTF-8</programlisting></para>
+ <para>To update the metadata of the object using cURL (for the above example), run the following
+command:
+</para>
+ <para><programlisting>curl -v -X POST -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/images -H &apos; X-Container-Meta-Zoo: Lion&apos; -H &apos;X-Container-Meta-Home: Dog&apos; -k</programlisting></para>
+ <para>The status code of 204 (No Content) indicates the container&apos;s metadata is updated successfully. If
+that object does not exist, the status code 404 (Not Found) is displayed.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Working_UFO-Setting_ACLs">
+ <title> Setting ACLs on Container </title>
+ <para>You can set the container access control list by using POST command on container with <command>x- container-read</command> and<command> x-container-write</command> keys.
+</para>
+ <para>The ACL format is <command>[item[,item...]]</command>. Each item can be a group name to give access to or a
+referrer designation to grant or deny based on the HTTP Referer header.
+</para>
+ <para>The referrer designation format is:<command> .r:[-]value</command>.
+</para>
+ <para>The .r can also be <command>.ref, .referer, </command>or .<command>referrer</command>; though it will be shortened to.r for
+decreased character count usage. The value can be <command>*</command> to specify any referrer host is allowed access. The leading minus sign (-)
+indicates referrer hosts that should be denied access.
+</para>
+ <para>Examples of valid ACLs:
+</para>
+ <para><programlisting>.r:*
+.r:*,bobs_account,sues_account:sue
+bobs_account,sues_account:sue</programlisting></para>
+ <para>Examples of invalid ACLs:</para>
+ <para><programlisting>.r:
+.r:-</programlisting></para>
+ <para>By default, allowing read access via <command><command>.</command>r </command>will not allow listing objects in the container but allows
+retrieving objects from the container. To turn on listings, use the .<command>rlistings</command> directive. Also, <command>.r</command>
+designations are not allowed in headers whose names include the word write.
+</para>
+ <para>For example, to set all the objects access rights to &quot;public‟ inside the container using cURL (for the
+above example), run the following command:
+</para>
+ <para><programlisting>curl -v -X POST -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/images
+-H &apos;X-Container-Read: .r:*&apos; -k</programlisting></para>
+ </section>
+ </section>
+ <section>
+ <title> Working with Objects </title>
+ <para>An object represents the data and any metadata for the files stored in the system. Through the REST
+interface, metadata for an object can be included by adding custom HTTP headers to the request
+and the data payload as the request body. Objects name should not exceed 1024 bytes after URL
+encoding.
+</para>
+ <para>This section describes the list of operations you can perform at the object level of the URL.
+</para>
+ <section>
+ <title>Creating or Updating Object </title>
+ <para>You can use PUT command to write or update an object&apos;s content and metadata.
+</para>
+ <para>You can verify the data integrity by including an MD5checksum for the object&apos;s data in the ETag
+header. ETag header is optional and can be used to ensure that the object&apos;s contents are stored
+successfully in the storage system.
+</para>
+ <para>You can assign custom metadata to objects by including additional HTTP headers on the PUT request.
+The objects created with custom metadata via HTTP headers are identified with the<command>X-Object- Meta</command>- prefix.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To create or update an object, run the following command:
+</para>
+ <para><programlisting>PUT /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/&lt;object&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;authentication-token-key&gt;
+ETag: da1e100dc9e7becc810986e37875ae38
+Content-Length: 342909
+X-Object-Meta-PIN: 2343</programlisting></para>
+ <para>For example,</para>
+ <para><programlisting>PUT /v1/AUTH_test/pictures/dog HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+ETag: da1e100dc9e7becc810986e37875ae38
+
+HTTP/1.1 201 Created
+Date: Wed, 13 Jul 2011 18:32:21 GMT
+Server: Apache
+ETag: da1e100dc9e7becc810986e37875ae38
+Content-Length: 0
+Content-Type: text/plain; charset=UTF-8</programlisting></para>
+ <para>To create or update an object using cURL (for the above example), run the following command:
+</para>
+ <para><programlisting>curl -v -X PUT -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/pictures/dog -H &apos;Content-
+Length: 0&apos; -k</programlisting></para>
+ <para>The status code of 201 (Created) indicates that you have successfully created or updated the object.
+If there is a missing content-Length or Content-Type header in the request, the status code of 412
+(Length Required) is displayed. (Optionally) If the MD5 checksum of the data written to the storage
+system does not match the ETag value, the status code of 422 (Unprocessable Entity) is displayed.
+</para>
+ </listitem>
+ </itemizedlist>
+ <section>
+ <title>Chunked Transfer Encoding </title>
+ <para>You can upload data without knowing the size of the data to be uploaded. You can do this by
+specifying an HTTP header of Transfer-Encoding: chunked and without using a Content-Length
+header.
+</para>
+ <para>You can use this feature while doing a DB dump, piping the output through gzip, and then piping the
+data directly into Object Storage without having to buffer the data to disk to compute the file size.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To create or update an object, run the following command:
+ </para>
+ <para><programlisting>PUT /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/&lt;object&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;authentication-token-key&gt;
+Transfer-Encoding: chunked
+X-Object-Meta-PIN: 2343</programlisting></para>
+ <para>For example,
+</para>
+ <para><programlisting>PUT /v1/AUTH_test/pictures/cat HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+Transfer-Encoding: chunked
+X-Object-Meta-PIN: 2343
+19
+A bunch of data broken up
+D
+into chunks.
+0</programlisting>
+
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section>
+ <title>Copying Object </title>
+ <para>You can copy object from one container to another or add a new object and then add reference to
+designate the source of the data from another container.
+</para>
+ <para><emphasis role="bold">To copy object from one container to another </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>To add a new object and designate the source of the data from another container, run the
+following command:
+</para>
+ <para><programlisting>COPY /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/&lt;sourceobject&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt; authentication-token-key&gt;
+Destination: /&lt;container&gt;/&lt;destinationobject&gt;</programlisting></para>
+ <para>For example,
+</para>
+ <para><programlisting>COPY /v1/AUTH_test/images/dogs HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+Destination: /photos/cats
+
+HTTP/1.1 201 Created
+Date: Wed, 13 Jul 2011 18:32:21 GMT
+Server: Apache
+Content-Length: 0
+Content-Type: text/plain; charset=UTF-8</programlisting></para>
+ <para>To copy an object using cURL (for the above example), run the following command:
+</para>
+ <para><programlisting>curl -v -X COPY -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos; -H &apos;Destination: /photos/cats&apos; -k https://example.storage.com:443/v1/AUTH_test/images/dogs</programlisting></para>
+ <para>The status code of 201 (Created) indicates that you have successfully copied the object. If there is a
+missing content-Length or Content-Type header in the request, the status code of 412 (Length
+Required) is displayed.
+</para>
+ <para>You can also use PUT command to copy object by using additional header <command>X-Copy-From: container/obj</command>.
+</para>
+ </listitem>
+ <listitem>
+ <para>To use PUT command to copy an object, run the following command:
+</para>
+ <para><programlisting>PUT /v1/AUTH_test/photos/cats HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+X-Copy-From: /images/dogs
+
+HTTP/1.1 201 Created
+Date: Wed, 13 Jul 2011 18:32:21 GMT
+Server: Apache
+Content-Type: text/plain; charset=UTF-8</programlisting></para>
+ <para>To copy an object using cURL (for the above example), run the following command:
+</para>
+ <para><programlisting>curl -v -X PUT -H &apos;X-Auth-Token: AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+-H &apos;X-Copy-From: /images/dogs&apos; –k
+https://example.storage.com:443/v1/AUTH_test/images/cats</programlisting></para>
+ <para>The status code of 201 (Created) indicates that you have successfully copied the object.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Displaying Object Information </title>
+ <para>You can issue GET command on an object to view the object data of the object.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To display the content of an object run the following command:</para>
+ <para><programlisting>GET /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/&lt;object&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;Authentication-token-key&gt;</programlisting></para>
+ <para>For example,
+</para>
+ <para><programlisting>GET /v1/AUTH_test/images/cat HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+
+HTTP/1.1 200 Ok
+Date: Wed, 13 Jul 2011 23:52:21 GMT
+Server: Apache
+Last-Modified: Thu, 14 Jul 2011 13:40:18 GMT
+ETag: 8a964ee2a5e88be344f36c22562a6486
+Content-Length: 534210
+[.........]</programlisting></para>
+ <para>To display the content of an object using cURL (for the above example), run the following
+command:
+</para>
+ <para><programlisting>curl -v -X GET -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/images/cat -k</programlisting></para>
+ <para>The status code of 200 (Ok) indicates the object‟s data is displayed successfully. If that object does
+not exist, the status code 404 (Not Found) is displayed.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Displaying Object Metadata </title>
+ <para>You can issue HEAD command on an object to view the object metadata and other standard HTTP
+headers. You must send only authorization token as header.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To display the metadata of the object, run the following command:
+</para>
+ </listitem>
+ </itemizedlist>
+ <para><programlisting>HEAD /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/&lt;object&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;Authentication-token-key&gt;</programlisting></para>
+ <para>For example,
+</para>
+ <para><programlisting>HEAD /v1/AUTH_test/images/cat HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+
+HTTP/1.1 204 No Content
+Date: Wed, 13 Jul 2011 21:52:21 GMT
+Server: Apache
+Last-Modified: Thu, 14 Jul 2011 13:40:18 GMT
+ETag: 8a964ee2a5e88be344f36c22562a6486
+Content-Length: 512000
+Content-Type: text/plain; charset=UTF-8
+X-Object-Meta-House: Cat
+X-Object-Meta-Zoo: Cat
+X-Object-Meta-Home: Cat
+X-Object-Meta-Park: Cat</programlisting></para>
+ <para>To display the metadata of the object using cURL (for the above example), run the following
+command:
+</para>
+ <para><programlisting>curl -v -X HEAD -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/images/cat -k</programlisting></para>
+ <para>The status code of 204 (No Content) indicates the object‟s metadata is displayed successfully. If that
+object does not exist, the status code 404 (Not Found) is displayed.
+</para>
+ </section>
+ <section>
+ <title>Updating Object Metadata </title>
+ <para>You can issue POST command on an object name only to set or overwrite arbitrary key metadata. You
+cannot change the object‟s other headers such as Content-Type, ETag and others using POST
+operation. The POST command will delete all the existing metadata and replace it with the new
+arbitrary key metadata.
+</para>
+ <para>You must prefix <emphasis role="bold">X-Object-Meta-</emphasis> to the key names.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To update the metadata of an object, run the following command:</para>
+ <para><programlisting>POST /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/&lt;object&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;Authentication-token-key&gt;
+X-Object-Meta-&lt;key&gt;: &lt;new value&gt;
+X-Object-Meta-&lt;key&gt;: &lt;new value&gt;</programlisting>
+</para>
+ <para>For example,
+</para>
+ <para><programlisting>POST /v1/AUTH_test/images/cat HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+X-Object-Meta-Zoo: Lion
+X-Object-Meta-Home: Dog
+
+HTTP/1.1 202 Accepted
+Date: Wed, 13 Jul 2011 22:52:21 GMT
+Server: Apache
+Content-Length: 0
+Content-Type: text/plain; charset=UTF-8</programlisting></para>
+ <para>To update the metadata of an object using cURL (for the above example), run the following
+command:
+</para>
+ <para><programlisting>curl -v -X POST -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/images/cat -H &apos; X-Object-
+Meta-Zoo: Lion&apos; -H &apos;X-Object-Meta-Home: Dog&apos; -k</programlisting></para>
+ <para>The status code of 202 (Accepted) indicates that you have successfully updated the object‟s
+metadata. If that object does not exist, the status code 404 (Not Found) is displayed.
+
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Deleting Object </title>
+ <para>You can use DELETE command to permanently delete the object.
+</para>
+ <para>The DELETE command on an object will be processed immediately and any subsequent operations
+like GET, HEAD, POST, or DELETE on the object will display 404 (Not Found) error.
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>To delete an object, run the following command:
+</para>
+ <para><programlisting>DELETE /&lt;apiversion&gt;/&lt;account&gt;/&lt;container&gt;/&lt;object&gt; HTTP/1.1
+Host: &lt;storage URL&gt;
+X-Auth-Token: &lt;Authentication-token-key&gt;</programlisting></para>
+ <para>For example,
+</para>
+ <para><programlisting>DELETE /v1/AUTH_test/pictures/cat HTTP/1.1
+Host: example.storage.com
+X-Auth-Token: AUTH_tkd3ad38b087b49bbbac0494f7600a554
+
+HTTP/1.1 204 No Content
+Date: Wed, 13 Jul 2011 20:52:21 GMT
+Server: Apache
+Content-Type: text/plain; charset=UTF-8</programlisting></para>
+ <para>To delete an object using cURL (for the above example), run the following command:
+</para>
+ <para><programlisting>curl -v -X DELETE -H &apos;X-Auth-Token:
+AUTH_tkde3ad38b087b49bbbac0494f7600a554&apos;
+https://example.storage.com:443/v1/AUTH_test/pictures/cat -k</programlisting></para>
+ <para>The status code of 204 (No Content) indicates that you have successfully deleted the object. If that
+object does not exist, the status code 404 (Not Found) is displayed.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_commandref.xml b/doc/admin-guide/en-US/admin_commandref.xml
new file mode 100644
index 000000000..05196b773
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_commandref.xml
@@ -0,0 +1,336 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter id="chap-Administration_Guide-Com_Ref">
+ <title>Command Reference </title>
+ <para>This section describes the available commands and includes thefollowing section:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>gluster Command
+</para>
+ <para>Gluster Console Manager (command line interpreter)
+</para>
+ </listitem>
+ <listitem>
+ <para>glusterd Daemon
+</para>
+ <para>Gluster elastic volume management daemon
+</para>
+ </listitem>
+ </itemizedlist>
+ <section>
+ <title>gluster Command </title>
+ <para><emphasis role="bold">NAME</emphasis>
+</para>
+ <para>gluster - Gluster Console Manager (command line interpreter)
+</para>
+ <para><emphasis role="bold">SYNOPSIS</emphasis>
+</para>
+ <para>To run the program and display the gluster prompt:
+</para>
+ <para><emphasis role="bold">gluster</emphasis>
+</para>
+ <para>To specify a command directly:
+gluster [COMMANDS] [OPTIONS]
+</para>
+ <para><emphasis role="bold">DESCRIPTION</emphasis>
+</para>
+ <para>The Gluster Console Manager is a command line utility for elastic volume management. 'gluster' command enables administrators to perform cloud
+operations such as creating, expanding, shrinking, rebalancing, and migrating volumes without needing to schedule server downtime.
+</para>
+ <para><emphasis role="bold">COMMANDS</emphasis>
+</para>
+ <para><informaltable frame="none">
+ <tgroup cols="3">
+ <colspec colnum="1" colname="c0" colsep="0"/>
+ <colspec colnum="2" colname="cgen1" colsep="0"/>
+ <colspec colnum="3" colname="c1" colsep="0"/>
+ <thead>
+ <row>
+ <entry>Command</entry>
+ <entry namest="cgen1" nameend="c1">Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Volume</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>volume info [all | VOLNAME]</entry>
+ <entry namest="cgen1" nameend="c1">Displays information about all volumes, or the specified volume.</entry>
+ </row>
+ <row>
+ <entry>volume create NEW-VOLNAME [stripe COUNT] [replica COUNT] [transport tcp | rdma | tcp,rdma] NEW-BRICK ...</entry>
+ <entry namest="cgen1" nameend="c1">Creates a new volume of the specified type using the specified bricks and transport type (the default transport type is tcp).
+ NOTE: with 3.3.0 release, transport type 'rdma' and 'tcp,rdma' are not fully supported.</entry>
+ </row>
+ <row>
+ <entry>volume delete VOLNAME</entry>
+ <entry namest="cgen1" nameend="c1">Deletes the specified volume.</entry>
+ </row>
+ <row>
+ <entry>volume start VOLNAME </entry>
+ <entry namest="cgen1" nameend="c1">Starts the specified volume.</entry>
+ </row>
+ <row>
+ <entry>volume stop VOLNAME [force] </entry>
+ <entry namest="cgen1" nameend="c1">Stops the specified volume. </entry>
+ </row>
+ <row>
+ <entry>volume help </entry>
+ <entry namest="cgen1" nameend="c1">Displays help for the volume command.</entry>
+ </row>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Brick</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>volume add-brick VOLNAME [replica N] [stripe N] NEW-BRICK1 ... </entry>
+ <entry namest="cgen1" nameend="c1">Adds the specified brick(s) to the given VOLUME. Using add-brick, users can increase the replica/stripe count of the volume, or increase the volume capacity by adding the brick(s) without changing volume type. </entry>
+ </row>
+ <row>
+ <entry>volume replace-brick VOLNAME (BRICK NEW-BRICK) [start | start force | abort | status | commit | commit force] </entry>
+ <entry namest="cgen1" nameend="c1">Used to replace BRICK with NEW-BRICK in a given VOLUME. After replace-brick is complete, the changes to get reflected in volume information, replace-brick 'commit' command is neccessary.</entry>
+ </row>
+ <row>
+ <entry>volume remove-brick VOLNAME [replica N] BRICK1 ... [start | stop | status | commit | force ] </entry>
+ <entry namest="cgen1" nameend="c1">Removes the specified brick(s) from the specified volume. 'remove-brick' command can be used to reduce the replica count of the volume when 'replica N' option is given. To ensure data migration from the removed brick to existing bricks, give 'start' sub-command at the end of the command. After the 'status' command says remove-brick operation is complete, user can 'commit' the changes to volume file. Using 'remove-brick' without 'start' option works similar to 'force' command, which makes the changes to volume configuration without migrating the data.</entry>
+ </row>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Rebalance</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>volume rebalance VOLNAME start</entry>
+ <entry namest="cgen1" nameend="c1">Starts rebalancing of the data on specified volume.</entry>
+ </row>
+ <row>
+ <entry>volume rebalance VOLNAME stop </entry>
+ <entry namest="cgen1" nameend="c1">Stops rebalancing the specified volume. </entry>
+ </row>
+ <row>
+ <entry>volume rebalance VOLNAME status </entry>
+ <entry namest="cgen1" nameend="c1">Displays the rebalance status of the specified volume.</entry>
+ </row>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Log</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>volume log rotate VOLNAME [BRICK] </entry>
+ <entry namest="cgen1" nameend="c1">Rotates the log file for corresponding volume/brick.</entry>
+ </row>
+
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Debugging</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>volume top VOLNAME {[open|read|write|opendir|readdir [nfs]] |[read-perf|write-perf [nfs|{bs COUNT count COUNT}]]|[clear [nfs]]} [BRICK] [list-cnt COUNT]</entry>
+ <entry namest="cgen1" nameend="c1">Shows the operation details on the volume depending on the arguments given. </entry>
+ </row>
+
+ <row>
+ <entry>volume profile VOLNAME {start|info|stop} [nfs]</entry>
+ <entry namest="cgen1" nameend="c1">Shows the file operation details on each bricks of the volume.</entry>
+ </row>
+ <row>
+ <entry>volume status [all | VOLNAME] [nfs|shd|BRICK] [detail|clients|mem|inode|fd|callpool]</entry>
+ <entry namest="cgen1" nameend="c1">Show details of activity, internal data of the processes (nfs/shd/BRICK) corresponding to one of the next argument given. If now argument is given, this command outputs bare minimum details of the current status (include PID of brick process etc) of volume's bricks.</entry>
+ </row>
+ <row>
+ <entry>statedump VOLNAME [nfs] [all|mem|iobuf|callpool|priv|fd|inode|history]</entry>
+ <entry namest="cgen1" nameend="c1">Command is used to take the statedump of the process, which is used captures most of the internal details. </entry>
+ </row>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Peer</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>peer probe HOSTNAME </entry>
+ <entry namest="cgen1" nameend="c1">Probes the specified peer. </entry>
+ </row>
+ <row>
+ <entry>peer detach HOSTNAME </entry>
+ <entry namest="cgen1" nameend="c1">Detaches the specified peer. </entry>
+ </row>
+ <row>
+ <entry>peer status </entry>
+ <entry namest="cgen1" nameend="c1">Displays the status of peers. </entry>
+ </row>
+ <row>
+ <entry>peer help </entry>
+ <entry namest="cgen1" nameend="c1">Displays help for the peer command.</entry>
+ </row>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Geo-replication</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>volume geo-replication MASTER SLAVE start</entry>
+ <entry namest="cgen1" nameend="c1">
+ <para>Start geo-replication between the hosts specified by MASTER and SLAVE. You can specify a local master volume as :VOLNAME.</para>
+ <para>You can specify a local slave volume as :VOLUME and a local slave directory as /DIRECTORY/SUB-DIRECTORY. You can specify a remote slave volume as DOMAIN::VOLNAME and a remote slave directory as DOMAIN:/DIRECTORY/SUB-DIRECTORY.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>volume geo-replication MASTER SLAVE stop</entry>
+ <entry namest="cgen1" nameend="c1">
+ <para>Stop geo-replication between the hosts specified by MASTER and SLAVE. You can specify a local master volume as :VOLNAME and a local master directory as /DIRECTORY/SUB-DIRECTORY.</para>
+ <para>You can specify a local slave volume as :VOLNAME and a local slave directory as /DIRECTORY/SUB-DIRECTORY. You can specify a remote slave volume as DOMAIN::VOLNAME and a remote slave directory as DOMAIN:/DIRECTORY/SUB-DIRECTORY.
+</para>
+ </entry>
+ </row>
+ <row>
+ <entry morerows="10">volume geo-replication MASTER SLAVE config [options]</entry>
+ <entry>Configure geo-replication options between the hosts specified by MASTER and SLAVE. </entry>
+ </row>
+ <row>
+ <entry>gluster-command COMMAND</entry>
+ <entry>The path where the gluster command is installed.</entry>
+ </row>
+ <row>
+ <entry>gluster-log-level LOGFILELEVEL</entry>
+ <entry>The log level for gluster processes.</entry>
+ </row>
+ <row>
+ <entry>log-file LOGFILE</entry>
+ <entry>The path to the geo-replication log file.</entry>
+ </row>
+ <row>
+ <entry>log-level LOGFILELEVEL</entry>
+ <entry>The log level for geo-replication.</entry>
+ </row>
+ <row>
+ <entry>remote-gsyncd COMMAND</entry>
+ <entry>The path where the gsyncd binary is installed on the remote machine.</entry>
+ </row>
+ <row>
+ <entry>ssh-command COMMAND</entry>
+ <entry>The ssh command to use to connect to the remote machine (the default is ssh).</entry>
+ </row>
+ <row>
+ <entry>rsync-command COMMAND</entry>
+ <entry>The rsync command to use for synchronizing the files (the default is rsync).</entry>
+ </row>
+ <row>
+ <entry>volume_id= UID</entry>
+ <entry>The command to delete the existing master UID for the intermediate/slave node.</entry>
+ </row>
+ <row>
+ <entry>timeout SECONDS</entry>
+ <entry>The timeout period.</entry>
+ </row>
+ <row>
+ <entry>sync-jobs N</entry>
+ <entry>The number of simultaneous files/directories that can be synchronized.</entry>
+ </row>
+ <row>
+ <entry>ignore-deletes</entry>
+ <entry>If this option is set to 1, a file deleted on master will not trigger a delete operation on the slave. Hence, the slave will remain as a superset of the master and can be used to recover the master in case of crash and/or accidental delete.</entry>
+ </row>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Other</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>help</entry>
+ <entry>Display the command options.</entry>
+ </row>
+ <row>
+ <entry>quit</entry>
+ <entry/>
+ <entry>Exit the gluster command line interface.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+ <para><emphasis role="bold">FILES</emphasis>
+
+</para>
+ <para>/var/lib/glusterd/*
+</para>
+ </section>
+ <section>
+ <title>glusterd Daemon </title>
+ <para><emphasis role="bold">NAME</emphasis>
+</para>
+ <para>glusterd - Gluster elastic volume management daemon</para>
+ <para><emphasis role="bold">SYNOPSIS</emphasis>
+</para>
+ <para>glusterd [OPTION...]
+</para>
+ <para><emphasis role="bold">DESCRIPTION</emphasis>
+</para>
+ <para>The glusterd daemon is used for elastic volume management. The daemon must be run on all export servers.
+</para>
+ <para><emphasis role="bold">OPTIONS</emphasis>
+</para>
+ <para><informaltable frame="none">
+ <tgroup cols="2">
+ <colspec colnum="1" colname="c0" colsep="0"/>
+ <colspec colnum="2" colname="c1" colsep="0"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Basic</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>-l=LOGFILE, --log-file=LOGFILE</entry>
+ <entry>Files to use for logging (the default is /usr/local/var/log/glusterfs/glusterfs.log).</entry>
+ </row>
+ <row>
+ <entry>-L=LOGLEVEL, --log-level=LOGLEVEL</entry>
+ <entry>Logging severity. Valid options are TRACE, DEBUG, INFO, WARNING, ERROR and CRITICAL (the default is INFO). </entry>
+ </row>
+ <row>
+ <entry>--debug</entry>
+ <entry>Runs the program in debug mode. This option sets --no-daemon, --log-level to DEBUG, and --log-file to console.</entry>
+ </row>
+ <row>
+ <entry>-N, --no-daemon</entry>
+ <entry>Runs the program in the foreground.</entry>
+ </row>
+ <row>
+ <entry namest="c0" nameend="c1" align="left">
+ <emphasis role="bold">Miscellaneous</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>-?, --help</entry>
+ <entry>Displays this help.</entry>
+ </row>
+ <row>
+ <entry>--usage</entry>
+ <entry>Displays a short usage message.</entry>
+ </row>
+ <row>
+ <entry>-V, --version</entry>
+ <entry>Prints the program version.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+ <para><emphasis role="bold">FILES</emphasis>
+
+</para>
+ <para>/var/lib/glusterd/*
+</para>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_console.xml b/doc/admin-guide/en-US/admin_console.xml
new file mode 100644
index 000000000..74d12b965
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_console.xml
@@ -0,0 +1,29 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter>
+ <title>Using the Gluster Console Manager – Command Line Utility</title>
+ <para>The Gluster Console Manager is a single command line utility that simplifies configuration and management of your storage environment. The Gluster Console Manager is similar to the LVM (Logical Volume Manager) CLI or ZFS Command Line Interface, but it works in sync with multiple storage servers. You can use the Gluster Console Manager while volumes are mounted and active too. Gluster automatically synchronizes volume configuration information across all Gluster servers.</para>
+ <para>Using the Gluster Console Manager, you can create new volumes, start volumes, and stop volumes, as required. You can also add bricks to volumes, remove bricks from existing volumes, as well as change volume settings (such as some translator specific options), among other operations.</para>
+ <para>You can also use these CLI commands to create scripts for automation, as well as use the commands as an API to allow integration with third-party applications. </para>
+ <para><emphasis role="bold">Running the Gluster Console Manager</emphasis></para>
+ <para>You can run the Gluster Console Manager on any GlusterFS server either by invoking the commands or by running the Gluster CLI in interactive mode. You can also use the gluster command remotely using SSH. </para>
+ <itemizedlist>
+ <listitem>
+ <para>To run commands directly: </para>
+ <para><command> # gluster peer <replaceable>command</replaceable></command></para>
+ <para>For example:</para>
+ <para><command> # gluster peer status </command></para>
+ </listitem>
+ <listitem>
+ <para>To run the Gluster Console Manager in interactive mode </para>
+ <para><command># gluster</command></para>
+ <para>You can execute gluster commands from the Console Manager prompt:</para>
+ <para><command> gluster&gt; <replaceable>command</replaceable></command> </para>
+ <para>For example, to view the status of the peer server:</para>
+ <para># <command>gluster </command></para>
+ <para><command>gluster &gt; peer status </command></para>
+ <para>Display the status of the peer.</para>
+ </listitem>
+ </itemizedlist>
+ <para> With any 'gluster' installation, to check all the supported CLI commands, use <command> 'gluster help' </command>.</para>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_directory_Quota.xml b/doc/admin-guide/en-US/admin_directory_Quota.xml
new file mode 100644
index 000000000..83c4ff451
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_directory_Quota.xml
@@ -0,0 +1,180 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter id="chap-Administration_Guide-Dir_Quota">
+ <title>Managing Directory Quota </title>
+ <para>Directory quotas in GlusterFS allow you to set limits on usage of disk space of a given directory.
+The storage administrators can control the disk space utilization at the directory level in GlusterFS by setting quota limits on the given directory. If
+admin sets the quota limit on the '/' of the volume, it can be treated as 'volume level quota'. GlusterFS's quota implementation can have different quota
+limit set on any directory and it can be nested. This is particularly useful in cloud deployments to facilitate utility billing model.
+ </para>
+ <para> <note>
+ <para>For now, only Hard limit is supported. Here, the limit cannot be exceeded and attempts to use
+more disk space beyond the set limit will be denied.
+</para>
+ </note></para>
+ <para>System administrators can also monitor the resource utilization to limit the storage for the users
+depending on their role in the organization.
+</para>
+ <para>You can set the quota at the following levels:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Directory level – limits the usage at the directory level
+ </para>
+ </listitem>
+ <listitem>
+ <para>Volume level – limits the usage at the volume level
+ </para>
+ </listitem>
+ </itemizedlist>
+ <note>
+ <para>You can set the disk limit on the directory even if it is not created. The disk limit is enforced
+immediately after creating that directory. For more information on setting disk limit, see <xref linkend="chap-Administration_Guide-Dir_Quota-Set_Replace"/>.
+</para>
+ </note>
+ <section id="chap-Administration_Guide-Dir_Quota-Enable">
+ <title>Enabling Quota </title>
+ <para>You must enable Quota to set disk limits.
+</para>
+ <para><emphasis role="bold">To enable quota</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Enable the quota using the following command:
+</para>
+ <para><command># gluster volume quota <replaceable>VOLNAME</replaceable> enable </command></para>
+ <para>For example, to enable quota on test-volume:
+</para>
+ <programlisting># gluster volume quota test-volume enable
+Quota is enabled on /test-volume</programlisting> <!-- why '/' here before test-volume? its volume name, not directory -->
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Dir_Quota-Disable">
+ <title>Disabling Quota </title>
+ <para>You can disable Quota, if needed.
+</para>
+ <para><emphasis role="bold">To disable quota:</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Disable the quota using the following command:
+</para>
+ <para><command># gluster volume quota <replaceable>VOLNAME</replaceable> disable </command></para>
+ <para>For example, to disable quota on test-volume:
+</para>
+ <programlisting># gluster volume quota test-volume disable
+Quota translator is disabled on /test-volume</programlisting> <!-- why '/' here before test-volume? its volume name, not directory -->
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Dir_Quota-Set_Replace">
+ <title>Setting or Replacing Disk Limit </title>
+ <para>You can create new directories in your storage environment and set the disk limit or set disk limit for
+the existing directories. The directory name should be relative to the volume with the export
+directory/mount being treated as &quot;/&quot;.
+</para>
+ <para><emphasis role="bold">To set or replace disk limit</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Set the disk limit using the following command:
+</para>
+ <para><command># gluster volume quota <replaceable>VOLNAME</replaceable> limit-usage /<replaceable>directory</replaceable><replaceable>limit-value</replaceable></command></para>
+ <para>For example, to set limit on data directory on test-volume where data is a directory under the
+export directory:
+</para>
+ <programlisting># gluster volume quota test-volume limit-usage /data 10GB
+Usage limit has been set on /data</programlisting>
+ <para><note>
+ <para>In a multi-level directory hierarchy, the minimum of disk limit in entire hierarchy will be considered for enforcement.
+</para>
+ </note></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Dir_Quota-Display">
+ <title>Displaying Disk Limit Information </title>
+ <para>You can display disk limit information on all the directories on which the limit is set.
+</para>
+ <para><emphasis role="bold">To display disk limit information</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Display disk limit information of all the directories on which limit is set, using the following
+command:
+</para>
+ <para><command># gluster volume quota <replaceable>VOLNAME</replaceable> list</command>
+</para>
+ <para>For example, to see the set disks limit on test-volume:
+</para>
+ <programlisting># gluster volume quota test-volume list
+
+<emphasis role="underline">
+ <emphasis role="underline"><emphasis role="underline">Path</emphasis>__________Limit______Set Size</emphasis>
+ </emphasis>
+/Test/data 10 GB 6 GB
+/Test/data1 10 GB 4 GB</programlisting>
+<para> NOTE that, the directory listed here is not absolute directory name, but relative path to the volume's root ('/'). For example, if 'test-volume' is mounted on '/mnt/glusterfs', then for the above example, '/Test/data' means, '/mnt/glusterfs/Test/data' </para>
+ </listitem>
+ <listitem>
+ <para>Display disk limit information on a particular directory on which limit is set, using the following
+command:
+</para>
+ <para><command># gluster volume quota <replaceable>VOLNAME</replaceable> list <replaceable>/directory name</replaceable></command>
+</para>
+ <para>For example, to see the set limit on /data directory of test-volume:</para>
+ <programlisting># gluster volume quota test-volume list /data
+
+<emphasis role="underline"><emphasis role="underline">Path</emphasis>__________Limit______Set Size</emphasis>
+/Test/data 10 GB 6 GB</programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Dir_Quota-Update">
+ <title> Updating Memory Cache Size </title>
+ <para>For performance reasons, quota caches the directory sizes on client. You can set timeout indicating
+the maximum valid duration of directory sizes in cache, from the time they are populated.
+</para>
+ <para>For example: If there are multiple clients writing to a single directory, there are chances that some
+other client might write till the quota limit is exceeded. However, this new file-size may not get
+reflected in the client till size entry in cache has become stale because of timeout. If writes happen
+on this client during this duration, they are allowed even though they would lead to exceeding of
+quota-limits, since size in cache is not in sync with the actual size. When timeout happens, the size
+in cache is updated from servers and will be in sync and no further writes will be allowed. A timeout
+of zero will force fetching of directory sizes from server for every operation that modifies file data
+and will effectively disables directory size caching on client side.
+</para>
+ <para><emphasis role="bold">To update the memory cache size</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Update the memory cache size using the following command:
+</para>
+ <para><command># gluster volume set <replaceable>VOLNAME</replaceable> features.quota-timeout<replaceable> value</replaceable></command></para>
+ <para>For example, to update the memory cache size for every 5 seconds on test-volume:
+</para>
+ <programlisting># gluster volume set test-volume features.quota-timeout 5
+Set volume successful</programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Dir_Quota-Remove">
+ <title>Removing Disk Limit </title>
+ <para>You can remove set disk limit, if you do not want quota anymore.
+</para>
+ <para><emphasis role="bold">To remove disk limit </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Remove disk limit set on a particular directory using the following command:
+</para>
+ <para><command># gluster volume quota <replaceable>VOLNAME</replaceable> remove <replaceable>/directory name</replaceable></command>
+</para>
+ <para>For example, to remove the disk limit on /data directory of test-volume:
+</para>
+ <programlisting># gluster volume quota test-volume remove /data
+Usage limit set on /data is removed</programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_geo-replication.xml b/doc/admin-guide/en-US/admin_geo-replication.xml
new file mode 100644
index 000000000..4691116ac
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_geo-replication.xml
@@ -0,0 +1,730 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter id="chap-Administration_Guide-Geo_Rep">
+ <title>Managing Geo-replication</title>
+ <para>Geo-replication provides a continuous, asynchronous, and incremental replication service from one site to another over Local Area Networks (LANs), Wide Area Network (WANs), and across the Internet. </para>
+ <para>Geo-replication uses a master–slave model, whereby replication and mirroring occurs between the following partners:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Master – a GlusterFS volume </para>
+ </listitem>
+ <listitem>
+ <para>Slave – a slave which can be of the following types: </para>
+ <itemizedlist>
+ <listitem>
+ <para>A local directory which can be represented as file URL like <filename>file:///path/to/dir</filename>. You can use shortened form, for example, <filename> /path/to/dir</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>A GlusterFS Volume - Slave volume can be either a local volume like <filename>gluster://localhost:volname</filename> (shortened form - <filename>:volname</filename>) or a volume served by different host like <filename>gluster://host:volname</filename> (shortened form - <filename>host:volname</filename>).</para>
+ </listitem>
+ </itemizedlist>
+ <note>
+ <para> Both of the above types can be accessed remotely using SSH tunnel. To use SSH, add an SSH prefix to either a file URL or gluster type URL. For example, <literal> ssh://root@remote-host:/path/to/dir</literal> (shortened form - <literal>root@remote-host:/path/to/dir</literal>) or <literal>ssh://root@remote-host:gluster://localhost:volname</literal> (shortened from - <literal>root@remote-host::volname</literal>). </para>
+ </note>
+ </listitem>
+ </itemizedlist>
+ <para>This section introduces Geo-replication, illustrates the various deployment scenarios, and explains how to configure the system to provide replication and mirroring in your environment. </para>
+ <section id="chap-Administration_Guide-Geo_Rep-Replicated_volumes">
+ <title>Replicated Volumes vs Geo-replication</title>
+ <para>The following table lists the difference between replicated volumes and geo-replication:</para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>Replicated Volumes</entry>
+ <entry>Geo-replication</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Mirrors data across nodes in a cluster</entry>
+ <entry>Mirrors data across geographically distributed clusters </entry>
+ </row>
+ <row>
+ <entry>Provides high-availability</entry>
+ <entry>Ensures backing up of data for disaster recovery</entry>
+ </row>
+ <row>
+ <entry>Synchronous replication (each and every file modify operation is sent across all the bricks)</entry>
+ <entry>Asynchronous replication (checks for the changes in files periodically and syncs them on detecting differences) </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Preparation">
+ <title>Preparing to Deploy Geo-replication</title>
+ <para>This section provides an overview of the Geo-replication deployment scenarios, describes how you can check the minimum system requirements, and explores common deployment scenarios.</para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Preparation-Deployment_options"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Preparation-Deployment_Overview"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Preparation-Minimum_Reqs"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Preparation-Settingup_Environment"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Preparation-Settingup_Slave"/></para>
+ </listitem>
+ </itemizedlist>
+ <section id="chap-Administration_Guide-Geo_Rep-Preparation-Deployment_options">
+ <title>Exploring Geo-replication Deployment Scenarios</title>
+ <para>Geo-replication provides an incremental replication service over Local Area Networks (LANs), Wide Area Network (WANs), and across the Internet. This section illustrates the most common deployment scenarios for Geo-replication, including the following: </para>
+ <itemizedlist>
+ <listitem>
+ <para>Geo-replication over LAN
+</para>
+ </listitem>
+ <listitem>
+ <para>Geo-replication over WAN
+</para>
+ </listitem>
+ <listitem>
+ <para>Geo-replication over the Internet</para>
+ </listitem>
+ <listitem>
+ <para>Multi-site cascading Geo-replication</para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">Geo-replication over LAN</emphasis></para>
+ <para>You can configure Geo-replication to mirror data over a Local Area Network. </para>
+ <mediaobject>
+ <textobject>
+ <phrase>Geo-replication over LAN</phrase>
+ </textobject>
+ <imageobject>
+ <imagedata fileref="images/Geo-Rep_LAN.png"/>
+ </imageobject>
+ </mediaobject>
+ <para><emphasis role="bold">Geo-replication over WAN</emphasis></para>
+ <para>You can configure Geo-replication to replicate data over a Wide Area Network.</para>
+ <mediaobject>
+ <textobject>
+ <phrase>
+ <phrase>Geo-replication over WAN</phrase>
+ </phrase>
+ </textobject>
+ <imageobject>
+ <imagedata fileref="images/Geo-Rep_WAN.png"/>
+ </imageobject>
+ </mediaobject>
+ <para><emphasis role="bold">Geo-replication over Internet</emphasis></para>
+ <para>You can configure Geo-replication to mirror data over the Internet.</para>
+ <mediaobject>
+ <textobject>
+ <phrase>
+ <phrase>Geo-replication over Internet</phrase>
+ </phrase>
+ </textobject>
+ <imageobject>
+ <imagedata fileref="images/Geo-Rep03_Internet.png"/>
+ </imageobject>
+ </mediaobject>
+ <para><emphasis role="bold">Multi-site cascading Geo-replication</emphasis> </para>
+ <para>You can configure Geo-replication to mirror data in a cascading fashion across multiple sites. </para>
+ <mediaobject>
+ <textobject>
+ <phrase>
+ <phrase>Multi-site cascading Geo-replication </phrase>
+ </phrase>
+ </textobject>
+ <imageobject>
+ <imagedata fileref="images/Geo-Rep04_Cascading.png"/>
+ </imageobject>
+ </mediaobject>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Preparation-Deployment_Overview">
+ <title>Geo-replication Deployment Overview</title>
+ <para>Deploying Geo-replication involves the following steps:</para>
+ <orderedlist>
+ <listitem>
+ <para>Verify that your environment matches the minimum system requirements. For more information, see <xref linkend="chap-Administration_Guide-Geo_Rep-Preparation-Minimum_Reqs"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Determine the appropriate deployment scenario. For more information, see <xref linkend="chap-Administration_Guide-Geo_Rep-Preparation-Deployment_options"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Start Geo-replication on master and slave systems, as required. For more information, see <xref linkend="chap-Administration_Guide-Geo_Rep-Starting"/>.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Preparation-Minimum_Reqs">
+ <title>Checking Geo-replication Minimum Requirements</title>
+ <para condition="gfs">Before deploying GlusterFS Geo-replication, verify that your systems match the minimum requirements. </para>
+ <para condition="gfs">The following table outlines the minimum requirements for both master and slave nodes within your environment:</para>
+ <informaltable frame="all" condition="gfs">
+ <tgroup cols="3">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <thead>
+ <row>
+ <entry>Component</entry>
+ <entry>Master</entry>
+ <entry>Slave</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Operating System </entry>
+ <entry>GNU/Linux</entry>
+ <entry>GNU/Linux</entry>
+ </row>
+ <row>
+ <entry>Filesystem</entry>
+ <entry>GlusterFS 3.2 or higher</entry>
+ <entry>GlusterFS 3.2 or higher, ext3, ext4, or XFS (any other POSIX compliant file system would work, but has not been tested extensively) </entry>
+ </row>
+ <row>
+ <entry>Python </entry>
+ <entry>Python 2.4 (with ctypes external module), or Python 2.5 (or higher)</entry>
+ <entry>Python 2.4 (with ctypes external module), or Python 2.5 (or higher)</entry>
+ </row>
+ <row>
+ <entry>Secure shell </entry>
+ <entry>OpenSSH version 4.0 (or higher)</entry>
+ <entry>SSH2-compliant daemon </entry>
+ </row>
+ <row>
+ <entry>Remote synchronization</entry>
+ <entry>rsync 3.0.0 or higher </entry>
+ <entry>rsync 3.0.0 or higher </entry>
+ </row>
+ <row>
+ <entry>FUSE </entry>
+ <entry>GlusterFS supported versions </entry>
+ <entry>GlusterFS supported versions </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Preparation-Settingup_Environment">
+ <title>Setting Up the Environment for Geo-replication</title>
+ <para><emphasis role="bold">Time Synchronization</emphasis> </para>
+ <itemizedlist>
+ <listitem>
+ <para>All servers that are part of a geo-replication master volume need to have their clocks in sync. You are recommended to set up NTP (Network Time Protocol) daemon service to keep the clocks in sync.</para>
+ <para>For example: In a Replicated volume where brick1 of the master is at 12.20 hrs and brick 2 of the master is at 12.10 hrs with 10 minutes time lag, all the changes in brick2 between this period may go unnoticed during synchronization of files with Slave.</para>
+ <para>For more information on setting up NTP daemon, see <ulink url="http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Migration_Planning_Guide/ch04s07.html"/>.</para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">To setup Geo-replication for SSH </emphasis></para>
+ <para>Password-less login has to be set up between the host machine (where geo-replication start command will be issued) and the remote machine (where slave process should be launched through SSH).</para>
+ <orderedlist>
+ <listitem>
+ <para>On the node where geo-replication start commands are to be issued, run the following command:</para>
+ <para><command># ssh-keygen -f /var/lib/glusterd/geo-replication/secret.pem</command>
+</para>
+ <para>Press Enter twice to avoid passphrase.
+</para>
+ </listitem>
+ <listitem>
+ <para>Run the following command on master for all the slave hosts: </para>
+ <para><command># ssh-copy-id -i /var/lib/glusterd/geo-replication/secret.pem.pub <varname>user</varname>@<varname>slavehost</varname></command></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Preparation-Settingup_Slave">
+ <title>Setting Up the Environment for a Secure Geo-replication Slave</title>
+ <para>You can configure a secure slave using SSH so that master is granted
+restricted access. With GlusterFS 3.3, you need not specify slave
+configuration parameters on the master-side. For example, the master does not require the location of
+the rsync program on slave but the slave must ensure that rsync is in
+the PATH of the user which the master connects using SSH. The only
+information that master and slave have to negotiate are the slave-side
+user account, slave&apos;s resources and
+the master&apos;s public key. Secure access to the slave can be established
+using the following options:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Restricting Remote Command Execution</para>
+ </listitem>
+ <listitem>
+ <para>Using <filename>Mountbroker</filename> for Slaves</para>
+ </listitem>
+ <listitem>
+ <para>Using IP based Access Control</para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">Backward Compatibility</emphasis> </para>
+ <para>Your existing Geo-replication environment will work with GlusterFS
+ 3.3, except for the following:</para>
+ <itemizedlist>
+ <listitem>
+ <para>The process of secure reconfiguration affects only the GlusterFS
+instance on slave. The changes are transparent to master with the
+exception that you may have to change the SSH target to an unprivileged
+ account on the slave.</para>
+ </listitem>
+ <listitem>
+ <para>The following are some exceptions where backward compatibility cannot be provided:</para>
+ <para><itemizedlist>
+ <listitem>
+ <para>Geo-replication URLs which specify the slave resource include the following special characters: space, *, ?, [;</para>
+ </listitem>
+ <listitem>
+ <para>Slave does not have glusterd running.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist>
+ <section>
+ <title>Restricting Remote Command Execution</title>
+ <para>If you restrict remote command execution, then the slave audits commands
+coming from the master and only the pre-configured commands are allowed. The slave also provides access only
+to the files which are pre-configured to be read or manipulated by the master.</para>
+ <para>To restrict remote command execution:</para>
+ <orderedlist>
+ <listitem>
+ <para>Identify the location of the gsyncd helper utility on Slave. This utility is installed in <filename>PREFIX/libexec/glusterfs/gsyncd</filename>, where PREFIX is a compile-time parameter of glusterfs. For example, <filename>--prefix=PREFIX</filename> to the configure script with the following common values<filename> /usr, /usr/local, and /opt/glusterfs/glusterfs_version</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>Ensure that command invoked from master to slave is passed through the slave&apos;s gsyncd utility. </para>
+ <para>You can use either of the following two options:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Set gsyncd with an absolute path as the shell for the account
+which the master connects through SSH. If you need to use a privileged
+account, then set it up by creating a new user with UID 0. </para>
+ </listitem>
+ <listitem>
+ <para>Setup key authentication with command enforcement to gsyncd. You must prefix the copy of master&apos;s public key in the Slave account&apos;s <filename>authorized_keys</filename> file with the following command:</para>
+ <para><filename>command=&lt;path to gsyncd&gt;</filename>. </para>
+ <para>For example, <command>command=&quot;PREFIX/glusterfs/gsyncd&quot; ssh-rsa AAAAB3Nza....</command></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>Using Mountbroker for Slaves </title>
+ <para><filename>mountbroker</filename> is a new service of glusterd. This service allows an
+unprivileged process to own a GlusterFS mount. This is accomplished by registering a label
+(and DSL (Domain-specific language) options ) with glusterd through the
+glusterd volfile. Using CLI, you can send a mount request to glusterd and
+receive an alias (symlink) to the mounted volume.</para>
+ <para>The unprivileged process/agent uses the
+mountbroker service of glusterd to set up an auxiliary gluster mount. The mount
+is setup so as to allow only that agent to provide administrative
+level access to the particular volume.</para>
+ <para><emphasis role="bold">To setup an auxiliary gluster mount for the agent</emphasis>:</para>
+ <orderedlist>
+ <listitem>
+ <para>Create a new group. For example, <filename>geogroup</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>Create a unprivileged account. For example, <filename> geoaccount</filename>. Make it a member of <filename> geogroup</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>Create a new directory as superuser to be used as mountbroker's root. </para>
+ </listitem>
+ <listitem>
+ <para> Change the permission of the directory to <emphasis role="italic">0711.</emphasis> </para>
+ </listitem>
+ <listitem>
+ <para>Add the following options to the glusterd volfile, located at /etc/glusterfs/glusterd.vol, assuming the name of the slave gluster volume as <filename>slavevol</filename>:</para>
+ <para><command>option mountbroker-root /var/mountbroker-root </command></para>
+ <para><command>option mountbroker-geo-replication.geoaccount slavevol</command></para>
+ <para><command>option geo-replication-log-group geogroup</command></para>
+ <para>A sample glusterd volfile along with default options:</para>
+ <para><screen>volume management
+ type mgmt/glusterd
+ option working-directory /etc/glusterd
+ option transport-type socket,rdma
+ option transport.socket.keepalive-time 10
+ option transport.socket.keepalive-interval 2
+ option transport.socket.read-fail-log off
+
+ option mountbroker-root /var/mountbroker-root
+ option mountbroker-geo-replication.geoaccount slavevol
+ option geo-replication-log-group geogroup
+end-volume</screen></para>
+ <para>If you host multiple slave volumes, you can repeat step 2. for each of the slave volumes and add the following options to the <filename>volfile</filename>:</para>
+ <para><screen>option mountbroker-geo-replication.geoaccount2 slavevol2
+option mountbroker-geo-replication.geoaccount3 slavevol3</screen></para>
+ </listitem>
+ <listitem>
+ <para>Setup Master to access Slave as <filename>geoaccount@Slave</filename>.</para>
+ <para>You can add multiple slave volumes within the same account (geoaccount) by providing comma-separated list of slave
+ volumes (without spaces) as the argument of <command>mountbroker-geo-replication.geogroup</command>. You can also have multiple options of the form <command>mountbroker-geo-replication.*</command>. It is recommended to use one service account per Master machine. For example, if there are multiple slave volumes on Slave for the master machines Master1, Master2, and Master3, then create a dedicated service user on Slave for them by repeating Step 2. for each (like geogroup1, geogroup2, and geogroup3), and then add the following corresponding options to the volfile:
+</para>
+ <para><command>option mountbroker-geo-replication.geoaccount1 slavevol11,slavevol12,slavevol13</command></para>
+ <para><command>option mountbroker-geo-replication.geoaccount2 slavevol21,slavevol22</command></para>
+ <para><command>option mountbroker-geo-replication.geoaccount3 slavevol31</command></para>
+ <para>
+Now set up Master1 to ssh to geoaccount1@Slave, etc.
+</para>
+ <para>You must restart glusterd to make the configuration changes effective. </para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>Using IP based Access Control</title>
+ <para>You can provide access control for the slave resources using IP
+ addresses. You can use method for both Gluster volume and and
+ file tree slaves, but in this section, we are focusing on file tree slaves.</para>
+ <para>To set IP address based access control for file tree slaves:</para>
+ <orderedlist>
+ <listitem>
+ <para>Set a general restriction for accessibility of file tree resources:
+</para>
+ <para><command># gluster volume geo-replication &apos;/*&apos; config allow-network ::1,127.0.0.1 </command></para>
+ <para>This will refuse all requests for spawning slave agents except for
+requests initiated locally.</para>
+ </listitem>
+ <listitem>
+ <para>If you want the to lease file tree at <filename>/data/slave-tree</filename> to Master, enter the following command:</para>
+ <para><command># gluster volume geo-replication<varname> /data/slave-tree </varname>config allow-network <varname>MasterIP</varname></command></para>
+ <para><varname>MasterIP</varname> is the IP address of Master. The slave agent spawn request from
+master will be accepted if it is executed at <filename>/data/slave-tree</filename>.</para>
+ </listitem>
+ </orderedlist>
+ <para>If the Master side network configuration does not enable the Slave to
+recognize the exact IP address of Master, you can use CIDR notation to
+specify a subnet instead of a single IP address as MasterIP or even
+comma-separated lists of CIDR subnets.</para>
+ <para>If you want to extend IP based access control to gluster slaves, use the following command:</para>
+ <para><command># gluster volume geo-replication &apos;*&apos; config allow-network ::1,127.0.0.1</command></para>
+ </section>
+ </section>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Starting">
+ <title>Starting Geo-replication</title>
+ <para>This section describes how to configure and start Gluster Geo-replication in your storage environment, and verify that it is functioning correctly. </para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Starting-Start"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Starting-Verify"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Starting-Display"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Starting-Configure"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Geo_Rep-Starting-Stop"/></para>
+ </listitem>
+ </itemizedlist>
+ <section id="chap-Administration_Guide-Geo_Rep-Starting-Start">
+ <title>Starting Geo-replication</title>
+ <para>To start Gluster Geo-replication </para>
+ <itemizedlist>
+ <listitem>
+ <para>Start geo-replication between the hosts using the following command:
+ </para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> start</command>
+</para>
+ <para>For example:
+</para>
+ <para><programlisting># gluster volume geo-replication Volume1 example.com:/data/remote_dir start
+Starting geo-replication session between Volume1
+example.com:/data/remote_dir has been successful</programlisting></para>
+ <para><note>
+ <para>You may need to configure the Geo-replication service before
+ starting it. For more information, see <xref linkend="chap-Administration_Guide-Geo_Rep-Starting-Configure"/>.</para>
+ </note></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Starting-Verify">
+ <title>Verifying Successful Deployment</title>
+ <para>You can use the gluster command to verify the status of Gluster Geo-replication in your environment.</para>
+ <para><emphasis role="bold">To verify the status Gluster Geo-replication</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Verify the status by issuing the following command on host:</para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> status</command>
+</para>
+ <para>For example:
+</para>
+ <para><command># gluster volume geo-replication Volume1 example.com:/data/remote_dir status</command>
+</para>
+ <para><programlisting># gluster volume geo-replication Volume1 example.com:/data/remote_dir status
+
+MASTER SLAVE STATUS
+______ ______________________________ ____________
+Volume1 root@example.com:/data/remote_dir Starting....</programlisting>
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Starting-Display">
+ <title>Displaying Geo-replication Status Information</title>
+ <para>You can display status information about a specific geo-replication master session, or a particular master-slave session, or all geo-replication sessions, as needed.</para>
+ <para><emphasis role="bold">To display geo-replication status information</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Display information of all geo-replication sessions using the following command:</para>
+ <para><programlisting># gluster volume geo-replication Volume1 example.com:/data/remote_dir status
+
+MASTER SLAVE STATUS
+______ ______________________________ ____________
+Volume1 root@example.com:/data/remote_dir Starting....</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>Display information of a particular master slave session using the following command:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> status</command>
+</para>
+ <para>For example, to display information of Volume1 and example.com:/data/remote_dir
+</para>
+ <para><command># gluster volume geo-replication Volume1 example.com:/data/remote_dir status</command>
+</para>
+ <para>The status of the geo-replication between Volume1 and example.com:/data/remote_dir is displayed.</para>
+ </listitem>
+ <listitem>
+ <para>Display information of all geo-replication sessions belonging to a master</para>
+ <para><command># gluster volume geo-replication MASTER status</command>
+</para>
+ <para>For example, to display information of Volume1</para>
+ <para><programlisting># gluster volume geo-replication Volume1 example.com:/data/remote_dir status
+
+MASTER SLAVE STATUS
+______ ______________________________ ____________
+Volume1 ssh://example.com:gluster://127.0.0.1:remove_volume OK
+
+Volume1 ssh://example.com:file:///data/remote_dir OK</programlisting></para>
+ <para>The status of a session could be one of the following four:</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Starting</emphasis>: This is the initial phase of the Geo-replication session; it remains in this state for a minute, to make sure no abnormalities are present.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">OK</emphasis>: The geo-replication session is in a stable state.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Faulty</emphasis>: The geo-replication session has witnessed some abnormality and the situation has to be investigated further. For further information, see <xref linkend="chap-Administration_Guide-Troubleshooting"/> section.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Corrupt</emphasis>: The monitor thread which is monitoring the geo-replication session has died. This situation should not occur normally, if it persists contact Red Hat Support<ulink url="www.redhat.com/support/"/>.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Starting-Configure">
+ <title>Configuring Geo-replication</title>
+ <para>To configure Gluster Geo-replication </para>
+ <itemizedlist>
+ <listitem>
+ <para>Use the following command at the Gluster command line:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> config [options]</command>
+</para>
+ <para>For more information about the options, see <xref linkend="chap-Administration_Guide-Com_Ref"/>.
+</para>
+ <para>For example:
+</para>
+ <para>To view list of all option/value pair, use the following command:
+</para>
+ <para><command># gluster volume geo-replication Volume1 example.com:/data/remote_dir config</command>
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Starting-Stop">
+ <title>Stopping Geo-replication</title>
+ <para>You can use the gluster command to stop Gluster Geo-replication (syncing of data from Master to Slave) in your environment. </para>
+ <para><emphasis role="bold">To stop Gluster Geo-replication</emphasis> </para>
+ <itemizedlist>
+ <listitem>
+ <para>Stop geo-replication between the hosts using the following command:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> stop </command></para>
+ <para>For example:
+</para>
+ <para><programlisting># gluster volume geo-replication Volume1 example.com:/data/remote_dir stop
+Stopping geo-replication session between Volume1 and
+example.com:/data/remote_dir has been successful</programlisting></para>
+ <para>See <xref linkend="chap-Administration_Guide-Com_Ref"/> for more information about the gluster command.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Restoring_Data">
+ <title>Restoring Data from the Slave</title>
+ <para>You can restore data from the slave to the master volume, whenever the master volume becomes faulty for reasons like hardware failure.
+</para>
+ <para>The example in this section assumes that you are using the Master Volume (Volume1) with the following configuration:
+</para>
+ <para><programlisting>machine1# gluster volume info
+Type: Distribute
+Status: Started
+Number of Bricks: 2
+Transport-type: tcp
+Bricks:
+Brick1: machine1:/export/dir16
+Brick2: machine2:/export/dir16
+Options Reconfigured:
+geo-replication.indexing: on</programlisting></para>
+ <para>The data is syncing from master volume (Volume1) to slave directory (example.com:/data/remote_dir). To view the status of this geo-replication session run the following command on Master: </para>
+ <programlisting># gluster volume geo-replication Volume1 root@example.com:/data/remote_dir status
+
+MASTER SLAVE STATUS
+______ ______________________________ ____________
+Volume1 root@example.com:/data/remote_dir OK</programlisting>
+ <para><emphasis role="bold">Before Failure</emphasis>
+</para>
+ <para>Assume that the Master volume had 100 files and was mounted at /mnt/gluster on one of the client machines (client). Run the following command on Client machine to view the list of files:
+</para>
+ <para><programlisting>client# ls /mnt/gluster | wc –l
+100</programlisting></para>
+ <para>The slave directory (example.com) will have same data as in the master volume and same can be viewed by running the following command on slave:
+</para>
+ <para><programlisting>example.com# ls /data/remote_dir/ | wc –l
+100</programlisting></para>
+ <para><emphasis role="bold">After Failure</emphasis>
+</para>
+ <para>If one of the bricks (machine2) fails, then the status of Geo-replication session is changed from &quot;OK&quot; to &quot;Faulty&quot;. To view the status of this geo-replication session run the following command on Master:
+</para>
+ <programlisting># gluster volume geo-replication Volume1 root@example.com:/data/remote_dir status
+
+MASTER SLAVE STATUS
+______ ______________________________ ____________
+Volume1 root@example.com:/data/remote_dir Faulty</programlisting>
+ <para>Machine2 is failed and now you can see discrepancy in number of files between master and slave. Few files will be missing from the master volume but they will be available only on slave as shown below.
+</para>
+ <para>Run the following command on Client:
+ </para>
+ <para><programlisting>client # ls /mnt/gluster | wc –l
+52</programlisting></para>
+ <para>Run the following command on slave (example.com):
+</para>
+ <para><programlisting>Example.com# # ls /data/remote_dir/ | wc –l
+100</programlisting></para>
+ <para><emphasis role="bold">To restore data from the slave machine</emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Stop all Master&apos;s geo-replication sessions using the following command:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> stop</command>
+</para>
+ <para>For example:
+</para>
+ <para><programlisting>machine1# gluster volume geo-replication Volume1
+example.com:/data/remote_dir stop
+
+Stopping geo-replication session between Volume1 &amp;
+example.com:/data/remote_dir has been successful</programlisting></para>
+ <para><note>
+ <para>Repeat <command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> stop </command>command on all active geo-replication sessions of master volume.</para>
+ </note></para>
+ </listitem>
+ <listitem>
+ <para>Replace the faulty brick in the master by using the following command:
+</para>
+ <para><command># gluster volume replace-brick <replaceable>VOLNAME BRICK NEW-BRICK</replaceable> start</command>
+</para>
+ <para>For example:
+</para>
+ <para><programlisting>machine1# gluster volume replace-brick Volume1 machine2:/export/dir16 machine3:/export/dir16 start
+Replace-brick started successfully</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Commit the migration of data using the following command:
+</para>
+ <para><command># gluster volume replace-brick <replaceable>VOLNAME BRICK NEW-BRICK</replaceable> commit force </command></para>
+ <para>For example:
+</para>
+ <para><programlisting>machine1# gluster volume replace-brick Volume1 machine2:/export/dir16 machine3:/export/dir16 commit force
+Replace-brick commit successful</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Verify the migration of brick by viewing the volume info using the following command:
+</para>
+ <para><command># gluster volume info <replaceable>VOLNAME</replaceable></command></para>
+ <para>For example:
+</para>
+ <para><programlisting>machine1# gluster volume info
+Volume Name: Volume1
+Type: Distribute
+Status: Started
+Number of Bricks: 2
+Transport-type: tcp
+Bricks:
+Brick1: machine1:/export/dir16
+Brick2: machine3:/export/dir16
+Options Reconfigured:
+geo-replication.indexing: on</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Run rsync command manually to sync data from slave to master volume&apos;s client (mount point).
+</para>
+ <para>For example:
+</para>
+ <para><command>example.com# rsync -PavhS --xattrs --ignore-existing /data/remote_dir/ client:/mnt/gluster</command></para>
+ <para>Verify that the data is synced by using the following command:
+</para>
+ <para>On master volume, run the following command:
+</para>
+ <para><programlisting>Client # ls | wc –l
+100</programlisting></para>
+ <para>On the Slave run the following command:
+</para>
+ <para><programlisting>example.com# ls /data/remote_dir/ | wc –l
+100</programlisting></para>
+ <para>Now Master volume and Slave directory is synced.
+</para>
+ </listitem>
+ <listitem>
+ <para>Restart geo-replication session from master to slave using the following command:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> start </command></para>
+ <para>For example:
+</para>
+ <para><programlisting>machine1# gluster volume geo-replication Volume1
+example.com:/data/remote_dir start
+Starting geo-replication session between Volume1 &amp;
+example.com:/data/remote_dir has been successful</programlisting></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="chap-Administration_Guide-Geo_Rep-Best_Practices">
+ <title>Best Practices</title>
+ <para><emphasis role="bold">Manually Setting Time </emphasis></para>
+ <para>If you have to change the time on your bricks manually, then you must set uniform time on all bricks. This avoids the out-of-time sync issue described in <xref linkend="chap-Administration_Guide-Geo_Rep-Preparation-Settingup_Environment"/>. Setting time backward corrupts the geo-replication index, so the recommended way to set the time manually is:
+</para>
+ <orderedlist>
+ <listitem>
+ <para>Stop geo-replication between the master and slave using the following command:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE</replaceable> sto</command>p
+</para>
+ </listitem>
+ <listitem>
+ <para>Stop the geo-replication indexing using the following command:
+</para>
+ <para><command># gluster volume set <replaceable>MASTER</replaceable> geo-replication.indexing of</command>f</para>
+ </listitem>
+ <listitem>
+ <para>Set uniform time on
+ all bricks.s</para>
+ </listitem>
+ <listitem>
+ <para>Restart your geo-replication sessions by using the following command:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>MASTER SLAVE </replaceable>start </command></para>
+ </listitem>
+ </orderedlist>
+ <para><emphasis role="bold">Running Geo-replication commands in one system</emphasis>
+</para>
+ <para>It is advisable to run the geo-replication commands in one of the bricks in the trusted storage pool. This is because, the log files for the geo-replication session would be stored in the *Server* where the Geo-replication start is initiated. Hence it would be easier to locate the log-files when required.
+</para>
+ <para><emphasis role="bold">Isolation </emphasis></para>
+ <para>Geo-replication slave operation is not sandboxed as of now and is ran as a privileged service. So for the security reason, it is advised to create a sandbox environment (dedicated machine / dedicated virtual machine / chroot/container type solution) by the administrator to run the geo-replication slave in it. Enhancement in this regard will be available in follow-up minor release.
+</para>
+ </section>
+</chapter>
+
diff --git a/doc/admin-guide/en-US/admin_managing_volumes.xml b/doc/admin-guide/en-US/admin_managing_volumes.xml
new file mode 100644
index 000000000..333d46cd6
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_managing_volumes.xml
@@ -0,0 +1,742 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Administration_Guide-Managing_Volumes">
+ <title>Managing GlusterFS Volumes</title>
+ <para>This section describes how to perform common GlusterFS management operations, including the following: </para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Managing_Volumes-Expanding"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Managing_Volumes-Shrinking"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Managing_Volumes-Migrating"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Managing_Volumes-Rebalancing"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Managing_Volumes-Stop"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Managing_Volumes-Delete"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Managing_Volumes-Self_heal"/></para>
+ </listitem>
+ </itemizedlist>
+ <section id="sect-Administration_Guide-Managing_Volumes-Tuning">
+ <title>Tuning Volume Options</title>
+ <para>You can tune volume options, as needed, while the cluster is online and available. </para>
+ <para><note>
+ <para>It is recommend to set server.allow-insecure option to ON if there are too many bricks in each volume or if there are too many services which have already utilized all the privileged ports in the system. Turning this option ON allows ports to accept/reject messages from insecure ports. So, use this option only if your deployment requires it. </para>
+ </note></para>
+ <para>To tune volume options </para>
+ <itemizedlist>
+ <listitem>
+ <para>Tune volume options using the following command:</para>
+ <para><command># gluster volume set <replaceable>VOLNAME OPTION PARAMETER</replaceable></command></para>
+ <para>For example, to specify the performance cache size for test-volume:</para>
+ <para><programlisting># gluster volume set test-volume performance.cache-size 256MB
+Set volume successful</programlisting></para>
+ <para>The following table lists the Volume options along with its description and default value: </para>
+ <para><note>
+ <para>The default options given here are subject to modification at any given time and may not be the same for all versions.</para>
+ </note></para>
+ <informaltable frame="all">
+ <tgroup cols="4">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <colspec colname="c3"/>
+ <colspec colname="c4"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ <entry>Default Value</entry>
+ <entry>Available Options</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>auth.allow</entry>
+ <entry>IP addresses of the clients which should be allowed to access the volume. </entry>
+ <entry>* (allow all)</entry>
+ <entry>Valid IP address which includes wild card patterns including *, such as 192.168.1.*</entry>
+ </row>
+ <row>
+ <entry>auth.reject</entry>
+ <entry>IP addresses of the clients which should be denied to access the volume. </entry>
+ <entry>NONE (reject none) </entry>
+ <entry>Valid IP address which includes wild card patterns including *, such as 192.168.2.*</entry>
+ </row>
+ <row>
+ <entry>client.grace-timeout</entry>
+ <entry>Specifies the duration for the lock state to be maintained on the client after a network disconnection.</entry>
+ <entry>10 </entry>
+ <entry>10 - 1800 secs</entry>
+ </row>
+ <row>
+ <entry>cluster.self-heal-window-size</entry>
+ <entry>Specifies the maximum number of blocks per file on which self-heal would happen simultaneously. </entry>
+ <entry>16 </entry>
+ <entry>0 - 1025 blocks</entry>
+ </row>
+ <row>
+ <entry>cluster.data-self-heal-algorithm</entry>
+ <entry>Specifies the type of self-heal. If you set the option as &quot;full&quot;, the entire file is copied from source to destinations. If the option is set to &quot;diff&quot; the file blocks that are not in sync are copied to destinations. Reset uses a heuristic model. If the file does not exist on one of the subvolumes, or a zero-byte file exists (created by entry self-heal) the entire content has to be copied anyway, so there is no benefit from using the &quot;diff&quot; algorithm. If the file size is about the same as page size, the entire file can be read and written with a few operations, which will be faster than &quot;diff&quot; which has to read checksums and then read and write. </entry>
+ <entry>reset</entry>
+ <entry>full | diff | reset</entry>
+ </row>
+ <row>
+ <entry>cluster.min-free-disk</entry>
+ <entry>Specifies the percentage of disk space that must be kept free. Might be useful for non-uniform bricks. </entry>
+ <entry>10%</entry>
+ <entry>Percentage of required minimum free disk space</entry>
+ </row>
+ <row>
+ <entry>cluster.stripe-block-size</entry>
+ <entry>Specifies the size of the stripe unit that will be read from or written to. </entry>
+ <entry>128 KB (for all files)</entry>
+ <entry>size in bytes</entry>
+ </row>
+ <row>
+ <entry>cluster.self-heal-daemon</entry>
+ <entry>Allows you to turn-off proactive self-heal on replicated volumes.</entry>
+ <entry>on</entry>
+ <entry>On | Off</entry>
+ </row>
+ <row>
+ <entry>diagnostics.brick-log-level</entry>
+ <entry>Changes the log-level of the bricks. </entry>
+ <entry>INFO </entry>
+ <entry>DEBUG|WARNING|ERROR|CRITICAL|NONE|TRACE</entry>
+ </row>
+ <row>
+ <entry>diagnostics.client-log-level</entry>
+ <entry>Changes the log-level of the clients. </entry>
+ <entry>INFO </entry>
+ <entry>DEBUG|WARNING|ERROR|CRITICAL|NONE|TRACE</entry>
+ </row>
+ <row>
+ <entry>diagnostics.latency-measurement</entry>
+ <entry>Statistics related to the latency of each operation would be tracked. </entry>
+ <entry>off </entry>
+ <entry>On | Off</entry>
+ </row>
+ <row>
+ <entry>diagnostics.dump-fd-stats</entry>
+ <entry>Statistics related to file-operations would be tracked.</entry>
+ <entry>off </entry>
+ <entry>On | Off</entry>
+ </row>
+ <row>
+ <entry>feature.read-only</entry>
+ <entry>Enables you to mount the entire volume as read-only for all the clients (including NFS clients) accessing it.</entry>
+ <entry>off</entry>
+ <entry>On | Off</entry>
+ </row>
+ <row>
+ <entry>features.lock-heal</entry>
+ <entry>Enables self-healing of locks when the network disconnects.</entry>
+ <entry>on</entry>
+ <entry>On | Off</entry>
+ </row>
+ <row>
+ <entry>features.quota-timeout</entry>
+ <entry>For performance reasons, quota caches the directory sizes on client. You can set timeout indicating the maximum duration of directory sizes in cache, from the time they are populated, during which they are considered valid. </entry>
+ <entry>0</entry>
+ <entry>0 - 3600 secs</entry>
+ </row>
+ <row>
+ <entry>geo-replication.indexing</entry>
+ <entry>Use this option to automatically sync the changes in the filesystem from Master to Slave.</entry>
+ <entry>off </entry>
+ <entry>On | Off</entry>
+ </row>
+ <row>
+ <entry>network.frame-timeout</entry>
+ <entry>The time frame after which the operation has to be declared as dead, if the server does not respond for a particular operation. </entry>
+ <entry>1800 (30 mins) </entry>
+ <entry>1800 secs</entry>
+ </row>
+ <row>
+ <entry>network.ping-timeout</entry>
+ <entry>The time duration for which the client waits to check if the server is responsive. When a ping timeout happens, there is a network disconnect between the client and server. All resources held by server on behalf of the client get cleaned up. When a reconnection happens, all resources will need to be re-acquired before the client can resume its operations on the server. Additionally, the locks will be acquired and the lock tables updated. <para>This reconnect is a very expensive operation and should be avoided.
+</para></entry>
+ <entry>42 Secs</entry>
+ <entry>42 Secs</entry>
+ </row>
+ <row>
+ <entry>nfs.enable-ino32</entry>
+ <entry>For 32-bit nfs clients or applications that do not support 64-bit inode numbers or large files, use this option from the CLI to make Gluster NFS return 32-bit inode numbers instead of 64-bit inode numbers. Applications that will benefit are those that were either: <para>* Built 32-bit and run on 32-bit machines.</para><para>* Built 32-bit on 64-bit systems.</para><para>* Built 64-bit but use a library built 32-bit, especially relevant for python and perl scripts.</para><para>Either of the conditions above can lead to application on Linux NFS clients failing with &quot;Invalid argument&quot; or &quot;Value too large for defined data type&quot; errors.</para></entry>
+ <entry>off</entry>
+ <entry>On | Off</entry>
+ </row>
+ <row>
+ <entry>nfs.volume-access </entry>
+ <entry>Set the access type for the specified sub-volume. </entry>
+ <entry>read-write </entry>
+ <entry>read-write|read-only </entry>
+ </row>
+ <row>
+ <entry>nfs.trusted-write </entry>
+ <entry>If there is an UNSTABLE write from the client, STABLE flag will be returned to force the client to not send a COMMIT request. <para>In some environments, combined with a replicated GlusterFS setup, this option can improve write performance. This flag allows users to trust Gluster replication logic to sync data to the disks and recover when required. COMMIT requests if received will be handled in a default manner by fsyncing. STABLE writes are still handled in a sync manner.</para></entry>
+ <entry> off </entry>
+ <entry>On | Off </entry>
+ </row>
+ <row>
+ <entry>nfs.trusted-sync</entry>
+ <entry> All writes and COMMIT requests are treated as async. This implies that no write requests are guaranteed to be on server disks when the write reply is received at the NFS client. Trusted sync includes trusted-write behavior. </entry>
+ <entry>off </entry>
+ <entry>On | Off </entry>
+ </row>
+ <row>
+ <entry>nfs.export-dir </entry>
+ <entry>By default, all sub-volumes of NFS are exported as individual exports. Now, this option allows you to export only the specified subdirectory or subdirectories in the volume. This option can also be used in conjunction with nfs3.export-volumes option to restrict exports only to the subdirectories specified through this option. You must provide an absolute path.</entry>
+ <entry>Enabled for all sub directories.</entry>
+ <entry>Enable | Disable </entry>
+ </row>
+ <row>
+ <entry>nfs.export-volumes </entry>
+ <entry>Enable/Disable exporting entire volumes, instead if used in conjunction with nfs3.export-dir, can allow setting up only subdirectories as exports. </entry>
+ <entry>on</entry>
+ <entry> On | Off </entry>
+ </row>
+ <row>
+ <entry>nfs.rpc-auth-unix </entry>
+ <entry>Enable/Disable the AUTH_UNIX authentication type. This option is enabled by default for better interoperability. However, you can disable it if required.</entry>
+ <entry>on </entry>
+ <entry> On | Off </entry>
+ </row>
+ <row>
+ <entry>nfs.rpc-auth-null </entry>
+ <entry>Enable/Disable the AUTH_NULL authentication type. It is not recommended to change the default value for this option. </entry>
+ <entry>on </entry>
+ <entry> On | Off </entry>
+ </row>
+ <row>
+ <entry>nfs.rpc-auth-allow&lt;IP- Addresses&gt; </entry>
+ <entry>Allow a comma separated list of addresses and/or hostnames to connect to the server. By default, all clients are disallowed. This allows you to define a general rule for all exported volumes.</entry>
+ <entry>Reject All </entry>
+ <entry>IP address or Host name </entry>
+ </row>
+ <row>
+ <entry>nfs.rpc-auth-reject IP- Addresses </entry>
+ <entry>Reject a comma separated list of addresses and/or hostnames from connecting to the server. By default, all connections are disallowed. This allows you to define a general rule for all exported volumes.</entry>
+ <entry>Reject All </entry>
+ <entry>IP address or Host name </entry>
+ </row>
+ <row>
+ <entry>nfs.ports-insecure </entry>
+ <entry>Allow client connections from unprivileged ports. By default only privileged ports are allowed. This is a global setting in case insecure ports are to be enabled for all exports using a single option. </entry>
+ <entry>off</entry>
+ <entry> On | Off </entry>
+ </row>
+ <row>
+ <entry>nfs.addr-namelookup </entry>
+ <entry>Turn-off name lookup for incoming client connections using this option. In some setups, the name server can take too long to reply to DNS queries resulting in timeouts of mount requests. Use this option to turn off name lookups during address authentication. Note, turning this off will prevent you from using hostnames in rpc-auth.addr.* filters. </entry>
+ <entry>on </entry>
+ <entry> On | Off </entry>
+ </row>
+ <row>
+ <entry>nfs.register-with- portmap </entry>
+ <entry>For systems that need to run multiple NFS servers, you need to prevent more than one from registering with portmap service. Use this option to turn off portmap registration for Gluster NFS. </entry>
+ <entry>on </entry>
+ <entry> On | Off </entry>
+ </row>
+ <row>
+ <entry>nfs.port &lt;PORT- NUMBER&gt; </entry>
+ <entry>Use this option on systems that need Gluster NFS to be associated with a non-default port number. </entry>
+ <entry>38465- 38467 </entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>nfs.disable</entry>
+ <entry>Turn-off volume being exported by NFS</entry>
+ <entry> off </entry>
+ <entry>On | Off </entry>
+ </row>
+ <row>
+ <entry>performance.write-behind-window-size </entry>
+ <entry>Size of the per-file write-behind buffer.</entry>
+ <entry>1 MB </entry>
+ <entry>Write-behind cache size </entry>
+ </row>
+ <row>
+ <entry>performance.io-thread-count </entry>
+ <entry>The number of threads in IO threads translator. </entry>
+ <entry>16</entry>
+ <entry>0 - 65 </entry>
+ </row>
+ <row>
+ <entry>performance.flush-behind </entry>
+ <entry>If this option is set ON, instructs write-behind translator to perform flush in background, by returning success (or any errors, if any of previous writes were failed) to application even before flush is sent to backend filesystem. </entry>
+ <entry>On </entry>
+ <entry>On | Off </entry>
+ </row>
+ <row>
+ <entry>performance.cache-max-file-size </entry>
+ <entry>Sets the maximum file size cached by the io-cache translator. Can use the normal size descriptors of KB, MB, GB,TB or PB (for example, 6GB). Maximum size uint64. </entry>
+ <entry>2 ^ 64 -1 bytes </entry>
+ <entry>size in bytes </entry>
+ </row>
+ <row>
+ <entry>performance.cache-min-file-size </entry>
+ <entry> Sets the minimum file size cached by the io-cache translator. Values same as &quot;max&quot; above.</entry>
+ <entry>0B</entry>
+ <entry>size in bytes </entry>
+ </row>
+ <row>
+ <entry>performance.cache-refresh-timeout </entry>
+ <entry>The cached data for a file will be retained till &apos;cache-refresh-timeout&apos; seconds, after which data re-validation is performed. </entry>
+ <entry>1 sec </entry>
+ <entry>0 - 61 </entry>
+ </row>
+ <row>
+ <entry>performance.cache-size </entry>
+ <entry>Size of the read cache.</entry>
+ <entry> 32 MB </entry>
+ <entry>size in bytes </entry>
+ </row>
+ <row>
+ <entry>server.allow-insecure </entry>
+ <entry>Allow client connections from unprivileged ports. By default only privileged ports are allowed. This is a global setting in case insecure ports are to be enabled for all exports using a single option. </entry>
+ <entry>on </entry>
+ <entry>On | Off </entry>
+ </row>
+ <row>
+ <entry>server.grace-timeout</entry>
+ <entry>Specifies the duration for the lock state to be maintained on the server after a network disconnection.</entry>
+ <entry>10</entry>
+ <entry>10 - 1800 secs</entry>
+ </row>
+ <row>
+ <entry>server.statedump-path </entry>
+ <entry>Location of the state dump file. </entry>
+ <entry>/tmp directory of the brick </entry>
+ <entry>New directory path</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ <para>You can view the changed volume options using the<command> # gluster volume info <replaceable>VOLNAME</replaceable></command> command. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Delete"/>.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="sect-Administration_Guide-Managing_Volumes-Expanding">
+ <title>Expanding Volumes</title>
+ <para>You can expand volumes, as needed, while the cluster is online and available. For example, you might want to add a brick to a distributed volume, thereby increasing the distribution and adding to the capacity of the GlusterFS volume. </para>
+ <para>Similarly, you might want to add a group of bricks to a distributed replicated volume, increasing the capacity of the GlusterFS volume. </para>
+ <para><note>
+ <para>When expanding distributed replicated and distributed striped volumes, you need to add a number of bricks that is a multiple of the replica or stripe count. For example, to expand a distributed replicated volume with a replica count of 2, you need to add bricks in multiples of 2 (such as 4, 6, 8, etc.). </para>
+ </note></para>
+ <para><emphasis role="bold">To expand a volume</emphasis> </para>
+ <orderedlist>
+ <listitem>
+ <para>On the first server in the cluster, probe the server to which you want to add the new brick using the following command:</para>
+ <para><command># gluster peer probe <replaceable>HOSTNAME</replaceable></command></para>
+ <para>For example:</para>
+ <para><programlisting># gluster peer probe server4
+Probe successful</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Add the brick using the following command: </para>
+ <para><command># gluster volume add-brick <replaceable>VOLNAME NEW-BRICK</replaceable></command></para>
+ <para>For example:</para>
+ <para><programlisting># gluster volume add-brick test-volume server4:/exp4
+Add Brick successful</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Check the volume information using the following command: </para>
+ <para><command># gluster volume info </command></para>
+ <para>The command displays information similar to the following:</para>
+ <para><programlisting>Volume Name: test-volume
+Type: Distribute
+Status: Started
+Number of Bricks: 4
+Bricks:
+Brick1: server1:/exp1
+Brick2: server2:/exp2
+Brick3: server3:/exp3
+Brick4: server4:/exp4</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Rebalance the volume to ensure that all files are distributed to the new brick.</para>
+ <para>You can use the rebalance command as described in <xref linkend="sect-Administration_Guide-Managing_Volumes-Rebalancing"/>.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Managing_Volumes-Shrinking">
+ <title>Shrinking Volumes</title>
+ <para>You can shrink volumes, as needed, while the cluster is online and available. For example, you might need to remove a brick that has become inaccessible in a distributed volume due to hardware or network failure. </para>
+ <para><note>
+ <para>Data residing on the brick that you are removing will no longer be accessible at the Gluster mount point. Note however that only the configuration information is removed - you can continue to access the data directly from the brick, as necessary. </para>
+ </note></para>
+ <para>When shrinking distributed replicated and distributed striped volumes, you need to remove a number of bricks that is a multiple of the replica or stripe count. For example, to shrink a distributed striped volume with a stripe count of 2, you need to remove bricks in multiples of 2 (such as 4, 6, 8, etc.). In addition, the bricks you are trying to remove must be from the same sub-volume (the same replica or stripe set). </para>
+ <para><emphasis role="bold">To shrink a volume</emphasis> </para>
+ <orderedlist>
+ <listitem>
+ <para>Remove the brick using the following command:</para>
+ <para><command># gluster volume remove-brick <varname>VOLNAME</varname><replaceable> BRICK</replaceable></command> <command>start</command></para>
+ <para>For example, to remove server2:/exp2:</para>
+ <para><programlisting># gluster volume remove-brick test-volume server2:/exp2 start
+
+Removing brick(s) can result in data loss. Do you want to Continue? (y/n)</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Enter &quot;y&quot; to confirm the operation. The command displays the following message indicating that the remove brick operation is successfully started: </para>
+ <para><programlisting>Remove Brick successful </programlisting></para>
+ </listitem>
+ <listitem>
+ <para>(Optional) View the status of the remove brick operation using the following command:</para>
+ <para><command># gluster volume remove-brick <varname>VOLNAME</varname><replaceable> BRICK</replaceable></command><command> status</command></para>
+ <para>For example, to view the status of remove brick operation on server2:/exp2 brick:</para>
+ <para><screen># gluster volume remove-brick test-volume server2:/exp2 status
+ Node Rebalanced-files size scanned status
+ --------- ---------------- ---- ------- -----------
+617c923e-6450-4065-8e33-865e28d9428f 34 340 162 in progress</screen></para>
+ </listitem>
+ <listitem>
+ <para>Commit the remove brick operation using the following command:</para>
+ <para><command># gluster volume remove-brick <varname>VOLNAME</varname><replaceable> BRICK</replaceable></command><command> commit</command></para>
+ <para>For example, to view the status of remove brick operation on server2:/exp2 brick:</para>
+ <para><screen># gluster volume remove-brick test-volume server2:/exp2 commit</screen></para>
+ <para><programlisting>Remove Brick successful </programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Check the volume information using the following command: </para>
+ <para><command># gluster volume info </command></para>
+ <para>The command displays information similar to the following:</para>
+ <para><programlisting># gluster volume info
+Volume Name: test-volume
+Type: Distribute
+Status: Started
+Number of Bricks: 3
+Bricks:
+Brick1: server1:/exp1
+Brick3: server3:/exp3
+Brick4: server4:/exp4</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Rebalance the volume to ensure that all files are distributed to the new brick.</para>
+ <para>You can use the rebalance command as described in <xref linkend="sect-Administration_Guide-Managing_Volumes-Rebalancing"/>.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Managing_Volumes-Migrating">
+ <title>Migrating Volumes</title>
+ <para>You can migrate the data from one brick to another, as needed, while the cluster is online and available. </para>
+ <para><emphasis role="bold">To migrate a volume</emphasis> </para>
+ <orderedlist>
+ <listitem>
+ <para>Make sure the new brick, server5 in this example, is successfully added to the cluster.</para>
+ <para>For more information, see <xref linkend="sect-Administration_Guide-Storage_Pools-Adding_Servers"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Migrate the data from one brick to another using the following command:</para>
+ <para><command> # gluster volume replace-brick <code>VOLNAME</code><code> BRICK</code><code>NEW-BRICK</code> start</command></para>
+ <para>For example, to migrate the data in server3:/exp3 to server5:/exp5 in test-volume:</para>
+ <para><programlisting># gluster volume replace-brick test-volume server3:/exp3 server5:exp5 start
+Replace brick start operation successful</programlisting></para>
+ <para><note>
+ <para>You need to have the FUSE package installed on the server on which you are running the replace-brick command for the command to work.</para>
+ </note></para>
+ </listitem>
+ <listitem>
+ <para>To pause the migration operation, if needed, use the following command: </para>
+ <para><command># gluster volume replace-brick <varname>VOLNAME BRICK NEW-BRICK </varname> pause </command></para>
+ <para>For example, to pause the data migration from server3:/exp3 to server5:/exp5 in test-volume:</para>
+ <para><programlisting># gluster volume replace-brick test-volume server3:/exp3 server5:exp5 pause
+Replace brick pause operation successful</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>To abort the migration operation, if needed, use the following command: </para>
+ <para><command> # gluster volume replace-brick <varname>VOLNAME BRICK NEW-BRICK </varname>abort </command></para>
+ <para>For example, to abort the data migration from server3:/exp3 to server5:/exp5 in test-volume:</para>
+ <para><programlisting># gluster volume replace-brick test-volume server3:/exp3 server5:exp5 abort
+Replace brick abort operation successful</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Check the status of the migration operation using the following command: </para>
+ <para><command> # gluster volume replace-brick <varname>VOLNAME BRICK NEW-BRICK </varname>status </command></para>
+ <para>For example, to check the data migration status from server3:/exp3 to server5:/exp5 in test-volume:</para>
+ <para><programlisting># gluster volume replace-brick test-volume server3:/exp3 server5:/exp5 status
+Current File = /usr/src/linux-headers-2.6.31-14/block/Makefile
+Number of files migrated = 10567
+Migration complete</programlisting></para>
+ <para>The status command shows the current file being migrated along with the current total number of files migrated. After completion of migration, it displays Migration complete.</para>
+ </listitem>
+ <listitem>
+ <para>Commit the migration of data from one brick to another using the following command: </para>
+ <para><command> # gluster volume replace-brick <varname>VOLNAME BRICK NEW-BRICK </varname>commit </command></para>
+ <para>For example, to commit the data migration from server3:/exp3 to server5:/exp5 in test-volume:</para>
+ <para><programlisting># gluster volume replace-brick test-volume server3:/exp3 server5:/exp5 commit
+replace-brick commit successful</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Verify the migration of brick by viewing the volume info using the following command: </para>
+ <para><command># gluster volume info <code>VOLNAME</code></command></para>
+ <para>For example, to check the volume information of new brick server5:/exp5 in test-volume:</para>
+ <para><programlisting># gluster volume info test-volume
+Volume Name: testvolume
+Type: Replicate
+Status: Started
+Number of Bricks: 4
+Transport-type: tcp
+Bricks:
+Brick1: server1:/exp1
+Brick2: server2:/exp2
+Brick3: server4:/exp4
+Brick4: server5:/exp5
+
+The new volume details are displayed.
+</programlisting></para>
+ <para>The new volume details are displayed.</para>
+ <para>In the above example, previously, there were bricks; 1,2,3, and 4 and now brick 3 is replaced by brick 5.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Managing_Volumes-Rebalancing">
+ <title>Rebalancing Volumes</title>
+ <para>After expanding or shrinking a volume (using the add-brick and remove-brick commands respectively), you need to rebalance the data among the servers. New directories created after expanding or shrinking of the volume will be evenly distributed automatically. For all the existing directories, the distribution can be fixed by rebalancing the layout and/or data. </para>
+ <para>This section describes how to rebalance GlusterFS volumes in your storage environment, using the following common scenarios: </para>
+ <itemizedlist>
+ <listitem>
+ <para>Fix Layout - Fixes the layout changes so that the files can actually go to newly added nodes. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Rebalancing-Fix_Layout"/>. </para>
+ </listitem>
+ <listitem>
+ <para>Fix Layout and Migrate Data - Rebalances volume by fixing the layout changes and migrating the existing data. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Rebalancing-Fix_Migrate"/>.</para>
+ </listitem>
+ </itemizedlist>
+ <section id="sect-Administration_Guide-Managing_Volumes-Rebalancing-Fix_Layout">
+ <title>Rebalancing Volume to Fix Layout Changes</title>
+ <para>Fixing the layout is necessary because the layout structure is static for a given directory. In a scenario where new bricks have been added to the existing volume, newly created files in existing directories will still be distributed only among the old bricks. The <command># gluster volume rebalance<varname> VOLNAME</varname> fix-layout start </command>command will fix the layout information so that the files can also go to newly added nodes. When this command is issued, all the file stat information which is already cached will get revalidated. </para>
+ <para>A fix-layout rebalance will only fix the layout changes and does not migrate data. If you want to migrate the existing data, use<command># gluster volume rebalance <varname>VOLNAME</varname> start </command> command to rebalance data among the servers. </para>
+ <para><emphasis role="bold">To rebalance a volume to fix layout changes</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Start the rebalance operation on any one of the server using the following command:</para>
+ <para><command># gluster volume rebalance<varname> VOLNAME</varname> fix-layout start</command></para>
+ <para>For example:</para>
+ <para><programlisting># gluster volume rebalance test-volume fix-layout start
+Starting rebalance on volume test-volume has been successful</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="sect-Administration_Guide-Managing_Volumes-Rebalancing-Fix_Migrate">
+ <title>Rebalancing Volume to Fix Layout and Migrate Data</title>
+ <para>After expanding or shrinking a volume (using the add-brick and remove-brick commands respectively), you need to rebalance the data among the servers. </para>
+ <para><emphasis role="bold">To rebalance a volume to fix layout and migrate the existing data</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Start the rebalance operation on any one of the server using the following command:</para>
+ <para><command># gluster volume rebalance<varname> VOLNAME</varname> start</command></para>
+ <para>For example:</para>
+ <para><programlisting># gluster volume rebalance test-volume start
+Starting rebalancing on volume test-volume has been successful</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Start the migration operation forcefully on any one of the server using the following command:</para>
+ <para><command># gluster volume rebalance<varname> VOLNAME</varname> start force</command></para>
+ <para>For example:</para>
+ <para><programlisting># gluster volume rebalance test-volume start force
+Starting rebalancing on volume test-volume has been successful</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Displaying Status of Rebalance Operation</title>
+ <para>You can display the status information about rebalance volume operation, as needed. </para>
+ <para><emphasis role="bold">To view status of rebalance volume</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Check the status of the rebalance operation, using the following command:</para>
+ <para><command># gluster volume rebalance <replaceable>VOLNAME</replaceable> status</command></para>
+ <para>For example:</para>
+ <para><screen># gluster volume rebalance test-volume status
+ Node Rebalanced-files size scanned status
+ --------- ---------------- ---- ------- -----------
+617c923e-6450-4065-8e33-865e28d9428f 416 1463 312 in progress</screen></para>
+ <para>The time to complete the rebalance operation depends on the number of files on the volume along with the corresponding file sizes. Continue checking the rebalance status, verifying that the number of files rebalanced or total files scanned keeps increasing.</para>
+ <para>For example, running the status command again might display a result similar to the following:</para>
+ <para><screen># gluster volume rebalance test-volume status
+ Node Rebalanced-files size scanned status
+ --------- ---------------- ---- ------- -----------
+617c923e-6450-4065-8e33-865e28d9428f 498 1783 378 in progress</screen></para>
+ <para>The rebalance status displays the following when the rebalance is complete:</para>
+ <para><screen># gluster volume rebalance test-volume status
+ Node Rebalanced-files size scanned status
+ --------- ---------------- ---- ------- -----------
+617c923e-6450-4065-8e33-865e28d9428f 502 1873 334 completed</screen></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Stopping Rebalance Operation</title>
+ <para>You can stop the rebalance operation, as needed.</para>
+ <para><emphasis role="bold">To stop rebalance</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Stop the rebalance operation using the following command:</para>
+ <para><command># gluster volume rebalance <replaceable>VOLNAME</replaceable> stop</command></para>
+ <para>For example:</para>
+ <para><screen># gluster volume rebalance test-volume stop
+ Node Rebalanced-files size scanned status
+ --------- ---------------- ---- ------- -----------
+617c923e-6450-4065-8e33-865e28d9428f 59 590 244 stopped
+Stopped rebalance process on volume test-volume </screen></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="sect-Administration_Guide-Managing_Volumes-Stop">
+ <title>Stopping Volumes</title>
+ <para>To stop a volume</para>
+ <orderedlist>
+ <listitem>
+ <para>Stop the volume using the following command:
+
+</para>
+ <para><command># gluster volume stop <varname>VOLNAME </varname></command></para>
+ <para>For example, to stop test-volume:</para>
+ <para><programlisting># gluster volume stop test-volume
+Stopping volume will make its data inaccessible. Do you want to continue? (y/n)
+</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Enter <userinput>y</userinput> to confirm the operation. The output of the command displays the following:
+
+</para>
+ <programlisting>Stopping volume test-volume has been successful</programlisting>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Managing_Volumes-Delete">
+ <title>Deleting Volumes</title>
+ <para>To delete a volume </para>
+ <orderedlist>
+ <listitem>
+ <para>Delete the volume using the following command:</para>
+ <para><command># gluster volume delete <varname>VOLNAME</varname></command></para>
+ <para>For example, to delete test-volume:</para>
+ <para><programlisting># gluster volume delete test-volume
+Deleting volume will erase all information about the volume. Do you want to continue? (y/n)</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Enter <userinput role="bold">y</userinput> to confirm the operation. The command displays the following:</para>
+ <para><programlisting>Deleting volume test-volume has been successful</programlisting></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Managing_Volumes-Self_heal">
+ <title>Triggering Self-Heal on Replicate</title>
+ <para>In replicate module, previously you had to manually trigger a self-heal when a brick goes offline and comes back online, to bring all the replicas in sync. Now the pro-active self-heal daemon runs in the background, diagnoses issues and automatically initiates self-healing every 10 minutes on the files which requires<emphasis role="italic"> healing</emphasis>. </para>
+ <para>You can view the list of files that need <emphasis role="italic">healing</emphasis>, the list of files which are currently/previously <emphasis role="italic">healed</emphasis>, list of files which are in split-brain state, and you can manually trigger self-heal on the entire volume or only on the files which need <emphasis role="italic">healing</emphasis>.</para>
+ <itemizedlist>
+ <listitem>
+ <para>Trigger self-heal only on the files which requires <emphasis role="italic">healing</emphasis>:</para>
+ <para><command># gluster volume heal <replaceable>VOLNAME</replaceable></command></para>
+ <para>For example, to trigger self-heal on files which requires <emphasis role="italic">healing</emphasis> of test-volume:</para>
+ <para><screen># gluster volume heal test-volume
+Heal operation on volume test-volume has been successful</screen></para>
+ </listitem>
+ <listitem>
+ <para>Trigger self-heal on all the files of a volume:</para>
+ <para><command># gluster volume heal <replaceable>VOLNAME</replaceable></command> <command>full</command></para>
+ <para>For example, to trigger self-heal on all the files of of test-volume:</para>
+ <para><screen># gluster volume heal test-volume full
+Heal operation on volume test-volume has been successful</screen></para>
+ </listitem>
+ <listitem>
+ <para>View the list of files that needs <emphasis role="italic">healing</emphasis>:</para>
+ <para><command># gluster volume heal <replaceable>VOLNAME</replaceable></command> <command>info</command></para>
+ <para>For example, to view the list of files on test-volume that needs <emphasis role="italic">healing</emphasis>:</para>
+ <para><screen># gluster volume heal test-volume info
+Brick <emphasis role="italic">server1</emphasis>:/gfs/test-volume_0
+Number of entries: 0
+
+Brick <emphasis role="italic">server2</emphasis>:/gfs/test-volume_1
+Number of entries: 101
+/95.txt
+/32.txt
+/66.txt
+/35.txt
+/18.txt
+/26.txt
+/47.txt
+/55.txt
+/85.txt
+...</screen></para>
+ </listitem>
+ <listitem>
+ <para>View the list of files that are self-healed:</para>
+ <para><command># gluster volume heal <replaceable>VOLNAME</replaceable></command> <command>info healed</command> </para>
+ <para>For example, to view the list of files on test-volume that are self-healed:</para>
+ <para><screen># gluster volume heal test-volume info healed
+Brick <emphasis role="italic">server1</emphasis>:/gfs/test-volume_0
+Number of entries: 0
+
+Brick <emphasis role="italic">server2</emphasis>:/gfs/test-volume_1
+Number of entries: 69
+/99.txt
+/93.txt
+/76.txt
+/11.txt
+/27.txt
+/64.txt
+/80.txt
+/19.txt
+/41.txt
+/29.txt
+/37.txt
+/46.txt
+...</screen></para>
+ </listitem>
+ <listitem>
+ <para>View the list of files of a particular volume on which the self-heal failed:</para>
+ <para><command># gluster volume heal <replaceable>VOLNAME</replaceable></command> <command>info failed</command> </para>
+ <para>For example, to view the list of files of test-volume that are not self-healed:</para>
+ <para><screen># gluster volume heal test-volume info failed
+Brick <emphasis role="italic">server1</emphasis>:/gfs/test-volume_0
+Number of entries: 0
+
+Brick server2:/gfs/test-volume_3
+Number of entries: 72
+/90.txt
+/95.txt
+/77.txt
+/71.txt
+/87.txt
+/24.txt
+...</screen></para>
+ </listitem>
+ <listitem>
+ <para>View the list of files of a particular volume which are in split-brain state:</para>
+ <para><command># gluster volume heal <replaceable>VOLNAME</replaceable></command> <command>info split-brain</command> </para>
+ <para>For example, to view the list of files of test-volume which are in split-brain state:</para>
+ <para><screen># gluster volume heal test-volume info split-brain
+Brick server1:/gfs/test-volume_2
+Number of entries: 12
+/83.txt
+/28.txt
+/69.txt
+...
+
+Brick <emphasis role="italic">server2</emphasis>:/gfs/test-volume_2
+Number of entries: 12
+/83.txt
+/28.txt
+/69.txt
+...</screen></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_monitoring_workload.xml b/doc/admin-guide/en-US/admin_monitoring_workload.xml
new file mode 100644
index 000000000..e85bc51d8
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_monitoring_workload.xml
@@ -0,0 +1,878 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter id="chap-Administration_Guide-Monitor_Workload">
+ <title>Monitoring your GlusterFS Workload</title>
+ <para>You can monitor the GlusterFS volumes on different parameters. Monitoring volumes helps in capacity planning and performance tuning tasks of the GlusterFS volume. Using these information, you can identify and troubleshoot issues. </para>
+ <para>You can use Volume Top and Profile commands to view the performance and identify bottlenecks/hotspots of each brick of a volume. This helps system administrators to get vital performance information whenever performance needs to be probed. </para>
+ <para>You can also perform statedump of the brick processes and nfs server process of a volume, and also view volume status and volume information. </para>
+ <section id="chap-Administration_Guide-Monitor_Workload-Profile">
+ <title>Running GlusterFS Volume Profile Command</title>
+ <para>GlusterFS Volume Profile command provides an interface to get the per-brick I/O information for each File Operation (FOP) of a volume. The per brick information helps in identifying bottlenecks in the storage system.
+</para>
+ <para>This section describes how to run GlusterFS Volume Profile command by performing the following operations:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Profile-Start"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Profile-Display"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Profile-Stop"/></para>
+ </listitem>
+ </itemizedlist>
+ <section id="chap-Administration_Guide-Monitor_Workload-Profile-Start">
+ <title>Start Profiling</title>
+ <para>You must start the Profiling to view the File Operation information for each brick.
+</para>
+ <para><emphasis role="bold">To start profiling: </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Start profiling using the following command:
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para><command># gluster volume profile <replaceable>VOLNAME</replaceable> start </command></para>
+ <para>For example, to start profiling on test-volume:
+</para>
+ <para><programlisting># gluster volume profile test-volume start
+Profiling started on test-volume</programlisting></para>
+ <para>When profiling on the volume is started, the following additional options are displayed in the Volume Info:
+</para>
+ <para><programlisting>diagnostics.count-fop-hits: on
+
+diagnostics.latency-measurement: on</programlisting></para>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Profile-Display">
+ <title>Displaying the I/0 Information</title>
+ <para>You can view the I/O information of each brick.
+</para>
+ <para>To display I/O information:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Display the I/O information using the following command:
+</para>
+ </listitem>
+ </itemizedlist>
+ <para><command># gluster volume profile <replaceable>VOLNAME</replaceable> info</command>
+
+</para>
+ <para>For example, to see the I/O information on test-volume:
+
+</para>
+ <para><programlisting># gluster volume profile test-volume info
+Brick: Test:/export/2
+Cumulative Stats:
+
+Block 1b+ 32b+ 64b+
+Size:
+ Read: 0 0 0
+ Write: 908 28 8
+
+Block 128b+ 256b+ 512b+
+Size:
+ Read: 0 6 4
+ Write: 5 23 16
+
+Block 1024b+ 2048b+ 4096b+
+Size:
+ Read: 0 52 17
+ Write: 15 120 846
+
+Block 8192b+ 16384b+ 32768b+
+Size:
+ Read: 52 8 34
+ Write: 234 134 286
+
+Block 65536b+ 131072b+
+Size:
+ Read: 118 622
+ Write: 1341 594
+
+
+%-latency Avg- Min- Max- calls Fop
+ latency Latency Latency
+___________________________________________________________
+4.82 1132.28 21.00 800970.00 4575 WRITE
+5.70 156.47 9.00 665085.00 39163 READDIRP
+11.35 315.02 9.00 1433947.00 38698 LOOKUP
+11.88 1729.34 21.00 2569638.00 7382 FXATTROP
+47.35 104235.02 2485.00 7789367.00 488 FSYNC
+
+------------------
+
+------------------
+
+Duration : 335
+
+BytesRead : 94505058
+
+BytesWritten : 195571980</programlisting></para>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Profile-Stop">
+ <title>Stop Profiling</title>
+ <para>You can stop profiling the volume, if you do not need profiling information anymore.
+</para>
+ <para><emphasis role="bold">To stop profiling</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Stop profiling using the following command:
+</para>
+ <para><command># gluster volume profile <replaceable>VOLNAME</replaceable> stop</command>
+</para>
+ <para>For example, to stop profiling on test-volume:</para>
+ <para><command># gluster volume profile <replaceable>test-volume</replaceable> stop</command> </para>
+ <para><computeroutput>Profiling stopped on test-volume</computeroutput></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Top">
+ <title> Running GlusterFS Volume TOP Command </title>
+ <para>GlusterFS Volume Top command allows you to view the glusterfs bricks’ performance metrics like
+read, write, file open calls, file read calls, file write calls, directory open calls, and directory real
+calls. The top command displays up to 100 results.
+</para>
+ <para>This section describes how to run and view the results for the following GlusterFS Top commands:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Top-Open_FD_Count"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Top-File_Read"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Top-File_Write"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Top-Open_Calls"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Top-Read_Calls"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Top-Read_Perf"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="chap-Administration_Guide-Monitor_Workload-Top-Write_Perf"/></para>
+ </listitem>
+ </itemizedlist>
+ <section id="chap-Administration_Guide-Monitor_Workload-Top-Open_FD_Count">
+ <title>Viewing Open fd Count and Maximum fd Count </title>
+ <para>You can view both current open fd count (list of files that are currently the most opened and the
+count) on the brick and the maximum open fd count (count of files that are the currently open and
+the count of maximum number of files opened at any given point of time, since the servers are up
+and running). If the brick name is not specified, then open fd metrics of all the bricks belonging to
+the volume will be displayed.
+</para>
+ <para><emphasis role="bold">To view open fd count and maximum fd count: </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>View open fd count and maximum fd count using the following command:</para>
+ <para><command># gluster volume top <replaceable>VOLNAME</replaceable> open [brick <replaceable>BRICK-NAME</replaceable>] [list-cnt <replaceable>cnt</replaceable>]</command>
+</para>
+ <para>For example, to view open fd count and maximum fd count on brick <replaceable>server:/export</replaceable> of <replaceable>test-volume</replaceable> and list top 10 open calls:
+</para>
+ <para><command># gluster volume top <replaceable>test-volume</replaceable> open brick <replaceable>server:/export/</replaceable> list-cnt <replaceable>10</replaceable></command></para>
+ <para><computeroutput>Brick: server:/export/dir1 </computeroutput></para>
+ <para><computeroutput>Current open fd&apos;s: 34 Max open fd&apos;s: 209 </computeroutput><programlisting> ==========Open file stats========
+
+open file name
+call count
+
+2 /clients/client0/~dmtmp/PARADOX/
+ COURSES.DB
+
+11 /clients/client0/~dmtmp/PARADOX/
+ ENROLL.DB
+
+11 /clients/client0/~dmtmp/PARADOX/
+ STUDENTS.DB
+
+10 /clients/client0/~dmtmp/PWRPNT/
+ TIPS.PPT
+
+10 /clients/client0/~dmtmp/PWRPNT/
+ PCBENCHM.PPT
+
+9 /clients/client7/~dmtmp/PARADOX/
+ STUDENTS.DB
+
+9 /clients/client1/~dmtmp/PARADOX/
+ STUDENTS.DB
+
+9 /clients/client2/~dmtmp/PARADOX/
+ STUDENTS.DB
+
+9 /clients/client0/~dmtmp/PARADOX/
+ STUDENTS.DB
+
+9 /clients/client8/~dmtmp/PARADOX/
+ STUDENTS.DB</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Top-File_Read">
+ <title>Viewing Highest File Read Calls </title>
+ <para>You can view highest read calls on each brick. If brick name is not specified, then by default, list of
+100 files will be displayed.
+</para>
+ <para><emphasis role="bold">To view highest file Read calls:</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>View highest file Read calls using the following command:
+</para>
+ <para><command># gluster volume top <replaceable>VOLNAME</replaceable> read [brick <replaceable>BRICK-NAME</replaceable>] [list-cnt <replaceable>cnt</replaceable>] </command></para>
+ <para>For example, to view highest Read calls on brick server:/export of test-volume:
+</para>
+ <para><command># gluster volume top <replaceable>test-volume</replaceable> read brick <replaceable>server:/export</replaceable> list-cnt <replaceable>10</replaceable></command></para>
+ <para><computeroutput>Brick:</computeroutput> <replaceable>server:/export/dir1</replaceable><programlisting> ==========Read file stats========
+
+read filename
+call count
+
+116 /clients/client0/~dmtmp/SEED/LARGE.FIL
+
+64 /clients/client0/~dmtmp/SEED/MEDIUM.FIL
+
+54 /clients/client2/~dmtmp/SEED/LARGE.FIL
+
+54 /clients/client6/~dmtmp/SEED/LARGE.FIL
+
+54 /clients/client5/~dmtmp/SEED/LARGE.FIL
+
+54 /clients/client0/~dmtmp/SEED/LARGE.FIL
+
+54 /clients/client3/~dmtmp/SEED/LARGE.FIL
+
+54 /clients/client4/~dmtmp/SEED/LARGE.FIL
+
+54 /clients/client9/~dmtmp/SEED/LARGE.FIL
+
+54 /clients/client8/~dmtmp/SEED/LARGE.FIL</programlisting> </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Top-File_Write">
+ <title>Viewing Highest File Write Calls </title>
+ <para>You can view list of files which has highest file write calls on each brick. If brick name is not
+specified, then by default, list of 100 files will be displayed.
+</para>
+ <para><emphasis role="bold">To view highest file Write calls:</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>View highest file Write calls using the following command:
+</para>
+ <para><command># gluster volume top <replaceable>VOLNAME</replaceable> write [brick <replaceable>BRICK-NAME</replaceable>] [list-cnt <replaceable>cnt</replaceable>] </command></para>
+ <para>For example, to view highest Write calls on brick <replaceable>server:/export</replaceable> of <replaceable>test-volume</replaceable>:
+</para>
+ <para><command># gluster volume top <replaceable>test-volume</replaceable> write brick <replaceable>server:/export</replaceable> list-cnt <replaceable>10</replaceable></command></para>
+ <para><code>Brick: server:/export/dir1 </code><programlisting> ==========Write file stats========
+write call count filename
+
+83 /clients/client0/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client7/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client1/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client2/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client0/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client8/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client5/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client4/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client6/~dmtmp/SEED/LARGE.FIL
+
+59 /clients/client3/~dmtmp/SEED/LARGE.FIL</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Top-Open_Calls">
+ <title>Viewing Highest Open Calls on Directories </title>
+ <para>You can view list of files which has highest open calls on directories of each brick. If brick name is
+not specified, then the metrics of all the bricks belonging to that volume will be displayed.
+</para>
+ <para>To view list of open calls on each directory</para>
+ <itemizedlist>
+ <listitem>
+ <para>View list of open calls on each directory using the following command:
+</para>
+ <para><command># gluster volume top <replaceable>VOLNAME</replaceable> opendir [brick <replaceable>BRICK-NAME</replaceable>] [list-cnt <replaceable>cnt</replaceable>] </command></para>
+ <para>For example, to view open calls on brick server:/export/ of test-volume:
+</para>
+ <para><command># gluster volume top <replaceable>test-volume</replaceable> opendir brick <replaceable>server:/export</replaceable> list-cnt <replaceable>10</replaceable></command></para>
+ <para><code>Brick: server:/export/dir1 </code><programlisting> ==========Directory open stats========
+
+Opendir count directory name
+
+1001 /clients/client0/~dmtmp
+
+454 /clients/client8/~dmtmp
+
+454 /clients/client2/~dmtmp
+
+454 /clients/client6/~dmtmp
+
+454 /clients/client5/~dmtmp
+
+454 /clients/client9/~dmtmp
+
+443 /clients/client0/~dmtmp/PARADOX
+
+408 /clients/client1/~dmtmp
+
+408 /clients/client7/~dmtmp
+
+402 /clients/client4/~dmtmp</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Top-Read_Calls">
+ <title>Viewing Highest Read Calls on Directory </title>
+ <para>You can view list of files which has highest directory read calls on each brick. If brick name is not
+specified, then the metrics of all the bricks belonging to that volume will be displayed.
+</para>
+ <para><emphasis role="bold">To view list of highest directory read calls on each brick</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>View list of highest directory read calls on each brick using the following command:
+</para>
+ <para><command># gluster volume top <replaceable>VOLNAME</replaceable> readdir [brick <replaceable>BRICK-NAME</replaceable>] [list-cnt <replaceable>cnt</replaceable>] </command></para>
+ <para>For example, to view highest directory read calls on brick <replaceable>server:/export</replaceable> of <replaceable>test-volume</replaceable>:</para>
+ <para><command># gluster volume top <replaceable>test-volume</replaceable> readdir brick <replaceable>server:/export</replaceable> list-cnt <replaceable>10</replaceable></command> </para>
+ <para><code>Brick: <replaceable>server:/export/dir1</replaceable></code><programlisting>==========Directory readdirp stats========
+
+readdirp count directory name
+
+1996 /clients/client0/~dmtmp
+
+1083 /clients/client0/~dmtmp/PARADOX
+
+904 /clients/client8/~dmtmp
+
+904 /clients/client2/~dmtmp
+
+904 /clients/client6/~dmtmp
+
+904 /clients/client5/~dmtmp
+
+904 /clients/client9/~dmtmp
+
+812 /clients/client1/~dmtmp
+
+812 /clients/client7/~dmtmp
+
+800 /clients/client4/~dmtmp</programlisting>
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Top-Read_Perf">
+ <title>Viewing List of Read Performance on each Brick </title>
+ <para>You can view the read throughput of files on each brick. If brick name is not specified, then the
+metrics of all the bricks belonging to that volume will be displayed. The output will be the read
+throughput.
+</para>
+ <para><programlisting> ==========Read throughput file stats========
+
+read filename Time
+through
+put(MBp
+s)
+
+2570.00 /clients/client0/~dmtmp/PWRPNT/ -2011-01-31
+ TRIDOTS.POT 15:38:36.894610
+2570.00 /clients/client0/~dmtmp/PWRPNT/ -2011-01-31
+ PCBENCHM.PPT 15:38:39.815310
+2383.00 /clients/client2/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:52:53.631499
+
+2340.00 /clients/client0/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:38:36.926198
+
+2299.00 /clients/client0/~dmtmp/SEED/ -2011-01-31
+ LARGE.FIL 15:38:36.930445
+
+2259.00 /clients/client0/~dmtmp/PARADOX/ -2011-01-31
+ COURSES.X04 15:38:40.549919
+
+2221.00 /clients/client0/~dmtmp/PARADOX/ -2011-01-31
+ STUDENTS.VAL 15:52:53.298766
+
+2221.00 /clients/client3/~dmtmp/SEED/ -2011-01-31
+ COURSES.DB 15:39:11.776780
+
+2184.00 /clients/client3/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:39:10.251764
+
+2184.00 /clients/client5/~dmtmp/WORD/ -2011-01-31
+ BASEMACH.DOC 15:39:09.336572 </programlisting>This command will initiate a dd for the specified count and block size and measures the
+corresponding throughput.
+</para>
+ <para><emphasis role="bold">To view list of read performance on each brick</emphasis>
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>View list of read performance on each brick using the following command:
+</para>
+ <para><command># gluster volume top <replaceable>VOLNAME</replaceable> read-perf [bs <replaceable>blk-size</replaceable> count <replaceable>count</replaceable>] [brick <replaceable>BRICK-NAME</replaceable>] [list-cnt <replaceable>cnt</replaceable>]</command>
+</para>
+ <para>For example, to view read performance on brick server:/export/ of test-volume, 256 block size
+of count 1, and list count 10:
+</para>
+ <para><command># gluster volume top <replaceable>test-volume</replaceable> read-perf bs 256 count 1 brick <replaceable>server:/export/ </replaceable>list-cnt <replaceable>10</replaceable></command></para>
+ <para><computeroutput>Brick: server:/export/dir1 256 bytes (256 B) copied, Throughput: 4.1 MB/s </computeroutput></para>
+ <programlisting> ==========Read throughput file stats========
+
+read filename Time
+through
+put(MBp
+s)
+
+2912.00 /clients/client0/~dmtmp/PWRPNT/ -2011-01-31
+ TRIDOTS.POT 15:38:36.896486
+
+2570.00 /clients/client0/~dmtmp/PWRPNT/ -2011-01-31
+ PCBENCHM.PPT 15:38:39.815310
+
+2383.00 /clients/client2/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:52:53.631499
+
+2340.00 /clients/client0/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:38:36.926198
+
+2299.00 /clients/client0/~dmtmp/SEED/ -2011-01-31
+ LARGE.FIL 15:38:36.930445
+
+2259.00 /clients/client0/~dmtmp/PARADOX/ -2011-01-31
+ COURSES.X04 15:38:40.549919
+
+2221.00 /clients/client9/~dmtmp/PARADOX/ -2011-01-31
+ STUDENTS.VAL 15:52:53.298766
+
+2221.00 /clients/client8/~dmtmp/PARADOX/ -2011-01-31
+ COURSES.DB 15:39:11.776780
+
+2184.00 /clients/client3/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:39:10.251764
+
+2184.00 /clients/client5/~dmtmp/WORD/ -2011-01-31
+ BASEMACH.DOC 15:39:09.336572
+ </programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="chap-Administration_Guide-Monitor_Workload-Top-Write_Perf">
+ <title>Viewing List of Write Performance on each Brick </title>
+ <para>You can view list of write throughput of files on each brick. If brick name is not specified, then the
+metrics of all the bricks belonging to that volume will be displayed. The output will be the write
+throughput.
+</para>
+ <para>This command will initiate a dd for the specified count and block size and measures the
+corresponding throughput.
+To view list of write performance on each brick:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>View list of write performance on each brick using the following command:
+</para>
+ <para><command># gluster volume top <replaceable>VOLNAME</replaceable> write-perf [bs <replaceable>blk-size</replaceable> count <replaceable>count</replaceable>] [brick <replaceable>BRICK-NAME</replaceable>] [list-cnt <replaceable>cnt</replaceable>] </command></para>
+ <para>For example, to view write performance on brick <replaceable>server:/export/</replaceable> of <replaceable>test-volume</replaceable>, 256 block size
+of count 1, and list count 10:
+</para>
+ <para><command># gluster volume top <replaceable>test-volume</replaceable> write-perf bs 256 count 1 brick <replaceable>server:/export/ </replaceable>list-cnt <replaceable>10</replaceable></command></para>
+ <para><code>Brick</code>: <replaceable>server:/export/dir1</replaceable>
+</para>
+ <para><code>256 bytes (256 B) copied, Throughput: 2.8 MB/s </code><programlisting> ==========Write throughput file stats========
+
+write filename Time
+throughput
+(MBps)
+
+1170.00 /clients/client0/~dmtmp/SEED/ -2011-01-31
+ SMALL.FIL 15:39:09.171494
+
+1008.00 /clients/client6/~dmtmp/SEED/ -2011-01-31
+ LARGE.FIL 15:39:09.73189
+
+949.00 /clients/client0/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:38:36.927426
+
+936.00 /clients/client0/~dmtmp/SEED/ -2011-01-31
+ LARGE.FIL 15:38:36.933177
+897.00 /clients/client5/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:39:09.33628
+
+897.00 /clients/client6/~dmtmp/SEED/ -2011-01-31
+ MEDIUM.FIL 15:39:09.27713
+
+885.00 /clients/client0/~dmtmp/SEED/ -2011-01-31
+ SMALL.FIL 15:38:36.924271
+
+528.00 /clients/client5/~dmtmp/SEED/ -2011-01-31
+ LARGE.FIL 15:39:09.81893
+
+516.00 /clients/client6/~dmtmp/ACCESS/ -2011-01-31
+ FASTENER.MDB 15:39:01.797317
+</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="sect-Administration_Guide-Monitor_Workload-Displaying_Volume_Information">
+ <title>Displaying Volume Information </title>
+ <para>You can display information about a specific volume, or all volumes, as needed.</para>
+ <para><emphasis role="bold">To display volume information </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Display information about a specific volume using the following command:</para>
+ <para><command># gluster volume info </command><varname>VOLNAME</varname></para>
+ <para>For example, to display information about test-volume:</para>
+ <para><programlisting># gluster volume info test-volume
+Volume Name: test-volume
+Type: Distribute
+Status: Created
+Number of Bricks: 4
+Bricks:
+Brick1: server1:/exp1
+Brick2: server2:/exp2
+Brick3: server3:/exp3
+Brick4: server4:/exp4</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Display information about all volumes using the following command:</para>
+ <para><command># gluster volume info all</command></para>
+ <para><programlisting># gluster volume info all
+
+Volume Name: test-volume
+Type: Distribute
+Status: Created
+Number of Bricks: 4
+Bricks:
+Brick1: server1:/exp1
+Brick2: server2:/exp2
+Brick3: server3:/exp3
+Brick4: server4:/exp4
+
+Volume Name: mirror
+Type: Distributed-Replicate
+Status: Started
+Number of Bricks: 2 X 2 = 4
+Bricks:
+Brick1: server1:/brick1
+Brick2: server2:/brick2
+Brick3: server3:/brick3
+Brick4: server4:/brick4
+
+Volume Name: Vol
+Type: Distribute
+Status: Started
+Number of Bricks: 1
+Bricks:
+Brick: server:/brick6
+
+</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="sect-Administration_Guide-Monitor_Workload-Performing_Statedump">
+ <title>Performing Statedump on a Volume </title>
+ <para>Statedump is a mechanism through which you can get details of all internal variables and state of the glusterfs process at the time of issuing the command.You can perform statedumps of the brick processes and nfs server process of a volume using the statedump command. The following options can be used to determine what information is to be dumped:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">mem</emphasis> - Dumps the memory usage and memory pool details of the bricks.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">iobuf</emphasis> - Dumps iobuf details of the bricks.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">priv</emphasis> - Dumps private information of loaded translators.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">callpool</emphasis> - Dumps the pending calls of the volume.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">fd</emphasis> - Dumps the open fd tables of the volume.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">inode</emphasis> - Dumps the inode tables of the volume.</para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">To display volume statedump </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Display statedump of a volume or NFS server using the following command:</para>
+ <para> <command># gluster volume statedump <replaceable>VOLNAME</replaceable> [nfs] [all|mem|iobuf|callpool|priv|fd|inode]</command></para>
+ <para>For example, to display statedump of test-volume:</para>
+ <para><programlisting># gluster volume statedump test-volume
+Volume statedump successful</programlisting></para>
+ <para>The statedump files are created on the brick servers in the<filename> /tmp</filename> directory or in the directory set using <command>server.statedump-path</command> volume option. The naming convention of the dump file is <filename>&lt;brick-path&gt;.&lt;brick-pid&gt;.dump</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>By defult, the output of the statedump is stored at <filename> /tmp/&lt;brickname.PID.dump&gt;</filename> file on that particular server. Change the directory of the statedump file using the following command:</para>
+ <para><command># gluster volume set <replaceable>VOLNAME</replaceable> server.statedump-path <replaceable>path</replaceable></command></para>
+ <para>For example, to change the location of the statedump file of test-volume:</para>
+ <para><programlisting># gluster volume set test-volume server.statedump-path /usr/local/var/log/glusterfs/dumps/
+Set volume successful</programlisting></para>
+ <para>You can view the changed path of the statedump file using the following command:</para>
+ <para><command># gluster volume info <replaceable>VOLNAME</replaceable></command></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="sect-Administration_Guide-Monitor_Workload-Displaying_Volume_Status">
+ <title>Displaying Volume Status </title>
+ <para>You can display the status information about a specific volume, brick or all volumes, as needed. Status information can be used to understand the current status of the brick, nfs processes, and overall file system. Status information can also be used to monitor and debug the volume information. You can view status of the volume along with the following details:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">detail</emphasis> - Displays additional information about the bricks.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">clients</emphasis> - Displays the list of clients connected to the volume.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">mem</emphasis> - Displays the memory usage and memory pool details of the bricks.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">inode</emphasis> - Displays the inode tables of the volume.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">fd</emphasis> - Displays the open fd (file descriptors) tables of the volume.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">callpool</emphasis> - Displays the pending calls of the volume.</para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">To display volume status </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Display information about a specific volume using the following command:</para>
+ <para><command># gluster volume status [all|<replaceable>VOLNAME</replaceable> [<replaceable>BRICKNAME</replaceable>]] [detail|clients|mem|inode|fd|callpool]</command> </para>
+ <para>For example, to display information about test-volume:</para>
+ <para><programlisting># gluster volume status test-volume
+STATUS OF VOLUME: test-volume
+BRICK PORT ONLINE PID
+--------------------------------------------------------
+arch:/export/1 24009 Y 22445
+--------------------------------------------------------
+arch:/export/2 24010 Y 22450</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Display information about all volumes using the following command:</para>
+ <para><command># gluster volume status all</command>
+</para>
+ <para><programlisting># gluster volume status all
+STATUS OF VOLUME: volume-test
+BRICK PORT ONLINE PID
+--------------------------------------------------------
+arch:/export/4 24010 Y 22455
+
+STATUS OF VOLUME: test-volume
+BRICK PORT ONLINE PID
+--------------------------------------------------------
+arch:/export/1 24009 Y 22445
+--------------------------------------------------------
+arch:/export/2 24010 Y 22450</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Display additional information about the bricks using the following command:</para>
+ <para><command># gluster volume status <replaceable>VOLNAME</replaceable> detail</command>
+</para>
+ <para>For example, to display additional information about the bricks of test-volume:</para>
+ <para><programlisting># gluster volume status test-volume details
+STATUS OF VOLUME: test-volume
+-------------------------------------------
+Brick : arch:/export/1
+Port : 24009
+Online : Y
+Pid : 16977
+File System : rootfs
+Device : rootfs
+Mount Options : rw
+Disk Space Free : 13.8GB
+Total Disk Space : 46.5GB
+Inode Size : N/A
+Inode Count : N/A
+Free Inodes : N/A
+
+Number of Bricks: 1
+Bricks:
+Brick: server:/brick6</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Display the list of clients accessing the volumes using the following command:</para>
+ <para><command># gluster volume status <replaceable>VOLNAME</replaceable> clients</command>
+</para>
+ <para>For example, to display the list of clients connected to test-volume:</para>
+ <para><programlisting># gluster volume status test-volume clients
+Brick : arch:/export/1
+Clients connected : 2
+Hostname Bytes Read BytesWritten
+-------- --------- ------------
+127.0.0.1:1013 776 676
+127.0.0.1:1012 50440 51200</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Display the memory usage and memory pool details of the bricks using the following command:</para>
+ <para><command># gluster volume status <replaceable>VOLNAME</replaceable> mem</command>
+</para>
+ <para>For example, to display the memory usage and memory pool details of the bricks of test-volume:</para>
+ <screen>Memory status for volume : test-volume
+----------------------------------------------
+Brick : arch:/export/1
+Mallinfo
+--------
+Arena : 434176
+Ordblks : 2
+Smblks : 0
+Hblks : 12
+Hblkhd : 40861696
+Usmblks : 0
+Fsmblks : 0
+Uordblks : 332416
+Fordblks : 101760
+Keepcost : 100400
+
+Mempool Stats
+-------------
+Name HotCount ColdCount PaddedSizeof AllocCount MaxAlloc
+---- -------- --------- ------------ ---------- --------
+test-volume-server:fd_t 0 16384 92 57 5
+test-volume-server:dentry_t 59 965 84 59 59
+test-volume-server:inode_t 60 964 148 60 60
+test-volume-server:rpcsvc_request_t 0 525 6372 351 2
+glusterfs:struct saved_frame 0 4096 124 2 2
+glusterfs:struct rpc_req 0 4096 2236 2 2
+glusterfs:rpcsvc_request_t 1 524 6372 2 1
+glusterfs:call_stub_t 0 1024 1220 288 1
+glusterfs:call_stack_t 0 8192 2084 290 2
+glusterfs:call_frame_t 0 16384 172 1728 6</screen>
+ </listitem>
+ <listitem>
+ <para>Display the inode tables of the volume using the following command:</para>
+ <para><command># gluster volume status <replaceable>VOLNAME</replaceable> inode</command>
+</para>
+ <para>For example, to display the inode tables of the test-volume:</para>
+ <para><programlisting># gluster volume status test-volume inode
+inode tables for volume test-volume
+----------------------------------------------
+Brick : arch:/export/1
+Active inodes:
+GFID Lookups Ref IA type
+---- ------- --- -------
+6f3fe173-e07a-4209-abb6-484091d75499 1 9 2
+370d35d7-657e-44dc-bac4-d6dd800ec3d3 1 1 2
+
+LRU inodes:
+GFID Lookups Ref IA type
+---- ------- --- -------
+80f98abe-cdcf-4c1d-b917-ae564cf55763 1 0 1
+3a58973d-d549-4ea6-9977-9aa218f233de 1 0 1
+2ce0197d-87a9-451b-9094-9baa38121155 1 0 2</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Display the open fd tables of the volume using the following command:</para>
+ <para><command># gluster volume status <replaceable>VOLNAME</replaceable> fd</command>
+</para>
+ <para>For example, to display the open fd tables of the test-volume:</para>
+ <para><screen># gluster volume status test-volume fd
+
+FD tables for volume test-volume
+----------------------------------------------
+Brick : arch:/export/1
+Connection 1:
+RefCount = 0 MaxFDs = 128 FirstFree = 4
+FD Entry PID RefCount Flags
+-------- --- -------- -----
+0 26311 1 2
+1 26310 3 2
+2 26310 1 2
+3 26311 3 2
+
+Connection 2:
+RefCount = 0 MaxFDs = 128 FirstFree = 0
+No open fds
+
+Connection 3:
+RefCount = 0 MaxFDs = 128 FirstFree = 0
+No open fds</screen></para>
+ </listitem>
+ <listitem>
+ <para>Display the pending calls of the volume using the following command:</para>
+ <para><command># gluster volume status <replaceable>VOLNAME</replaceable> callpool</command>
+</para>
+ <para>Each call has a call stack containing call frames.</para>
+ <para>For example, to display the pending calls of test-volume:</para>
+ <para><programlisting># gluster volume status test-volume
+
+Pending calls for volume test-volume
+----------------------------------------------
+Brick : arch:/export/1
+Pending calls: 2
+Call Stack1
+ UID : 0
+ GID : 0
+ PID : 26338
+ Unique : 192138
+ Frames : 7
+ Frame 1
+ Ref Count = 1
+ Translator = test-volume-server
+ Completed = No
+ Frame 2
+ Ref Count = 0
+ Translator = test-volume-posix
+ Completed = No
+ Parent = test-volume-access-control
+ Wind From = default_fsync
+ Wind To = FIRST_CHILD(this)-&gt;fops-&gt;fsync
+ Frame 3
+ Ref Count = 1
+ Translator = test-volume-access-control
+ Completed = No
+ Parent = repl-locks
+ Wind From = default_fsync
+ Wind To = FIRST_CHILD(this)-&gt;fops-&gt;fsync
+ Frame 4
+ Ref Count = 1
+ Translator = test-volume-locks
+ Completed = No
+ Parent = test-volume-io-threads
+ Wind From = iot_fsync_wrapper
+ Wind To = FIRST_CHILD (this)-&gt;fops-&gt;fsync
+ Frame 5
+ Ref Count = 1
+ Translator = test-volume-io-threads
+ Completed = No
+ Parent = test-volume-marker
+ Wind From = default_fsync
+ Wind To = FIRST_CHILD(this)-&gt;fops-&gt;fsync
+ Frame 6
+ Ref Count = 1
+ Translator = test-volume-marker
+ Completed = No
+ Parent = /export/1
+ Wind From = io_stats_fsync
+ Wind To = FIRST_CHILD(this)-&gt;fops-&gt;fsync
+ Frame 7
+ Ref Count = 1
+ Translator = /export/1
+ Completed = No
+ Parent = test-volume-server
+ Wind From = server_fsync_resume
+ Wind To = bound_xl-&gt;fops-&gt;fsync</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_setting_volumes.xml b/doc/admin-guide/en-US/admin_setting_volumes.xml
new file mode 100644
index 000000000..051fb723a
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_setting_volumes.xml
@@ -0,0 +1,325 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Administration_Guide-Setting_Volumes">
+ <title>Setting up GlusterFS Server Volumes</title>
+ <para>A volume is a logical collection of bricks where each brick is an export directory on a server in the trusted storage pool. Most of the gluster management operations are performed on the volume. </para>
+ <para>To create a new volume in your storage environment, specify the bricks that comprise the volume. After you have created a new volume, you must start it before attempting to mount it. </para>
+ <itemizedlist>
+ <listitem>
+ <para>Volumes of the following types can be created in your storage environment: </para>
+ <itemizedlist>
+ <listitem>
+ <para>Distributed - Distributed volumes distributes files throughout the bricks in the volume. You can use distributed volumes where the requirement is to scale storage and the redundancy is either not important or is provided by other hardware/software layers. For more information, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Distributed"/> .</para>
+ </listitem>
+ <listitem>
+ <para>Replicated – Replicated volumes replicates files across bricks in the volume. You can use replicated volumes in environments where high-availability and high-reliability are critical. For more information, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Replicated"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Striped – Striped volumes stripes data across bricks in the volume. For best results, you should use striped volumes only in high concurrency environments accessing very large files. For more information, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Striped"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Distributed Striped - Distributed striped volumes stripe data across two or more nodes in the cluster. You should use distributed striped volumes where the requirement is to scale storage and in high concurrency environments accessing very large files is critical. For more information, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Distributed_Striped"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Distributed Replicated - Distributed replicated volumes distributes files across replicated bricks in the volume. You can use distributed replicated volumes in environments where the requirement is to scale storage and high-reliability is critical. Distributed replicated volumes also offer improved read performance in most environments. For more information, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Distributed_Replicated"/>. </para>
+ </listitem>
+ <listitem>
+ <para>Distributed Striped Replicated – Distributed striped replicated volumes distributes striped data across replicated bricks in the cluster. For best results, you should use distributed striped replicated volumes in highly concurrent environments where parallel access of very large files and performance is critical. In this release, configuration of this volume type is supported only for Map Reduce workloads. For more information, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Distributed_Striped_Replicated"/>.
+</para>
+ </listitem>
+ <listitem>
+ <para>Striped Replicated – Striped replicated volumes stripes data across replicated bricks in the cluster. For best results, you should use striped replicated volumes in highly concurrent environments where there is parallel access of very large files and performance is critical. In this release, configuration of this volume type is supported only for Map Reduce workloads. For more
+information, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Striped_Replicated"/>.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">To create a new volume </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Create a new volume :</para>
+ <para><command># gluster volume create<replaceable> NEW-VOLNAME</replaceable> [stripe <replaceable>COUNT</replaceable> | replica <replaceable>COUNT</replaceable>] [transport [tcp | rdma | tcp,rdma]] <replaceable>NEW-BRICK1 NEW-BRICK2 NEW-BRICK3...</replaceable></command></para>
+ <para>For example, to create a volume called test-volume consisting of server3:/exp3 and server4:/exp4:</para>
+ <para><programlisting># gluster volume create test-volume server3:/exp3 server4:/exp4
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ <section id="sect-Administration_Guide-Setting_Volumes-Distributed">
+ <title>Creating Distributed Volumes</title>
+ <para>In a distributed volumes files are spread randomly across the bricks in the volume. Use distributed volumes where you need to scale storage and redundancy is either not important or is provided by other hardware/software layers. </para>
+ <para><note>
+ <para>Disk/server failure in distributed volumes can result in a serious loss of data because directory contents are spread randomly across the bricks in the volume. </para>
+ </note></para>
+ <figure>
+ <title>Illustration of a Distributed Volume</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Distributed_Volume.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para><emphasis role="bold">To create a distributed volume</emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Create a trusted storage pool as described earlier in <xref linkend="sect-Administration_Guide-Storage_Pools-Adding_Servers"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Create the distributed volume:</para>
+ <para><command># gluster volume create <replaceable>NEW-VOLNAME</replaceable> [transport [tcp | rdma | tcp,rdma]] <replaceable>NEW-BRICK...</replaceable></command></para>
+ <para>For example, to create a distributed volume with four storage servers using tcp:</para>
+ <para><programlisting># gluster volume create test-volume server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>(Optional) You can display the volume information:</para>
+ <para><programlisting># gluster volume info
+Volume Name: test-volume
+Type: Distribute
+Status: Created
+Number of Bricks: 4
+Transport-type: tcp
+Bricks:
+Brick1: server1:/exp1
+Brick2: server2:/exp2
+Brick3: server3:/exp3
+Brick4: server4:/exp4</programlisting></para>
+ <para>For example, to create a distributed volume with four storage servers over InfiniBand:</para>
+ <para><programlisting># gluster volume create test-volume transport rdma server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>If the transport type is not specified, <emphasis role="italic"> tcp</emphasis> is used as the default. You can also set additional options if required, such as auth.allow or auth.reject. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/></para>
+ <para><note>
+ <para>Make sure you start your volumes before you try to mount them or else client operations after the mount will hang, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Starting"/> for details. </para>
+ </note></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Setting_Volumes-Replicated">
+ <title>Creating Replicated Volumes </title>
+ <para>Replicated volumes create copies of files across multiple bricks in the volume. You can use replicated volumes in environments where high-availability and high-reliability are critical. </para>
+ <para><note>
+ <para>The number of bricks should be equal to of the replica count for a replicated volume.
+To protect against server and disk failures, it is recommended that the bricks of the volume are from different servers. </para>
+ </note></para>
+ <figure>
+ <title>Illustration of a Replicated Volume</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Replicated_Volume.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para><emphasis role="bold">To create a replicated volume </emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Create a trusted storage pool as described earlier in <xref linkend="sect-Administration_Guide-Storage_Pools-Adding_Servers"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Create the replicated volume:</para>
+ <para><command># gluster volume create <replaceable>NEW-VOLNAME</replaceable> [replica <replaceable>COUNT</replaceable>] [transport [tcp | rdma | tcp,rdma]] <replaceable>NEW-BRICK...</replaceable></command></para>
+ <para>For example, to create a replicated volume with two storage servers:</para>
+ <para><programlisting># gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>If the transport type is not specified, <emphasis role="italic"> tcp</emphasis> is used as the default. You can also set additional options if required, such as auth.allow or auth.reject. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/></para>
+ <para><note>
+ <para>Make sure you start your volumes before you try to mount them or else client operations after the mount will hang, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Starting"/> for details. </para>
+ </note></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Setting_Volumes-Striped">
+ <title>Creating Striped Volumes</title>
+ <para>Striped volumes stripes data across bricks in the volume. For best results, you should use striped volumes only in high concurrency environments accessing very large files.</para>
+ <para><note>
+ <para>The number of bricks should be a equal to the stripe count for a striped volume. </para>
+ </note></para>
+ <figure>
+ <title>Illustration of a Striped Volume</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Striped_Volume.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para><emphasis role="bold">To create a striped volume </emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Create a trusted storage pool as described earlier in <xref linkend="sect-Administration_Guide-Storage_Pools-Adding_Servers"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Create the striped volume:</para>
+ <para><command># gluster volume create <replaceable>NEW-VOLNAME</replaceable> [stripe <replaceable>COUNT</replaceable>] [transport [tcp | rdma | tcp,rdma]] <replaceable>NEW-BRICK...</replaceable></command></para>
+ <para>For example, to create a striped volume across two storage servers:</para>
+ <para><programlisting># gluster volume create test-volume stripe 2 transport tcp server1:/exp1 server2:/exp2
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>If the transport type is not specified, <emphasis role="italic"> tcp</emphasis> is used as the default. You can also set additional options if required, such as auth.allow or auth.reject. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/></para>
+ <para><note>
+ <para>Make sure you start your volumes before you try to mount them or else client operations after the mount will hang, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Starting"/> for details. </para>
+ </note></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Setting_Volumes-Distributed_Striped">
+ <title>Creating Distributed Striped Volumes </title>
+ <para>Distributed striped volumes stripes files across two or more nodes in the cluster. For best results, you should use distributed striped volumes where the requirement is to scale storage and in high concurrency environments accessing very large files is critical.</para>
+ <para><note>
+ <para>The number of bricks should be a multiple of the stripe count for a distributed striped volume. </para>
+ </note></para>
+ <figure>
+ <title>Illustration of a Distributed Striped Volume</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Distributed_Striped_Volume.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para><emphasis role="bold">To create a distributed striped volume </emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Create a trusted storage pool as described earlier in <xref linkend="sect-Administration_Guide-Storage_Pools-Adding_Servers"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Create the distributed striped volume:</para>
+ <para><command># gluster volume create <replaceable>NEW-VOLNAME</replaceable> [stripe <replaceable>COUNT</replaceable>] [transport [tcp | rdma | tcp,rdma]] <replaceable>NEW-BRICK...</replaceable></command></para>
+ <para>For example, to create a distributed striped volume across eight storage servers:</para>
+ <para><programlisting># gluster volume create test-volume stripe 4 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4 server5:/exp5 server6:/exp6 server7:/exp7 server8:/exp8
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>If the transport type is not specified, <emphasis role="italic"> tcp</emphasis> is used as the default. You can also set additional options if required, such as auth.allow or auth.reject. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/></para>
+ <para><note>
+ <para>Make sure you start your volumes before you try to mount them or else client operations after the mount will hang, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Starting"/> for details. </para>
+ </note></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Setting_Volumes-Distributed_Replicated">
+ <title>Creating Distributed Replicated Volumes </title>
+ <para>Distributes files across replicated bricks in the volume. You can use distributed replicated volumes in environments where the requirement is to scale storage and high-reliability is critical. Distributed replicated volumes also offer improved read performance in most environments.</para>
+ <para><note>
+ <para>The number of bricks should be a multiple of the replica count for a distributed replicated volume. Also, the order in which bricks are specified has a great effect on data protection. Each replica_count consecutive bricks in the list you give will form a replica set, with all replica sets combined into a volume-wide distribute set. To make sure that replica-set members are not placed on the same node, list the first brick on every server, then the second brick on every server in the same order, and so on. </para>
+ </note></para>
+ <figure>
+ <title>Illustration of a Distributed Replicated Volume</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Distributed_Replicated_Volume.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para><emphasis role="bold">To create a distributed replicated volume </emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Create a trusted storage pool as described earlier in <xref linkend="sect-Administration_Guide-Storage_Pools-Adding_Servers"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Create the distributed replicated volume:</para>
+ <para><command># gluster volume create <replaceable>NEW-VOLNAME</replaceable> [replica <replaceable>COUNT</replaceable>] [transport [tcp | rdma | tcp,rdma]] <replaceable>NEW-BRICK...</replaceable></command></para>
+ <para>For example, four node distributed (replicated) volume with a two-way mirror:
+</para>
+ <para><programlisting># gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>For example, to create a six node distributed (replicated) volume with a two-way mirror:</para>
+ <para><programlisting># gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4 server5:/exp5 server6:/exp6
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>If the transport type is not specified, <emphasis role="italic"> tcp</emphasis> is used as the default. You can also set additional options if required, such as auth.allow or auth.reject. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/></para>
+ <para><note>
+ <para>Make sure you start your volumes before you try to mount them or else client operations after the mount will hang, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Starting"/> for details. </para>
+ </note></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Setting_Volumes-Distributed_Striped_Replicated">
+ <title>Creating Distributed Striped Replicated Volumes </title>
+ <para>Distributed striped replicated volumes distributes striped data across replicated bricks in the cluster. For best results, you should use distributed striped replicated volumes in highly concurrent environments where parallel access of very large files and performance is critical. In this release, configuration of this volume type is supported only for Map Reduce workloads. </para>
+ <para><note>
+ <para>The number of bricks should be a multiples of number of stripe count and replica count for
+a distributed striped replicated volume.
+ </para>
+ </note></para>
+ <para><emphasis role="bold">To create a distributed striped replicated volume</emphasis>
+</para>
+ <orderedlist>
+ <listitem>
+ <para>Create a trusted storage pool as described earlier in <xref linkend="sect-Administration_Guide-Storage_Pools-Adding_Servers"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Create a distributed striped replicated volume using the following command:</para>
+ <para><command># gluster volume create <replaceable>NEW-VOLNAME</replaceable> [stripe <replaceable>COUNT</replaceable>] [replica <replaceable>COUNT</replaceable>] [transport [tcp | rdma | tcp,rdma]] <replaceable>NEW-BRICK...</replaceable></command></para>
+ <para>For example, to create a distributed replicated striped volume across eight storage servers:
+</para>
+ <para><programlisting># gluster volume create test-volume stripe 2 replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4 server5:/exp5 server6:/exp6 server7:/exp7 server8:/exp8
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>If the transport type is not specified, <emphasis role="italic"> tcp</emphasis> is used as the default. You can also set additional options if required, such as auth.allow or auth.reject. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/></para>
+ <para><note>
+ <para>Make sure you start your volumes before you try to mount them or else client operations after the mount will hang, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Starting"/> for details. </para>
+ </note></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Setting_Volumes-Striped_Replicated">
+ <title>Creating Striped Replicated Volumes </title>
+ <para>Striped replicated volumes stripes data across replicated bricks in the cluster. For best results, you should use striped replicated volumes in highly concurrent environments where there is parallel access of very large files and performance is critical. In this release, configuration of this volume type is supported only for Map Reduce workloads.</para>
+ <para><note>
+ <para>The number of bricks should be a multiple of the replicate count and stripe count for a
+striped replicated volume.
+</para>
+ </note></para>
+ <figure>
+ <title>Illustration of a Striped Replicated Volume</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Striped_Replicated_Volume.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para><emphasis role="bold">To create a striped replicated volume</emphasis>
+</para>
+ <orderedlist>
+ <listitem>
+ <para>Create a trusted storage pool consisting of the storage servers that will comprise the volume.</para>
+ <para>For more information, see <xref linkend="sect-Administration_Guide-Storage_Pools-Adding_Servers"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Create a striped replicated volume :</para>
+ <para><command># gluster volume create <replaceable>NEW-VOLNAME</replaceable> [stripe <replaceable>COUNT</replaceable>] [replica <replaceable>COUNT</replaceable>] [transport [tcp | rdma | tcp,rdma]] <replaceable>NEW-BRICK...</replaceable></command></para>
+ <para>For example, to create a striped replicated volume across four storage servers:
+
+</para>
+ <para><programlisting># gluster volume create test-volume stripe 2 replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>To create a striped replicated volume across six storage servers:
+</para>
+ <para><programlisting># gluster volume create test-volume stripe 3 replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4 server5:/exp5 server6:/exp6
+Creation of test-volume has been successful
+Please start the volume to access data.</programlisting></para>
+ <para>If the transport type is not specified, <emphasis role="italic"> tcp</emphasis> is used as the default. You can also set additional options if required, such as auth.allow or auth.reject. For more information, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/></para>
+ <para><note>
+ <para>Make sure you start your volumes before you try to mount them or else client operations after the mount will hang, see <xref linkend="sect-Administration_Guide-Setting_Volumes-Starting"/> for details. </para>
+ </note></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sect-Administration_Guide-Setting_Volumes-Starting">
+ <title>Starting Volumes </title>
+ <para>You must start your volumes before you try to mount them. </para>
+ <para><emphasis role="bold">To start a volume </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Start a volume:</para>
+ <para><command># gluster volume start <replaceable>VOLNAME</replaceable></command></para>
+ <para>For example, to start test-volume:</para>
+ <para><programlisting># gluster volume start test-volume
+Starting test-volume has been successful</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_settingup_clients.xml b/doc/admin-guide/en-US/admin_settingup_clients.xml
new file mode 100644
index 000000000..382319d07
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_settingup_clients.xml
@@ -0,0 +1,412 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Administration_Guide-GlusterFS_Client">
+ <title>Accessing Data - Setting Up GlusterFS Client</title>
+ <para>Gluster volumes can be accessed in multiple ways. One can use Gluster Native Client method for high concurrency, performance and transparent failover in GNU/Linux clients. Gluster exports volumes using NFS v3 protocol too.</para>
+ <para>CIFS can also be used to access volumes by exporting the Gluster Native mount point as a samba export.</para>
+ <section id="sect-Administration_Guide-GlusterFS_Client-Native">
+ <title>Gluster Native Client</title>
+ <para>The Gluster Native Client is a FUSE-based client running in user space. Gluster Native Client is the recommended method for accessing volumes if all the clustered features of GlusterFS has to be utilized.</para>
+ <para>This section introduces the Gluster Native Client and explains how to install the software on client machines. This section also describes how to mount volumes on clients (both manually and automatically). </para>
+ <section>
+ <title>Installing the Gluster Native Client</title>
+ <para>Gluster Native Client has a dependancy on FUSE module. To make sure FUSE module is loaded, execute below commands: </para>
+ <orderedlist>
+ <listitem>
+ <para>Add the FUSE loadable kernel module (LKM) to the Linux kernel:</para>
+ <para><command># modprobe fuse</command></para>
+ </listitem>
+ <listitem>
+ <para>Verify that the FUSE module is loaded:</para>
+ <para><command># dmesg | grep -i fuse </command></para>
+ <para><command>fuse init (API version 7.13)</command></para>
+ </listitem>
+ </orderedlist>
+ <section id="sect-Administration_Guide-GlusterFS_Client-Native-RPM">
+ <title>Installing on RPM Based Distributions </title>
+ <para>To install Gluster Native Client on RPM distribution-based systems</para>
+ <orderedlist>
+ <listitem>
+ <para>Install required prerequisites on the client using the following command:</para>
+ <para><command>$ sudo yum -y install fuse fuse-libs</command></para>
+ </listitem>
+ <listitem>
+ <para>Download the latest glusterfs, glusterfs-fuse RPM files on each client. The glusterfs package contains the GlusterFS Binary and required libraries. The glusterfs-fuse package contains the FUSE plugin (in GlusterFS terms, its called Translator) required for mounting.</para>
+ <para><note><para>Install 'glusterfs-rdma' RPM if RDMA support is required. 'glusterfs-rdma' contains RDMA transport module for Infiniband interconnect.</para></note></para>
+ <para>You can download the software at <ulink url="http://bits.gluster.com/gluster/glusterfs/3.3.0/x86_64/"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Install Gluster Native Client on the client.</para>
+ <para><command>$ sudo rpm -i glusterfs-3.3.0-1.x86_64.rpm </command></para>
+ <para><command>$ sudo rpm -i glusterfs-fuse-3.3.0-1.x86_64.rpm </command></para>
+ <para><command>$ sudo rpm -i glusterfs-rdma-3.3.0-1.x86_64.rpm</command></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section condition="gfs">
+ <title>Installing on Debian-based Distributions</title>
+ <para>To install Gluster Native Client on Debian-based distributions</para>
+ <orderedlist>
+ <listitem>
+ <para>Download the latest GlusterFS .deb file.</para>
+ <para>You can download the software at <ulink url="http://www.gluster.org/download/"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Uninstall GlusterFS v3.1.x/v3.2.x (or an earlier version) from the client using the following command:
+</para>
+ <para><command>$ sudo dpkg -r glusterfs </command></para>
+ <para>(Optional) Run <command>$ sudo dpkg -purge glusterfs </command>to purge the configuration files.</para>
+ </listitem>
+ <listitem>
+ <para>Install Gluster Native Client on the client using the following command:
+</para>
+ <para><command>$ sudo dpkg -i glusterfs-$version.deb </command></para>
+ <para>For example:
+</para>
+ <para><command>$ sudo dpkg -i glusterfs-3.3.0.deb </command></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>Performing a Source Installation</title>
+ <para>To build and install Gluster Native Client from the source code</para>
+ <orderedlist>
+ <listitem>
+ <para>Create a new directory using the following commands:</para>
+ <para><command># mkdir glusterfs </command></para>
+ <para><command># cd glusterfs</command></para>
+ </listitem>
+ <listitem>
+ <para>Download the source code.</para>
+ <para>You can download the source at <ulink url="http://www.gluster.org/download/"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Extract the source code using the following command:
+</para>
+ <para><command># tar -xvzf glusterfs-3.3.0.tar.gz </command></para>
+ </listitem>
+ <listitem>
+ <para>Run the configuration utility using the following command:
+</para>
+ <para><code># ./configure </code></para>
+ <para><code>...</code></para>
+ <para><code>GlusterFS configure summary </code></para>
+ <para><code>=========================== </code></para>
+ <para><code>FUSE client : yes </code></para>
+ <para><code>Infiniband verbs : yes </code></para>
+ <para><code>epoll IO multiplex : yes </code></para>
+ <para><code>argp-standalone : no </code></para>
+ <para><code>fusermount : no </code></para>
+ <para><code>readline : yes</code></para>
+ <para><note><para>The configuration summary shown above is sample, it can vary depending on other packages.</para></note></para>
+ </listitem>
+ <listitem>
+ <para>Build the Gluster Native Client software using the following commands:
+</para>
+ <para><command># make </command></para>
+ <para><command># make install</command></para>
+ </listitem>
+ <listitem>
+ <para>Verify that the correct version of Gluster Native Client is installed, using the following command:
+</para>
+ <para><command># glusterfs –-version</command></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ </section>
+ <section id="sect-Administration_Guide-GlusterFS_Client-Mounting_Volumes">
+ <title>Mounting Volumes</title>
+ <para>After installing the Gluster Native Client, you need to mount Gluster volumes to access data. There are two methods you can choose: </para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-GlusterFS_Client-Manuall"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-GlusterFS_Client-Automatic"/></para>
+ </listitem>
+ </itemizedlist>
+ <para>After mounting a volume, you can test the mounted volume using the procedure described in <xref linkend="sect-Administration_Guide-GlusterFS_Client-Testing"/>. </para>
+ <para><note>
+ <para>Server names selected during creation of Volumes should be resolvable in the client machine. You can use appropriate /etc/hosts entries or DNS server to resolve server names to IP addresses. </para>
+ </note></para>
+ <section id="sect-Administration_Guide-GlusterFS_Client-Manuall">
+ <title>Manually Mounting Volumes</title>
+ <para>To manually mount a Gluster volume </para>
+ <itemizedlist>
+ <listitem>
+ <para>To mount a volume, use the following command:
+</para>
+ <para><command># mount -t glusterfs HOSTNAME-OR-IPADDRESS:/VOLNAME MOUNTDIR</command>
+</para>
+ <para>For example:
+</para>
+ <para><command># mount -t glusterfs server1:/test-volume /mnt/glusterfs</command></para>
+ <note>
+ <para>The server specified in the mount command is only used to fetch the gluster configuration volfile describing the volume name. Subsequently, the client will communicate directly with the servers mentioned in the volfile (which might not even include the one used for mount). </para>
+ </note>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="sect-Administration_Guide-GlusterFS_Client-Automatic" dir="lro">
+ <title>Automatically Mounting Volumes</title>
+ <para><emphasis role="bold">To automatically mount a Gluster volume</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>To mount a volume, edit the /etc/fstab file and add the following line:
+</para>
+ <para><command>HOSTNAME-OR-IPADDRESS:/VOLNAME MOUNTDIR glusterfs defaults,_netdev 0 0 </command></para>
+ <para>For example:
+</para>
+ <para><code>server1:/test-volume /mnt/glusterfs glusterfs defaults,_netdev 0 0</code></para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">Mounting Options</emphasis></para>
+ <para>You can specify the following options when using the <command>mount -t glusterfs</command> command. Note that you need to separate all options with commas.</para>
+ <para>backupvolfile-server=server-name</para>
+ <para>fetch-attempts=N (where N is number of attempts)</para>
+ <para>log-level=loglevel</para>
+ <para>log-file=logfile</para>
+ <para>direct-io-mode=[enable|disable]</para>
+ <para>ro (for readonly mounts)</para>
+ <para>acl (for enabling posix-ACLs)</para>
+ <para>worm (making the mount WORM - Write Once, Read Many type)</para>
+ <para>selinux (enable selinux on GlusterFS mount)</para>
+ <para>enable-ino32 (enable to use 32-bit inodes)</para>
+ <para></para>
+ <para>For example: </para>
+ <para><code># mount -t glusterfs -o backupvolfile-server=volfile_server2,fetch-attempts=2,log-level=WARNING,log-file=/var/log/gluster.log server1:/test-volume /mnt/glusterfs</code></para>
+ <para>Using /etc/fstab, options would look like below:</para>
+ <para><code>HOSTNAME-OR-IPADDRESS:/VOLNAME MOUNTDIR glusterfs defaults,_netdev,log-level=WARNING,log-file=/var/log/gluster.log 0 0 </code></para>
+ <para>If <option>backupvolfile-server</option> option is added while mounting fuse client, when the first
+ volfile server fails, then the server specified in <option>backupvolfile-server</option> option is used as volfile server to mount the client.</para>
+ <para>In <code>fetch-attempts=N</code> option, specify the number of attempts to fetch volume files while mounting a volume. This option will be useful when round-robin DNS is configured for the server-name. </para>
+ </section>
+ </section>
+ </section>
+
+ <section id="sect-Administration_Guide-GlusterFS_Client-NFS">
+ <title>NFS</title>
+ <para>You can use NFS v3 to access to gluster volumes.</para>
+ <para>GlusterFS 3.3.0, now includes network lock manager (NLM) v4 feature too. NLM enables applications on NFSv3 clients to do record locking on files. NLM program is started automatically with the NFS server process.</para>
+ <para>This section describes how to use NFS to mount Gluster volumes (both manually and automatically). </para>
+
+ <section>
+ <title>Using NFS to Mount Volumes</title>
+ <para>You can use either of the following methods to mount Gluster volumes: </para>
+ <para><itemizedlist>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-GlusterFS_Client-NFS-Manual"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-GlusterFS_Client-NFS-Automatic"/></para>
+ </listitem>
+ </itemizedlist></para>
+ <para>After mounting a volume, you can test the mounted volume using the procedure described in <xref linkend="sect-Administration_Guide-GlusterFS_Client-Testing"/>. </para>
+
+ <section id="sect-Administration_Guide-GlusterFS_Client-NFS-Manual">
+ <title>Manually Mounting Volumes Using NFS </title>
+ <para>To manually mount a Gluster volume using NFS </para>
+ <itemizedlist>
+ <listitem>
+ <para>To mount a volume, use the following command:
+</para>
+ <para><command># mount -t nfs -o vers=3 HOSTNAME-OR-IPADDRESS:/VOLNAME MOUNTDIR</command>
+</para>
+ <para>For example:</para>
+ <para><command># mount -t nfs -o vers=3 server1:/test-volume /mnt/glusterfs</command></para>
+ <para><note>
+ <para> Gluster NFS server does not support UDP. If the NFS client you are using defaults to connecting using UDP, the following message appears: </para>
+ <para><code>requested NFS version or transport protocol is not supported</code>. </para>
+ </note></para>
+ <para><emphasis role="bold">To connect using TCP</emphasis></para>
+ </listitem>
+ <listitem>
+ <para>Add the following option to the mount command:
+</para>
+ <para><command>-o mountproto=tcp </command></para>
+ <para>For example:
+</para>
+ <para><command># mount -o mountproto=tcp,vers=3 -t nfs server1:/test-volume /mnt/glusterfs</command></para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">To mount Gluster NFS server from a Solaris client </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Use the following command:
+</para>
+ <para><command># mount -o proto=tcp,vers=3 nfs://HOSTNAME-OR-IPADDRESS:38467/VOLNAME MOUNTDIR</command></para>
+ <para>
+For example:</para>
+ <para><command> # mount -o proto=tcp,vers=3 nfs://server1:38467/test-volume /mnt/glusterfs</command></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section id="sect-Administration_Guide-GlusterFS_Client-NFS-Automatic">
+ <title>Automatically Mounting Volumes Using NFS</title>
+ <para>You can configure your system to automatically mount Gluster volumes using NFS each time the system starts.</para>
+ <para><emphasis role="bold">To automatically mount a Gluster volume using NFS </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>To mount a volume, edit the /etc/fstab file and add the following line:</para>
+ <para><command>HOSTNAME-OR-IPADDRESS:/VOLNAME MOUNTDIR nfs defaults,_netdev,vers=3 0 0</command></para>
+ <para>For example,</para>
+ <para><command>server1:/test-volume /mnt/glusterfs nfs defaults,_netdev,vers=3 0 0</command></para>
+ <para>If default transport to mount NFS is UDP, use below line in fstab</para>
+ <para><command>server1:/test-volume /mnt/glusterfs nfs defaults,_netdev,mountproto=tcp 0 0</command></para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">To automount NFS mounts</emphasis></para>
+ <para>Gluster supports *nix standard method of automounting NFS mounts. Update the /etc/auto.master and /etc/auto.misc and restart the autofs service. After that, whenever a user or process attempts to access the directory it will be mounted in the background. </para>
+ </section>
+
+ </section>
+
+ </section>
+
+ <section id="sect-Administration_Guide-GlusterFS_Client-CIFS">
+ <title>CIFS</title>
+ <para>You can use CIFS to access to volumes when using Microsoft Windows as well as SAMBA clients. For this access method, Samba packages need to be present on the client side. You can export glusterfs mount point as the samba export, and then mount it using CIFS protocol.</para>
+ <para>This section describes how to mount CIFS shares on Microsoft Windows-based clients (both manually and automatically) and how to verify that the volume has mounted successfully.</para>
+ <para><note>
+ <para> CIFS access using the Mac OS X Finder is not supported, however, you can use the Mac OS X command line to access Gluster volumes using CIFS.</para>
+ </note></para>
+
+ <section>
+ <title>Using CIFS to Mount Volumes</title>
+ <para>You can use either of the following methods to mount Gluster volumes: </para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-GlusterFS_Client-CIFS-Manual"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-GlusterFS_Client-CIFS-Automatic"/></para>
+ </listitem>
+ </itemizedlist>
+ <para>After mounting a volume, you can test the mounted volume using the procedure described in <xref linkend="sect-Administration_Guide-GlusterFS_Client-Testing"/>.</para>
+ <para>You can also use Samba for exporting Gluster Volumes through CIFS protocol.</para>
+
+ <section>
+ <title>Exporting Gluster Volumes Through Samba</title>
+ <para>We recommend you to use Samba for exporting Gluster volumes through the CIFS protocol. </para>
+ <para><emphasis role="bold">To export volumes through CIFS protocol </emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Mount a Gluster volume. For more information on mounting volumes, see <xref linkend="sect-Administration_Guide-GlusterFS_Client-Mounting_Volumes"/>.</para>
+ </listitem>
+ <listitem>
+ <para>Setup Samba configuration to export the mount point of the Gluster volume.</para>
+ <para>For example, if a Gluster volume is mounted on /mnt/gluster, you must edit smb.conf file to enable exporting this through CIFS. Open smb.conf file in an editor and add the following lines for a simple configuration:</para>
+ <para>[glustertest]
+ </para>
+ <para> comment = For testing a Gluster volume exported through CIFS
+ </para>
+ <para> path = /mnt/glusterfs
+ </para>
+ <para> read only = no
+ </para>
+ <para> guest ok = yes</para>
+ </listitem>
+ </orderedlist>
+ <para>Save the changes and start the smb service using your systems init scripts (/etc/init.d/smb [re]start).</para>
+ <para><note>
+ <para>To be able mount from any server in the trusted storage pool, you must repeat these steps on each Gluster node. For more advanced configurations, see Samba documentation. </para>
+ </note></para>
+ </section>
+
+ <section id="sect-Administration_Guide-GlusterFS_Client-CIFS-Manual">
+ <title>Manually Mounting Volumes Using CIFS </title>
+ <para>You can manually mount Gluster volumes using CIFS on Microsoft Windows-based client machines. </para>
+ <para><emphasis role="bold">To manually mount a Gluster volume using CIFS </emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Using Windows Explorer, choose <emphasis role="bold">Tools &gt; Map Network Drive…</emphasis> from the menu. The <emphasis role="bold">Map Network Drive </emphasis>window appears. </para>
+ </listitem>
+ <listitem>
+ <para>Choose the drive letter using the <emphasis role="bold">Drive</emphasis> drop-down list. </para>
+ </listitem>
+ <listitem>
+ <para>Click <emphasis role="bold">Browse</emphasis>, select the volume to map to the network drive, and click <emphasis role="bold">OK</emphasis>. </para>
+ </listitem>
+ <listitem>
+ <para>Click <emphasis role="bold">Finish.</emphasis></para>
+ </listitem>
+ </orderedlist>
+ <para>The network drive (mapped to the volume) appears in the Computer window.</para>
+ <para><emphasis role="bold">Alternatively, to manually mount a Gluster volume using CIFS.</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Click <emphasis role="bold">Start &gt; Run</emphasis> and enter the following:</para>
+ <para><command>
+ <code>\\SERVERNAME\VOLNAME</code>
+ </command></para>
+ <para>For example:</para>
+ <para><command>
+ <code>\\server1\test-volume</code>
+ </command></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section id="sect-Administration_Guide-GlusterFS_Client-CIFS-Automatic">
+ <title>Automatically Mounting Volumes Using CIFS</title>
+ <para>You can configure your system to automatically mount Gluster volumes using CIFS on Microsoft Windows-based clients each time the system starts.</para>
+ <para><emphasis role="bold">To automatically mount a Gluster volume using CIFS</emphasis></para>
+ <para>The network drive (mapped to the volume) appears in the Computer window and is reconnected each time the system starts.</para>
+ <orderedlist>
+ <listitem>
+ <para>Using Windows Explorer, choose <emphasis role="bold">Tools &gt; Map Network Drive…</emphasis> from the menu. The <emphasis role="bold">Map Network Drive </emphasis>window appears. </para>
+ </listitem>
+ <listitem>
+ <para>Choose the drive letter using the <emphasis role="bold">Drive</emphasis> drop-down list. </para>
+ </listitem>
+ <listitem>
+ <para>Click <emphasis role="bold">Browse</emphasis>, select the volume to map to the network drive, and click <emphasis role="bold">OK</emphasis>. </para>
+ </listitem>
+ <listitem>
+ <para>Click the <emphasis role="bold">Reconnect</emphasis> at logon checkbox.</para>
+ </listitem>
+ <listitem>
+ <para>Click <emphasis role="bold">Finish.</emphasis></para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ </section>
+ </section>
+ <section id="sect-Administration_Guide-GlusterFS_Client-Testing">
+ <title>Testing Mounted Volumes</title>
+ <para>To test mounted volumes</para>
+ <itemizedlist>
+ <listitem>
+ <para>Use the following command:</para>
+ <para><command># mount </command></para>
+ <para>If the gluster volume was successfully mounted, the output of the mount command on the client will be similar to this example:</para>
+ <para><code>server1:/test-volume on /mnt/glusterfs type fuse.glusterfs (rw,allow_other,default_permissions,max_read=131072</code></para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>Use the following command:</para>
+ <para><command># df -h </command></para>
+ <para>The output of df command on the client will display the aggregated storage space from all the bricks in a volume similar to this example:</para>
+ <para><code># df -h /mnt/glusterfs</code></para>
+ <para><code>Filesystem Size Used Avail Use% Mounted on </code></para>
+ <para><code>server1:/test-volume 28T 22T 5.4T 82% /mnt/glusterfs</code></para>
+ </listitem>
+ <listitem>
+ <para>Change to the directory and list the contents by entering the following:</para>
+ <para><command># cd MOUNTDIR </command></para>
+ <para><command># ls</command></para>
+ </listitem>
+ <listitem>
+ <para>For example,</para>
+ <para><code># cd /mnt/glusterfs </code></para>
+ <para><code># ls</code></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_start_stop_daemon.xml b/doc/admin-guide/en-US/admin_start_stop_daemon.xml
new file mode 100644
index 000000000..bdab0b8b6
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_start_stop_daemon.xml
@@ -0,0 +1,56 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Administration_Guide-Start_Stop_Daemon">
+ <title id="chap-Administration_Guide-Stop_Start_Daemon">Managing the glusterd Service</title>
+ <para>After installing GlusterFS, you must start glusterd service. The glusterd service serves as the Gluster elastic volume manager, overseeing glusterfs processes, and co-ordinating dynamic volume operations, such as adding and removing volumes across multiple storage servers non-disruptively.</para>
+ <para>This section describes how to start the glusterd service in the following ways: </para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Start_Stop_Daemon-Manually"/></para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="sect-Administration_Guide-Start_Stop_Daemon-Automatically"/></para>
+ </listitem>
+ </itemizedlist>
+ <note>
+ <para>You must start glusterd on all GlusterFS servers.</para>
+ </note>
+ <section id="sect-Administration_Guide-Start_Stop_Daemon-Manually">
+ <title>Starting and Stopping glusterd Manually</title>
+ <para>This section describes how to start and stop glusterd manually</para>
+ <itemizedlist>
+ <listitem>
+ <para>To start glusterd manually, enter the following command:</para>
+ <para><command># /etc/init.d/glusterd start </command></para>
+ </listitem>
+ <listitem>
+ <para>To stop glusterd manually, enter the following command: </para>
+ <para><command># /etc/init.d/glusterd stop</command></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="sect-Administration_Guide-Start_Stop_Daemon-Automatically">
+ <title>Starting glusterd Automatically</title>
+ <para condition="gfs">This section describes how to configure the system to automatically start the glusterd service every time the system boots. </para>
+ <para condition="appliance">To automatically start the glusterd service every time the system boots, enter the following from the command line: </para>
+ <para condition="appliance"><command># chkconfig glusterd on </command></para>
+ <section condition="gfs">
+ <title condition="gfs">Red Hat-based Systems</title>
+ <para>To configure Red Hat-based systems to automatically start the glusterd service every time the system boots, enter the following from the command line: </para>
+ <para><command># chkconfig glusterd on </command></para>
+ </section>
+ <section condition="gfs">
+ <title condition="gfs">Debian-based Systems</title>
+ <para>To configure Debian-based systems to automatically start the glusterd service every time the system boots, enter the following from the command line:</para>
+ <para><command># update-rc.d glusterd defaults</command></para>
+ </section>
+ <section condition="gfs">
+ <title condition="gfs">Systems Other than Red Hat and Debain</title>
+ <para>To configure systems other than Red Hat or Debian to automatically start the glusterd service every time the system boots, enter the following entry to the<emphasis role="italic"> /etc/rc.local</emphasis> file: </para>
+ <para><command># echo &quot;glusterd&quot; &gt;&gt; /etc/rc.local </command></para>
+ </section>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_storage_pools.xml b/doc/admin-guide/en-US/admin_storage_pools.xml
new file mode 100644
index 000000000..2c4a5cabe
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_storage_pools.xml
@@ -0,0 +1,57 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter id="chap-Administration_Guide-Storage-pool">
+ <title>Setting up Trusted Storage Pools</title>
+ <para>Before you can configure a GlusterFS volume, you must create a trusted storage pool consisting of the storage servers that provides bricks to a volume. </para>
+ <para>A storage pool is a trusted network of storage servers. When you start the first server, the storage pool consists of that server alone. To add additional storage servers to the storage pool, you can use the probe command from a storage server that is already part of the trusted storage pool. </para>
+ <para><note>
+ <para>Do not self-probe the first server/localhost.</para>
+ </note></para>
+ <para>The glusterd service must be running on all storage servers that you want to add to the storage pool. See <xref linkend="chap-Administration_Guide-Start_Stop_Daemon"/> for more information.</para>
+ <section id="sect-Administration_Guide-Storage_Pools-Adding_Servers">
+ <title>Adding Servers to Trusted Storage Pool</title>
+ <para>To create a trusted storage pool, add servers to the trusted storage pool</para>
+ <orderedlist>
+ <listitem>
+ <para>The hostnames used to create the storage pool must be resolvable by DNS. Also make sure that firewall is not blocking the probe requests/replies. (iptables -F)</para>
+ <para>To add a server to the storage pool:</para>
+ <para><command># gluster peer probe <replaceable>server</replaceable></command></para>
+ <para>For example, to create a trusted storage pool of four servers, add three servers to the storage pool from server1:</para>
+ <para><programlisting># gluster peer probe server2
+Probe successful
+
+# gluster peer probe server3
+Probe successful
+
+# gluster peer probe server4
+Probe successful
+</programlisting></para>
+ </listitem>
+ <listitem>
+ <para>Verify the peer status from the first server using the following commands:</para>
+ <para><programlisting># gluster peer status
+Number of Peers: 3
+
+Hostname: server2
+Uuid: 5e987bda-16dd-43c2-835b-08b7d55e94e5
+State: Peer in Cluster (Connected)
+
+Hostname: server3
+Uuid: 1e0ca3aa-9ef7-4f66-8f15-cbc348f29ff7
+State: Peer in Cluster (Connected)
+
+Hostname: server4
+Uuid: 3e0caba-9df7-4f66-8e5d-cbc348f29ff7
+State: Peer in Cluster (Connected)</programlisting></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>Removing Servers from the Trusted Storage Pool</title>
+ <para>To remove a server from the storage pool:</para>
+ <para><command># gluster peer detach<replaceable> server</replaceable></command></para>
+ <para> For example, to remove server4 from the trusted storage pool:</para>
+ <para><programlisting># gluster peer detach server4
+Detach successful</programlisting></para>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/admin_troubleshooting.xml b/doc/admin-guide/en-US/admin_troubleshooting.xml
new file mode 100644
index 000000000..1c6866d8b
--- /dev/null
+++ b/doc/admin-guide/en-US/admin_troubleshooting.xml
@@ -0,0 +1,508 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter id="chap-Administration_Guide-Troubleshooting">
+ <title>Troubleshooting GlusterFS </title>
+ <para>This section describes how to manage GlusterFS logs and most common troubleshooting scenarios
+related to GlusterFS.
+</para>
+ <section>
+ <title>Managing GlusterFS Logs </title>
+ <para>This section describes how to manage GlusterFS logs by performing the following operation:
+
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Rotating Logs
+</para>
+ </listitem>
+ </itemizedlist>
+ <section>
+ <title>Rotating Logs </title>
+ <para>Administrators can rotate the log file in a volume, as needed.
+</para>
+ <para><emphasis role="bold">To rotate a log file </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Rotate the log file using the following command:
+</para>
+ <para><command># gluster volume log rotate <replaceable>VOLNAME</replaceable></command></para>
+ <para>For example, to rotate the log file on test-volume:
+</para>
+ <programlisting># gluster volume log rotate test-volume
+log rotate successful
+</programlisting>
+ <note>
+ <para>When a log file is rotated, the contents of the current log file are moved to log-file-
+name.epoch-time-stamp.
+</para>
+ </note>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section>
+ <title>Troubleshooting Geo-replication </title>
+ <para>This section describes the most common troubleshooting scenarios related to GlusterFS Geo-replication.
+</para>
+ <section>
+ <title>Locating Log Files </title>
+ <para>For every Geo-replication session, the following three log files are associated to it (four, if the slave is a
+gluster volume):
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Master-log-file - log file for the process which monitors the Master volume
+</para>
+ </listitem>
+ <listitem>
+ <para>Slave-log-file - log file for process which initiates the changes in slave
+</para>
+ </listitem>
+ <listitem>
+ <para>Master-gluster-log-file - log file for the maintenance mount point that Geo-replication module
+uses to monitor the master volume
+</para>
+ </listitem>
+ <listitem>
+ <para>Slave-gluster-log-file - is the slave&apos;s counterpart of it
+</para>
+ </listitem>
+ </itemizedlist>
+ <para><emphasis role="bold">Master Log File</emphasis>
+</para>
+ <para>To get the Master-log-file for geo-replication, use the following command:
+</para>
+ <para><command>gluster volume geo-replication <code>MASTER SLAVE</code> config log-file</command>
+</para>
+ <para>For example:
+</para>
+ <para><command># gluster volume geo-replication Volume1 example.com:/data/remote_dir config log-file </command></para>
+ <para><emphasis role="bold">Slave Log File </emphasis></para>
+ <para>To get the log file for Geo-replication on slave (glusterd must be running on slave machine), use the
+following commands:
+</para>
+ <orderedlist>
+ <listitem>
+ <para>On master, run the following command:
+</para>
+ <para><command># gluster volume geo-replication Volume1 example.com:/data/remote_dir config session-owner 5f6e5200-756f-11e0-a1f0-0800200c9a66 </command></para>
+ <para>Displays the session owner details.
+</para>
+ </listitem>
+ <listitem>
+ <para>On slave, run the following command:
+</para>
+ <para><command># gluster volume geo-replication /data/remote_dir config log-file /var/log/gluster/${session-owner}:remote-mirror.log </command></para>
+ </listitem>
+ <listitem>
+ <para>Replace the session owner details (output of Step 1) to the output of the Step 2 to get the
+location of the log file.
+</para>
+ <para><command>/var/log/gluster/5f6e5200-756f-11e0-a1f0-0800200c9a66:remote-mirror.log</command>
+</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>Rotating Geo-replication Logs</title>
+ <para>Administrators can rotate the log file of a particular master-slave session, as needed.
+When you run geo-replication&apos;s <command> log-rotate</command> command, the log file
+is backed up with the current timestamp suffixed to the file
+name and signal is sent to gsyncd to start logging to a new
+log file.</para>
+ <para><emphasis role="bold">To rotate a geo-replication log file </emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <para>Rotate log file for a particular master-slave session using the following command:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>master slave</replaceable> log-rotate</command>
+</para>
+ <para>For example, to rotate the log file of master <filename>Volume1</filename> and slave <filename>example.com:/data/remote_dir</filename>
+:
+</para>
+ <programlisting># gluster volume geo-replication Volume1 example.com:/data/remote_dir log rotate
+log rotate successful</programlisting>
+ </listitem>
+ <listitem>
+ <para>Rotate log file for all sessions for a master volume using the following command:
+</para>
+ <para><command># gluster volume geo-replication <replaceable>master</replaceable> log-rotate</command>
+</para>
+ <para>For example, to rotate the log file of master <filename>Volume1</filename>:
+</para>
+ <programlisting># gluster volume geo-replication Volume1 log rotate
+log rotate successful</programlisting>
+ </listitem>
+ <listitem>
+ <para>Rotate log file for all sessions using the following command:
+</para>
+ <para><command># gluster volume geo-replication log-rotate</command>
+</para>
+ <para>For example, to rotate the log file for all sessions:</para>
+ <programlisting># gluster volume geo-replication log-rotate
+log rotate successful</programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Synchronization is not complete </title>
+ <para><emphasis role="bold">Description</emphasis>: GlusterFS Geo-replication did not synchronize the data completely but still the geo-
+replication status displayed is OK.
+</para>
+ <para><emphasis role="bold">Solution</emphasis>: You can enforce a full sync of the data by erasing the index and restarting GlusterFS Geo-
+replication. After restarting, GlusterFS Geo-replication begins synchronizing all the data. All files are compared using checksum, which can be a lengthy and high resource utilization operation on large
+data sets. If the error situation persists, contact Red Hat Support.
+</para>
+ <para>For more information about erasing index, see <xref linkend="sect-Administration_Guide-Managing_Volumes-Tuning"/>.
+</para>
+ </section>
+ <section>
+ <title>Issues in Data Synchronization </title>
+ <para><emphasis role="bold">Description</emphasis>: Geo-replication display status as OK, but the files do not get synced, only
+directories and symlink gets synced with the following error message in the log:
+</para>
+ <para><errortext>[2011-05-02 13:42:13.467644] E [master:288:regjob] GMaster: failed to sync ./some_file` </errortext></para>
+ <para><emphasis role="bold">Solution</emphasis>: Geo-replication invokes rsync v3.0.0 or higher on the host and the remote machine. You must verify if
+you have installed the required version.
+</para>
+ </section>
+ <section>
+ <title>Geo-replication status displays Faulty very often </title>
+ <para><emphasis role="bold">Description</emphasis>: Geo-replication displays status as faulty very often with a backtrace similar to
+the following:
+</para>
+ <para><errortext>2011-04-28 14:06:18.378859] E [syncdutils:131:log_raise_exception] &lt;top&gt;: FAIL: Traceback (most recent call last): File &quot;/usr/local/libexec/glusterfs/python/syncdaemon/syncdutils.py&quot;, line 152, in twraptf(*aa) File &quot;/usr/local/libexec/glusterfs/python/syncdaemon/repce.py&quot;, line 118, in listen rid, exc, res = recv(self.inf) File &quot;/usr/local/libexec/glusterfs/python/syncdaemon/repce.py&quot;, line 42, in recv return pickle.load(inf) EOFError </errortext></para>
+ <para><emphasis role="bold">Solution</emphasis>: This error indicates that the RPC communication between the master geo-replication module and slave
+geo-replication module is broken and this can happen for various reasons. Check if it satisfies all the following
+pre-requisites:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Password-less SSH is set up properly between the host where geo-replication command is executed and the remote machine where the slave geo-replication is located.
+</para>
+ </listitem>
+ <listitem>
+ <para>If FUSE is installed in the machine where the geo-replication command is executed, because geo-replication module mounts the GlusterFS volume using FUSE to sync data.
+</para>
+ </listitem>
+ <listitem>
+ <para>If the <emphasis role="bold">Slave</emphasis> is a volume, check if that volume is started.
+</para>
+ </listitem>
+ <listitem>
+ <para>If the Slave is a plain directory, verify if the directory has been created already with the
+required permissions.
+</para>
+ </listitem>
+ <listitem>
+ <para>If GlusterFS 3.3 or higher is not installed in the default location (in Master) and has been prefixed to be
+installed in a custom location, configure the <command>gluster-command</command> for it to point to the exact
+location.
+</para>
+ </listitem>
+ <listitem>
+ <para>If GlusterFS 3.3 or higher is not installed in the default location (in slave) and has been prefixed to be
+installed in a custom location, configure the <command>remote-gsyncd-command</command> for it to point to the
+exact place where geo-replication is located.
+</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section>
+ <title>Intermediate Master goes to Faulty State </title>
+ <para><emphasis role="bold">Description</emphasis>: In a cascading set-up, the intermediate master goes to faulty state with the following
+log:
+</para>
+ <para><errortext>raise RuntimeError (&quot;aborting on uuid change from %s to %s&quot; % \ RuntimeError: aborting on uuid change from af07e07c-427f-4586-ab9f- 4bf7d299be81 to de6b5040-8f4e-4575-8831-c4f55bd41154 </errortext></para>
+ <para><emphasis role="bold">Solution</emphasis>: In a cascading set-up the Intermediate master is loyal to the original primary master. The
+above log means that the geo-replication module has detected change in primary master.
+If this is the desired behavior, delete the config option volume-id in the session initiated from the
+intermediate master.
+</para>
+ </section>
+ </section>
+ <section>
+ <title>Troubleshooting POSIX ACLs </title>
+ <para>This section describes the most common troubleshooting issues related to POSIX ACLs.
+</para>
+ <section>
+ <title>setfacl command fails with “setfacl: &lt;file or directory name&gt;: Operation not supported” error </title>
+ <para>You may face this error when the backend file systems in one of the servers is not mounted with
+the &quot;-o acl&quot; option. The same can be confirmed by viewing the following error message in the log file
+of the server &quot;Posix access control list is not supported&quot;.
+</para>
+ <para><emphasis role="bold">Solution</emphasis>: Remount the backend file system with &quot;-o acl&quot; option. For more information, see <xref linkend="sect-Administration_Guide-ACLs-Activating_ACLs-Server"/>.
+</para>
+ </section>
+ </section>
+ <section>
+ <title>Troubleshooting Hadoop Compatible Storage </title>
+ <para>This section describes the most common troubleshooting issues related to Hadoop Compatible
+Storage.
+
+ </para>
+ <section id="sect-Administration_Guide-Troubleshooting-Test_Section_1">
+ <title>Time Sync</title>
+ <para>Running MapReduce job may throw exceptions if the clocks are out-of-sync on the hosts in the cluster.
+
+ </para>
+ <para><emphasis role="bold">Solution</emphasis>: Sync the time on all hosts using ntpd program.
+</para>
+ </section>
+ </section>
+ <section>
+ <title>Troubleshooting NFS </title>
+ <para>This section describes the most common troubleshooting issues related to NFS .
+</para>
+ <section>
+ <title>mount command on NFS client fails with “RPC Error: Program not registered” </title>
+ <para>Start portmap or rpcbind service on the machine where NFS server is running.
+</para>
+ <para>This error is encountered when the server has not started correctly.
+</para>
+ <para>On most Linux distributions this is fixed by starting portmap:
+</para>
+ <para><command>$ /etc/init.d/portmap start</command>
+</para>
+ <para>On some distributions where portmap has been replaced by rpcbind, the following command is
+required:
+</para>
+ <para><command>$ /etc/init.d/rpcbind start </command></para>
+ <para>After starting portmap or rpcbind, gluster NFS server needs to be restarted.
+</para>
+ </section>
+ <section>
+ <title>NFS server start-up fails with “Port is already in use” error in the log file.&quot; </title>
+ <para>Another Gluster NFS server is running on the same machine.
+</para>
+ <para>This error can arise in case there is already a Gluster NFS server running on the same machine.
+This situation can be confirmed from the log file, if the following error lines exist:
+</para>
+ <para><screen>[2010-05-26 23:40:49] E [rpc-socket.c:126:rpcsvc_socket_listen] rpc-socket: binding socket failed:Address already in use
+[2010-05-26 23:40:49] E [rpc-socket.c:129:rpcsvc_socket_listen] rpc-socket: Port is already in use
+[2010-05-26 23:40:49] E [rpcsvc.c:2636:rpcsvc_stage_program_register] rpc-service: could not create listening connection
+[2010-05-26 23:40:49] E [rpcsvc.c:2675:rpcsvc_program_register] rpc-service: stage registration of program failed
+[2010-05-26 23:40:49] E [rpcsvc.c:2695:rpcsvc_program_register] rpc-service: Program registration failed: MOUNT3, Num: 100005, Ver: 3, Port: 38465
+[2010-05-26 23:40:49] E [nfs.c:125:nfs_init_versions] nfs: Program init failed
+[2010-05-26 23:40:49] C [nfs.c:531:notify] nfs: Failed to initialize protocols</screen></para>
+ <para>To resolve this error one of the Gluster NFS servers will have to be shutdown. At this time,
+Gluster NFS server does not support running multiple NFS servers on the same machine.
+</para>
+ </section>
+ <section>
+ <title>mount command fails with “rpc.statd” related error message </title>
+ <para>If the mount command fails with the following error message:
+</para>
+ <para><errortext>mount.nfs: rpc.statd is not running but is required for remote locking. mount.nfs: Either use &apos;-o nolock&apos; to keep locks local, or start statd. </errortext></para>
+ <para><errortext>Start rpc.statd </errortext></para>
+ <para>For NFS clients to mount the NFS server, rpc.statd service must be running on the client machine. </para>
+ <para>Start
+rpc.statd service by running the following command:
+</para>
+ <para><command>$ rpc.statd </command></para>
+ </section>
+ <section>
+ <title>mount command takes too long to finish. </title>
+ <para>Start rpcbind service on the NFS client.
+</para>
+ <para>The problem is that the rpcbind or portmap service is not running on the NFS client. The
+resolution for this is to start either of these services by running the following command:
+</para>
+ <para><command>$ /etc/init.d/portmap start</command>
+</para>
+ <para>On some distributions where portmap has been replaced by rpcbind, the following command is
+required:
+</para>
+ <para><command>$ /etc/init.d/rpcbind start</command></para>
+ </section>
+ <section>
+ <title>NFS server, glusterfsd starts but initialization fails with “nfsrpc- service: portmap registration of program failed” error message in the log. </title>
+ <para>NFS start-up can succeed but the initialization of the NFS service can still fail preventing clients
+from accessing the mount points. Such a situation can be confirmed from the following error
+messages in the log file:
+</para>
+ <para><screen>[2010-05-26 23:33:47] E [rpcsvc.c:2598:rpcsvc_program_register_portmap] rpc-service: Could notregister with portmap
+[2010-05-26 23:33:47] E [rpcsvc.c:2682:rpcsvc_program_register] rpc-service: portmap registration of program failed
+[2010-05-26 23:33:47] E [rpcsvc.c:2695:rpcsvc_program_register] rpc-service: Program registration failed: MOUNT3, Num: 100005, Ver: 3, Port: 38465
+[2010-05-26 23:33:47] E [nfs.c:125:nfs_init_versions] nfs: Program init failed
+[2010-05-26 23:33:47] C [nfs.c:531:notify] nfs: Failed to initialize protocols
+[2010-05-26 23:33:49] E [rpcsvc.c:2614:rpcsvc_program_unregister_portmap] rpc-service: Could not unregister with portmap
+[2010-05-26 23:33:49] E [rpcsvc.c:2731:rpcsvc_program_unregister] rpc-service: portmap unregistration of program failed
+[2010-05-26 23:33:49] E [rpcsvc.c:2744:rpcsvc_program_unregister] rpc-service: Program unregistration failed: MOUNT3, Num: 100005, Ver: 3, Port: 38465</screen></para>
+ <orderedlist>
+ <listitem>
+ <para>Start portmap or rpcbind service on the NFS server.
+</para>
+ <para>On most Linux distributions, portmap can be started using the following command:
+</para>
+ <para><command>$ /etc/init.d/portmap start </command></para>
+ <para>On some distributions where portmap has been replaced by rpcbind, run the following command:
+</para>
+ <para><command>$ /etc/init.d/rpcbind start </command></para>
+ <para>After starting portmap or rpcbind, gluster NFS server needs to be restarted.
+</para>
+ </listitem>
+ <listitem>
+ <para>Stop another NFS server running on the same machine.
+</para>
+ <para>Such an error is also seen when there is another NFS server running on the same machine but it is
+not the Gluster NFS server. On Linux systems, this could be the kernel NFS server. Resolution
+involves stopping the other NFS server or not running the Gluster NFS server on the machine.
+Before stopping the kernel NFS server, ensure that no critical service depends on access to that
+NFS server&apos;s exports.
+</para>
+ <para>On Linux, kernel NFS servers can be stopped by using either of the following commands
+depending on the distribution in use:
+</para>
+ <para><command>$ /etc/init.d/nfs-kernel-server stop</command>
+</para>
+ <para><command>$ /etc/init.d/nfs stop</command></para>
+ </listitem>
+ <listitem>
+ <para>Restart Gluster NFS server.
+</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>mount command fails with NFS server failed error. </title>
+ <para>mount command fails with following error
+</para>
+ <para><emphasis role="italic">mount: mount to NFS server &apos;10.1.10.11&apos; failed: timed out (retrying).</emphasis></para>
+ <para>Perform one of the following to resolve this issue:
+</para>
+ <orderedlist>
+ <listitem>
+ <para>Disable name lookup requests from NFS server to a DNS server.
+</para>
+ <para>The NFS server attempts to authenticate NFS clients by performing a reverse DNS lookup to
+match hostnames in the volume file with the client IP addresses. There can be a situation where
+the NFS server either is not able to connect to the DNS server or the DNS server is taking too long
+to responsd to DNS request. These delays can result in delayed replies from the NFS server to the
+NFS client resulting in the timeout error seen above.
+</para>
+ <para>NFS server provides a work-around that disables DNS requests, instead relying only on the client
+IP addresses for authentication. The following option can be added for successful mounting in
+such situations:
+</para>
+ <para><command>option rpc-auth.addr.namelookup off </command></para>
+ <para><note>
+ <para>Note: Remember that disabling the NFS server forces authentication of clients to use only IP
+addresses and if the authentication rules in the volume file use hostnames, those authentication
+rules will fail and disallow mounting for those clients.
+</para>
+ </note></para>
+ <para>or</para>
+ </listitem>
+ <listitem>
+ <para>NFS version used by the NFS client is other than version 3.
+</para>
+ <para>Gluster NFS server supports version 3 of NFS protocol. In recent Linux kernels, the default NFS
+version has been changed from 3 to 4. It is possible that the client machine is unable to connect
+to the Gluster NFS server because it is using version 4 messages which are not understood by
+Gluster NFS server. The timeout can be resolved by forcing the NFS client to use version 3. The
+<emphasis role="bold">vers</emphasis> option to mount command is used for this purpose:
+</para>
+ <para><command>$ mount <replaceable>nfsserver</replaceable><replaceable>:export</replaceable> -o vers=3 <replaceable>mount-point</replaceable></command>
+</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>showmount fails with clnt_create: RPC: Unable to receive </title>
+ <para>Check your firewall setting to open ports 111 for portmap requests/replies and Gluster NFS
+server requests/replies. Gluster NFS server operates over the following port numbers: 38465,
+38466, and 38467.
+</para>
+ <para>For more information, see <xref linkend="sect-Administration_Guide-GlusterFS_Client-Native-RPM"/>.
+</para>
+ </section>
+ <section>
+ <title>Application fails with &quot;Invalid argument&quot; or &quot;Value too large for defined data type&quot; error. </title>
+ <para>These two errors generally happen for 32-bit nfs clients or applications that do not support 64-bit
+inode numbers or large files.
+Use the following option from the CLI to make Gluster NFS server return 32-bit inode numbers instead:
+nfs.enable-ino32 &lt;on|off&gt;
+</para>
+ <para>Applications that will benefit are those that were either:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>built 32-bit and run on 32-bit machines such that they do not support large files by default</para>
+ </listitem>
+ <listitem>
+ <para>built 32-bit on 64-bit systems
+</para>
+ </listitem>
+ </itemizedlist>
+ <para>This option is disabled by default. So Gluster NFS server returns 64-bit inode numbers by default.
+</para>
+ <para>Applications which can be rebuilt from source are recommended to rebuild using the following
+flag with gcc:</para>
+ <para><command> -D_FILE_OFFSET_BITS=64</command>
+</para>
+ </section>
+ </section>
+ <section>
+ <title>Troubleshooting File Locks</title>
+ <para>In GlusterFS 3.3 you can use <command>statedump</command> command to list the locks held on files. The statedump output also provides information on each lock with its range, basename, PID of the application holding the lock, and so on. You can analyze the output to know about the locks whose owner/application is no longer running or interested in that lock. After ensuring that the no application is using the file, you can clear the lock using the following <command>clear lock</command> command:</para>
+ <para><command># <command>gluster volume clear-locks <replaceable>VOLNAME path</replaceable> kind {blocked | granted | all}{inode [range] | entry [basename] | posix [range]}</command></command></para>
+ <para>For more information on performing <command>statedump</command>, see <xref linkend="sect-Administration_Guide-Monitor_Workload-Performing_Statedump"/></para>
+ <para><emphasis role="bold">To identify locked file and clear locks</emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Perform statedump on the volume to view the files that are locked using the following command:</para>
+ <para> <command># gluster volume statedump <replaceable>VOLNAME</replaceable> inode</command></para>
+ <para>For example, to display statedump of test-volume:</para>
+ <para><programlisting># gluster volume statedump test-volume
+Volume statedump successful</programlisting></para>
+ <para>The statedump files are created on the brick servers in the<filename> /tmp</filename> directory or in the directory set using <command>server.statedump-path</command> volume option. The naming convention of the dump file is <filename>&lt;brick-path&gt;.&lt;brick-pid&gt;.dump</filename>.</para>
+ <para>The following are the sample contents of the statedump file. It indicates that GlusterFS has entered into a state where there is an entry lock (entrylk) and an inode lock (inodelk). Ensure that those are stale locks and no resources own them before clearing. </para>
+ <para><screen>[xlator.features.locks.vol-locks.inode]
+path=/
+mandatory=0
+entrylk-count=1
+lock-dump.domain.domain=vol-replicate-0
+xlator.feature.locks.lock-dump.domain.entrylk.entrylk[0](ACTIVE)=type=ENTRYLK_WRLCK on basename=file1, pid = 714782904, owner=ffffff2a3c7f0000, transport=0x20e0670, , granted at Mon Feb 27 16:01:01 2012
+
+conn.2.bound_xl./gfs/brick1.hashsize=14057
+conn.2.bound_xl./gfs/brick1.name=/gfs/brick1/inode
+conn.2.bound_xl./gfs/brick1.lru_limit=16384
+conn.2.bound_xl./gfs/brick1.active_size=2
+conn.2.bound_xl./gfs/brick1.lru_size=0
+conn.2.bound_xl./gfs/brick1.purge_size=0
+
+[conn.2.bound_xl./gfs/brick1.active.1]
+gfid=538a3d4a-01b0-4d03-9dc9-843cd8704d07
+nlookup=1
+ref=2
+ia_type=1
+[xlator.features.locks.vol-locks.inode]
+path=/file1
+mandatory=0
+inodelk-count=1
+lock-dump.domain.domain=vol-replicate-0
+inodelk.inodelk[0](ACTIVE)=type=WRITE, whence=0, start=0, len=0, pid = 714787072, owner=00ffff2a3c7f0000, transport=0x20e0670, , granted at Mon Feb 27 16:01:01 2012</screen></para>
+ </listitem>
+ <listitem>
+ <para>Clear the lock using the following command:</para>
+ <para><command># <command>gluster volume clear-locks <replaceable>VOLNAME path</replaceable> kind granted entry basename</command></command></para>
+ <para>For example, to clear the entry lock on <filename>file1</filename> of test-volume:
+</para>
+ <para><screen># gluster volume clear-locks test-volume / kind granted entry file1
+Volume clear-locks successful
+vol-locks: entry blocked locks=0 granted locks=1</screen></para>
+ </listitem>
+ <listitem>
+ <para>Clear the inode lock using the following command:</para>
+ <para><command># <command>gluster volume clear-locks <replaceable>VOLNAME path</replaceable> kind granted inode range </command></command></para>
+ <para>For example, to clear the inode lock on <filename>file1</filename> of test-volume:
+</para>
+ <para><screen># gluster volume clear-locks test-volume /file1 kind granted inode 0,0-0
+Volume clear-locks successful
+vol-locks: inode blocked locks=0 granted locks=1</screen></para>
+ <para>You can perform statedump on test-volume again to verify that the above inode and entry locks are cleared.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+</chapter>
diff --git a/doc/admin-guide/en-US/gfs_introduction.xml b/doc/admin-guide/en-US/gfs_introduction.xml
new file mode 100644
index 000000000..64b1c0779
--- /dev/null
+++ b/doc/admin-guide/en-US/gfs_introduction.xml
@@ -0,0 +1,54 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter>
+ <title>Introducing Gluster File System</title>
+ <para>GlusterFS is an open source, clustered file system capable of scaling to several petabytes and handling thousands of clients. GlusterFS can be flexibly combined with commodity physical, virtual, and cloud resources to deliver highly available and performant enterprise storage at a fraction of the cost of traditional solutions.</para>
+ <para>GlusterFS clusters together storage building blocks over Infiniband RDMA and/or TCP/IP interconnect, aggregating disk and memory resources and managing data in a single global namespace. GlusterFS is based on a stackable user space design, delivering exceptional performance for diverse workloads.
+</para>
+ <figure>
+ <title>Virtualized Cloud Environments</title>
+ <mediaobject>
+ <textobject>
+ <phrase>Virtualized Cloud Environments</phrase>
+ </textobject>
+ <imageobject>
+ <imagedata align="center" fileref="images/640px-GlusterFS_3.2_Architecture.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para>GlusterFS is designed for today&apos;s high-performance, virtualized cloud environments. Unlike traditional data centers, cloud environments require multi-tenancy along with the ability to grow or shrink resources on demand. Enterprises can scale capacity, performance, and availability on demand, with no vendor lock-in, across on-premise, public cloud, and hybrid environments. </para>
+ <para>GlusterFS is in production at thousands of enterprises spanning media, healthcare, government, education, web 2.0, and financial services. The following table lists the commercial offerings and its documentation location:
+</para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="16%"/>
+ <colspec colname="c2" colwidth="84%"/>
+ <thead>
+ <row>
+ <entry>Product</entry>
+ <entry>Documentation Location</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Red Hat Storage Software Appliance</entry>
+ <entry>
+ <ulink url="http://docs.redhat.com/docs/en-US/Red_Hat_Storage_Software_Appliance/index.html"/>
+ </entry>
+ </row>
+ <row>
+ <entry>Red Hat Virtual Storage Appliance</entry>
+ <entry>
+ <ulink url="http://docs.redhat.com/docs/en-US/Red_Hat_Virtual_Storage_Appliance/index.html"/>
+ </entry>
+ </row>
+ <row>
+ <entry>Red Hat Storage </entry>
+ <entry>
+ <ulink url="http://docs.redhat.com/docs/en-US/Red_Hat_Storage/index.html"/>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+</chapter>
diff --git a/doc/admin-guide/en-US/glossary.xml b/doc/admin-guide/en-US/glossary.xml
new file mode 100644
index 000000000..8c314feaa
--- /dev/null
+++ b/doc/admin-guide/en-US/glossary.xml
@@ -0,0 +1,126 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter>
+ <title>Glossary</title>
+ <glosslist>
+ <glossentry>
+ <glossterm>Brick</glossterm>
+ <glossdef>
+ <para>A Brick is the GlusterFS basic unit of storage, represented by an export directory on a server in the trusted storage pool. A Brick is expressed by combining a server with an export directory in the following format:</para>
+ <para><code>SERVER:EXPORT</code></para>
+ <para>For example:</para>
+ <para><filename>myhostname:/exports/myexportdir/</filename></para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Cluster</glossterm>
+ <glossdef>
+ <para>A cluster is a group of linked computers, working together closely thus in many respects forming a single computer.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Distributed File System</glossterm>
+ <glossdef>
+ <para>A file system that allows multiple clients to concurrently access data over a computer network.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Filesystem</glossterm>
+ <glossdef>
+ <para>A method of storing and organizing computer files and their data. Essentially, it organizes these files into a database for the storage, organization, manipulation, and retrieval by the computer&apos;s operating system.</para>
+ <para>Source: <ulink url="http://en.wikipedia.org/wiki/Filesystem">Wikipedia</ulink></para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>FUSE</glossterm>
+ <glossdef>
+ <para>Filesystem in Userspace (<acronym>FUSE</acronym>) is a loadable kernel module for Unix-like computer operating systems that lets non-privileged users create their own file systems without editing kernel code. This is achieved by running file system code in user space while the <acronym>FUSE</acronym> module provides only a &quot;bridge&quot; to the actual kernel interfaces.</para>
+ <para>Source: <ulink url="http://en.wikipedia.org/wiki/Filesystem_in_Userspace">Wikipedia</ulink></para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Geo-Replication</glossterm>
+ <glossdef>
+ <para>Geo-replication provides a continuous, asynchronous, and incremental replication service from site to another over Local Area Networks (<acronym>LAN</acronym>), Wide Area Network (<acronym>WAN</acronym>), and across the Internet.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>glusterd</glossterm>
+ <glossdef>
+ <para>The Gluster management daemon that needs to run on all servers in the trusted storage pool.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Metadata</glossterm>
+ <glossdef>
+ <para>Metadata is data providing information about one or more other pieces of data.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Namespace</glossterm>
+ <glossdef>
+ <para>Namespace is an abstract container or environment created to hold a logical grouping of unique identifiers or symbols. Each Gluster volume exposes a single namespace as a POSIX mount point that contains every file in the cluster.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Open Source</glossterm>
+ <glossdef>
+ <para>Open source describes practices in production and development that promote access to the end product&apos;s source materials. Some consider open source a philosophy, others consider it a pragmatic methodology.</para>
+ <para>Before the term open source became widely adopted, developers and producers used a variety of phrases to describe the concept; open source gained hold with the rise of the Internet, and the attendant need for massive retooling of the computing source code.</para>
+ <para>Opening the source code enabled a self-enhancing diversity of production models, communication paths, and interactive communities. Subsequently, a new, three-word phrase &quot;open source software&quot; was born to describe the environment that the new copyright, licensing, domain, and consumer issues created.</para>
+ <para>Source: <ulink url="http://en.wikipedia.org/wiki/Open_source">Wikipedia</ulink></para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Petabyte</glossterm>
+ <glossdef>
+ <para>A petabyte (derived from the SI prefix peta- ) is a unit of information equal to one quadrillion (short scale) bytes, or 1000 terabytes. The unit symbol for the petabyte is PB. The prefix peta- (P) indicates a power of 1000:</para>
+ <para>1 PB = 1,000,000,000,000,000 B = 10005 B = 1015 B.</para>
+ <para>The term &quot;pebibyte&quot; (<acronym>PiB</acronym>), using a binary prefix, is used for the corresponding power of 1024.</para>
+ <para>Source: <ulink url="http://en.wikipedia.org/wiki/Petabyte">Wikipedia</ulink></para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>POSIX</glossterm>
+ <glossdef>
+ <para>Portable Operating System Interface (for Unix) is the name of a family of related standards specified by the IEEE to define the application programming interface (<acronym>API</acronym>), along with shell and utilities interfaces for software compatible with variants of the Unix operating system. Gluster exports a fully <acronym>POSIX</acronym> compliant file system.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>RAID</glossterm>
+ <glossdef>
+ <para>Redundant Array of Inexpensive Disks (<acronym>RAID</acronym>) is a technology that provides increased storage reliability through redundancy, combining multiple low-cost, less-reliable disk drives components into a logical unit where all drives in the array are interdependent.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>RRDNS</glossterm>
+ <glossdef>
+ <para>Round Robin Domain Name Service (<acronym>RRDNS</acronym>) is a method to distribute load across application servers. <acronym>RRDNS</acronym> is implemented by creating multiple A records with the same name and different IP addresses in the zone file of a DNS server.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Trusted Storage Pool</glossterm>
+ <glossdef>
+ <para>A storage pool is a trusted network of storage servers. When you start the first server, the storage pool consists of that server alone.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Userspace</glossterm>
+ <glossdef>
+ <para>Applications running in user space don’t directly interact with hardware, instead using the kernel to moderate access. Userspace applications are generally more portable than applications in kernel space. Gluster is a user space application.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Volfile</glossterm>
+ <glossdef>
+ <para>Volfile is a configuration file used by glusterfs process. Volfile will be usually located at <filename>/etc/glusterd/vols/VOLNAME</filename>.</para>
+ </glossdef>
+ </glossentry>
+ <glossentry>
+ <glossterm>Volume</glossterm>
+ <glossdef>
+ <para>A volume is a logical collection of bricks. Most of the gluster management operations happen on the volume.</para>
+ </glossdef>
+ </glossentry>
+ </glosslist>
+</chapter>
diff --git a/doc/admin-guide/en-US/images/640px-GlusterFS_3.2_Architecture.png b/doc/admin-guide/en-US/images/640px-GlusterFS_3.2_Architecture.png
new file mode 100644
index 000000000..95f89ec82
--- /dev/null
+++ b/doc/admin-guide/en-US/images/640px-GlusterFS_3.2_Architecture.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Distributed_Replicated_Volume.png b/doc/admin-guide/en-US/images/Distributed_Replicated_Volume.png
new file mode 100644
index 000000000..dfc0a2c56
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Distributed_Replicated_Volume.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Distributed_Striped_Replicated_Volume.png b/doc/admin-guide/en-US/images/Distributed_Striped_Replicated_Volume.png
new file mode 100644
index 000000000..d286fa99e
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Distributed_Striped_Replicated_Volume.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Distributed_Striped_Volume.png b/doc/admin-guide/en-US/images/Distributed_Striped_Volume.png
new file mode 100644
index 000000000..752fa982f
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Distributed_Striped_Volume.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Distributed_Volume.png b/doc/admin-guide/en-US/images/Distributed_Volume.png
new file mode 100644
index 000000000..4386ca935
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Distributed_Volume.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Geo-Rep03_Internet.png b/doc/admin-guide/en-US/images/Geo-Rep03_Internet.png
new file mode 100644
index 000000000..3cd0eaded
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Geo-Rep03_Internet.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Geo-Rep04_Cascading.png b/doc/admin-guide/en-US/images/Geo-Rep04_Cascading.png
new file mode 100644
index 000000000..54bf9f05c
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Geo-Rep04_Cascading.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Geo-Rep_LAN.png b/doc/admin-guide/en-US/images/Geo-Rep_LAN.png
new file mode 100644
index 000000000..a74f6dbb5
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Geo-Rep_LAN.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Geo-Rep_WAN.png b/doc/admin-guide/en-US/images/Geo-Rep_WAN.png
new file mode 100644
index 000000000..d72d72768
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Geo-Rep_WAN.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/GlusterFS_3.2_Architecture.png b/doc/admin-guide/en-US/images/GlusterFS_3.2_Architecture.png
new file mode 100644
index 000000000..b506db1f4
--- /dev/null
+++ b/doc/admin-guide/en-US/images/GlusterFS_3.2_Architecture.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Hadoop_Architecture.png b/doc/admin-guide/en-US/images/Hadoop_Architecture.png
new file mode 100644
index 000000000..8725bd330
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Hadoop_Architecture.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Replicated_Volume.png b/doc/admin-guide/en-US/images/Replicated_Volume.png
new file mode 100644
index 000000000..135a63f34
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Replicated_Volume.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Striped_Replicated_Volume.png b/doc/admin-guide/en-US/images/Striped_Replicated_Volume.png
new file mode 100644
index 000000000..ee88af731
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Striped_Replicated_Volume.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/Striped_Volume.png b/doc/admin-guide/en-US/images/Striped_Volume.png
new file mode 100644
index 000000000..63a84b242
--- /dev/null
+++ b/doc/admin-guide/en-US/images/Striped_Volume.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/UFO_Architecture.png b/doc/admin-guide/en-US/images/UFO_Architecture.png
new file mode 100644
index 000000000..be85d7b28
--- /dev/null
+++ b/doc/admin-guide/en-US/images/UFO_Architecture.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/VSA_Architecture.png b/doc/admin-guide/en-US/images/VSA_Architecture.png
new file mode 100644
index 000000000..c3ab80cf3
--- /dev/null
+++ b/doc/admin-guide/en-US/images/VSA_Architecture.png
Binary files differ
diff --git a/doc/admin-guide/en-US/images/arhitecture.png b/doc/admin-guide/en-US/images/arhitecture.png
new file mode 100644
index 000000000..4e5188bf8
--- /dev/null
+++ b/doc/admin-guide/en-US/images/arhitecture.png
@@ -0,0 +1,13 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>HTTP Error 403</title>
+</head>
+<body>
+<h1>Error 403</h1>
+<p>We're sorry, but we could not fulfill your request for
+/community/documentation/index.php/Image:GlusterFS_3.2_Architecture.png on this server.</p>
+<p>An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.</p>
+<p>Your technical support key is: <strong>7ab5-0b6a-1756-6707</strong></p>
+<p>You can use this key to <a href="http://www.ioerror.us/bb2-support-key?key=7ab5-0b6a-1756-6707">fix this problem yourself</a>.</p>
+<p>If you are unable to fix the problem yourself, please contact <a href="mailto:webmaster+nospam@nospam.gluster.com">webmaster at gluster.com</a> and be sure to provide the technical support key shown above.</p>
diff --git a/doc/admin-guide/en-US/images/icon.svg b/doc/admin-guide/en-US/images/icon.svg
new file mode 100644
index 000000000..b2f16d0f6
--- /dev/null
+++ b/doc/admin-guide/en-US/images/icon.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="32" height="32" id="svg3017">
+ <defs id="defs3019">
+ <linearGradient id="linearGradient2381">
+ <stop id="stop2383" style="stop-color:#ffffff;stop-opacity:1" offset="0"/>
+ <stop id="stop2385" style="stop-color:#ffffff;stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <linearGradient x1="296.4996" y1="188.81061" x2="317.32471" y2="209.69398" id="linearGradient2371" xlink:href="#linearGradient2381" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.90776,0,0,0.90776,24.35648,49.24131)"/>
+ </defs>
+ <g transform="matrix(0.437808,-0.437808,0.437808,0.437808,-220.8237,43.55311)" id="g5089">
+ <path d="m 8.4382985,-6.28125 c -0.6073916,0 -4.3132985,5.94886271 -4.3132985,8.25 l 0,26.71875 c 0,0.846384 0.5818159,1.125 1.15625,1.125 l 25.5625,0 c 0.632342,0 1.125001,-0.492658 1.125,-1.125 l 0,-5.21875 0.28125,0 c 0.49684,0 0.906249,-0.409411 0.90625,-0.90625 l 0,-27.9375 c 0,-0.4968398 -0.40941,-0.90625 -0.90625,-0.90625 l -23.8117015,0 z" transform="translate(282.8327,227.1903)" id="path5091" style="fill:#5c5c4f;stroke:#000000;stroke-width:3.23021388;stroke-miterlimit:4;stroke-dasharray:none"/>
+ <rect width="27.85074" height="29.369793" rx="1.1414107" ry="1.1414107" x="286.96509" y="227.63805" id="rect5093" style="fill:#032c87"/>
+ <path d="m 288.43262,225.43675 25.2418,0 0,29.3698 -26.37615,0.0241 1.13435,-29.39394 z" id="rect5095" style="fill:#ffffff"/>
+ <path d="m 302.44536,251.73726 c 1.38691,7.85917 -0.69311,11.28365 -0.69311,11.28365 2.24384,-1.60762 3.96426,-3.47694 4.90522,-5.736 0.96708,2.19264 1.83294,4.42866 4.27443,5.98941 0,0 -1.59504,-7.2004 -1.71143,-11.53706 l -6.77511,0 z" id="path5097" style="fill:#a70000;fill-opacity:1;stroke-width:2"/>
+ <rect width="25.241802" height="29.736675" rx="0.89682275" ry="0.89682275" x="290.73544" y="220.92249" id="rect5099" style="fill:#809cc9"/>
+ <path d="m 576.47347,725.93939 6.37084,0.41502 0.4069,29.51809 c -1.89202,-1.31785 -6.85427,-3.7608 -8.26232,-1.68101 l 0,-26.76752 c 0,-0.82246 0.66212,-1.48458 1.48458,-1.48458 z" transform="matrix(0.499065,-0.866565,0,1,0,0)" id="rect5101" style="fill:#4573b3;fill-opacity:1"/>
+ <path d="m 293.2599,221.89363 20.73918,0 c 0.45101,0 0.8141,0.3631 0.8141,0.81411 0.21547,6.32836 -19.36824,21.7635 -22.36739,17.59717 l 0,-17.59717 c 0,-0.45101 0.3631,-0.81411 0.81411,-0.81411 z" id="path5103" style="opacity:0.65536726;fill:url(#linearGradient2371);fill-opacity:1"/>
+ </g>
+</svg>
diff --git a/doc/admin-guide/publican.cfg b/doc/admin-guide/publican.cfg
new file mode 100644
index 000000000..e42fa1b3d
--- /dev/null
+++ b/doc/admin-guide/publican.cfg
@@ -0,0 +1,12 @@
+# Config::Simple 4.59
+# Thu Apr 5 11:09:15 2012
+
+xml_lang: "en-US"
+type: Book
+brand: Gluster_Brand
+prod_url: http://www.gluster.org
+doc_url: http://www.gluster.com/community/documentation/index.php/Main_Page
+condition: gfs
+show_remarks: 1
+
+
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
deleted file mode 100644
index b4c93f4c9..000000000
--- a/doc/examples/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-EXTRA = README unify.vol replicate.vol stripe.vol protocol-client.vol protocol-server.vol posix-locks.vol trash.vol write-behind.vol io-threads.vol io-cache.vol read-ahead.vol filter.vol trace.vol
-EXTRA_DIST = $(EXTRA)
-
-docdir = $(datadir)/doc/$(PACKAGE_NAME)
-Examplesdir = $(docdir)/examples
-Examples_DATA = $(EXTRA)
-
-CLEANFILES =
diff --git a/doc/examples/io-threads.vol b/doc/examples/io-threads.vol
deleted file mode 100644
index 9954724e1..000000000
--- a/doc/examples/io-threads.vol
+++ /dev/null
@@ -1,21 +0,0 @@
-
-volume brick
- type storage/posix # POSIX FS translator
- option directory /home/export # Export this directory
-end-volume
-
-### 'IO-threads' translator gives a threading behaviour to File I/O calls. All other normal fops are having default behaviour. Loading this on server side helps to reduce the contension of network. (Which is assumed as a GlusterFS hang).
-# One can load it in client side to reduce the latency involved in case of a slow network, when loaded below write-behind.
-volume iot
- type performance/io-threads
- subvolumes brick
- option thread-count 4 # default value is 1
-end-volume
-
-volume server
- type protocol/server
- subvolumes iot brick
- option transport-type tcp # For TCP/IP transport
- option auth.addr.brick.allow 192.168.* # Allow access to "brick" volume
- option auth.addr.iot.allow 192.168.* # Allow access to "p-locks" volume
-end-volume
diff --git a/doc/examples/legacy/Makefile.am b/doc/examples/legacy/Makefile.am
new file mode 100644
index 000000000..49c9701ef
--- /dev/null
+++ b/doc/examples/legacy/Makefile.am
@@ -0,0 +1,8 @@
+EXTRA = README replicate.vol stripe.vol protocol-client.vol protocol-server.vol posix-locks.vol trash.vol write-behind.vol io-threads.vol io-cache.vol read-ahead.vol filter.vol trace.vol
+EXTRA_DIST = $(EXTRA)
+
+docdir = $(datadir)/doc/$(PACKAGE_NAME)
+Examplesdir = $(docdir)/examples
+Examples_DATA = $(EXTRA)
+
+CLEANFILES =
diff --git a/doc/examples/README b/doc/examples/legacy/README
index 4d472ac08..732751571 100644
--- a/doc/examples/README
+++ b/doc/examples/legacy/README
@@ -1,8 +1,8 @@
-GlusterFS's translator feature is very flexible and there are quite a lot of ways one
-can configure their filesystem to behave like.
+GlusterFS's translator feature is very flexible and there are quite a lot of
+ways one can configure their filesystem to behave like.
-Volume Specification is a way in which GlusterFS understands how it has to work, based
-on what is written there.
+Volume Specification is a way in which GlusterFS understands how it has to work,
+based on what is written there.
Going through the following URLs may give you more idea about all these.
diff --git a/doc/examples/filter.vol b/doc/examples/legacy/filter.vol
index ca5c59837..59bb23ecf 100644
--- a/doc/examples/filter.vol
+++ b/doc/examples/legacy/filter.vol
@@ -8,9 +8,9 @@ end-volume
## In normal clustered storage type, any of the cluster translators can come here.
#
# Definition of other clients
-#
+#
# Definition of cluster translator (may be unify, afr, or unify over afr)
-#
+#
### 'Filter' translator is used on client side (or server side according to needs). This traslator makes all the below translators, (or say volumes) as read-only. Hence if one wants a 'read-only' filesystem, using filter as the top most volume will make it really fast as the fops are returned from this level itself.
@@ -20,4 +20,4 @@ volume filter-ro
# option completely-read-only yes
# translate-uid 1-99=0
subvolumes client
-end-volume \ No newline at end of file
+end-volume
diff --git a/doc/examples/io-cache.vol b/doc/examples/legacy/io-cache.vol
index 5f3eca4c5..a71745017 100644
--- a/doc/examples/io-cache.vol
+++ b/doc/examples/legacy/io-cache.vol
@@ -5,21 +5,27 @@ volume client
option remote-subvolume brick # name of the remote volume
end-volume
-## In normal clustered storage type, any of the cluster translators can come here.
+## In normal clustered storage type, any of the cluster translators can come
+# here.
#
# Definition of other clients
-#
-# Definition of cluster translator (may be unify, replicate, or unify over replicate)
-#
+#
+# Definition of cluster translator (may be distribute, replicate, or distribute
+# over replicate)
+#
-### 'IO-Cache' translator is best used on client side when a filesystem has file which are not modified frequently but read several times. For example, while compiling a kernel, *.h files are read while compiling every *.c file, in these case, io-cache translator comes very handy, as it keeps the whole file content in the cache, and serves from the cache.
+### 'IO-Cache' translator is best used on client side when a filesystem has file
+# which are not modified frequently but read several times. For example, while
+# compiling a kernel, *.h files are read while compiling every *.c file, in
+# these case, io-cache translator comes very handy, as it keeps the whole file
+# content in the cache, and serves from the cache.
# One can provide the priority of the cache too.
volume ioc
type performance/io-cache
- subvolumes client # In this example it is 'client' you may have to change it according to your spec file.
- option page-size 1MB # 128KB is default
+ subvolumes client # In this example it is 'client' you may have to
+ # change it according to your spec file.
option cache-size 64MB # 32MB is default
- option force-revalidate-timeout 5 # 1second is default
+ option force-revalidate-timeout 5 # 1second is default
option priority *.html:2,*:1 # default is *:0
end-volume
diff --git a/doc/examples/legacy/io-threads.vol b/doc/examples/legacy/io-threads.vol
new file mode 100644
index 000000000..236f5b8b1
--- /dev/null
+++ b/doc/examples/legacy/io-threads.vol
@@ -0,0 +1,22 @@
+volume brick
+ type storage/posix # POSIX FS translator
+ option directory /home/export # Export this directory
+end-volume
+
+### 'IO-threads' translator gives a threading behaviour to File I/O calls. All
+# other normal fops are having default behaviour. Loading this on server side
+# helps to reduce the contension of network. (Which is assumed as a GlusterFS
+# hang).
+
+volume iot
+ type performance/io-threads
+ subvolumes brick
+ option thread-count 4 # default value is 1
+end-volume
+
+volume server
+ type protocol/server
+ subvolumes iot
+ option transport-type tcp # For TCP/IP transport
+ option auth.addr.iot.allow 192.168.*
+end-volume
diff --git a/doc/examples/posix-locks.vol b/doc/examples/legacy/posix-locks.vol
index b9c9e7a64..673afa3f8 100644
--- a/doc/examples/posix-locks.vol
+++ b/doc/examples/legacy/posix-locks.vol
@@ -1,10 +1,10 @@
-
volume brick
type storage/posix # POSIX FS translator
option directory /home/export # Export this directory
end-volume
-### 'Posix-locks' feature should be added on the server side (as posix volume as subvolume) because it contains the actual file.
+# 'Posix-locks' feature should be added on the server side.
+
volume p-locks
type features/posix-locks
subvolumes brick
@@ -13,8 +13,7 @@ end-volume
volume server
type protocol/server
- subvolumes p-locks brick
+ subvolumes p-locks
option transport-type tcp
- option auth.addr.brick.allow 192.168.* # Allow access to "brick" volume
option auth.addr.p-locks.allow 192.168.* # Allow access to "p-locks" volume
end-volume
diff --git a/doc/examples/legacy/protocol-client.vol b/doc/examples/legacy/protocol-client.vol
new file mode 100644
index 000000000..c34ef790d
--- /dev/null
+++ b/doc/examples/legacy/protocol-client.vol
@@ -0,0 +1,12 @@
+volume client
+ type protocol/client
+ option transport-type tcp # for TCP/IP transport
+ option remote-host 192.168.1.10 # IP address of the remote brick
+# option transport.socket.remote-port 24016
+
+# option transport-type rdma # for Infiniband verbs transport
+# option transport.rdma.work-request-send-count 16
+# option transport.rdma.work-request-recv-count 16
+# option transport.rdma.remote-port 24016
+ option remote-subvolume brick # name of the remote volume
+end-volume
diff --git a/doc/examples/protocol-server.vol b/doc/examples/legacy/protocol-server.vol
index e8e4a4643..195e49657 100644
--- a/doc/examples/protocol-server.vol
+++ b/doc/examples/legacy/protocol-server.vol
@@ -1,4 +1,3 @@
-
### Export volume "brick" with the contents of "/home/export" directory.
volume brick
type storage/posix # POSIX FS translator
@@ -9,17 +8,14 @@ end-volume
volume server
type protocol/server
option transport-type tcp # For TCP/IP transport
-# option transport.socket.listen-port 24016
+# option transport.socket.listen-port 24016
-# option transport-type ib-verbs # For Infiniband Verbs transport
-# option transport.ib-verbs.work-request-send-size 131072
-# option transport.ib-verbs.work-request-send-count 64
-# option transport.ib-verbs.work-request-recv-size 131072
-# option transport.ib-verbs.work-request-recv-count 64
-# option transport.ib-verbs.listen-port 24016
+# option transport-type rdma
+# option transport.rdma.work-request-send-count 64
+# option transport.rdma.work-request-recv-count 64
+# option transport.rdma.listen-port 24016
# option bind-address 192.168.1.10 # Default is to listen on all interfaces
-# option client-volume-filename /etc/glusterfs/glusterfs-client.vol
- subvolumes brick
+ subvolumes brick
option auth.addr.brick.allow 192.168.* # Allow access to "brick" volume
end-volume
diff --git a/doc/examples/read-ahead.vol b/doc/examples/legacy/read-ahead.vol
index 3ce0d95ac..9e4dba556 100644
--- a/doc/examples/read-ahead.vol
+++ b/doc/examples/legacy/read-ahead.vol
@@ -8,15 +8,17 @@ end-volume
## In normal clustered storage type, any of the cluster translators can come here.
#
# Definition of other clients
-#
-# Definition of cluster translator (may be unify, replicate, or unify over replicate)
-#
+#
+# Definition of cluster translator (may be distribute, replicate, or distribute
+# over replicate)
+#
+
+# 'Read-Ahead' translator is best utilized on client side, as it prefetches
+# the file contents when the first read() call is issued.
-### 'Read-Ahead' translator is best utilized on client side, as it prefetches the file contents when the first read() call is issued.
volume ra
type performance/read-ahead
- subvolumes client # In this example it is 'client' you may have to change it according to your spec file.
- option page-size 1MB # default is 256KB
+ subvolumes client
option page-count 4 # default is 2
option force-atime-update no # defalut is 'no'
end-volume
diff --git a/doc/examples/replicate.vol b/doc/examples/legacy/replicate.vol
index 333ba7de1..10626d46f 100644
--- a/doc/examples/replicate.vol
+++ b/doc/examples/legacy/replicate.vol
@@ -1,5 +1,6 @@
### 'NOTE'
-# This file has both server spec and client spec to get an understanding of stripe's spec file. Hence can't be used as it is, as a GlusterFS spec file.
+# This file has both server spec and client spec to get an understanding of
+# replicate spec file. Hence can't be used as it is, as a GlusterFS spec file.
# One need to seperate out server spec and client spec to get it working.
#=========================================================================
@@ -23,8 +24,7 @@ end-volume
volume server
type protocol/server
option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24016
-# option client-volume-filename /etc/glusterfs/glusterfs-client.vol
+ option transport.socket.listen-port 24016
subvolumes brick1
option auth.addr.brick1.allow * # access to "brick" volume
end-volume
@@ -49,7 +49,7 @@ end-volume
volume server
type protocol/server
option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24017
+ option transport.socket.listen-port 24017
subvolumes brick2
option auth.addr.brick2.allow * # Allow access to "brick" volume
end-volume
@@ -75,7 +75,7 @@ end-volume
volume server
type protocol/server
option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24018
+ option transport.socket.listen-port 24018
subvolumes brick3
option auth.addr.brick3.allow * # access to "brick" volume
end-volume
@@ -90,7 +90,7 @@ volume client1
type protocol/client
option transport-type tcp # for TCP/IP transport
option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24016
+ option transport.socket.remote-port 24016
option remote-subvolume brick1 # name of the remote volume
end-volume
@@ -99,7 +99,7 @@ volume client2
type protocol/client
option transport-type tcp # for TCP/IP transport
option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24017
+ option transport.socket.remote-port 24017
option remote-subvolume brick2 # name of the remote volume
end-volume
@@ -107,7 +107,7 @@ volume client3
type protocol/client
option transport-type tcp # for TCP/IP transport
option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24018
+ option transport.socket.remote-port 24018
option remote-subvolume brick3 # name of the remote volume
end-volume
@@ -116,4 +116,3 @@ volume replicate
type cluster/replicate
subvolumes client1 client2 client3
end-volume
-
diff --git a/doc/examples/stripe.vol b/doc/examples/legacy/stripe.vol
index 6055b66b9..9524e8198 100644
--- a/doc/examples/stripe.vol
+++ b/doc/examples/legacy/stripe.vol
@@ -1,6 +1,7 @@
### 'NOTE'
-# This file has both server spec and client spec to get an understanding of stripe's spec file. Hence can't be used as it is, as a GlusterFS spec file.
+# This file has both server spec and client spec to get an understanding of
+# stripe's spec file. Hence can't be used as it is, as a GlusterFS spec file.
# One need to seperate out server spec and client spec to get it working.
#=========================================================================
@@ -24,8 +25,7 @@ end-volume
volume server
type protocol/server
option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24016
-# option client-volume-filename /etc/glusterfs/glusterfs-client.vol
+ option transport.socket.listen-port 24016
subvolumes brick1
option auth.addr.brick1.allow * # access to "brick" volume
end-volume
@@ -50,7 +50,7 @@ end-volume
volume server
type protocol/server
option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24017
+ option transport.socket.listen-port 24017
subvolumes brick2
option auth.addr.brick2.allow * # Allow access to "brick" volume
end-volume
@@ -76,7 +76,7 @@ end-volume
volume server
type protocol/server
option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24018
+ option transport.socket.listen-port 24018
subvolumes brick3
option auth.addr.brick3.allow * # access to "brick" volume
end-volume
@@ -91,7 +91,7 @@ volume client1
type protocol/client
option transport-type tcp # for TCP/IP transport
option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24016
+ option transport.socket.remote-port 24016
option remote-subvolume brick1 # name of the remote volume
end-volume
@@ -100,7 +100,7 @@ volume client2
type protocol/client
option transport-type tcp # for TCP/IP transport
option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24017
+ option transport.socket.remote-port 24017
option remote-subvolume brick2 # name of the remote volume
end-volume
@@ -108,7 +108,7 @@ volume client3
type protocol/client
option transport-type tcp # for TCP/IP transport
option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24018
+ option transport.socket.remote-port 24018
option remote-subvolume brick3 # name of the remote volume
end-volume
@@ -118,4 +118,3 @@ volume stripe
subvolumes client1 client2 client3
option block-size 1MB
end-volume
-
diff --git a/doc/examples/trace.vol b/doc/examples/legacy/trace.vol
index 3f4864db4..59830f26a 100644
--- a/doc/examples/trace.vol
+++ b/doc/examples/legacy/trace.vol
@@ -5,12 +5,17 @@ volume client
option remote-subvolume brick # name of the remote volume
end-volume
-### 'Trace' translator is a very handy debug tool for GlusterFS, as it can be loaded between any of the two volumes without changing the behaviour of the filesystem.
-# On client side it can be the top most volume in spec (like now) to understand what calls are made on FUSE filesystem, when a mounted filesystem is accessed.
+### 'Trace' translator is a very handy debug tool for GlusterFS, as it can be
+# loaded between any of the two volumes without changing the behaviour of the
+# filesystem.
+# On client side it can be the top most volume in spec (like now) to understand
+# what calls are made on FUSE filesystem, when a mounted filesystem is
+# accessed.
volume trace
type debug/trace
subvolumes client
end-volume
-# 'NOTE:' By loading 'debug/trace' translator, filesystem will be very slow as it logs each and every calls to the log file.
+# 'NOTE:' By loading 'debug/trace' translator, filesystem will be very slow as
+# it logs each and every calls to the log file.
diff --git a/doc/examples/trash.vol b/doc/examples/legacy/trash.vol
index 16e71be32..3fcf315af 100644
--- a/doc/examples/trash.vol
+++ b/doc/examples/legacy/trash.vol
@@ -1,10 +1,11 @@
-
volume brick
type storage/posix # POSIX FS translator
option directory /home/export # Export this directory
end-volume
-### 'Trash' translator is best used on server side as it just renames the deleted file inside 'trash-dir', and it makes 4 seperate fops for one unlink call.
+### 'Trash' translator is best used on server side as it just renames the
+# deleted file inside 'trash-dir', and it makes 4 seperate fops for one unlink
+# call.
volume trashcan
type features/trash
subvolumes brick
@@ -13,8 +14,7 @@ end-volume
volume server
type protocol/server
- subvolumes trashcan brick
+ subvolumes trashcan
option transport-type tcp # For TCP/IP transport
option auth.addr.brick.allow 192.168.* # Allow access to "brick" volume
- option auth.addr.trashcan.allow 192.168.* # Allow access to "p-locks" volume
end-volume
diff --git a/doc/examples/write-behind.vol b/doc/examples/legacy/write-behind.vol
index 9c6bae11c..2b5ed4139 100644
--- a/doc/examples/write-behind.vol
+++ b/doc/examples/legacy/write-behind.vol
@@ -8,19 +8,20 @@ end-volume
## In normal clustered storage type, any of the cluster translators can come here.
#
# Definition of other clients
-#
+#
# Definition of cluster translator (may be unify, replicate, or unify over replicate)
-#
+#
-### 'Write-behind' translator is a performance booster for write operation. Best used on client side, as its main intension is to reduce the network latency caused for each write operation.
+# 'Write-behind' translator is a performance booster for write operation. Best
+# used on client side, as its main intension is to reduce the network latency
+# caused for each write operation.
volume wb
type performance/write-behind
- subvolumes client # In this example it is 'client' you may have to change it according to your spec file.
+ subvolumes client
option flush-behind on # default value is 'off'
option window-size 2MB
- option aggregate-size 1MB # default value is 0
- option enable_O_SYNC no # default is no
- option disable-for-first-nbytes 128KB #default is 1
+ option enable-O_SYNC no # default is no
+ option disable-for-first-nbytes 128KB #default is 1
end-volume
diff --git a/doc/examples/protocol-client.vol b/doc/examples/protocol-client.vol
deleted file mode 100644
index 43c43e02d..000000000
--- a/doc/examples/protocol-client.vol
+++ /dev/null
@@ -1,17 +0,0 @@
-volume client
- type protocol/client
- option transport-type tcp # for TCP/IP transport
-# option transport-type ib-sdp # for Infiniband transport
- option remote-host 192.168.1.10 # IP address of the remote brick
-# option transport.socket.remote-port 24016
-
-# option transport-type ib-verbs # for Infiniband verbs transport
-# option transport.ib-verbs.work-request-send-size 1048576
-# option transport.ib-verbs.work-request-send-count 16
-# option transport.ib-verbs.work-request-recv-size 1048576
-# option transport.ib-verbs.work-request-recv-count 16
-# option transport.ib-verbs.remote-port 24016
-
- option remote-subvolume brick # name of the remote volume
-# option transport-timeout 30 # default value is 120seconds
-end-volume
diff --git a/doc/examples/unify.vol b/doc/examples/unify.vol
deleted file mode 100644
index 3fb7e8320..000000000
--- a/doc/examples/unify.vol
+++ /dev/null
@@ -1,178 +0,0 @@
-### 'NOTE'
-# This file has both server spec and client spec to get an understanding of stripe's spec file. Hence can't be used as it is, as a GlusterFS spec file.
-# One need to seperate out server spec and client spec to get it working.
-
-
-#=========================================================================
-
-# **** server1 spec file ****
-
-### Export volume "brick" with the contents of "/home/export" directory.
-volume posix1
- type storage/posix # POSIX FS translator
- option directory /home/export1 # Export this directory
-end-volume
-
-### Add POSIX record locking support to the storage brick
-volume brick1
- type features/posix-locks
- option mandatory on # enables mandatory locking on all files
- subvolumes posix1
-end-volume
-
-### Add network serving capability to above brick.
-volume server
- type protocol/server
- option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24016
-# option client-volume-filename /etc/glusterfs/glusterfs-client.vol
- subvolumes brick1
- option auth.addr.brick1.allow * # access to "brick" volume
-end-volume
-
-
-#=========================================================================
-
-# **** server2 spec file ****
-volume posix2
- type storage/posix # POSIX FS translator
- option directory /home/export2 # Export this directory
-end-volume
-
-### Add POSIX record locking support to the storage brick
-volume brick2
- type features/posix-locks
- option mandatory on # enables mandatory locking on all files
- subvolumes posix2
-end-volume
-
-### Add network serving capability to above brick.
-volume server
- type protocol/server
- option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24017
- subvolumes brick2
- option auth.addr.brick2.allow * # Allow access to "brick" volume
-end-volume
-
-
-#=========================================================================
-
-# **** server3 spec file ****
-
-volume posix3
- type storage/posix # POSIX FS translator
- option directory /home/export3 # Export this directory
-end-volume
-
-### Add POSIX record locking support to the storage brick
-volume brick3
- type features/posix-locks
- option mandatory on # enables mandatory locking on all files
- subvolumes posix3
-end-volume
-
-### Add network serving capability to above brick.
-volume server
- type protocol/server
- option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24018
- subvolumes brick3
- option auth.addr.brick3.allow * # access to "brick" volume
-end-volume
-
-#=========================================================================
-
-# *** server for namespace ***
-### Export volume "brick" with the contents of "/home/export" directory.
-volume brick-ns
- type storage/posix # POSIX FS translator
- option directory /home/export-ns # Export this directory
-end-volume
-
-volume server
- type protocol/server
- option transport-type tcp # For TCP/IP transport
- option transport.socket.listen-port 24019
- subvolumes brick-ns
- option auth.addr.brick-ns.allow * # access to "brick" volume
-end-volume
-
-
-#=========================================================================
-
-# **** Clustered Client config file ****
-
-### Add client feature and attach to remote subvolume of server1
-volume client1
- type protocol/client
- option transport-type tcp # for TCP/IP transport
-# option transport-type ib-sdp # for Infiniband transport
- option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24016
- option remote-subvolume brick1 # name of the remote volume
-end-volume
-
-### Add client feature and attach to remote subvolume of server2
-volume client2
- type protocol/client
- option transport-type tcp # for TCP/IP transport
-# option transport-type ib-sdp # for Infiniband transport
- option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24017
- option remote-subvolume brick2 # name of the remote volume
-end-volume
-
-volume client3
- type protocol/client
- option transport-type tcp # for TCP/IP transport
-# option transport-type ib-sdp # for Infiniband transport
- option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24018
- option remote-subvolume brick3 # name of the remote volume
-end-volume
-
-
-volume client-ns
- type protocol/client
- option transport-type tcp # for TCP/IP transport
-# option transport-type ib-sdp # for Infiniband transport
- option remote-host 127.0.0.1 # IP address of the remote brick
- option transport.socket.remote-port 24019
- option remote-subvolume brick-ns # name of the remote volume
-end-volume
-
-### Add unify feature to cluster the servers. Associate an
-### appropriate scheduler that matches your I/O demand.
-volume bricks
- type cluster/unify
- option namespace client-ns # this will not be storage child of unify.
- subvolumes client1 client2 client3
-### ** ALU Scheduler Option **
- option self-heal background # foreground off # default is foreground
- option scheduler alu
- option alu.limits.min-free-disk 5% #%
- option alu.limits.max-open-files 10000
- option alu.order disk-usage:read-usage:write-usage:open-files-usage:disk-speed-usage
- option alu.disk-usage.entry-threshold 2GB
- option alu.disk-usage.exit-threshold 128MB
- option alu.open-files-usage.entry-threshold 1024
- option alu.open-files-usage.exit-threshold 32
- option alu.read-usage.entry-threshold 20 #%
- option alu.read-usage.exit-threshold 4 #%
- option alu.write-usage.entry-threshold 20 #%
- option alu.write-usage.exit-threshold 4 #%
- option alu.disk-speed-usage.entry-threshold 0 # DO NOT SET IT. SPEED IS CONSTANT!!!.
- option alu.disk-speed-usage.exit-threshold 0 # DO NOT SET IT. SPEED IS CONSTANT!!!.
- option alu.stat-refresh.interval 10sec
- option alu.stat-refresh.num-file-create 10
-### ** Random Scheduler **
-# option scheduler random
-### ** NUFA Scheduler **
-# option scheduler nufa
-# option nufa.local-volume-name posix1
-### ** Round Robin (RR) Scheduler **
-# option scheduler rr
-# option rr.limits.min-free-disk 5% #%
-end-volume
-
diff --git a/doc/gluster.8 b/doc/gluster.8
index e99e98e99..7ff07d62e 100644
--- a/doc/gluster.8
+++ b/doc/gluster.8
@@ -1,17 +1,17 @@
.\" Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
.\" This file is part of GlusterFS.
.\"
-.\" GlusterFS is GF_FREE software; you can redistribute it and/or modify
-.\" it under the terms of the GNU Affero General Public License as published
+.\" GlusterFS is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published
.\" by the Free Software Foundation; either version 3 of the License,
.\" or (at your option) any later version.
.\"
.\" GlusterFS is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-.\" Affero General Public License for more details.
+.\" General Public License for more details.
.\"
-.\" You should have received a copy of the GNU Affero General Public License
+.\" You should have received a copy of the GNU General Public License
.\" along with this program. If not, see " <http://www.gnu.org/licenses/>.
.\"
.\"
@@ -36,13 +36,16 @@ To specify a command directly:
The Gluster Console Manager is a command line utility for elastic volume management. You can run the gluster command on any export server. The command enables administrators to perform cloud operations, such as creating, expanding, shrinking, rebalancing, and migrating volumes without needing to schedule server downtime.
.SH COMMANDS
-.SS "Volume Commands"
+.SS "Basic Volume Commands"
.PP
.TP
\fB\ volume info [all|<VOLNAME>] \fR
Display information about all volumes, or the specified volume.
.TP
+\fB\ volume list \fR
+List the available volumes.
+.TP
\fB\ volume create <NEW-VOLNAME> [stripe <COUNT>] [replica <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... \fR
Create a new volume of the specified type using the specified bricks and transport type (the default transport type is tcp).
To create a volume with both transports (tcp and rdma), give 'transport tcp,rdma' as an option.
@@ -56,46 +59,82 @@ Start the specified volume.
\fB\ volume stop <VOLNAME> [force] \fR
Stop the specified volume.
.TP
-\fB\ volume rename <VOLNAME> <NEW-VOLNAME> \fR
-Rename the specified volume.
-.TP
\fB\ volume set <VOLNAME> <OPTION> <PARAMETER> [<OPTION> <PARAMETER>] ... \fR
-Set the volume options.
+Set the given volume options.
+.TP
+\fB\ volume reset [<OPTION>] [force] \fR
+Reset all or the given volume options.
.TP
\fB\ volume help \fR
Display help for the volume command.
+
.SS "Brick Commands"
.PP
.TP
-\fB\ volume add-brick <VOLNAME> <NEW-BRICK> ... \fR
-Add the specified brick to the specified volume.
+\fB\ volume add-brick <VOLNAME> [<stripe|replica> <COUNT>] <NEW-BRICK> ... \fR
+Add the specified bricks to the specified volume.
.TP
-\fB\ volume remove-brick <VOLNAME> <BRICK> ... \fR
-Remove the specified brick from the specified volume.
-.IP
-.B Note:
-If you remove the brick, the data stored in that brick will not be available. You can migrate data from one brick to another using
-.B replace-brick
-option.
+\fB\ volume remove-brick <VOLNAME> [replica <COUNT>] <BRICK> ... {start|stop|status|commit|force} \fR
+Remove the specified bricks from the specified volume.
.TP
-\fB\ volume rebalance-brick <VOLNAME>(<BRICK> <NEW-BRICK>) start \fR
-Start rebalancing the specified volume.
-.TP
-\fB\ volume rebalance <VOLNAME> stop \fR
-Stop rebalancing the specified volume.
-.TP
-\fB\ volume rebalance <VOLNAME> status \fR
-Display the rebalance status of the specified volume.
+\fB\ volume rebalance <VOLNAME> [fix-layout] {start|stop|status} [force] \fR
+Performs rebalance operation on the volume.
.TP
\fB\ volume replace-brick <VOLNAME> (<BRICK> <NEW-BRICK>) start|pause|abort|status|commit \fR
Replace the specified brick.
-.SS "Log Commands"
+
+.SS "Quota Commands"
+.PP
+.TP
+\fB\ volume quota <VOLNAME> {enable|disable} \fR
+Enable or disable quota on a volume
+.TP
+\fB\ volume quota <VOLNAME> limit-usage <PATH> <VALUE> \fR
+Set quoata on PATH to VALUE
.TP
-\fB\ volume log filename <VOLNAME> [BRICK] <DIRECTORY> \fB
-Set the log directory for the corresponding volume/brick.
+\fB\ volume quota <VOLNAME> remove <PATH> \fR
+Remove quota on path
+.TP
+\fB\ volume quota <VOLNAME> list \fR
+List the set quotas
+
+.SS "Volume Monitoring Commands"
+.PP
.TP
-\fB\volume log locate <VOLNAME> [BRICK] \fB
-Locate the log file for corresponding volume/brick.
+\fB\ volume profile <VOLNAME> {start|stop} \fR
+Start or stop profiling a volume.
+.TP
+\fB\ volume profile <VOLNAME> info [nfs] \fR
+Show the gathered profiling information for the volume.
+.TP
+\fB\ volume top <VOLNAME> {open|read|write|opendir|readdir} [nfs] [brick <BRICK>] [list-cnt <COUNT>] \fR
+Display the counts of specified operation in the volume.
+.TP
+\fB\ volume top <VOLNAME> {read-perf|write-perf} [nfs | {bs <SIZE} count <COUNT>] [brick <BRICK>] [list-cnt <COUNT>]\fR
+Display the throughput of the volume.
+.TP
+\fB\ volume status [all| {<VOLNAME> [nfs|shd|<BRICK>]] [detail|clients|mem|inode|fd|callpool] \fR
+Display the present status of the processes of specified volume.
+
+.SS "Other Volume Commands"
+.PP
+.TP
+\fB\ volume geo-replication [<VOLNAME>] [<SLAVE-URL>] {start|stop|config|status|log-rotate} [options...] \fR
+Geo-replication operations
+.TP
+\fB\ volume heal <VOLNAME> [{full | info {healed|heal-failed|split-brain}}] \fR
+Self-heal commands
+.TP
+\fB\ volume clear-locks <VOLNAME> <PATH> kind {blocked|granted|all} {inode <RANGE>|entry <BASENAME>|posix <RANGE>} \fR
+Clear locks held on path in the volume
+.TP
+\fB\ volume statedump <VOLNAME> [nfs] [all|mem|iobuf|callpool|priv|fd|inode|history]
+Perform a statedump of the brick or nfs-server processes of the volume
+.TP
+\fB\ volume sync <HOSTNAME> [all|<VOLNAME>] \fR
+Sync volume information from specified peer
+
+.SS "Log Commands"
.TP
\fB\ volume log rotate <VOLNAME> [BRICK] \fB
Rotate the log file for corresponding volume/brick.
diff --git a/doc/glusterd.8 b/doc/glusterd.8
index 43c1570f6..267a7e00f 100644
--- a/doc/glusterd.8
+++ b/doc/glusterd.8
@@ -2,17 +2,17 @@
.\" Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
.\" This file is part of GlusterFS.
.\"
-.\" GlusterFS is GF_FREE software; you can redistribute it and/or modify
-.\" it under the terms of the GNU Affero General Public License as published
+.\" GlusterFS is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published
.\" by the Free Software Foundation; either version 3 of the License,
.\" or (at your option) any later version.
.\"
.\" GlusterFS is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-.\" Affero General Public License for more details.
+.\" General Public License for more details.
.\"
-.\" You should have received a copy of the GNU Affero General Public License
+.\" You should have received a copy of the GNU General Public License
.\" along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
@@ -33,10 +33,10 @@ The glusterd daemon is used for elastic volume management. The daemon must be ru
.PP
.TP
-\fB\-l=<LOGFILE>, \fB\-\-log\-file=<LOGFILE>\fR
+\fB\-l <LOGFILE>, \fB\-\-log\-file=<LOGFILE>\fR
File to use for logging.
.TP
-\fB\-L=<LOGLEVEL>, \fB\-\-log\-level=<LOGLEVEL>\fR
+\fB\-L <LOGLEVEL>, \fB\-\-log\-level=<LOGLEVEL>\fR
Logging severity. Valid options are TRACE, DEBUG, INFO, WARNING, ERROR and CRITICAL (the default is INFO).
.TP
\fB\-\-debug\fR
diff --git a/doc/glusterd.vol b/doc/glusterd.vol
index 4e43fb0da..de17d8fd8 100644
--- a/doc/glusterd.vol
+++ b/doc/glusterd.vol
@@ -1,8 +1,8 @@
volume management
type mgmt/glusterd
- option working-directory /etc/glusterd
+ option working-directory /var/lib/glusterd
option transport-type socket,rdma
option transport.socket.keepalive-time 10
option transport.socket.keepalive-interval 2
+ option transport.socket.read-fail-log off
end-volume
-
diff --git a/doc/glusterfs.8 b/doc/glusterfs.8
index 7e4b2b49d..be4448e40 100644
--- a/doc/glusterfs.8
+++ b/doc/glusterfs.8
@@ -2,16 +2,16 @@
.\" This file is part of GlusterFS.
.\"
.\" GlusterFS is free software; you can redistribute it and/or modify
-.\" it under the terms of the GNU Affero General Public License as published
+.\" it under the terms of the GNU General Public License as published
.\" by the Free Software Foundation; either version 3 of the License,
.\" or (at your option) any later version.
.\"
.\" GlusterFS is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-.\" Affero General Public License for more details.
+.\" General Public License for more details.
.\"
-.\" You should have received a copy of the GNU Affero General Public License
+.\" You should have received a copy of the GNU General Public License
.\" long with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
@@ -32,7 +32,8 @@ be made of any commodity hardware, such as x86-64 server with SATA-II RAID and
Infiniband HBA.
GlusterFS is fully POSIX compliant file system. On client side, it has dependency
-on FUSE package, on server side, it works seemlessly on different operating systems. Currently supported on GNU/Linux and Solaris.
+on FUSE package, on server side, it works seemlessly on different operating systems.
+Currently supported on GNU/Linux and Solaris.
.SH OPTIONS
@@ -40,33 +41,55 @@ on FUSE package, on server side, it works seemlessly on different operating syst
.PP
.TP
\fB\-f, \fB\-\-volfile=VOLUME-FILE\fR
-File to use as VOLUME-FILE (the default is /etc/glusterfs/glusterfs.vol).
+File to use as VOLUME-FILE.
.TP
\fB\-l, \fB\-\-log\-file=LOGFILE\fR
-File to use for logging.
+File to use for logging (the default is <INSTALL-DIR>/var/log/glusterfs/<MOUNT-POINT>.log).
.TP
\fB\-L, \fB\-\-log\-level=LOGLEVEL\fR
-Logging severity. Valid options are TRACE, DEBUG, INFO, WARNING, ERROR and CRITICAL (the default is WARNING).
+Logging severity. Valid options are TRACE, DEBUG, INFO, WARNING, ERROR and CRITICAL (the default is INFO).
.TP
\fB\-s, \fB\-\-volfile\-server=SERVER\fR
Server to get the volume from. This option overrides \fB\-\-volfile \fR option.
+.TP
+\fB\-\-volfile\-max\-fetch\-attempts=MAX\-ATTEMPTS\fR
+Maximum number of connect attempts to server. This option should be provided with
+\fB\-\-volfile\-server\fR option (the default is 1).
.SS "Advanced options"
.PP
.TP
+\fB\-\-acl\fR
+Mount the filesystem with POSIX ACL support.
+.TP
\fB\-\-debug\fR
Run in debug mode. This option sets \fB\-\-no\-daemon\fR, \fB\-\-log\-level\fR to DEBUG,
and \fB\-\-log\-file\fR to console.
.TP
+\fB\-\-enable\-ino32=BOOL\fR
+Use 32-bit inodes when mounting to workaround application that doesn't support 64-bit inodes.
+.TP
+\fB\-\-fopen\-keep\-cache\fR
+Do not purge the cache on file open.
+.TP
+\fB\-\-mac\-compat=BOOL\fR
+Provide stubs for attributes needed for seamless operation on Macs (the default is off).
+.TP
\fB\-N, \fB\-\-no\-daemon\fR
Run in the foreground.
.TP
-\fB\-\-read\-only\fR
-Make the file system read-only.
-.TP
\fB\-p, \fB\-\-pid\-file=PIDFILE\fR
File to use as PID file.
.TP
+\fB\-\-read\-only\fR
+Mount the file system in 'read-only' mode.
+.TP
+\fB\-\-selinux\fR
+Enable SELinux label (extended attributes) support on inodes.
+.TP
+\fB\-S, \fB\-\-socket\-file=SOCKFILE\fR
+File to use as unix-socket.
+.TP
\fB\-\-volfile\-id=KEY\fR
Key of the volume file to be fetched from the server.
.TP
@@ -74,11 +97,14 @@ Key of the volume file to be fetched from the server.
Port number of volfile server.
.TP
\fB\-\-volfile\-server\-transport=TRANSPORT\fR
-Transport type to get volume file from server (the deafult is socket).
+Transport type to get volume file from server (the default is socket).
.TP
\fB\-\-volume\-name=VOLUME\-NAME\fR
Volume name to be used for MOUNT-POINT (the default is top most volume in VOLUME-FILE).
.TP
+\fB\-\-worm\fR
+Mount the filesystem in 'worm' mode.
+.TP
\fB\-\-xlator\-option=VOLUME\-NAME.OPTION=VALUE\fR
Add/Override a translator option for a volume with the specified value.
@@ -89,11 +115,29 @@ Add/Override a translator option for a volume with the specified value.
\fB\-\-attribute\-timeout=SECONDS\fR
Set attribute timeout to SECONDS for inodes in fuse kernel module (the default is 1).
.TP
-\fB\-\-entry\-timeout=SECONDS\fR
-Set entry timeout to SECONDS in fuse kernel module (the default is 1).
+\fB\-\-background\-qlen=N\fR
+Set fuse module's background queue length to N (the default is 64).
+.TP
+\fB\-\-congestion\-threshold=N\fR
+Set fuse module's congestion threshold to N (the default is 48).
.TP
\fB\-\-direct\-io\-mode=BOOL\fR
Enable/Disable the direct-I/O mode in fuse module (the default is enable).
+.TP
+\fB\-\-dump-fuse=PATH\f\R
+Dump fuse traffic to PATH
+.TP
+\fB\-\-entry\-timeout=SECONDS\fR
+Set entry timeout to SECONDS in fuse kernel module (the default is 1).
+.TP
+\fB\-\-gid\-timeout=SECONDS\fR
+Set auxilary group list timeout to SECONDS for fuse translator (the default is 0).
+.TP
+\fB\-\-negative\-timeout=SECONDS\fR
+Set negative timeout to SECONDS in fuse kernel module (the default is 0).
+.TP
+\fB\-\-volfile-check\fR
+Enable strict volume file checking.
.SS "Miscellaneous Options"
.PP
@@ -102,7 +146,7 @@ Enable/Disable the direct-I/O mode in fuse module (the default is enable).
\fB\-?, \fB\-\-help\fR
Display this help.
.TP
-\fB\-\-usage\fReew
+\fB\-\-usage\fR
Display a short usage message.
.TP
\fB\-V, \fB\-\-version\fR
@@ -110,7 +154,12 @@ Print the program version.
.PP
.SH FILES
-/etc/glusterfs/*.vol, /etc/glusterd/vols/*/*.vol
+/var/lib/glusterd/vols/*/*.vol
+.SH EXAMPLES
+mount a volume named foo on server bar with log level DEBUG on mount point
+/mnt/foo
+
+# glusterfs \-\-log\-level=DEBUG \-\-volfile\-id=foo \-\-volfile\-server=bar /mnt/foo
.SH SEE ALSO
.nf
@@ -119,6 +168,6 @@ Print the program version.
.fi
.SH COPYRIGHT
.nf
-Copyright(c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+Copyright(c) 2006-2011 Red Hat, Inc. <http://www.redhat.com>
\fR
.fi
diff --git a/doc/glusterfs.vol.sample b/doc/glusterfs.vol.sample
index 3b1f18517..977363b92 100644
--- a/doc/glusterfs.vol.sample
+++ b/doc/glusterfs.vol.sample
@@ -8,7 +8,7 @@
### "#" is comment character.
### - Config file is case sensitive
### - Options within a volume block can be in any order.
-### - Spaces or tabs are used as delimitter within a line.
+### - Spaces or tabs are used as delimitter within a line.
### - Each option should end within a line.
### - Missing or commented fields will assume default values.
### - Blank/commented lines are allowed.
@@ -21,24 +21,19 @@ volume client
# option transport-type unix
# option transport-type ib-sdp
option remote-host 127.0.0.1 # IP address of the remote brick
-# option transport.socket.remote-port 24016
+# option transport.socket.remote-port 24016
-# option transport-type ib-verbs
-# option transport.ib-verbs.remote-port 24016
-# option transport.ib-verbs.work-request-send-size 1048576
-# option transport.ib-verbs.work-request-send-count 16
-# option transport.ib-verbs.work-request-recv-size 1048576
-# option transport.ib-verbs.work-request-recv-count 16
+# option transport-type rdma
+# option transport.rdma.remote-port 24016
+# option transport.rdma.work-request-send-count 16
+# option transport.rdma.work-request-recv-count 16
-# option transport-timeout 30 # seconds to wait for a reply
- # from server for each request
option remote-subvolume brick # name of the remote volume
end-volume
### Add readahead feature
#volume readahead
# type performance/read-ahead
-# option page-size 1MB # unit in bytes
# option page-count 2 # cache per file = (page-count x page-size)
# subvolumes client
#end-volume
@@ -46,16 +41,13 @@ end-volume
### Add IO-Cache feature
#volume iocache
# type performance/io-cache
-# option page-size 256KB
-# option page-count 2
# subvolumes readahead
#end-volume
### Add writeback feature
#volume writeback
# type performance/write-behind
-# option aggregate-size 1MB
# option window-size 2MB
# option flush-behind off
-# subvolumes iocache
+# subvolumes iocache
#end-volume
diff --git a/doc/glusterfsd.8 b/doc/glusterfsd.8
index dbf3e3fda..17d053a5c 100644
--- a/doc/glusterfsd.8
+++ b/doc/glusterfsd.8
@@ -2,16 +2,16 @@
.\" This file is part of GlusterFS.
.\"
.\" GlusterFS is free software; you can redistribute it and/or modify
-.\" it under the terms of the GNU Affero General Public License as published
+.\" it under the terms of the GNU General Public License as published
.\" by the Free Software Foundation; either version 3 of the License,
.\" or (at your option) any later version.
.\"
.\" GlusterFS is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-.\" Affero General Public License for more details.
+.\" General Public License for more details.
.\"
-.\" You should have received a copy of the GNU Affero General Public License
+.\" You should have received a copy of the GNU General Public License
.\" long with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
@@ -73,6 +73,15 @@ Makes the filesystem read-only
\fB\-p, \fB\-\-pid\-file=PIDFILE\fR
File to use as pid file
.TP
+\fB\-S SOCKFILE
+Socket file to used for inter-process communication
+.TP
+\fB\-\-brick\-name DIRECTORY
+Directory to be used as export directory for GlusterFS
+.TP
+\fB\-\-brick\-port PORT
+Brick Port to be registered with Gluster portmapper
+.TP
\fB\-\-volfile\-id=KEY\fR
KEY of the volume file to be fetched from server
.TP
@@ -119,6 +128,11 @@ Print program version
.SH FILES
/etc/glusterfs/*.vol
+.SH EXAMPLES
+Start a GlusterFS server on localhost with volume name foo
+
+glusterfsd \-s localhost \-\-volfile\-id foo.server.media-disk\-1 \-p /etc/glusterd/vols/foo/run/server\-media\-disk\-1.pid \-S /tmp/<uniqueid>.socket \-\-brick-name /media/disk\-1 \-l /var/log/glusterfs/bricks/media\-disk\-1.log \-\-brick\-port 24009 \-\-xlator\-option foo\-server.listen-port=24009
+
.SH SEE ALSO
.nf
\fBfusermount\fR(1), \fBmount.glusterfs\fR(8), \fBgluster\fR(8)
diff --git a/doc/glusterfsd.vol.sample b/doc/glusterfsd.vol.sample
index e91df3290..ec2fd341e 100644
--- a/doc/glusterfsd.vol.sample
+++ b/doc/glusterfsd.vol.sample
@@ -8,8 +8,8 @@
### "#" is comment character.
### - Config file is case sensitive
### - Options within a volume block can be in any order.
-### - Spaces or tabs are used as delimitter within a line.
-### - Multiple values to options will be : delimitted.
+### - Spaces or tabs are used as delimitter within a line.
+### - Multiple values to options will be : delimited.
### - Each option should end within a line.
### - Missing or commented fields will assume default values.
### - Blank/commented lines are allowed.
@@ -27,18 +27,15 @@ volume server
option transport-type tcp
# option transport-type unix
# option transport-type ib-sdp
-# option transport.socket.bind-address 192.168.1.10 # Default is to listen on all interfaces
-# option transport.socket.listen-port 24016
+# option transport.socket.bind-address 192.168.1.10 # Default is to listen
+ # on all interfaces
+# option transport.socket.listen-port 24016
-# option transport-type ib-verbs
-# option transport.ib-verbs.bind-address 192.168.1.10 # Default is to listen on all interfaces
-# option transport.ib-verbs.listen-port 24016
-# option transport.ib-verbs.work-request-send-size 131072
-# option transport.ib-verbs.work-request-send-count 64
-# option transport.ib-verbs.work-request-recv-size 131072
-# option transport.ib-verbs.work-request-recv-count 64
+# option transport-type rdma
+# option transport.rdma.listen-port 24016
+# option transport.rdma.work-request-send-count 64
+# option transport.rdma.work-request-recv-count 64
-# option client-volume-filename /etc/glusterfs/glusterfs-client.vol
subvolumes brick
# NOTE: Access to any volume through protocol/server is denied by
# default. You need to explicitly grant access through # "auth"
diff --git a/doc/authentication.txt b/doc/legacy/authentication.txt
index 70aafd933..73cb21d73 100644
--- a/doc/authentication.txt
+++ b/doc/legacy/authentication.txt
@@ -48,7 +48,7 @@
protocol/client:
option remote-subvolume foo-brick
* Client is connecting from a.b.c.d
-
+
protocol/server:
option auth.addr.foo-brick.allow a.b.c.d,e.f.g.h,i.j.k.l #, other ip addresses from which clients are allowed to connect to foo-brick
@@ -79,19 +79,19 @@
* reject only "user shoo from a.b.c.d"
protcol/client:
option remote-subvolume shoo-brick
-
+
protocol/server:
# observe that no "option auth.login.shoo-brick.allow shoo" given
# Also other users from a.b.c.d have to be explicitly allowed using auth.login.shoo-brick.allow ...
option auth.addr.shoo-brick.allow !a.b.c.d
- * reject only "user shoo" from a.b.c.d i.e., user shoo from a.b.c.d has to be rejected.
+ * reject only "user shoo" from a.b.c.d i.e., user shoo from a.b.c.d has to be rejected.
* same as reject only "user shoo from a.b.c.d" above, but rules have to be added whether to allow ip addresses (and users from those ips) other than a.b.c.d
****************************************************************************************************
* ip or username/password based authentication
-
+
* allow user foo or clients from a.b.c.d
protocol/client:
option remote-subvolume foo-brick
@@ -104,7 +104,7 @@
* reject user shoo or clients from a.b.c.d
protocol/client:
option remote-subvolume shoo-brick
-
+
protocol/server:
option auth.login.shoo-brick.allow <usernames other than shoo>
#for each username mentioned in the above <usernames other than shoo> list, specify password as below
diff --git a/doc/booster.txt b/doc/legacy/booster.txt
index 684ac8965..051401a28 100644
--- a/doc/booster.txt
+++ b/doc/legacy/booster.txt
@@ -1,6 +1,6 @@
Introduction
============
-* booster is a LD_PRELOADable library which boosts read/write performance by bypassing fuse for
+* booster is a LD_PRELOADable library which boosts read/write performance by bypassing fuse for
read() and write() calls.
Requirements
@@ -14,29 +14,29 @@ Design
* contents of client volume-file.
* mount point.
-* LD_PRELOADed booster.so maintains an hash table storing mount-points and libglusterfsclient handles
- so that handles are reused for files from same mount point.
+* LD_PRELOADed booster.so maintains an hash table storing mount-points and libglusterfsclient handles
+ so that handles are reused for files from same mount point.
* it also maintains a fdtable. fdtable maps the fd (integer) returned to application to fd (pointer to fd struct)
used by libglusterfsclient. application is returned the same fd as the one returned from libc apis.
* During fork, these tables are overwritten to enable creation of fresh glusterfs context in child.
-
+
Working
=======
-* application willing to use booster LD_PRELOADs booster.so which is a wrapper library implementing
+* application willing to use booster LD_PRELOADs booster.so which is a wrapper library implementing
open, read and write.
-* application should specify the path to logfile through the environment variable GLFS_BOOSTER_LOGFILE. If
+* application should specify the path to logfile through the environment variable GLFS_BOOSTER_LOGFILE. If
not specified, logging is done to /dev/stderr.
* open call does,
* real_open on the file.
* fgetxattr(fd).
- * store the volume-file content got in the dictionary to a temparory file.
- * look in the hashtable for the mount-point, if already present get the libglusterfsclient handle from the
- hashtable. Otherwise get a new handle from libglusterfsclient (be careful about mount point not present in
- the hashtable and multiple glusterfs_inits running simultaneously for the same mount-point there by using
+ * store the volume-file content got in the dictionary to a temporary file.
+ * look in the hashtable for the mount-point, if already present get the libglusterfsclient handle from the
+ hashtable. Otherwise get a new handle from libglusterfsclient (be careful about mount point not present in
+ the hashtable and multiple glusterfs_inits running simultaneously for the same mount-point there by using
multiple handles for the same mount point).
* real_close (fd).
* delete temporary volume-volfile.
@@ -51,4 +51,4 @@ Working
* close call does,
* remove the fd from the fdtable.
-* other calls use real_calls.
+* other calls use real_calls.
diff --git a/doc/coding-standard.pdf b/doc/legacy/coding-standard.pdf
index bc9cb5620..bc9cb5620 100644
--- a/doc/coding-standard.pdf
+++ b/doc/legacy/coding-standard.pdf
Binary files differ
diff --git a/doc/coding-standard.tex b/doc/legacy/coding-standard.tex
index 92f799c01..abaedb69c 100644
--- a/doc/coding-standard.tex
+++ b/doc/legacy/coding-standard.tex
@@ -27,7 +27,7 @@ purpose. The comment should be descriptive without being overly verbose.
\textsl{Good}:
\begin{verbatim}
- DBTYPE access_mode; /* access mode for accessing
+ DBTYPE access_mode; /* access mode for accessing
* the databases, can be
* DB_HASH, DB_BTREE
* (option access-mode <mode>)
@@ -69,7 +69,7 @@ Never use a non-constant expression as the initialization value for a variable.
\section*{$\bullet$ Validate all arguments to a function}
All pointer arguments to a function must be checked for \texttt{NULL}.
-A macro named \texttt{VALIDATE} (in \texttt{common-utils.h})
+A macro named \texttt{VALIDATE} (in \texttt{common-utils.h})
takes one argument, and if it is \texttt{NULL}, writes a log message and
jumps to a label called \texttt{err} after setting op\_ret and op\_errno
appropriately. It is recommended to use this template.
@@ -142,8 +142,8 @@ for success or failure.
\begin{verbatim}
op_ret = close (_fd);
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "close on file %s failed (%s)", real_path,
+ gf_log (this->name, GF_LOG_ERROR,
+ "close on file %s failed (%s)", real_path,
strerror (errno));
op_errno = errno;
goto out;
@@ -157,9 +157,9 @@ memory allocation fails, the call should be unwound and an error
returned to the user.
\section*{$\bullet$ Use result args and reserve the return value to indicate success or failure}
-The return value of every functions must indicate success or failure (unless
-it is impossible for the function to fail --- e.g., boolean functions). If
-the function needs to return additional data, it must be returned using a
+The return value of every functions must indicate success or failure (unless
+it is impossible for the function to fail --- e.g., boolean functions). If
+the function needs to return additional data, it must be returned using a
result (pointer) argument.
\vspace{2ex}
@@ -192,11 +192,11 @@ Unless impossible, use the length-limited versions of the string functions.
\end{verbatim}
\section*{$\bullet$ No dead or commented code}
-There must be no dead code (code to which control can never be passed) or
+There must be no dead code (code to which control can never be passed) or
commented out code in the codebase.
\section*{$\bullet$ Only one unwind and return per function}
-There must be only one exit out of a function. \texttt{UNWIND} and return
+There must be only one exit out of a function. \texttt{UNWIND} and return
should happen at only point in the function.
\section*{$\bullet$ Function length or Keep functions small}
@@ -305,7 +305,7 @@ documentation.
\end{verbatim}
\subsection*{Indicating critical sections}
-To clearly show regions of code which execute with locks held, use
+To clearly show regions of code which execute with locks held, use
the following format:
\begin{verbatim}
@@ -324,7 +324,7 @@ point, \texttt{out}. At that point, the code should detect the error
that has occured and do appropriate cleanup.
\begin{verbatim}
-int32_t
+int32_t
sample_fop (call_frame_t *frame, xlator_t *this, ...)
{
char * var1 = NULL;
@@ -337,13 +337,13 @@ sample_fop (call_frame_t *frame, xlator_t *this, ...)
VALIDATE_OR_GOTO (this, out);
/* other validations */
-
+
dir = opendir (...);
if (dir == NULL) {
op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "opendir failed on %s (%s)", loc->path,
+ gf_log (this->name, GF_LOG_ERROR,
+ "opendir failed on %s (%s)", loc->path,
strerror (op_errno));
goto out;
}
@@ -367,8 +367,8 @@ sample_fop (call_frame_t *frame, xlator_t *this, ...)
if (dir) {
closedir (dir);
dir = NULL;
- }
-
+ }
+
if (pfd) {
if (pfd->path)
FREE (pfd->path);
diff --git a/doc/errno.list.bsd.txt b/doc/legacy/errno.list.bsd.txt
index 350af25e4..350af25e4 100644
--- a/doc/errno.list.bsd.txt
+++ b/doc/legacy/errno.list.bsd.txt
diff --git a/doc/errno.list.linux.txt b/doc/legacy/errno.list.linux.txt
index baa50792d..cc868644b 100644
--- a/doc/errno.list.linux.txt
+++ b/doc/legacy/errno.list.linux.txt
@@ -95,7 +95,7 @@ extern "C" {
/**
* @defgroup apr_errno Error Codes
- * @ingroup APR
+ * @ingroup APR
* @{
*/
@@ -110,7 +110,7 @@ typedef int apr_status_t;
* @param buf A buffer to hold the error string.
* @param bufsize Size of the buffer to hold the string.
*/
-APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
+APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
apr_size_t bufsize);
#if defined(DOXYGEN)
@@ -130,7 +130,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* Fold an apr_status_t code back to the native platform defined error.
* @param e The apr_status_t folded platform os error code.
* @warning macro implementation; the statcode argument may be evaluated
- * multiple times. If the statcode was not created by apr_get_os_error
+ * multiple times. If the statcode was not created by apr_get_os_error
* or APR_FROM_OS_ERROR, the results are undefined.
*/
#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)
@@ -166,7 +166,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* @warning This is a macro implementation; the statcode argument may be evaluated
* multiple times. If the statcode was not created by apr_get_os_error
* or APR_FROM_OS_ERROR, the results are undefined. This macro sets
- * errno, or calls a WSASetLastError() style function, unfolding
+ * errno, or calls a WSASetLastError() style function, unfolding
* socketcode with APR_TO_OS_ERROR.
*/
@@ -206,12 +206,12 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_OS_START_CANONERR (APR_OS_START_USERERR \
+ (APR_OS_ERRSPACE_SIZE * 10))
/**
- * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into
+ * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into
* apr_status_t values.
*/
#define APR_OS_START_EAIERR (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE)
/**
- * APR_OS_START_SYSERR folds platform-specific system error values into
+ * APR_OS_START_SYSERR folds platform-specific system error values into
* apr_status_t values.
*/
#define APR_OS_START_SYSERR (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE)
@@ -219,13 +219,13 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** no error. */
#define APR_SUCCESS 0
-/**
+/**
* @defgroup APR_Error APR Error Values
* <PRE>
* <b>APR ERROR VALUES</b>
- * APR_ENOSTAT APR was unable to perform a stat on the file
+ * APR_ENOSTAT APR was unable to perform a stat on the file
* APR_ENOPOOL APR was not provided a pool with which to allocate memory
- * APR_EBADDATE APR was given an invalid date
+ * APR_EBADDATE APR was given an invalid date
* APR_EINVALSOCK APR was given an invalid socket
* APR_ENOPROC APR was not given a process structure
* APR_ENOTIME APR was not given a time structure
@@ -236,7 +236,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* APR_ENOTHREAD APR was not given a thread structure
* APR_ENOTHDKEY APR was not given a thread key structure
* APR_ENOSHMAVAIL There is no more shared memory available
- * APR_EDSOOPEN APR was unable to open the dso object. For more
+ * APR_EDSOOPEN APR was unable to open the dso object. For more
* information call apr_dso_error().
* APR_EGENERAL General failure (specific information not available)
* APR_EBADIP The specified IP address is invalid
@@ -256,17 +256,17 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* APR_INCOMPLETE The operation was incomplete although some processing
* was performed and the results are partially valid
* APR_BADCH Getopt found an option not in the option string
- * APR_BADARG Getopt found an option that is missing an argument
+ * APR_BADARG Getopt found an option that is missing an argument
* and an argument was specified in the option string
* APR_EOF APR has encountered the end of the file
* APR_NOTFOUND APR was unable to find the socket in the poll structure
* APR_ANONYMOUS APR is using anonymous shared memory
* APR_FILEBASED APR is using a file name as the key to the shared memory
* APR_KEYBASED APR is using a shared key as the key to the shared memory
- * APR_EINIT Ininitalizer value. If no option has been found, but
+ * APR_EINIT Ininitalizer value. If no option has been found, but
* the status variable requires a value, this should be used
- * APR_ENOTIMPL The APR function has not been implemented on this
- * platform, either because nobody has gotten to it yet,
+ * APR_ENOTIMPL The APR function has not been implemented on this
+ * platform, either because nobody has gotten to it yet,
* or the function is impossible on this platform.
* APR_EMISMATCH Two passwords do not match.
* APR_EABSOLUTE The given path was absolute.
@@ -334,7 +334,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_ENOTENOUGHENTROPY (APR_OS_START_ERROR + 28)
/** @} */
-/**
+/**
* @defgroup APR_STATUS_IS Status Value Tests
* @warning For any particular error condition, more than one of these tests
* may match. This is because platform-specific error codes may not
@@ -345,16 +345,16 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* adjust the order of the tests accordingly.
* @{
*/
-/**
- * APR was unable to perform a stat on the file
+/**
+ * APR was unable to perform a stat on the file
* @warning always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_ENOSTAT(s) ((s) == APR_ENOSTAT)
-/**
- * APR was not provided a pool with which to allocate memory
+/**
+ * APR was not provided a pool with which to allocate memory
* @warning always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_ENOPOOL(s) ((s) == APR_ENOPOOL)
/** APR was given an invalid date */
@@ -386,8 +386,8 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** The specified netmask is invalid */
#define APR_STATUS_IS_EBADMASK(s) ((s) == APR_EBADMASK)
/* empty slot: +18 */
-/**
- * APR was unable to open the dso object.
+/**
+ * APR was unable to open the dso object.
* For more information call apr_dso_error().
*/
#if defined(WIN32)
@@ -425,7 +425,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** @} */
-/**
+/**
* @addtogroup APR_Error
* @{
*/
@@ -466,7 +466,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** @see APR_STATUS_IS_KEYBASED */
#define APR_KEYBASED (APR_OS_START_STATUS + 21)
/** @see APR_STATUS_IS_EINIT */
-#define APR_EINIT (APR_OS_START_STATUS + 22)
+#define APR_EINIT (APR_OS_START_STATUS + 22)
/** @see APR_STATUS_IS_ENOTIMPL */
#define APR_ENOTIMPL (APR_OS_START_STATUS + 23)
/** @see APR_STATUS_IS_EMISMATCH */
@@ -475,156 +475,156 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_EBUSY (APR_OS_START_STATUS + 25)
/** @} */
-/**
+/**
* @addtogroup APR_STATUS_IS
* @{
*/
-/**
- * Program is currently executing in the child
+/**
+ * Program is currently executing in the child
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code */
#define APR_STATUS_IS_INCHILD(s) ((s) == APR_INCHILD)
-/**
- * Program is currently executing in the parent
+/**
+ * Program is currently executing in the parent
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_INPARENT(s) ((s) == APR_INPARENT)
-/**
- * The thread is detached
+/**
+ * The thread is detached
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_DETACH(s) ((s) == APR_DETACH)
-/**
- * The thread is not detached
+/**
+ * The thread is not detached
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_NOTDETACH(s) ((s) == APR_NOTDETACH)
-/**
+/**
* The child has finished executing
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_CHILD_DONE(s) ((s) == APR_CHILD_DONE)
-/**
+/**
* The child has not finished executing
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_CHILD_NOTDONE(s) ((s) == APR_CHILD_NOTDONE)
-/**
+/**
* The operation did not finish before the timeout
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP)
-/**
+/**
* The operation was incomplete although some processing was performed
* and the results are partially valid.
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_INCOMPLETE(s) ((s) == APR_INCOMPLETE)
/* empty slot: +9 */
/* empty slot: +10 */
/* empty slot: +11 */
-/**
+/**
* Getopt found an option not in the option string
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_BADCH(s) ((s) == APR_BADCH)
-/**
- * Getopt found an option not in the option string and an argument was
+/**
+ * Getopt found an option not in the option string and an argument was
* specified in the option string
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_BADARG(s) ((s) == APR_BADARG)
-/**
+/**
* APR has encountered the end of the file
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_EOF(s) ((s) == APR_EOF)
-/**
+/**
* APR was unable to find the socket in the poll structure
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_NOTFOUND(s) ((s) == APR_NOTFOUND)
/* empty slot: +16 */
/* empty slot: +17 */
/* empty slot: +18 */
-/**
+/**
* APR is using anonymous shared memory
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_ANONYMOUS(s) ((s) == APR_ANONYMOUS)
-/**
+/**
* APR is using a file name as the key to the shared memory
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_FILEBASED(s) ((s) == APR_FILEBASED)
-/**
+/**
* APR is using a shared key as the key to the shared memory
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_KEYBASED(s) ((s) == APR_KEYBASED)
-/**
- * Ininitalizer value. If no option has been found, but
+/**
+ * Ininitalizer value. If no option has been found, but
* the status variable requires a value, this should be used
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_EINIT(s) ((s) == APR_EINIT)
-/**
- * The APR function has not been implemented on this
- * platform, either because nobody has gotten to it yet,
+/**
+ * The APR function has not been implemented on this
+ * platform, either because nobody has gotten to it yet,
* or the function is impossible on this platform.
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_ENOTIMPL(s) ((s) == APR_ENOTIMPL)
-/**
+/**
* Two passwords do not match.
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_EMISMATCH(s) ((s) == APR_EMISMATCH)
-/**
+/**
* The given lock was busy
* @warning always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_EBUSY(s) ((s) == APR_EBUSY)
/** @} */
-/**
+/**
* @addtogroup APR_Error APR Error Values
* @{
*/
@@ -713,8 +713,8 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_ESPIPE (APR_OS_START_CANONERR + 12)
#endif
-/**
- * @see APR_STATUS_IS_EAGAIN
+/**
+ * @see APR_STATUS_IS_EAGAIN
* @warning use APR_STATUS_IS_EAGAIN instead of just testing this value
*/
#ifdef EAGAIN
@@ -753,7 +753,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_EINPROGRESS (APR_OS_START_CANONERR + 17)
#endif
-/**
+/**
* @see APR_STATUS_IS_ECONNABORTED
* @warning use APR_STATUS_IS_ECONNABORTED instead of just testing this value
*/
@@ -771,7 +771,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_ECONNRESET (APR_OS_START_CANONERR + 19)
#endif
-/** @see APR_STATUS_IS_ETIMEDOUT
+/** @see APR_STATUS_IS_ETIMEDOUT
* @deprecated */
#ifdef ETIMEDOUT
#define APR_ETIMEDOUT ETIMEDOUT
@@ -849,7 +849,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
*/
#define APR_OS2_STATUS(e) (APR_FROM_OS_ERROR(e))
-/* These can't sit in a private header, so in spite of the extra size,
+/* These can't sit in a private header, so in spite of the extra size,
* they need to be made available here.
*/
#define SOCBASEERR 10000
@@ -946,10 +946,10 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
|| (s) == APR_OS_START_SYSERR + SOCECONNRESET)
/* XXX deprecated */
#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \
- || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
+ || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
#undef APR_STATUS_IS_TIMEUP
#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \
- || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
+ || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \
|| (s) == APR_OS_START_SYSERR + SOCEHOSTUNREACH)
#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \
@@ -1182,7 +1182,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define apr_get_netos_error() (errno)
#define apr_set_netos_error(e) (errno = (e))
-/**
+/**
* @addtogroup APR_STATUS_IS
* @{
*/
@@ -1246,15 +1246,15 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** operation now in progress */
#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS)
-/**
- * Software caused connection abort
+/**
+ * Software caused connection abort
* @remark
- * EPROTO on certain older kernels really means ECONNABORTED, so we need to
+ * EPROTO on certain older kernels really means ECONNABORTED, so we need to
* ignore it for them. See discussion in new-httpd archives nh.9701 & nh.9603
*
- * There is potentially a bug in Solaris 2.x x<6, and other boxes that
+ * There is potentially a bug in Solaris 2.x x<6, and other boxes that
* implement tcp sockets in userland (i.e. on top of STREAMS). On these
- * systems, EPROTO can actually result in a fatal loop. See PR#981 for
+ * systems, EPROTO can actually result in a fatal loop. See PR#981 for
* example. It's hard to handle both uses of EPROTO.
*/
#ifdef EPROTO
diff --git a/doc/errno.list.macosx.txt b/doc/legacy/errno.list.macosx.txt
index 728753ac7..4954e03d8 100644
--- a/doc/errno.list.macosx.txt
+++ b/doc/legacy/errno.list.macosx.txt
@@ -34,7 +34,7 @@ extern "C" {
/**
* @defgroup apr_errno Error Codes
- * @ingroup APR
+ * @ingroup APR
* @{
*/
@@ -49,7 +49,7 @@ typedef int apr_status_t;
* @param buf A buffer to hold the error string.
* @param bufsize Size of the buffer to hold the string.
*/
-APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
+APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
apr_size_t bufsize);
#if defined(DOXYGEN)
@@ -69,7 +69,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* Fold an apr_status_t code back to the native platform defined error.
* @param e The apr_status_t folded platform os error code.
* @warning macro implementation; the statcode argument may be evaluated
- * multiple times. If the statcode was not created by apr_get_os_error
+ * multiple times. If the statcode was not created by apr_get_os_error
* or APR_FROM_OS_ERROR, the results are undefined.
*/
#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)
@@ -105,7 +105,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* @warning This is a macro implementation; the statcode argument may be evaluated
* multiple times. If the statcode was not created by apr_get_os_error
* or APR_FROM_OS_ERROR, the results are undefined. This macro sets
- * errno, or calls a WSASetLastError() style function, unfolding
+ * errno, or calls a WSASetLastError() style function, unfolding
* socketcode with APR_TO_OS_ERROR.
*/
@@ -145,12 +145,12 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_OS_START_CANONERR (APR_OS_START_USERERR \
+ (APR_OS_ERRSPACE_SIZE * 10))
/**
- * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into
+ * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into
* apr_status_t values.
*/
#define APR_OS_START_EAIERR (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE)
/**
- * APR_OS_START_SYSERR folds platform-specific system error values into
+ * APR_OS_START_SYSERR folds platform-specific system error values into
* apr_status_t values.
*/
#define APR_OS_START_SYSERR (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE)
@@ -158,13 +158,13 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** no error. */
#define APR_SUCCESS 0
-/**
+/**
* @defgroup APR_Error APR Error Values
* <PRE>
* <b>APR ERROR VALUES</b>
- * APR_ENOSTAT APR was unable to perform a stat on the file
+ * APR_ENOSTAT APR was unable to perform a stat on the file
* APR_ENOPOOL APR was not provided a pool with which to allocate memory
- * APR_EBADDATE APR was given an invalid date
+ * APR_EBADDATE APR was given an invalid date
* APR_EINVALSOCK APR was given an invalid socket
* APR_ENOPROC APR was not given a process structure
* APR_ENOTIME APR was not given a time structure
@@ -175,7 +175,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* APR_ENOTHREAD APR was not given a thread structure
* APR_ENOTHDKEY APR was not given a thread key structure
* APR_ENOSHMAVAIL There is no more shared memory available
- * APR_EDSOOPEN APR was unable to open the dso object. For more
+ * APR_EDSOOPEN APR was unable to open the dso object. For more
* information call apr_dso_error().
* APR_EGENERAL General failure (specific information not available)
* APR_EBADIP The specified IP address is invalid
@@ -195,17 +195,17 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* APR_INCOMPLETE The operation was incomplete although some processing
* was performed and the results are partially valid
* APR_BADCH Getopt found an option not in the option string
- * APR_BADARG Getopt found an option that is missing an argument
+ * APR_BADARG Getopt found an option that is missing an argument
* and an argument was specified in the option string
* APR_EOF APR has encountered the end of the file
* APR_NOTFOUND APR was unable to find the socket in the poll structure
* APR_ANONYMOUS APR is using anonymous shared memory
* APR_FILEBASED APR is using a file name as the key to the shared memory
* APR_KEYBASED APR is using a shared key as the key to the shared memory
- * APR_EINIT Ininitalizer value. If no option has been found, but
+ * APR_EINIT Ininitalizer value. If no option has been found, but
* the status variable requires a value, this should be used
- * APR_ENOTIMPL The APR function has not been implemented on this
- * platform, either because nobody has gotten to it yet,
+ * APR_ENOTIMPL The APR function has not been implemented on this
+ * platform, either because nobody has gotten to it yet,
* or the function is impossible on this platform.
* APR_EMISMATCH Two passwords do not match.
* APR_EABSOLUTE The given path was absolute.
@@ -273,7 +273,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_ENOTENOUGHENTROPY (APR_OS_START_ERROR + 28)
/** @} */
-/**
+/**
* @defgroup APR_STATUS_IS Status Value Tests
* @warning For any particular error condition, more than one of these tests
* may match. This is because platform-specific error codes may not
@@ -284,16 +284,16 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* adjust the order of the tests accordingly.
* @{
*/
-/**
- * APR was unable to perform a stat on the file
+/**
+ * APR was unable to perform a stat on the file
* @warning always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_ENOSTAT(s) ((s) == APR_ENOSTAT)
-/**
- * APR was not provided a pool with which to allocate memory
+/**
+ * APR was not provided a pool with which to allocate memory
* @warning always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_ENOPOOL(s) ((s) == APR_ENOPOOL)
/** APR was given an invalid date */
@@ -325,8 +325,8 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** The specified netmask is invalid */
#define APR_STATUS_IS_EBADMASK(s) ((s) == APR_EBADMASK)
/* empty slot: +18 */
-/**
- * APR was unable to open the dso object.
+/**
+ * APR was unable to open the dso object.
* For more information call apr_dso_error().
*/
#if defined(WIN32)
@@ -364,7 +364,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** @} */
-/**
+/**
* @addtogroup APR_Error
* @{
*/
@@ -405,7 +405,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** @see APR_STATUS_IS_KEYBASED */
#define APR_KEYBASED (APR_OS_START_STATUS + 21)
/** @see APR_STATUS_IS_EINIT */
-#define APR_EINIT (APR_OS_START_STATUS + 22)
+#define APR_EINIT (APR_OS_START_STATUS + 22)
/** @see APR_STATUS_IS_ENOTIMPL */
#define APR_ENOTIMPL (APR_OS_START_STATUS + 23)
/** @see APR_STATUS_IS_EMISMATCH */
@@ -414,156 +414,156 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_EBUSY (APR_OS_START_STATUS + 25)
/** @} */
-/**
+/**
* @addtogroup APR_STATUS_IS
* @{
*/
-/**
- * Program is currently executing in the child
+/**
+ * Program is currently executing in the child
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code */
#define APR_STATUS_IS_INCHILD(s) ((s) == APR_INCHILD)
-/**
- * Program is currently executing in the parent
+/**
+ * Program is currently executing in the parent
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_INPARENT(s) ((s) == APR_INPARENT)
-/**
- * The thread is detached
+/**
+ * The thread is detached
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_DETACH(s) ((s) == APR_DETACH)
-/**
- * The thread is not detached
+/**
+ * The thread is not detached
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_NOTDETACH(s) ((s) == APR_NOTDETACH)
-/**
+/**
* The child has finished executing
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_CHILD_DONE(s) ((s) == APR_CHILD_DONE)
-/**
+/**
* The child has not finished executing
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_CHILD_NOTDONE(s) ((s) == APR_CHILD_NOTDONE)
-/**
+/**
* The operation did not finish before the timeout
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP)
-/**
+/**
* The operation was incomplete although some processing was performed
* and the results are partially valid.
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_INCOMPLETE(s) ((s) == APR_INCOMPLETE)
/* empty slot: +9 */
/* empty slot: +10 */
/* empty slot: +11 */
-/**
+/**
* Getopt found an option not in the option string
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_BADCH(s) ((s) == APR_BADCH)
-/**
- * Getopt found an option not in the option string and an argument was
+/**
+ * Getopt found an option not in the option string and an argument was
* specified in the option string
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_BADARG(s) ((s) == APR_BADARG)
-/**
+/**
* APR has encountered the end of the file
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_EOF(s) ((s) == APR_EOF)
-/**
+/**
* APR was unable to find the socket in the poll structure
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_NOTFOUND(s) ((s) == APR_NOTFOUND)
/* empty slot: +16 */
/* empty slot: +17 */
/* empty slot: +18 */
-/**
+/**
* APR is using anonymous shared memory
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_ANONYMOUS(s) ((s) == APR_ANONYMOUS)
-/**
+/**
* APR is using a file name as the key to the shared memory
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_FILEBASED(s) ((s) == APR_FILEBASED)
-/**
+/**
* APR is using a shared key as the key to the shared memory
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_KEYBASED(s) ((s) == APR_KEYBASED)
-/**
- * Ininitalizer value. If no option has been found, but
+/**
+ * Ininitalizer value. If no option has been found, but
* the status variable requires a value, this should be used
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_EINIT(s) ((s) == APR_EINIT)
-/**
- * The APR function has not been implemented on this
- * platform, either because nobody has gotten to it yet,
+/**
+ * The APR function has not been implemented on this
+ * platform, either because nobody has gotten to it yet,
* or the function is impossible on this platform.
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_ENOTIMPL(s) ((s) == APR_ENOTIMPL)
-/**
+/**
* Two passwords do not match.
* @warning
* always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_EMISMATCH(s) ((s) == APR_EMISMATCH)
-/**
+/**
* The given lock was busy
* @warning always use this test, as platform-specific variances may meet this
- * more than one error code
+ * more than one error code
*/
#define APR_STATUS_IS_EBUSY(s) ((s) == APR_EBUSY)
/** @} */
-/**
+/**
* @addtogroup APR_Error APR Error Values
* @{
*/
@@ -652,8 +652,8 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_ESPIPE (APR_OS_START_CANONERR + 12)
#endif
-/**
- * @see APR_STATUS_IS_EAGAIN
+/**
+ * @see APR_STATUS_IS_EAGAIN
* @warning use APR_STATUS_IS_EAGAIN instead of just testing this value
*/
#ifdef EAGAIN
@@ -692,7 +692,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_EINPROGRESS (APR_OS_START_CANONERR + 17)
#endif
-/**
+/**
* @see APR_STATUS_IS_ECONNABORTED
* @warning use APR_STATUS_IS_ECONNABORTED instead of just testing this value
*/
@@ -710,7 +710,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define APR_ECONNRESET (APR_OS_START_CANONERR + 19)
#endif
-/** @see APR_STATUS_IS_ETIMEDOUT
+/** @see APR_STATUS_IS_ETIMEDOUT
* @deprecated */
#ifdef ETIMEDOUT
#define APR_ETIMEDOUT ETIMEDOUT
@@ -788,7 +788,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
*/
#define APR_OS2_STATUS(e) (APR_FROM_OS_ERROR(e))
-/* These can't sit in a private header, so in spite of the extra size,
+/* These can't sit in a private header, so in spite of the extra size,
* they need to be made available here.
*/
#define SOCBASEERR 10000
@@ -885,10 +885,10 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
|| (s) == APR_OS_START_SYSERR + SOCECONNRESET)
/* XXX deprecated */
#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \
- || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
+ || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
#undef APR_STATUS_IS_TIMEUP
#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \
- || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
+ || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \
|| (s) == APR_OS_START_SYSERR + SOCEHOSTUNREACH)
#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \
@@ -1121,7 +1121,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
#define apr_get_netos_error() (errno)
#define apr_set_netos_error(e) (errno = (e))
-/**
+/**
* @addtogroup APR_STATUS_IS
* @{
*/
@@ -1185,15 +1185,15 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
/** operation now in progress */
#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS)
-/**
- * Software caused connection abort
+/**
+ * Software caused connection abort
* @remark
- * EPROTO on certain older kernels really means ECONNABORTED, so we need to
+ * EPROTO on certain older kernels really means ECONNABORTED, so we need to
* ignore it for them. See discussion in new-httpd archives nh.9701 & nh.9603
*
- * There is potentially a bug in Solaris 2.x x<6, and other boxes that
+ * There is potentially a bug in Solaris 2.x x<6, and other boxes that
* implement tcp sockets in userland (i.e. on top of STREAMS). On these
- * systems, EPROTO can actually result in a fatal loop. See PR#981 for
+ * systems, EPROTO can actually result in a fatal loop. See PR#981 for
* example. It's hard to handle both uses of EPROTO.
*/
#ifdef EPROTO
@@ -1236,14 +1236,14 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -1251,7 +1251,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <sys/errno.h>
@@ -1261,7 +1261,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
@@ -1270,10 +1270,10 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
- *
+ *
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -1281,7 +1281,7 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
@@ -1484,7 +1484,7 @@ __END_DECLS
#define ECANCELED 89 /* Operation canceled */
#define EIDRM 90 /* Identifier removed */
-#define ENOMSG 91 /* No message of desired type */
+#define ENOMSG 91 /* No message of desired type */
#define EILSEQ 92 /* Illegal byte sequence */
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#define ENOATTR 93 /* Attribute not found */
diff --git a/doc/errno.list.solaris.txt b/doc/legacy/errno.list.solaris.txt
index 23601e9d3..23601e9d3 100644
--- a/doc/errno.list.solaris.txt
+++ b/doc/legacy/errno.list.solaris.txt
diff --git a/doc/get_put_api_using_xattr.txt b/doc/legacy/get_put_api_using_xattr.txt
index 58951f5bf..243f9f1ae 100644
--- a/doc/get_put_api_using_xattr.txt
+++ b/doc/legacy/get_put_api_using_xattr.txt
@@ -16,7 +16,7 @@ internals:
* posix handling setxattr/getxattr
- setxattr
posix setxattr does a open with O_CREAT|O_TRUNC on the <path>/<name>, writes value of the setxattr as data into the file and closes the file. when data is null, posix setxattr avoids doing write. file is closed after write.
-
+
- getxattr
posix getxattr does open with O_RDONLY on the <path>/<name>, reads the complete content of the file. file is closed after read.
diff --git a/doc/hacker-guide/Makefile.am b/doc/legacy/hacker-guide/Makefile.am
index 65c92ac23..65c92ac23 100644
--- a/doc/hacker-guide/Makefile.am
+++ b/doc/legacy/hacker-guide/Makefile.am
diff --git a/doc/hacker-guide/adding-fops.txt b/doc/legacy/hacker-guide/adding-fops.txt
index e70dbbdc8..e70dbbdc8 100644
--- a/doc/hacker-guide/adding-fops.txt
+++ b/doc/legacy/hacker-guide/adding-fops.txt
diff --git a/doc/hacker-guide/bdb.txt b/doc/legacy/hacker-guide/bdb.txt
index fd0bd3652..1a80be813 100644
--- a/doc/hacker-guide/bdb.txt
+++ b/doc/legacy/hacker-guide/bdb.txt
@@ -21,24 +21,24 @@ as key/value pair inside the glusterfs_storage.db.
* internal data cache
---------------------
- db does not provide a way to find out the size of the value corresponding to a key.
-so, bdb makes DB->get() call for key and takes the length of the value returned.
+ db does not provide a way to find out the size of the value corresponding to a key.
+so, bdb makes DB->get() call for key and takes the length of the value returned.
since DB->get() also returns file contents for key, bdb maintains an internal cache and
stores the file contents in the cache.
every directory maintains a seperate cache.
-
+
* inode number transformation
-----------------------------
- bdb allocates a inode number to each file and directory on its own. bdb maintains a
+ bdb allocates a inode number to each file and directory on its own. bdb maintains a
global counter and increments it after allocating inode number for each file
(regular, symlink or directory). NOTE: bdb does not guarantee persistent inode numbers.
* checkpoint thread
-------------------
- bdb creates a checkpoint thread at the time of init(). checkpoint thread does a
-periodic checkpoint on the DB_ENV. checkpoint is the mechanism, provided by db, to
+ bdb creates a checkpoint thread at the time of init(). checkpoint thread does a
+periodic checkpoint on the DB_ENV. checkpoint is the mechanism, provided by db, to
forcefully commit the logged transactions to the storage.
NOTES ABOUT FOPS:
@@ -48,7 +48,7 @@ lookup() -
1> do lstat() on the path, if lstat fails, we assume that the file being looked up
is either a regular file or doesn't exist.
2> lookup in the DB of parent directory for key corresponding to path. if key exists,
- return key, with.
+ return key, with.
NOTE: 'struct stat' stat()ed from DB file is used as a container for 'struct stat'
of the regular file. st_ino, st_size, st_blocks are updated with file's values.
@@ -58,7 +58,7 @@ readv() -
writev():
1> flush any cached content of this file.
- 2> do a DB->put(), with DB_DBT_PARTIAL flag.
+ 2> do a DB->put(), with DB_DBT_PARTIAL flag.
NOTE: DB_DBT_PARTIAL is used to do partial update of a value in DB.
readdir():
diff --git a/doc/hacker-guide/call-stub.txt b/doc/legacy/hacker-guide/call-stub.txt
index bca1579b2..021037a35 100644
--- a/doc/hacker-guide/call-stub.txt
+++ b/doc/legacy/hacker-guide/call-stub.txt
@@ -2,8 +2,8 @@ creating a call stub and pausing a call
---------------------------------------
libglusterfs provides seperate API to pause each of the fop. parameters to each API is
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
- NOTE: @fn should exactly take the same type and number of parameters that
+@fn - procedure to call during call_resume().
+ NOTE: @fn should exactly take the same type and number of parameters that
the corresponding regular fop takes.
rest will be the regular parameters to corresponding fop.
@@ -17,7 +17,7 @@ specific parameters.
here is the list of stub creation APIs for xlator fops.
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -30,7 +30,7 @@ fop_lookup_stub (call_frame_t *frame,
int32_t need_xattr);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -41,7 +41,7 @@ fop_stat_stub (call_frame_t *frame,
loc_t *loc);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to lk fop.
NOTE: @fd is stored with a fd_ref().
call_stub_t *
@@ -50,7 +50,7 @@ fop_fstat_stub (call_frame_t *frame,
fd_t *fd);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to @loc->inode and
@loc->parent, if not NULL. also @loc->path will be copied to a different location.
@@ -62,7 +62,7 @@ fop_chmod_stub (call_frame_t *frame,
mode_t mode);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to lk fop.
NOTE: @fd is stored with a fd_ref().
@mode - mode parameter for fchmod fop.
@@ -73,7 +73,7 @@ fop_fchmod_stub (call_frame_t *frame,
mode_t mode);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to @loc->inode and
@loc->parent, if not NULL. also @loc->path will be copied to a different location.
@@ -87,7 +87,7 @@ fop_chown_stub (call_frame_t *frame,
gid_t gid);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to lk fop.
NOTE: @fd is stored with a fd_ref().
@uid - uid parameter to fchown.
@@ -100,7 +100,7 @@ fop_fchown_stub (call_frame_t *frame,
gid_t gid);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -113,7 +113,7 @@ fop_truncate_stub (call_frame_t *frame,
off_t off);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to lk fop.
NOTE: @fd is stored with a fd_ref().
@off - offset parameter to ftruncate fop.
@@ -124,7 +124,7 @@ fop_ftruncate_stub (call_frame_t *frame,
off_t off);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -137,7 +137,7 @@ fop_utimens_stub (call_frame_t *frame,
struct timespec tv[2]);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -150,7 +150,7 @@ fop_access_stub (call_frame_t *frame,
int32_t mask);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -163,7 +163,7 @@ fop_readlink_stub (call_frame_t *frame,
size_t size);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -178,7 +178,7 @@ fop_mknod_stub (call_frame_t *frame,
dev_t rdev);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -191,7 +191,7 @@ fop_mkdir_stub (call_frame_t *frame,
mode_t mode);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -202,7 +202,7 @@ fop_unlink_stub (call_frame_t *frame,
loc_t *loc);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -213,7 +213,7 @@ fop_rmdir_stub (call_frame_t *frame,
loc_t *loc);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@linkname - linkname parameter to symlink fop.
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@@ -226,10 +226,10 @@ fop_symlink_stub (call_frame_t *frame,
loc_t *loc);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@oldloc - pointer to location structure.
- NOTE: @oldloc will be copied to a different location, with inode_ref() to
- @oldloc->inode and @oldloc->parent, if not NULL. also @oldloc->path will
+ NOTE: @oldloc will be copied to a different location, with inode_ref() to
+ @oldloc->inode and @oldloc->parent, if not NULL. also @oldloc->path will
be copied to a different location, if not NULL.
@newloc - pointer to location structure.
NOTE: @newloc will be copied to a different location, with inode_ref() to
@@ -242,7 +242,7 @@ fop_rename_stub (call_frame_t *frame,
loc_t *newloc);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -255,7 +255,7 @@ fop_link_stub (call_frame_t *frame,
const char *newpath);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -272,7 +272,7 @@ fop_create_stub (call_frame_t *frame,
mode_t mode, fd_t *fd);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@flags - flags parameter to open fop.
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@@ -286,7 +286,7 @@ fop_open_stub (call_frame_t *frame,
fd_t *fd);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to lk fop.
NOTE: @fd is stored with a fd_ref().
@size - size parameter to readv fop.
@@ -299,10 +299,10 @@ fop_readv_stub (call_frame_t *frame,
off_t off);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to lk fop.
NOTE: @fd is stored with a fd_ref().
-@vector - vector parameter to writev fop.
+@vector - vector parameter to writev fop.
NOTE: @vector is iov_dup()ed while creating stub. and frame->root->req_refs
dictionary is dict_ref()ed.
@count - count parameter to writev fop.
@@ -316,7 +316,7 @@ fop_writev_stub (call_frame_t *frame,
off_t off);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to flush fop.
NOTE: @fd is stored with a fd_ref().
call_stub_t *
@@ -326,7 +326,7 @@ fop_flush_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to lk fop.
NOTE: @fd is stored with a fd_ref().
@datasync - datasync parameter to fsync fop.
@@ -337,7 +337,7 @@ fop_fsync_stub (call_frame_t *frame,
int32_t datasync);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to @loc->inode and
@loc->parent, if not NULL. also @loc->path will be copied to a different location.
@@ -346,11 +346,11 @@ fop_fsync_stub (call_frame_t *frame,
call_stub_t *
fop_opendir_stub (call_frame_t *frame,
fop_opendir_t fn,
- loc_t *loc,
+ loc_t *loc,
fd_t *fd);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to getdents fop.
NOTE: @fd is stored with a fd_ref().
@size - size parameter to getdents fop.
@@ -365,7 +365,7 @@ fop_getdents_stub (call_frame_t *frame,
int32_t flag);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to setdents fop.
NOTE: @fd is stored with a fd_ref().
@flags - flags parameter to setdents fop.
@@ -379,7 +379,7 @@ fop_setdents_stub (call_frame_t *frame,
int32_t count);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to setdents fop.
NOTE: @fd is stored with a fd_ref().
@datasync - datasync parameter to fsyncdir fop.
@@ -390,7 +390,7 @@ fop_fsyncdir_stub (call_frame_t *frame,
int32_t datasync);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -401,9 +401,9 @@ fop_statfs_stub (call_frame_t *frame,
loc_t *loc);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
- NOTE: @loc will be copied to a different location, with inode_ref() to
+ NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
copied to a different location.
@dict - dict parameter to setxattr fop.
@@ -416,7 +416,7 @@ fop_setxattr_stub (call_frame_t *frame,
int32_t flags);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -429,7 +429,7 @@ fop_getxattr_stub (call_frame_t *frame,
const char *name);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -443,7 +443,7 @@ fop_removexattr_stub (call_frame_t *frame,
const char *name);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to lk fop.
NOTE: @fd is stored with a fd_ref().
@cmd - command parameter to lk fop.
@@ -457,13 +457,13 @@ fop_lk_stub (call_frame_t *frame,
struct flock *lock);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - fd parameter to gf_lk fop.
NOTE: @fd is fd_ref()ed while creating stub, if not NULL.
@cmd - cmd parameter to gf_lk fop.
@lock - lock paramater to gf_lk fop.
NOTE: @lock is copied to a different memory location while creating
- stub.
+ stub.
call_stub_t *
fop_gf_lk_stub (call_frame_t *frame,
fop_gf_lk_t fn,
@@ -472,7 +472,7 @@ fop_gf_lk_stub (call_frame_t *frame,
struct flock *lock);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@fd - file descriptor parameter to readdir fop.
NOTE: @fd is stored with a fd_ref().
@size - size parameter to readdir fop.
@@ -485,7 +485,7 @@ fop_readdir_stub (call_frame_t *frame,
off_t off);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@loc - pointer to location structure.
NOTE: @loc will be copied to a different location, with inode_ref() to
@loc->inode and @loc->parent, if not NULL. also @loc->path will be
@@ -498,7 +498,7 @@ fop_checksum_stub (call_frame_t *frame,
int32_t flags);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@inode - inode parameter to @fn.
@@ -516,7 +516,7 @@ fop_lookup_cbk_stub (call_frame_t *frame,
struct stat *buf,
dict_t *dict);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -529,7 +529,7 @@ fop_stat_cbk_stub (call_frame_t *frame,
struct stat *buf);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -542,7 +542,7 @@ fop_fstat_cbk_stub (call_frame_t *frame,
struct stat *buf);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -555,7 +555,7 @@ fop_chmod_cbk_stub (call_frame_t *frame,
struct stat *buf);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -568,7 +568,7 @@ fop_fchmod_cbk_stub (call_frame_t *frame,
struct stat *buf);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -582,7 +582,7 @@ fop_chown_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -596,7 +596,7 @@ fop_fchown_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -610,7 +610,7 @@ fop_truncate_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -624,7 +624,7 @@ fop_ftruncate_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -638,7 +638,7 @@ fop_utimens_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -649,7 +649,7 @@ fop_access_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@path - path parameter to @fn.
@@ -663,7 +663,7 @@ fop_readlink_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@inode - inode parameter to @fn.
@@ -680,7 +680,7 @@ fop_mknod_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@inode - inode parameter to @fn.
@@ -697,7 +697,7 @@ fop_mkdir_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -708,7 +708,7 @@ fop_unlink_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -719,7 +719,7 @@ fop_rmdir_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@inode - inode parameter to @fn.
@@ -736,7 +736,7 @@ fop_symlink_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -750,7 +750,7 @@ fop_rename_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@inode - inode parameter to @fn.
@@ -766,7 +766,7 @@ fop_link_cbk_stub (call_frame_t *frame,
struct stat *buf);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@fd - fd parameter to @fn.
@@ -786,7 +786,7 @@ fop_create_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@fd - fd parameter to @fn.
@@ -800,10 +800,10 @@ fop_open_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
-@vector - vector parameter to @fn.
+@vector - vector parameter to @fn.
NOTE: @vector is copied to a different memory location, if not NULL. also
frame->root->rsp_refs is dict_ref()ed.
@stbuf - stbuf parameter to @fn.
@@ -819,7 +819,7 @@ fop_readv_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@stbuf - stbuf parameter to @fn.
@@ -833,7 +833,7 @@ fop_writev_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -843,7 +843,7 @@ fop_flush_cbk_stub (call_frame_t *frame,
int32_t op_errno);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -854,7 +854,7 @@ fop_fsync_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@fd - fd parameter to @fn.
@@ -868,7 +868,7 @@ fop_opendir_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@entries - entries parameter to @fn.
@@ -883,7 +883,7 @@ fop_getdents_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -893,7 +893,7 @@ fop_setdents_cbk_stub (call_frame_t *frame,
int32_t op_errno);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -904,7 +904,7 @@ fop_fsyncdir_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@buf - buf parameter to @fn.
@@ -918,7 +918,7 @@ fop_statfs_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -929,7 +929,7 @@ fop_setxattr_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@value - value dictionary parameter to @fn.
@@ -943,7 +943,7 @@ fop_getxattr_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
call_stub_t *
@@ -954,12 +954,12 @@ fop_removexattr_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@lock - lock parameter to @fn.
NOTE: @lock is copied to a different memory location while creating
- stub.
+ stub.
call_stub_t *
fop_lk_cbk_stub (call_frame_t *frame,
fop_lk_cbk_t fn,
@@ -968,12 +968,12 @@ fop_lk_cbk_stub (call_frame_t *frame,
struct flock *lock);
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@lock - lock parameter to @fn.
NOTE: @lock is copied to a different memory location while creating
- stub.
+ stub.
call_stub_t *
fop_gf_lk_cbk_stub (call_frame_t *frame,
fop_gf_lk_cbk_t fn,
@@ -983,7 +983,7 @@ fop_gf_lk_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@entries - entries parameter to @fn.
@@ -996,14 +996,14 @@ fop_readdir_cbk_stub (call_frame_t *frame,
@frame - call frame which has to be used to resume the call at call_resume().
-@fn - procedure to call during call_resume().
+@fn - procedure to call during call_resume().
@op_ret - op_ret parameter to @fn.
@op_errno - op_errno parameter to @fn.
@file_checksum - file_checksum parameter to @fn.
- NOTE: file_checksum will be copied to a different memory location
+ NOTE: file_checksum will be copied to a different memory location
while creating stub.
@dir_checksum - dir_checksum parameter to @fn.
- NOTE: file_checksum will be copied to a different memory location
+ NOTE: file_checksum will be copied to a different memory location
while creating stub.
call_stub_t *
fop_checksum_cbk_stub (call_frame_t *frame,
@@ -1025,9 +1025,9 @@ resuming a call:
in stub->args.<operation>.<fd_t-or-inode_t-or-dict_t>. so, if any fd_t, dict_t or
inode_t pointers are assigned at stub->args.<operation>.<fd_t-or-inode_t-or-dict_t> after
fop_<operation>_stub() call, they must be <fd_t-or-inode_t-or-dict_t>_ref()ed.
-
+
call_resume does not STACK_DESTROY() for any fop.
-
+
if stub->fn is NULL, call_resume does STACK_WIND() or STACK_UNWIND() using the stub->frame.
return - call resume fails only if stub is NULL. call resume fails with errno set to EINVAL.
diff --git a/doc/hacker-guide/hacker-guide.tex b/doc/legacy/hacker-guide/hacker-guide.tex
index c2d7255d7..11101e7a8 100644
--- a/doc/hacker-guide/hacker-guide.tex
+++ b/doc/legacy/hacker-guide/hacker-guide.tex
@@ -31,7 +31,7 @@ most part.
\chapter{Major components}
\section{libglusterfs}
-\texttt{libglusterfs} contains supporting code used by all the other components.
+\texttt{libglusterfs} contains supporting code used by all the other components.
The important files here are:
\texttt{dict.c}: This is an implementation of a serializable dictionary type. It is
@@ -165,8 +165,8 @@ First we include the requisite headers.
#include "logging.h"
/*
- * This is a rot13 ``encryption'' xlator. It rot13's data when
- * writing to disk and rot13's it back when reading it.
+ * This is a rot13 ``encryption'' xlator. It rot13's data when
+ * writing to disk and rot13's it back when reading it.
* This xlator is meant as an example, not for production
* use ;) (hence no error-checking)
*/
@@ -178,7 +178,7 @@ letters. Any other byte is passed through as it is.
\begin{verbatim}
/* We only handle lower case letters for simplicity */
-static void
+static void
rot13 (char *buf, int len)
{
int i;
@@ -252,12 +252,12 @@ rot13_writev (call_frame_t *frame,
xlator_t *this,
dict_t *ctx,
struct iovec *vector,
- int32_t count,
+ int32_t count,
off_t offset)
{
rot13_iovec (vector, count);
- STACK_WIND (frame,
+ STACK_WIND (frame,
rot13_writev_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->writev,
@@ -267,9 +267,9 @@ rot13_writev (call_frame_t *frame,
\end{verbatim}
-Every xlator must define two functions and two external symbols. The functions are
+Every xlator must define two functions and two external symbols. The functions are
\texttt{init} and \texttt{fini}, and the symbols are \texttt{fops} and \texttt{mops}.
-The \texttt{init} function is called when the xlator is loaded by GlusterFS, and
+The \texttt{init} function is called when the xlator is loaded by GlusterFS, and
contains code for the xlator to initialize itself. Note that if an xlator is present
multiple times in the spec tree, the \texttt{init} function will be called each time
the xlator is loaded.
@@ -279,7 +279,7 @@ int32_t
init (xlator_t *this)
{
if (!this->children) {
- gf_log ("rot13", GF_LOG_ERROR,
+ gf_log ("rot13", GF_LOG_ERROR,
"FATAL: rot13 should have exactly one child");
return -1;
}
@@ -291,7 +291,7 @@ init (xlator_t *this)
\begin{verbatim}
-void
+void
fini (xlator_t *this)
{
return;
diff --git a/doc/hacker-guide/lock-ahead.txt b/doc/legacy/hacker-guide/lock-ahead.txt
index 63392b7fa..70aa452d3 100644
--- a/doc/hacker-guide/lock-ahead.txt
+++ b/doc/legacy/hacker-guide/lock-ahead.txt
@@ -9,7 +9,7 @@ further locks will be requested within the same universal set.
So, for example, when cluster/replicate locks a region before
writing to it, lock-ahead would instead lock the entire file.
-On further writes, lock-ahead can immediately return success for
+On further writes, lock-ahead can immediately return success for
the lock requests, since the entire file has been previously locked.
To avoid starvation of other clients/mountpoints, we employ a
@@ -50,7 +50,7 @@ lock:
send lock-notify fop
hold universal lock and return
(set inode context, add subset to it, save loc_t or fd)
-
+
if this fails:
forward the lock request
diff --git a/doc/hacker-guide/posix.txt b/doc/legacy/hacker-guide/posix.txt
index d0132abfe..7958af2ea 100644
--- a/doc/hacker-guide/posix.txt
+++ b/doc/legacy/hacker-guide/posix.txt
@@ -4,11 +4,11 @@
- SET_FS_ID
- This is so that all filesystem checks are done with the user's
+ This is so that all filesystem checks are done with the user's
uid/gid and not GlusterFS's uid/gid.
- MAKE_REAL_PATH
-
+
This macro concatenates the base directory of the posix volume
('option directory') with the given path.
@@ -18,8 +18,8 @@
the file's create time, the file's contents, and the version number
of the file.
- This is a hack to increase small file performance. If an application
- wants to read a small file, it can finish its job with just a lookup
+ This is a hack to increase small file performance. If an application
+ wants to read a small file, it can finish its job with just a lookup
call instead of a lookup followed by read.
- getdents/setdents
@@ -27,7 +27,7 @@
These are used by unify to set and get directory entries.
- ALIGN_BUF
-
+
Macro to align an address to a page boundary (4K).
- priv->export_statfs
@@ -42,7 +42,7 @@
- xattrop
- This fop is used by replicate to set version numbers on files.
+ This fop is used by replicate to set version numbers on files.
- getxattr/setxattr hack to read/write files
@@ -52,7 +52,7 @@
the value as the entire content of the file.
- posix_checksum
-
+
This calculates a simple XOR checksum on all entry names in a
directory that is used by unify to compare directory contents.
diff --git a/doc/hacker-guide/replicate.txt b/doc/legacy/hacker-guide/replicate.txt
index fd1ef2747..133c72afa 100644
--- a/doc/hacker-guide/replicate.txt
+++ b/doc/legacy/hacker-guide/replicate.txt
@@ -5,7 +5,7 @@
Before understanding replicate, one must understand two internal FOPs:
GF_FILE_LK:
- This is exactly like fcntl(2) locking, except the locks are in a
+ This is exactly like fcntl(2) locking, except the locks are in a
separate domain from locks held by applications.
GF_DIR_LK (loc_t *loc, char *basename):
@@ -17,7 +17,7 @@ GF_DIR_LK (loc_t *loc, char *basename):
If one wishes to lock *all* the names under a particular directory,
supply the basename argument as NULL.
- The locks can either be read locks or write locks; consult the
+ The locks can either be read locks or write locks; consult the
function prototype for more details.
Both these operations are implemented by the features/locks (earlier
@@ -79,7 +79,7 @@ Each of the four major groups has its own algorithm:
All operations are done in parallel unless specified otherwise.
- (1) Send a GF_FILE_LK request on all children for a write lock on
+ (1) Send a GF_FILE_LK request on all children for a write lock on
the appropriate region
(for metadata operations: entire file (0, 0)
for writev: (offset, offset+size of buffer))
@@ -87,11 +87,11 @@ Each of the four major groups has its own algorithm:
- If a lock request fails on a child:
unlock all children
try to acquire a blocking lock (F_SETLKW) on each child, serially.
-
+
If this fails (due to ENOTCONN or EINVAL):
Consider this child as dead for rest of transaction.
- (2) Mark all children as "pending" on all (alive) children
+ (2) Mark all children as "pending" on all (alive) children
(see below for meaning of "pending").
- If it fails on any child:
@@ -105,7 +105,7 @@ Each of the four major groups has its own algorithm:
(4) Unmark all successful children as not "pending" on all nodes.
(5) Unlock region on all (alive) children.
-
+
-----------
- dir-write
-----------
@@ -121,11 +121,11 @@ Each of the four major groups has its own algorithm:
The "pending" number is like a journal entry. A pending entry is an
array of 32-bit integers stored in network byte-order as the extended
attribute of an inode (which can be a directory as well).
-
+
There are three keys corresponding to three types of pending operations:
- AFR_METADATA_PENDING
- There are some metadata operations pending on this inode (perms, ctime/mtime,
+ There are some metadata operations pending on this inode (perms, ctime/mtime,
xattr, etc.).
- AFR_DATA_PENDING
@@ -134,7 +134,7 @@ Each of the four major groups has its own algorithm:
- AFR_ENTRY_PENDING
There are some directory operations pending on this directory
(create, unlink, etc.).
-
+
-----------
* Self heal
-----------
@@ -155,7 +155,7 @@ Each of the four major groups has its own algorithm:
other is directory):
- Announce to the user via log that a split-brain situation has been
detected, and do nothing.
-
+
- On open, gather extended attribute data:
- Consider the file with the highest AFR_DATA_PENDING number as
the definitive one and replicate its contents on all other
@@ -190,7 +190,7 @@ Thus, if lookup on c1 returns an inode number "2", it is scaled to "4"
This way we ensure that there is never a collision of inode numbers from
two different children.
-This reduction of inode space doesn't really reduce the usability of
+This reduction of inode space doesn't really reduce the usability of
replicate since even if we assume replicate has 1024 children (which would be a
highly unusual scenario), each child still has a 54-bit inode space.
diff --git a/doc/hacker-guide/write-behind.txt b/doc/legacy/hacker-guide/write-behind.txt
index a6e9a8890..50b7d2a1d 100644
--- a/doc/hacker-guide/write-behind.txt
+++ b/doc/legacy/hacker-guide/write-behind.txt
@@ -4,7 +4,7 @@ basic working
write behind is basically a translator to lie to the application that the write-requests are finished, even before it is actually finished.
on a regular translator tree without write-behind, control flow is like this:
-
+
1. application makes a write() system call.
2. VFS ==> FUSE ==> /dev/fuse.
3. fuse-bridge initiates a glusterfs writev() call.
@@ -12,13 +12,13 @@ basic working
5. client-protocol, on receiving reply from server, starts STACK_UNWIND() towards the fuse-bridge.
on a translator tree with write-behind, control flow is like this:
-
+
1. application makes a write() system call.
2. VFS ==> FUSE ==> /dev/fuse.
3. fuse-bridge initiates a glusterfs writev() call.
4. writev() is STACK_WIND()ed upto write-behind translator.
5. write-behind adds the write buffer to its internal queue and does a STACK_UNWIND() towards the fuse-bridge.
-
+
write call is completed in application's percepective. after STACK_UNWIND()ing towards the fuse-bridge, write-behind initiates a fresh writev() call to its child translator, whose replies will be consumed by write-behind itself. write-behind _doesn't_ cache the write buffer, unless 'option flush-behind on' is specified in volume specification file.
windowing
@@ -26,20 +26,20 @@ windowing
write respect to write-behind, each write-buffer has three flags: 'stack_wound', 'write_behind' and 'got_reply'.
- stack_wound: if set, indicates that write-behind has initiated STACK_WIND() towards child translator.
+ stack_wound: if set, indicates that write-behind has initiated STACK_WIND() towards child translator.
write_behind: if set, indicates that write-behind has done STACK_UNWIND() towards fuse-bridge.
got_reply: if set, indicates that write-behind has received reply from child translator for a writev() STACK_WIND(). a request will be destroyed by write-behind only if this flag is set.
currently pending write requests = aggregate size of requests with write_behind = 1 and got_reply = 0.
-
- window size limits the aggregate size of currently pending write requests. once the pending requests' size has reached the window size, write-behind blocks writev() calls from fuse-bridge.
+
+ window size limits the aggregate size of currently pending write requests. once the pending requests' size has reached the window size, write-behind blocks writev() calls from fuse-bridge.
blocking is only from application's perspective. write-behind does STACK_WIND() to child translator straight-away, but hold behind the STACK_UNWIND() towards fuse-bridge. STACK_UNWIND() is done only once write-behind gets enough replies to accomodate for currently blocked request.
-
+
flush behind
------------
if 'option flush-behind on' is specified in volume specification file, then write-behind sends aggregate write requests to child translator, instead of regular per request STACK_WIND()s.
-
+
diff --git a/doc/handling-options.txt b/doc/legacy/handling-options.txt
index cac1fe939..9a3b2510a 100644
--- a/doc/handling-options.txt
+++ b/doc/legacy/handling-options.txt
@@ -2,12 +2,12 @@
How to add a new option to a given volume ?
===========================================
-* Add a entry in 'struct volume_options options[]' with your key, what is
+* Add a entry in 'struct volume_options options[]' with your key, what is
the type of the 'key', etc.
-* The 'key' and corresponding 'value' given for the same by user are validated
+* The 'key' and corresponding 'value' given for the same by user are validated
before calling init() of the translator/transport/scheduler/auth-module.
-* Once the complete init() is successful, user will get a warning if he has
+* Once the complete init() is successful, user will get a warning if he has
given a 'key' which is not defined in these modules.
diff --git a/doc/mac-related-xattrs.txt b/doc/legacy/mac-related-xattrs.txt
index 805658334..92bb2ceef 100644
--- a/doc/mac-related-xattrs.txt
+++ b/doc/legacy/mac-related-xattrs.txt
@@ -1,21 +1,21 @@
-This document is intended to briefly explain how the Extended Attributes on
+This document is intended to briefly explain how the Extended Attributes on
Darwin 10.5.x releases works
----
-On Darwin other than all the normal filesystem operations, 'Finder' (like
-Explorer in Windows but a little more) keeps its information in two extended
-attributes named 'com.apple.FinderInfo' and 'com.apple.ResourceFork'. If these
-xattrs are not implemented the filesystem won't be shown on Finder, and if they
-are not implemented properly there may be issues when some of the file operations
-are done through GUI of Finder. But when a filesystem is used over mountpoint in a
-terminal, everything is fine and these xattrs are not required.
+On Darwin other than all the normal filesystem operations, 'Finder' (like
+Explorer in Windows but a little more) keeps its information in two extended
+attributes named 'com.apple.FinderInfo' and 'com.apple.ResourceFork'. If these
+xattrs are not implemented the filesystem won't be shown on Finder, and if they
+are not implemented properly there may be issues when some of the file operations
+are done through GUI of Finder. But when a filesystem is used over mountpoint in a
+terminal, everything is fine and these xattrs are not required.
-Currently the way these xattrs are implemented is simple. All the xattr calls
+Currently the way these xattrs are implemented is simple. All the xattr calls
(getxattr, setxattr, listxattr, removexattr) are passed down to underlaying filesystem,
most of the cases when exported FS is on MacOS X itself, these keys are supported, hence
-the fops succeed. But in the case of using exports of different OS on Darwin the issue is
-extended attribute prefix like 'com.apple.' may not be supported, hence the problem with
+the fops succeed. But in the case of using exports of different OS on Darwin the issue is
+extended attribute prefix like 'com.apple.' may not be supported, hence the problem with
Finder. To solve this issue, GlusterFS returns virtual default values to these keys, which
works fine on most of the cases.
diff --git a/doc/porting_guide.txt b/doc/legacy/porting_guide.txt
index 905bb4228..5705cd964 100644
--- a/doc/porting_guide.txt
+++ b/doc/legacy/porting_guide.txt
@@ -3,7 +3,7 @@
* General setup
-The configure script will detect the target platform for the build.
+The configure script will detect the target platform for the build.
All platform-specific CFLAGS, macro definitions should be done
in configure.ac
@@ -15,11 +15,11 @@ Platform-specific code can be written like this:
* Coding guidelines
-In general, avoid glibc extensions. For example, nested functions don't work
+In general, avoid glibc extensions. For example, nested functions don't work
on Mac OS X. It is best to stick to C99.
When using library calls and system calls, pay attention to the
-portability notes. As far as possible stick to POSIX-specified behavior.
+portability notes. As far as possible stick to POSIX-specified behavior.
Do not use anything expressly permitted by the specification. For example,
some fields in structures may be present only on certain platforms. Avoid
use of such things.
@@ -27,14 +27,14 @@ use of such things.
Do not pass values of constants such as F_*, O_*, errno values, etc. across
platforms.
-Please refer compat-errno.h for more details about errno handling inside
-glusterfs for cross platform.
+Please refer compat-errno.h for more details about errno handling inside
+glusterfs for cross platform.
* Specific issues
- The argp library is available only on Linux through glibc, but for other
platforms glusterfs has already included argp-standalone library which will
- statically linked during the glusterfs build.
+ statically linked during the glusterfs build.
- Extended attribute calls (setxattr, listxattr, etc.) have differing prototypes
on different platforms. See compat.h for macro definitions to resolve this, also
diff --git a/doc/replicate.lyx b/doc/legacy/replicate.lyx
index d11a92bee..58ba6b2e0 100644
--- a/doc/replicate.lyx
+++ b/doc/legacy/replicate.lyx
@@ -36,7 +36,7 @@ Automatic File Replication (replicate) in GlusterFS
\end_layout
\begin_layout Author
-Vikas Gorur
+Vikas Gorur
\family typewriter
\size larger
<vikas@gluster.com>
@@ -77,7 +77,7 @@ The replicate translator of GlusterFS aims to keep identical copies of a file
\end_layout
\begin_layout Standard
-In the rest of the document the terms
+In the rest of the document the terms
\begin_inset Quotes eld
\end_inset
@@ -85,7 +85,7 @@ subvolume
\begin_inset Quotes erd
\end_inset
- and
+ and
\begin_inset Quotes eld
\end_inset
@@ -167,7 +167,7 @@ end{verbatim}
\begin_layout Standard
This defines an replicate volume with two subvolumes, brick1, and brick2.
- For replicate to work properly, it is essential that its subvolumes support
+ For replicate to work properly, it is essential that its subvolumes support
\series bold
extended attributes
\series default
@@ -177,7 +177,7 @@ extended attributes
\end_layout
\begin_layout Standard
-The storage volumes used as backend for replicate
+The storage volumes used as backend for replicate
\emph on
must
\emph default
@@ -262,7 +262,7 @@ replicate divides all filesystem write operations into three classes:
\begin_layout Itemize
\series bold
-data:
+data:
\series default
Operations that modify the contents of a file (write, truncate).
\end_layout
@@ -270,7 +270,7 @@ Operations that modify the contents of a file (write, truncate).
\begin_layout Itemize
\series bold
-metadata:
+metadata:
\series default
Operations that modify attributes of a file or directory (permissions, ownership
, etc.).
@@ -279,7 +279,7 @@ Operations that modify attributes of a file or directory (permissions, ownership
\begin_layout Itemize
\series bold
-entry:
+entry:
\series default
Operations that create or delete directory entries (mkdir, create, rename,
rmdir, unlink, etc.).
@@ -345,7 +345,7 @@ Self-Heal
\begin_layout Standard
replicate automatically tries to fix any inconsistencies it detects among different
copies of a file.
- It uses information in the change log to determine which copy is the
+ It uses information in the change log to determine which copy is the
\begin_inset Quotes eld
\end_inset
@@ -357,7 +357,7 @@ correct
\end_layout
\begin_layout Standard
-Self-heal is triggered when a file or directory is first
+Self-heal is triggered when a file or directory is first
\begin_inset Quotes eld
\end_inset
@@ -374,7 +374,7 @@ If the entry being accessed is a directory:
\end_layout
\begin_layout Itemize
-The contents of the
+The contents of the
\begin_inset Quotes eld
\end_inset
@@ -412,7 +412,7 @@ It may happen that one replicate client can access only some of the servers in
a cluster and another replicate client can access the remaining servers.
Or it may happen that in a cluster of two servers, one server goes down
and comes back up, but the other goes down immediately.
- Both these scenarios result in a
+ Both these scenarios result in a
\begin_inset Quotes eld
\end_inset
@@ -425,7 +425,7 @@ split-brain
\begin_layout Standard
In a split-brain situation, there will be two or more copies of a file,
- all of which are
+ all of which are
\begin_inset Quotes eld
\end_inset
@@ -484,12 +484,12 @@ split-brain
).
This means if a discrepancy is noticed in the attributes or content of
a file, the copy on the `favorite-child' will be considered the definitive
- version and its contents will
+ version and its contents will
\emph on
-overwrite
+overwrite
\emph default
the contents of all other copies.
- Use this option with caution! It is possible to
+ Use this option with caution! It is possible to
\emph on
lose data
\emph default
@@ -502,7 +502,7 @@ Self-heal options
\end_layout
\begin_layout Standard
-Setting any of these options to
+Setting any of these options to
\begin_inset Quotes eld
\end_inset
@@ -549,7 +549,7 @@ If any of these options is turned off, it disables writing of change log
entries for that class of file operations.
That is, steps 2 and 4 of the write algorithm (see above) are not done.
Note that if the change log is not written, the self-heal algorithm cannot
- determine the
+ determine the
\begin_inset Quotes eld
\end_inset
@@ -557,7 +557,7 @@ correct
\begin_inset Quotes erd
\end_inset
- version of a file and hence self-heal will only be able to fix
+ version of a file and hence self-heal will only be able to fix
\begin_inset Quotes eld
\end_inset
@@ -602,7 +602,7 @@ These options let you specify the number of lock servers to use for each
The default values are satisfactory in most cases.
If you are extra paranoid, you may want to increase the values.
However, be very cautious if you set the data- or entry- lock server counts
- to zero, since this can result in
+ to zero, since this can result in
\emph on
lost data.
@@ -610,11 +610,11 @@ lost data.
For example, if you set the data-lock-server-count to zero, and two application
s write to the same region of a file, there is a possibility that none of
your servers will have all the data.
- In other words, the copies will be
+ In other words, the copies will be
\emph on
inconsistent
\emph default
-, and
+, and
\emph on
incomplete
\emph default
diff --git a/doc/replicate.pdf b/doc/legacy/replicate.pdf
index b7212af2b..b7212af2b 100644
--- a/doc/replicate.pdf
+++ b/doc/legacy/replicate.pdf
Binary files differ
diff --git a/doc/rpc-for-glusterfs.changes-done.txt b/doc/legacy/rpc-for-glusterfs.changes-done.txt
index 6bbbca788..6bbbca788 100644
--- a/doc/rpc-for-glusterfs.changes-done.txt
+++ b/doc/legacy/rpc-for-glusterfs.changes-done.txt
diff --git a/doc/solaris-related-xattrs.txt b/doc/legacy/solaris-related-xattrs.txt
index e26efa5d1..3a4643948 100644
--- a/doc/solaris-related-xattrs.txt
+++ b/doc/legacy/solaris-related-xattrs.txt
@@ -1,42 +1,42 @@
Solaris Extended Attributes
In solaris extended attributes are logically supported as files
-within the filesystem. The file system is therefore augmented
+within the filesystem. The file system is therefore augmented
with an orthogonal namespace of file attributes. Attribute values
are accessed by file descriptors obtained through a special attribute
-interface. This type of logical view of "attributes as files" allows
-the leveraging of existing file system interface functionality to
-support the construction, deletion and manipulation of attributes.
+interface. This type of logical view of "attributes as files" allows
+the leveraging of existing file system interface functionality to
+support the construction, deletion and manipulation of attributes.
But as we have tested through this functionality provided by Solaris
we have come accross two major issues as written below.
-1. Symlink XATTR_NOFOLLOW not present for creating extended attributes
+1. Symlink XATTR_NOFOLLOW not present for creating extended attributes
directly on the symlinks like other platforms Linux,MAC-OSX,BSD etc.
- An implementation is present for O_NOFOLLOW for "openat()" call sets
- up errno ELOOP whenever encountered with a symlink and also another
+ An implementation is present for O_NOFOLLOW for "openat()" call sets
+ up errno ELOOP whenever encountered with a symlink and also another
implementation AT_SYMLINK_NOFOLLOW which is not present for calls like
"attropen(), openat()"
a snippet of test code which helped us understand this behaviour
--------------------------------------
- attrfd = attropen (path, key,
+ attrfd = attropen (path, key,
flags|AT_SYMLINK_NOFOLLOW|O_CREAT|O_WRONLY|O_NOFOLLOW, 0777);
if (attrfd >= 0) {
ftruncate (attrfd, 0);
ret = write (attrfd, value, size);
close (attrfd);
} else {
- fprintf (stderr, "Couldn't set extended attribute for %s (%d)\n",
+ fprintf (stderr, "Couldn't set extended attribute for %s (%d)\n",
path, errno);
- }
+ }
--------------------------------------
2. Extended attribute support for special files like device files, fifo files
- is not supported under solaris.
+ is not supported under solaris.
Apart from these glitches almost everything regarding porting functionality
-for extended attribute calls has been properly implemented in compat.c
+for extended attribute calls has been properly implemented in compat.c
with writing wrapper around functions over
"attropen()", "openat()", "unlinkat()"
diff --git a/doc/stat-prefetch-design.txt b/doc/legacy/stat-prefetch-design.txt
index 06d0ad37e..68ed423d3 100644
--- a/doc/stat-prefetch-design.txt
+++ b/doc/legacy/stat-prefetch-design.txt
@@ -1,64 +1,64 @@
what is stat-prefetch?
======================
It is a translator which caches the dentries read in readdir. This dentry
-list is stored in the context of fd. Later when lookup happens on
+list is stored in the context of fd. Later when lookup happens on
[parent-inode, basename (path)] combination, this list is searched for the
basename. The dentry thus searched is used to fill up the stat corresponding
to path being looked upon, thereby short-cutting lookup calls. This cache is
-preserved till closedir is called on the fd. The purpose of this translator
-is to optimize operations like 'ls -l', where a readdir is followed by
+preserved till closedir is called on the fd. The purpose of this translator
+is to optimize operations like 'ls -l', where a readdir is followed by
lookup (stat) calls on each directory entry.
-1. stat-prefetch harnesses the efficiency of short lookup calls
- (saves network roundtrip time for lookup calls from being accounted to
+1. stat-prefetch harnesses the efficiency of short lookup calls
+ (saves network roundtrip time for lookup calls from being accounted to
the stat call).
-2. To maintain the correctness, it does lookup-behind - lookup is winded to
- underlying translators after it is unwound to upper translators.
+2. To maintain the correctness, it does lookup-behind - lookup is winded to
+ underlying translators after it is unwound to upper translators.
lookup-behind is necessary as inode gets populated in server inode table
- only in lookup-cbk and also because various translators store their
+ only in lookup-cbk and also because various translators store their
contexts in inode contexts during lookup calls.
fops to be implemented:
=======================
* lookup
- 1. check the dentry cache stored in context of fds opened by the same process
+ 1. check the dentry cache stored in context of fds opened by the same process
on parent inode for basename. If found unwind with cached stat, else wind
- the lookup call to underlying translators.
- 2. stat is stored in the context of inode if the path being looked upon
+ the lookup call to underlying translators.
+ 2. stat is stored in the context of inode if the path being looked upon
happens to be directory. This stat will be used to fill postparent stat
when lookup happens on any of the directory contents.
* readdir
1. cache the direntries returned in readdir_cbk in the context of fd.
- 2. if the readdir is happening on non-expected offsets (means a seekdir/rewinddir
+ 2. if the readdir is happening on non-expected offsets (means a seekdir/rewinddir
has happened), cache has to be flushed.
- 3. delete the entry corresponding to basename of path on which fd is opened
+ 3. delete the entry corresponding to basename of path on which fd is opened
from cache stored in parent.
* chmod/fchmod
delete the entry corresponding to basename from cache stored in context of
- fds opened on parent inode, since these calls change st_mode and st_ctime of
+ fds opened on parent inode, since these calls change st_mode and st_ctime of
stat.
-
+
* chown/fchown
- delete the entry corresponding to basename from cache stored in context of
- fds opened on parent inode, since these calls change st_uid/st_gid and
+ delete the entry corresponding to basename from cache stored in context of
+ fds opened on parent inode, since these calls change st_uid/st_gid and
st_ctime of stat.
* truncate/ftruncate
- delete the entry corresponding to basename from cache stored in context of
+ delete the entry corresponding to basename from cache stored in context of
fds opened on parent inode, since these calls change st_size/st_mtime of stat.
* utimens
- delete the entry corresponding to basename from cache stored in context of
+ delete the entry corresponding to basename from cache stored in context of
fds opened on parent inode, since this call changes st_atime/st_mtime of stat.
* readlink
delete the entry corresponding to basename from cache stored in context of fds
opened on parent inode, since this call changes st_atime of stat.
-
+
* unlink
- 1. delete the entry corresponding to basename from cache stored in context of
+ 1. delete the entry corresponding to basename from cache stored in context of
fds, opened on parent directory containing the file being unlinked.
2. delete the entry corresponding to basename of parent directory from cache
of grand-parent.
@@ -66,14 +66,14 @@ fops to be implemented:
* rmdir
1. delete the entry corresponding to basename from cache stored in context of
fds opened on parent inode.
- 2. remove the entire cache from all fds opened on inode corresponding to
+ 2. remove the entire cache from all fds opened on inode corresponding to
directory being removed.
3. delete the entry correspondig to basename of parent from cache stored in
grand-parent.
* readv
delete the entry corresponding to basename from cache stored in context of fds
- opened on parent inode, since readv changes st_atime of file.
+ opened on parent inode, since readv changes st_atime of file.
* writev
delete the entry corresponding to basename from cache stored in context of fds
@@ -82,29 +82,29 @@ fops to be implemented:
* fsync
there is a confusion here as to whether fsync updates mtime/ctimes. Disk based
- filesystems (atleast ext2) just writes the times stored in inode to disk
- during fsync and not the time at which fsync is being done. But in glusterfs,
- a translator like write-behind actually sends writes during fsync which will
- change mtime/ctime. Hence stat-prefetch implements fsync to delete the entry
+ filesystems (atleast ext2) just writes the times stored in inode to disk
+ during fsync and not the time at which fsync is being done. But in glusterfs,
+ a translator like write-behind actually sends writes during fsync which will
+ change mtime/ctime. Hence stat-prefetch implements fsync to delete the entry
corresponding to basename from cache stored in context of fds opened on parent
inode.
-
+
* rename
- 1. remove entry corresponding to oldname from cache stored in fd contexts of
+ 1. remove entry corresponding to oldname from cache stored in fd contexts of
oldparent.
2. remove entry corresponding to newname from cache stored in fd contexts of
- newparent.
- 3. remove entry corresponding to oldparent from cache stored in
+ newparent.
+ 3. remove entry corresponding to oldparent from cache stored in
old-grand-parent, since removing oldname changes st_mtime and st_ctime
of oldparent stat.
- 4. remove entry corresponding to newparent from cache stored in
+ 4. remove entry corresponding to newparent from cache stored in
new-grand-parent, since adding newname changes st_mtime and st_ctime
of newparent stat.
- 5. if oldname happens to be a directory, remove entire cache from all fds
+ 5. if oldname happens to be a directory, remove entire cache from all fds
opened on it.
* create/mknod/mkdir/symlink/link
- delete entry corresponding to basename of parent directory in which these
+ delete entry corresponding to basename of parent directory in which these
operations are happening, from cache stored in context of fds opened on
grand-parent, since adding a new entry to a directory changes st_mtime
and st_ctime of parent directory.
@@ -116,13 +116,13 @@ fops to be implemented:
* setdents
1. remove entry corresponding to basename of path on which fd is opened from
cache stored in context of fds opened on parent.
- 2. for each of the entry in the direntry list, delete from cache stored in
+ 2. for each of the entry in the direntry list, delete from cache stored in
context of fd, the entry corresponding to basename of path being passed.
* getdents
1. remove entry corresponding to basename of path on which fd is opened from
- cache stored in parent, since getdents changes st_atime.
- 2. remove entries corresponding to symbolic links from cache, since readlink
+ cache stored in parent, since getdents changes st_atime.
+ 2. remove entries corresponding to symbolic links from cache, since readlink
would've changed st_atime.
* checksum
@@ -144,11 +144,11 @@ callbacks to be implemented:
limitations:
============
* since a readdir does not return extended attributes of file, if need_xattr is
- set, short-cutting of lookup does not happen and lookup is passed to
+ set, short-cutting of lookup does not happen and lookup is passed to
underlying translators.
* posix_readdir does not check whether the dentries are spanning across multiple
- mount points. Hence it is not transforming inode numbers in stat buffers if
+ mount points. Hence it is not transforming inode numbers in stat buffers if
posix is configured to allow export directory spanning on multiple mountpoints.
- This is a bug which needs to be fixed. posix_readdir should treat dentries the
+ This is a bug which needs to be fixed. posix_readdir should treat dentries the
same way as if lookup is happening on dentries.
diff --git a/doc/translator-options.txt b/doc/legacy/translator-options.txt
index 278ef5b00..3422c058a 100644
--- a/doc/translator-options.txt
+++ b/doc/legacy/translator-options.txt
@@ -1,7 +1,7 @@
mount/fuse:
* direct-io-mode GF_OPTION_TYPE_BOOL on|off|yes|no
* mount-point (mountpoint) GF_OPTION_TYPE_PATH <any-posix-valid-path>
- * attribute-timeout GF_OPTION_TYPE_DOUBLE 0.0
+ * attribute-timeout GF_OPTION_TYPE_DOUBLE 0.0
* entry-timeout GF_OPTION_TYPE_DOUBLE 0.0
protocol/server:
@@ -13,20 +13,20 @@ protocol/server:
protocol/client:
* username GF_OPTION_TYPE_ANY
- * password GF_OPTION_TYPE_ANY
+ * password GF_OPTION_TYPE_ANY
* transport-type GF_OPTION_TYPE_STR tcp|socket|ib-verbs|unix|ib-sdp|
tcp/client|ib-verbs/client
- * remote-host GF_OPTION_TYPE_ANY
- * remote-subvolume GF_OPTION_TYPE_ANY
- * transport-timeout GF_OPTION_TYPE_TIME 5-1013
+ * remote-host GF_OPTION_TYPE_ANY
+ * remote-subvolume GF_OPTION_TYPE_ANY
+ * transport-timeout GF_OPTION_TYPE_TIME 5-1013
cluster/replicate:
* read-subvolume GF_OPTION_TYPE_XLATOR
* favorite-child GF_OPTION_TYPE_XLATOR
- * data-self-heal GF_OPTION_TYPE_BOOL
+ * data-self-heal GF_OPTION_TYPE_BOOL
* metadata-self-heal GF_OPTION_TYPE_BOOL
- * entry-self-heal GF_OPTION_TYPE_BOOL
- * data-change-log GF_OPTION_TYPE_BOOL
+ * entry-self-heal GF_OPTION_TYPE_BOOL
+ * data-change-log GF_OPTION_TYPE_BOOL
* metadata-change-log GF_OPTION_TYPE_BOOL
* entry-change-log GF_OPTION_TYPE_BOOL
* data-lock-server-count GF_OPTION_TYPE_INT 0
@@ -34,54 +34,54 @@ cluster/replicate:
* entry-lock-server-count GF_OPTION_TYPE_INT 0
cluster/distribute:
- * lookup-unhashed GF_OPTION_TYPE_BOOL
+ * lookup-unhashed GF_OPTION_TYPE_BOOL
cluster/unify:
- * namespace GF_OPTION_TYPE_XLATOR
- * scheduler GF_OPTION_TYPE_STR alu|rr|random|nufa|switch
+ * namespace GF_OPTION_TYPE_XLATOR
+ * scheduler GF_OPTION_TYPE_STR alu|rr|random|nufa|switch
* self-heal GF_OPTION_TYPE_STR foreground|background|off
- * optimist GF_OPTION_TYPE_BOOL
+ * optimist GF_OPTION_TYPE_BOOL
cluster/nufa:
- local-volume-name GF_OPTION_TYPE_XLATOR
+ local-volume-name GF_OPTION_TYPE_XLATOR
cluster/stripe:
- * block-size GF_OPTION_TYPE_ANY
+ * block-size GF_OPTION_TYPE_ANY
* use-xattr GF_OPTION_TYPE_BOOL
debug/trace:
* include-ops (include) GF_OPTION_TYPE_STR
- * exclude-ops (exclude) GF_OPTION_TYPE_STR
+ * exclude-ops (exclude) GF_OPTION_TYPE_STR
encryption/rot-13:
* encrypt-write GF_OPTION_TYPE_BOOL
- * decrypt-read GF_OPTION_TYPE_BOOL
+ * decrypt-read GF_OPTION_TYPE_BOOL
features/path-convertor:
- * start-offset GF_OPTION_TYPE_INT 0-4095
- * end-offset GF_OPTION_TYPE_INT 1-4096
+ * start-offset GF_OPTION_TYPE_INT 0-4095
+ * end-offset GF_OPTION_TYPE_INT 1-4096
* replace-with GF_OPTION_TYPE_ANY
features/trash:
- * trash-dir GF_OPTION_TYPE_PATH
+ * trash-dir GF_OPTION_TYPE_PATH
features/locks:
- * mandatory-locks (mandatory) GF_OPTION_TYPE_BOOL
+ * mandatory-locks (mandatory) GF_OPTION_TYPE_BOOL
features/filter:
- * root-squashing GF_OPTION_TYPE_BOOL
+ * root-squashing GF_OPTION_TYPE_BOOL
* read-only GF_OPTION_TYPE_BOOL
* fixed-uid GF_OPTION_TYPE_INT
* fixed-gid GF_OPTION_TYPE_INT
- * translate-uid GF_OPTION_TYPE_ANY
+ * translate-uid GF_OPTION_TYPE_ANY
* translate-gid GF_OPTION_TYPE_ANY
- * filter-uid GF_OPTION_TYPE_ANY
- * filter-gid GF_OPTION_TYPE_ANY
+ * filter-uid GF_OPTION_TYPE_ANY
+ * filter-gid GF_OPTION_TYPE_ANY
features/quota:
* min-free-disk-limit GF_OPTION_TYPE_PERCENT
* refresh-interval GF_OPTION_TYPE_TIME
- * disk-usage-limit GF_OPTION_TYPE_SIZET
+ * disk-usage-limit GF_OPTION_TYPE_SIZET
storage/posix:
* o-direct GF_OPTION_TYPE_BOOL
@@ -104,16 +104,16 @@ storage/bdb:
* access-mode GF_OPTION_TYPE_STR
performance/read-ahead:
- * force-atime-update GF_OPTION_TYPE_BOOL
+ * force-atime-update GF_OPTION_TYPE_BOOL
* page-size GF_OPTION_TYPE_SIZET (64 * GF_UNIT_KB)-(2 * GF_UNIT_MB)
- * page-count GF_OPTION_TYPE_INT 1-16
+ * page-count GF_OPTION_TYPE_INT 1-16
performance/write-behind:
* flush-behind GF_OPTION_TYPE_BOOL
- * aggregate-size GF_OPTION_TYPE_SIZET (128 * GF_UNIT_KB)-(4 * GF_UNIT_MB)
- * window-size GF_OPTION_TYPE_SIZET (512 * GF_UNIT_KB)-(1 * GF_UNIT_GB)
- * enable-O_SYNC GF_OPTION_TYPE_BOOL
- * disable-for-first-nbytes GF_OPTION_TYPE_SIZET 1 - (1 * GF_UNIT_MB)
+ * aggregate-size GF_OPTION_TYPE_SIZET (128 * GF_UNIT_KB)-(4 * GF_UNIT_MB)
+ * window-size GF_OPTION_TYPE_SIZET (512 * GF_UNIT_KB)-(1 * GF_UNIT_GB)
+ * enable-O_SYNC GF_OPTION_TYPE_BOOL
+ * disable-for-first-nbytes GF_OPTION_TYPE_SIZET 1 - (1 * GF_UNIT_MB)
performance/symlink-cache:
@@ -121,9 +121,9 @@ performance/io-threads:
* thread-count GF_OPTION_TYPE_INT 1-32
performance/io-cache:
- * priority GF_OPTION_TYPE_ANY
- * cache-timeout (force-revalidate-timeout) GF_OPTION_TYPE_INT 0-60
- * page-size GF_OPTION_TYPE_SIZET (16 * GF_UNIT_KB)-(4 * GF_UNIT_MB)
+ * priority GF_OPTION_TYPE_ANY
+ * cache-timeout (force-revalidate-timeout) GF_OPTION_TYPE_INT 0-60
+ * page-size GF_OPTION_TYPE_SIZET (16 * GF_UNIT_KB)-(4 * GF_UNIT_MB)
* cache-size GF_OPTION_TYPE_SIZET (4 * GF_UNIT_MB)-(6 * GF_UNIT_GB)
performance/quick-read:
@@ -132,16 +132,16 @@ performance/quick-read:
auth:
- addr:
- * auth.addr.*.allow GF_OPTION_TYPE_ANY
- * auth.addr.*.reject GF_OPTION_TYPE_ANY
+ * auth.addr.*.allow GF_OPTION_TYPE_ANY
+ * auth.addr.*.reject GF_OPTION_TYPE_ANY
- login:
- * auth.login.*.allow GF_OPTION_TYPE_ANY
+ * auth.login.*.allow GF_OPTION_TYPE_ANY
* auth.login.*.password GF_OPTION_TYPE_ANY
scheduler/alu:
- * scheduler.alu.order (alu.order)
- GF_OPTION_TYPE_ANY
+ * scheduler.alu.order (alu.order)
+ GF_OPTION_TYPE_ANY
* scheduler.alu.disk-usage.entry-threshold (alu.disk-usage.entry-threshold)
GF_OPTION_TYPE_SIZET
* scheduler.alu.disk-usage.exit-threshold (alu.disk-usage.exit-threshold)
@@ -149,17 +149,17 @@ scheduler/alu:
* scheduler.alu.write-usage.entry-threshold (alu.write-usage.entry-threshold)
GF_OPTION_TYPE_SIZET
* scheduler.alu.write-usage.exit-threshold (alu.write-usage.exit-threshold)
- GF_OPTION_TYPE_SIZET
+ GF_OPTION_TYPE_SIZET
* scheduler.alu.read-usage.entry-threshold (alu.read-usage.entry-threshold)
GF_OPTION_TYPE_SIZET
* scheduler.alu.read-usage.exit-threshold (alu.read-usage.exit-threshold)
- GF_OPTION_TYPE_SIZET
+ GF_OPTION_TYPE_SIZET
* scheduler.alu.open-files-usage.entry-threshold (alu.open-files-usage.entry-threshold)
GF_OPTION_TYPE_INT
* scheduler.alu.open-files-usage.exit-threshold (alu.open-files-usage.exit-threshold)
- GF_OPTION_TYPE_INT
+ GF_OPTION_TYPE_INT
* scheduler.read-only-subvolumes (alu.read-only-subvolumes)
- GF_OPTION_TYPE_ANY
+ GF_OPTION_TYPE_ANY
* scheduler.refresh-interval (alu.refresh-interval)
GF_OPTION_TYPE_TIME
* scheduler.limits.min-free-disk (alu.limits.min-free-disk)
@@ -168,11 +168,11 @@ scheduler/alu:
GF_OPTION_TYPE_INT
scheduler/nufa:
- * scheduler.refresh-interval (nufa.refresh-interval)
+ * scheduler.refresh-interval (nufa.refresh-interval)
GF_OPTION_TYPE_TIME
- * scheduler.limits.min-free-disk (nufa.limits.min-free-disk)
+ * scheduler.limits.min-free-disk (nufa.limits.min-free-disk)
GF_OPTION_TYPE_PERCENT
- * scheduler.local-volume-name (nufa.local-volume-name)
+ * scheduler.local-volume-name (nufa.local-volume-name)
GF_OPTION_TYPE_XLATOR
scheduler/random:
@@ -204,20 +204,20 @@ transport/ib-verbs:
* transport.ib-verbs.work-request-recv-count (ib-verbs-work-request-recv-count)
GF_OPTION_TYPE_INT
* remote-port (transport.remote-port,transport.ib-verbs.remote-port)
- GF_OPTION_TYPE_INT
- * transport.ib-verbs.listen-port GF_OPTION_TYPE_INT
- * transport.ib-verbs.connect-path (connect-path) GF_OPTION_TYPE_ANY
- * transport.ib-verbs.bind-path (bind-path) GF_OPTION_TYPE_ANY
- * transport.ib-verbs.listen-path (listen-path) GF_OPTION_TYPE_ANY
+ GF_OPTION_TYPE_INT
+ * transport.ib-verbs.listen-port GF_OPTION_TYPE_INT
+ * transport.ib-verbs.connect-path (connect-path) GF_OPTION_TYPE_ANY
+ * transport.ib-verbs.bind-path (bind-path) GF_OPTION_TYPE_ANY
+ * transport.ib-verbs.listen-path (listen-path) GF_OPTION_TYPE_ANY
* transport.address-family (address-family) GF_OPTION_TYPE_STR inet|inet6|inet/inet6|
inet6/inet|unix|inet-sdp
transport/socket:
- * transport.remote-port (remote-port,transport.socket.remote-port) GF_OPTION_TYPE_INT
- * transport.socket.listen-port (listen-port) GF_OPTION_TYPE_INT
- * transport.socket.bind-address (bind-address) GF_OPTION_TYPE_ANY
- * transport.socket.connect-path (connect-path) GF_OPTION_TYPE_ANY
- * transport.socket.bind-path (bind-path) GF_OPTION_TYPE_ANY
+ * transport.remote-port (remote-port,transport.socket.remote-port) GF_OPTION_TYPE_INT
+ * transport.socket.listen-port (listen-port) GF_OPTION_TYPE_INT
+ * transport.socket.bind-address (bind-address) GF_OPTION_TYPE_ANY
+ * transport.socket.connect-path (connect-path) GF_OPTION_TYPE_ANY
+ * transport.socket.bind-path (bind-path) GF_OPTION_TYPE_ANY
* transport.socket.listen-path (listen-path) GF_OPTION_TYPE_ANY
* transport.address-family (address-family) GF_OPTION_TYPE_STR inet|inet6|
inet/inet6|inet6/inet|
diff --git a/doc/mount.glusterfs.8 b/doc/mount.glusterfs.8
index 0552f7f61..10e1d59f0 100644
--- a/doc/mount.glusterfs.8
+++ b/doc/mount.glusterfs.8
@@ -2,16 +2,16 @@
.\" This file is part of GlusterFS.
.\"
.\" GlusterFS is free software; you can redistribute it and/or modify
-.\" it under the terms of the GNU Affero General Public License as published
+.\" it under the terms of the GNU General Public License as published
.\" by the Free Software Foundation; either version 3 of the License,
.\" or (at your option) any later version.
.\"
.\" GlusterFS is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-.\" Affero General Public License for more details.
+.\" General Public License for more details.
.\"
-.\" You should have received a copy of the GNU Affero General Public License
+.\" You should have received a copy of the GNU General Public License
.\" long with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
diff --git a/doc/qa/qa-client.vol b/doc/qa/legacy/qa-client.vol
index 176dda589..bcf242347 100644
--- a/doc/qa/qa-client.vol
+++ b/doc/qa/legacy/qa-client.vol
@@ -1,17 +1,17 @@
# This spec file should be used for testing before any release
-#
+#
# 1st client
volume client1
type protocol/client
option transport-type tcp # for TCP/IP transport
# option transport-type ib-sdp # for Infiniband transport
-# option transport-type ib-verbs # for ib-verbs transport
+# option transport-type ib-verbs # for ib-verbs transport
# option transport.ib-verbs.work-request-send-size 131072
# option transport.ib-verbs.work-request-send-count 64
# option transport.ib-verbs.work-request-recv-size 131072
# option transport.ib-verbs.work-request-recv-count 64
- option remote-host 127.0.0.1
+ option remote-host 127.0.0.1
option remote-subvolume ra1
end-volume
@@ -20,8 +20,8 @@ volume client2
type protocol/client
option transport-type tcp # for TCP/IP transport
# option transport-type ib-sdp # for Infiniband transport
-# option transport-type ib-verbs # for ib-verbs transport
- option remote-host 127.0.0.1
+# option transport-type ib-verbs # for ib-verbs transport
+ option remote-host 127.0.0.1
option remote-subvolume ra2
end-volume
@@ -30,8 +30,8 @@ volume client3
type protocol/client
option transport-type tcp # for TCP/IP transport
# option transport-type ib-sdp # for Infiniband transport
-# option transport-type ib-verbs # for ib-verbs transport
- option remote-host 127.0.0.1
+# option transport-type ib-verbs # for ib-verbs transport
+ option remote-host 127.0.0.1
option remote-subvolume ra3
end-volume
@@ -40,8 +40,8 @@ volume client4
type protocol/client
option transport-type tcp # for TCP/IP transport
# option transport-type ib-sdp # for Infiniband transport
-# option transport-type ib-verbs # for ib-verbs transport
- option remote-host 127.0.0.1
+# option transport-type ib-verbs # for ib-verbs transport
+ option remote-host 127.0.0.1
option remote-subvolume ra4
end-volume
@@ -50,8 +50,8 @@ volume client5
type protocol/client
option transport-type tcp # for TCP/IP transport
# option transport-type ib-sdp # for Infiniband transport
-# option transport-type ib-verbs # for ib-verbs transport
- option remote-host 127.0.0.1
+# option transport-type ib-verbs # for ib-verbs transport
+ option remote-host 127.0.0.1
option remote-subvolume ra5
end-volume
@@ -60,8 +60,8 @@ volume client6
type protocol/client
option transport-type tcp # for TCP/IP transport
# option transport-type ib-sdp # for Infiniband transport
-# option transport-type ib-verbs # for ib-verbs transport
- option remote-host 127.0.0.1
+# option transport-type ib-verbs # for ib-verbs transport
+ option remote-host 127.0.0.1
option remote-subvolume ra6
end-volume
@@ -70,18 +70,18 @@ volume client7
type protocol/client
option transport-type tcp # for TCP/IP transport
# option transport-type ib-sdp # for Infiniband transport
-# option transport-type ib-verbs # for ib-verbs transport
- option remote-host 127.0.0.1
+# option transport-type ib-verbs # for ib-verbs transport
+ option remote-host 127.0.0.1
option remote-subvolume ra7
end-volume
-# 8th client
+# 8th client
volume client8
type protocol/client
option transport-type tcp # for TCP/IP transport
# option transport-type ib-sdp # for Infiniband transport
-# option transport-type ib-verbs # for ib-verbs transport
- option remote-host 127.0.0.1
+# option transport-type ib-verbs # for ib-verbs transport
+ option remote-host 127.0.0.1
option remote-subvolume ra8
end-volume
diff --git a/doc/qa/qa-high-avail-client.vol b/doc/qa/legacy/qa-high-avail-client.vol
index 69cb8dd30..69cb8dd30 100644
--- a/doc/qa/qa-high-avail-client.vol
+++ b/doc/qa/legacy/qa-high-avail-client.vol
diff --git a/doc/qa/qa-high-avail-server.vol b/doc/qa/legacy/qa-high-avail-server.vol
index 3556b9dae..784e8d208 100644
--- a/doc/qa/qa-high-avail-server.vol
+++ b/doc/qa/legacy/qa-high-avail-server.vol
@@ -110,7 +110,7 @@ volume server1
option transport.socket.listen-port 7001
option auth.addr.server1-posix1.allow *
option auth.addr.server1-ns1.allow *
- option auth.addr.server1-iot.allow *
+ option auth.addr.server1-iot.allow *
end-volume
@@ -225,7 +225,7 @@ volume server2
option transport.socket.listen-port 7002
option auth.addr.server2-posix2.allow *
option auth.addr.server2-ns2.allow *
- option auth.addr.server2-iot.allow *
+ option auth.addr.server2-iot.allow *
end-volume
# == server 3 ==
@@ -339,6 +339,6 @@ volume server3
option transport.socket.listen-port 7003
option auth.addr.server3-posix3.allow *
option auth.addr.server3-ns3.allow *
- option auth.addr.server3-iot.allow *
+ option auth.addr.server3-iot.allow *
end-volume
diff --git a/doc/qa/qa-server.vol b/doc/qa/legacy/qa-server.vol
index 1c245c324..d948f701f 100644
--- a/doc/qa/qa-server.vol
+++ b/doc/qa/legacy/qa-server.vol
@@ -1,5 +1,5 @@
# This spec file should be used for testing before any release
-#
+#
# Namespace posix
volume brick-ns
diff --git a/doc/release-notes/en-US/Author_Group.xml b/doc/release-notes/en-US/Author_Group.xml
new file mode 100644
index 000000000..43a491ea9
--- /dev/null
+++ b/doc/release-notes/en-US/Author_Group.xml
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Administration_Guide.ent">
+%BOOK_ENTITIES;
+]>
+<authorgroup>
+ <author>
+ <firstname>GlusterFS</firstname>
+ <surname>Developers</surname>
+ <affiliation>
+ <orgname>Red Hat</orgname>
+ <orgdiv>Storage</orgdiv>
+ </affiliation>
+ <email>gluster-devel@nongnu.org</email>
+ </author>
+</authorgroup>
+
diff --git a/doc/release-notes/en-US/Book_Info.xml b/doc/release-notes/en-US/Book_Info.xml
new file mode 100644
index 000000000..d3bbb9f68
--- /dev/null
+++ b/doc/release-notes/en-US/Book_Info.xml
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. -->
+<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<bookinfo id="book-Release_Notes-Release_Notes">
+ <title>Release Notes</title>
+ <subtitle>Release Notes for GlusterFS<remark> 3.3.0 </remark></subtitle>
+ <productname>GlusterFS</productname>
+ <productnumber>3.3</productnumber>
+ <edition>1</edition>
+ <pubsnumber>1</pubsnumber>
+ <abstract>
+ <para>
+ This Release Notes introduces GlusterFS and provides information including key features and managing the software.
+ </para>
+ </abstract>
+ <corpauthor>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="Common_Content/images/title_logo.svg" format="SVG"/>
+ </imageobject>
+ </inlinemediaobject>
+ </corpauthor>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Common_Content/Legal_Notice.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Author_Group.xml"/>
+</bookinfo>
diff --git a/doc/release-notes/en-US/Chapter.xml b/doc/release-notes/en-US/Chapter.xml
new file mode 100644
index 000000000..8a2957971
--- /dev/null
+++ b/doc/release-notes/en-US/Chapter.xml
@@ -0,0 +1,33 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Release_Notes-Test_Chapter">
+ <title>Test Chapter</title>
+ <para>
+ This is a test paragraph
+ </para>
+ <section id="sect-Release_Notes-Test_Chapter-Test_Section_1">
+ <title>Test Section 1</title>
+ <para>
+ This is a test paragraph in a section
+ </para>
+ </section>
+
+ <section id="sect-Release_Notes-Test_Chapter-Test_Section_2">
+ <title>Test Section 2</title>
+ <para>
+ This is a test paragraph in Section 2
+ <orderedlist>
+ <listitem>
+ <para>
+ listitem text
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </section>
+
+</chapter>
+
diff --git a/doc/release-notes/en-US/Download_Install.xml b/doc/release-notes/en-US/Download_Install.xml
new file mode 100644
index 000000000..10bc5663b
--- /dev/null
+++ b/doc/release-notes/en-US/Download_Install.xml
@@ -0,0 +1,107 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Release_Notes-Launch">
+ <title>Downloading and Installing GlusterFS </title>
+ <para>You can download and install the GlusterFS 3.3.0 or upgrade to latest version
+ </para>
+ <section id="sect-Release_Notes-Download_and_Install-Test_Section_1">
+ <title>Downloading GlusterFS 3.3 </title>
+ <para>You can download the latest software to each server in your cluster from <ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.0/3.3.0/ "/>.
+ </para>
+ </section>
+ <section id="sect-Release_Notes-Download_and_Install-Test_Section_2">
+ <title>New Installation </title>
+ <para>
+The installation process for GlusterFS server is available at:
+
+ <ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.2/Documentation/IG/html/chap-Installation_Guide-Installing.html"/>
+ </para>
+ </section>
+ <section>
+ <title>Compatibility </title>
+ <para>Release 3.3 of GlusterFS is not compatible with 2.0.x, 3.0.x, 3.1.x, and 3.2.x releases of GlusterFS.
+</para>
+ </section>
+ <section>
+ <title>Upgrade </title>
+ <para>Red Hat recommends that you back up your data before upgrading to GlusterFS 3.3.
+</para>
+ <note>
+ <para>Configurations generated outside the scope of gluster CLI are neither recommended nor
+supported by Red Hat.
+</para>
+ </note>
+ <section>
+ <title>Upgrade from GlusterFS v3.2.x or 3.1.x to GlusterFS v3.3 </title>
+ <para>In an environment with replicated bricks it is recommended that you upgrade a single storage server,
+confirm stability, and then upgrade the replica.
+</para>
+ <para>Use the same installation method for the upgrade as the original glusterfs installation.
+</para>
+ <para><emphasis role="bold">Using RPMs on RHEL, CentOS, Fedora</emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Download the 3.3 RPMs from the following location:
+</para>
+ <para><emphasis role="bold">RHEL:</emphasis> <ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.0/3.3.0/RHEL/ "/></para>
+ <para><emphasis role="bold">Fedora:</emphasis> <ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.0/3.3.0/Fedora/ "/></para>
+ </listitem>
+ <listitem>
+ <para>Run rpm using the following command:
+</para>
+ <para><command># rpm -U glusterfs*</command>
+</para>
+ </listitem>
+ </orderedlist>
+ <para><emphasis role="bold">Using dpkg on Debian, Ubuntu</emphasis>
+</para>
+ <orderedlist>
+ <listitem>
+ <para>Download the 3.3 packages from
+</para>
+ <para><emphasis role="bold">Debian:</emphasis> <ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.0/3.3.0/Debian/ "/></para>
+ <para><emphasis role="bold">Ubuntu:</emphasis> <ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.0/3.3.0/Ubuntu/ "/></para>
+ </listitem>
+ <listitem>
+ <para>Run dpkg using the following command:
+</para>
+ <para><command># dpkg -i glusterfs* </command></para>
+ </listitem>
+ </orderedlist>
+ <para><emphasis role="bold">Building from source </emphasis></para>
+ <orderedlist>
+ <listitem>
+ <para>Download the 3.3 source code from
+</para>
+ <para><ulink url="http://download.gluster.com/pub/gluster/glusterfs/3.0/3.3.0/glusterf3-3.0.tar.gz"/></para>
+ </listitem>
+ <listitem>
+ <para>Unpack and install GlusterFS using the following commands:
+</para>
+ <screen># gunzip glusterfs-3.3.0.tar.gz
+# tar xvf glusterfs-3.3.0.tar
+# cd glusterfs-3.3.0
+# ./configure
+# make
+# make install</screen>
+ </listitem>
+ <listitem>
+ <para>Stop and start GlusterFS using the following commands, this step will disconnect Gluster Native
+clients.
+</para>
+ <para><command># killall glusterfsd </command></para>
+ <para><command># killall glusterfs </command></para>
+ <para><command># killall glusterd </command></para>
+ </listitem>
+ <listitem>
+ <para>Start GlusterFS using the following command:
+</para>
+ <para><command># /etc/init.d/glusterd start </command></para>
+ </listitem>
+ </orderedlist>
+ </section>
+ </section>
+</chapter>
diff --git a/doc/release-notes/en-US/Key_Features.xml b/doc/release-notes/en-US/Key_Features.xml
new file mode 100644
index 000000000..4e11bec84
--- /dev/null
+++ b/doc/release-notes/en-US/Key_Features.xml
@@ -0,0 +1,72 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Release_Notes-Key_Features">
+ <title>Key Features</title>
+ <para>This section describes the key features available in Red Hat Storage. The following is a list of feature highlights of this new version of the Red Hat Storage software: </para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">High Availability</emphasis></para>
+ <para>The Red Hat Storage provides both synchronous and asynchronous n-way file replication to assure data availability:</para>
+ <para><itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Synchronous replication</emphasis> provides redundancy and protection within a single data center or multiple data centers and availability zones in a region.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Asynchronous geo-replication</emphasis>- Red Hat Storage supports Geo-Rep long distance replication. Customers can configure storage server nodes and Red Hat Storage to asynchronously replicate data
+over vast geographical distances.
+.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Deploy in Minutes</emphasis></para>
+ <para>The Red Hat Storage S can be deployed in minutes, providing one of the fastest ways to create an on-demand, high-performance, petabyte-scale storage environment. </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">No Application Rewrites</emphasis></para>
+ <para>Red Hat Storage Appliance provides full support for the semantics of a normal Linux file system like ext4 so there is no need to rewrite applications when moving data to the cloud as with cloud-based object storage. </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Flexibility</emphasis>
+</para>
+ <para>Runs in userspace, eliminating the need for complex
+kernel patches or dependencies.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Scalability</emphasis>
+</para>
+ <para>Elastic volume management enables storage volumes
+to be abstracted from the hardware so data and hardware can be managed independently. Storage can be
+added while data continues to be available, with no
+application interruption. Volumes can grow across
+machines in the system and can be migrated within the
+system to rebalance capacity. Storage server nodes
+can be added on the fly.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Simple Management</emphasis>
+</para>
+ <para>Simple, single command for storage management. It also includes performance monitoring and analysis tools like Top and Profile. Top provides visibility into the workload pattern and Profile provides performance
+statistics over a user-defined
+time period for metrics including latency and amount of
+data read or written.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">No Metadata Server </emphasis></para>
+ <para>Rather than using a centralized or
+distributed metadata server, Red Hat Storage software
+ uses an elastic hashing algorithm to locate
+data in the storage pool removing this common source
+of I/O bottlenecks and vulnerability to failure. Data
+access is fully parallelized and performance scales
+linearly.
+</para>
+ </listitem>
+ </itemizedlist>
+</chapter>
diff --git a/doc/release-notes/en-US/Known_Issues.xml b/doc/release-notes/en-US/Known_Issues.xml
new file mode 100644
index 000000000..834ed5336
--- /dev/null
+++ b/doc/release-notes/en-US/Known_Issues.xml
@@ -0,0 +1,164 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Release_Notes-Known_Issues">
+ <title>Known Issues</title>
+ <para>
+ The following are the known issues:
+
+ </para>
+ <para><itemizedlist>
+ <listitem>
+ <para>Issues related to Distributed Replicated Volumes:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>When process has done <emphasis role="italic">
+ <emphasis role="italic">
+ <command>cd</command>
+ </emphasis>
+ </emphasis> into a directory, stat of deleted file recreates it (directory self-
+heal not triggered).
+</para>
+ <para>In GlusterFS replicated setup, if you are inside a directory (for example, <filename>Test</filename> directory) of
+replicated volume. From another node, you will delete a file inside <filename>Test</filename> directory. Then if you
+perform <command>stat</command> operation on the same file name, the file will be automatically created. (that is, a
+proper directory self-heal is not triggered when process has done <command>cd</command> into a path).
+</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>Issues related to Distributed Volumes:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Rebalance does not happen if bricks are down.
+
+</para>
+ <para>Currently while running rebalance, make sure all the bricks are in operating or connected state.
+
+</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>glusterfsd - Error return code is not proper after daemonizing the process.
+</para>
+ <para>Due to this, scripts that mount glusterfs or start glusterfs process must not depend on its return
+value.
+</para>
+ </listitem>
+ <listitem>
+ <para>After <command># gluster volume replace-brick <replaceable>VOLNAME Brick New-Brick</replaceable> commit</command> command
+is issued, the file system operations on that particular volume, which are in transit will fail.
+</para>
+ </listitem>
+ <listitem>
+ <para>Command <command># gluster volume replace-brick ...</command> will fail in a RDMA set up.
+</para>
+ </listitem>
+ <listitem>
+ <para>If files and directories have different GFIDs on different backends, GlusterFS client may hang or
+display errors.
+</para>
+ <para><emphasis role="bold">Work Around</emphasis>: The workaround for this issue is explained at <ulink url="http://gluster.org/pipermail/gluster-users/2011-July/008215.html"/>
+.
+</para>
+ </listitem>
+ <listitem>
+ <para>Issues related to Directory Quota:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Some writes can appear to pass even though the quota limit is exceeded (write returns
+success). This is because they could be cached in write-behind. However disk-space would
+not exceed the quota limit, since when writes to backend happen, quota does not allow
+them. Hence it is advised that applications should check for return value of close call.
+</para>
+ </listitem>
+ <listitem>
+ <para>If a user has done <command>cd</command> into a directory on which the administrator is setting the limit, even
+ though the command succeeds and the new limit value will be applicable to all the users
+except for those users’ who has done <command>cd</command> in to that particular directory. The old limit value
+ will be applicable until the user has <command>cd</command> out of that directory.
+</para>
+ </listitem>
+ <listitem>
+ <para>Rename operation (that is, removing oldpath and creating newpath) requires additional disk
+space equal to file size. This is because, during rename, it subtracts the size on oldpath after
+rename operation is performed, but it checks whether quota limit is exceeded on parents of
+newfile before rename operation.
+</para>
+ </listitem>
+ <listitem>
+ <para>With striped volumes, Quota feature is not available.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>Issues related to POSIX ACLs:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>Even though POSIX ACLs are set on the file or directory, the <computeroutput>+</computeroutput> (plus) sign in the file
+ permissions will not be displayed. This is for performance optimization and will be fixed in a
+ future release.
+</para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>When glusterfs is mounted with <command>-o acl</command>, directory read performance can be bad. Commands
+like recursive directory listing can be slower than normal.
+</para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>When POSIX ACLs are set and multiple NFS clients are used, there could be inconsistency in
+the way ACLs are applied due to attribute caching in NFS. For a consistent view of POSIX ACLs
+in a multiple client setup, use <command>-o noac</command> option on NFS mount to switch off attribute caching.
+ This could have a performance impact on operations involving attributes.
+</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>If you have enabled Gluster NLM, you cannot mount kernel NFS client on your storage nodes.
+
+</para>
+ </listitem>
+ <listitem condition="gfs">
+ <para>Error with lost and found directory while using multiple disks.</para>
+ <para><emphasis role="bold">Work Around</emphasis>: You must ensure that the brick directories are one of the extra directories in the back-end mount point. For Example, if <filename>/dev/sda1</filename> is mounted on <filename>/export1</filename>, use <filename>/export1/volume</filename> as the glusterfs&apos;s export directory. </para>
+ </listitem>
+ <listitem>
+ <para>Due to enhancements in Graphs, you may experience excessive memory usage with this release.
+
+</para>
+ </listitem>
+ <listitem>
+ <para>After you restart the NFS server, the unlock within the grace-period may fail and previously held locks may not be reclaimed.
+
+</para>
+ </listitem>
+ <listitem>
+ <para>After a rebalancing a volume, if you run <command>rm -rf</command> command at the mount point to remove all contents of the current working directory recursively without prompting, you may get &quot;Directory not Empty&quot; error message.
+
+</para>
+ </listitem>
+ <listitem>
+ <para>The following is a known missing (minor) feature:
+</para>
+ <itemizedlist>
+ <listitem>
+ <para>locks - <emphasis role="italic">mandatory</emphasis> locking is not supported.
+</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist></para>
+</chapter>
diff --git a/doc/release-notes/en-US/Preface.xml b/doc/release-notes/en-US/Preface.xml
new file mode 100644
index 000000000..597dc5da0
--- /dev/null
+++ b/doc/release-notes/en-US/Preface.xml
@@ -0,0 +1,24 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. -->
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<preface id="pref-Release_Notes-Preface">
+ <title>Preface</title>
+ <para>This guide describes how to configure, operate, and manage Gluster File System (GlusterFS).</para>
+ <section>
+ <title>Audience</title>
+ <para>This guide is intended for Systems Administrators interested in configuring and managing GlusterFS.</para>
+ <para>This guide assumes that you are familiar with the Linux operating system, concepts of File System, GlusterFS concepts, and GlusterFS Installation</para>
+ </section>
+ <section>
+ <title>License</title>
+ <para>The License information is available at <ulink url="http://www.redhat.com/licenses/rhel_rha_eula.html"/>.</para>
+ </section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Common_Content/Conventions.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Feedback.xml">
+ <xi:fallback xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Common_Content/Feedback.xml"/>
+ </xi:fallback>
+ </xi:include>
+</preface>
diff --git a/doc/release-notes/en-US/Product_Documentation.xml b/doc/release-notes/en-US/Product_Documentation.xml
new file mode 100644
index 000000000..77329ab01
--- /dev/null
+++ b/doc/release-notes/en-US/Product_Documentation.xml
@@ -0,0 +1,12 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Release_Notes-Product_Documentation">
+ <title>Product Documentation</title>
+ <para>Product documentation of GlusterFS
+
+ is available at <ulink url="http://www.gluster.org/community/documentation/index.php/Main_Page"/> .
+</para>
+</chapter>
diff --git a/doc/release-notes/en-US/Product_Support.xml b/doc/release-notes/en-US/Product_Support.xml
new file mode 100644
index 000000000..ab44e5182
--- /dev/null
+++ b/doc/release-notes/en-US/Product_Support.xml
@@ -0,0 +1,12 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-Release_Notes-Product_Support">
+ <title>Product Support</title>
+ <para>
+
+ You can reach support at <ulink url="http://www.redhat.com/support"/>.
+</para>
+</chapter>
diff --git a/doc/release-notes/en-US/Release_Notes.ent b/doc/release-notes/en-US/Release_Notes.ent
new file mode 100644
index 000000000..9275f166d
--- /dev/null
+++ b/doc/release-notes/en-US/Release_Notes.ent
@@ -0,0 +1,4 @@
+<!ENTITY PRODUCT "Documentation">
+<!ENTITY BOOKID "Release_Notes">
+<!ENTITY YEAR "2012">
+<!ENTITY HOLDER "Red Hat Inc">
diff --git a/doc/release-notes/en-US/Release_Notes.xml b/doc/release-notes/en-US/Release_Notes.xml
new file mode 100644
index 000000000..d23fb4d7f
--- /dev/null
+++ b/doc/release-notes/en-US/Release_Notes.xml
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<book>
+ <xi:include href="Book_Info.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="gfs_introduction.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Whats_New.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Download_Install.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Known_Issues.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Product_Support.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Product_Documentation.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Revision_History.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+</book>
+
diff --git a/doc/release-notes/en-US/Revision_History.xml b/doc/release-notes/en-US/Revision_History.xml
new file mode 100644
index 000000000..f473d0a29
--- /dev/null
+++ b/doc/release-notes/en-US/Revision_History.xml
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. -->
+<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<appendix id="appe-Release_Notes-Revision_History">
+ <title>Revision History</title>
+ <simpara>
+ <revhistory>
+ <revision>
+ <revnumber> 1-0</revnumber>
+ <date>Mon Apr 9 2012</date>
+ <author>
+ <firstname>Divya </firstname>
+ <surname>Muntimadugu</surname>
+ <email>divya@redhat.com</email>
+ </author>
+ <revdescription>
+ <simplelist>
+ <member>Draft</member>
+ </simplelist>
+ </revdescription>
+ </revision>
+ </revhistory>
+ </simpara>
+</appendix>
diff --git a/doc/release-notes/en-US/Whats_New.xml b/doc/release-notes/en-US/Whats_New.xml
new file mode 100644
index 000000000..c320c1aa3
--- /dev/null
+++ b/doc/release-notes/en-US/Whats_New.xml
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "Release_Notes.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="chap-2.0_Release_Notes-Whats_New">
+ <title>What is New in this Release?</title>
+ <para>This section describes the key features available in GlusterFS. The following is a list of feature highlights of this new version of the GlusterFS software: </para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Unified File and Object Storage</emphasis></para>
+ <para>Unified File and Object Storage (UFO) unifies NAS and object storage technology. It provides a system for data storage that enables users to access the same data, both as an object and as a file, thus simplifying management and controlling storage costs.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Replicate Improvements (Pro-active Self-heal)</emphasis></para>
+ <para>In replicate module, previously you had to manually trigger a self-heal when a brick goes offline and comes back online, to bring all the replicas in sync. Now the pro-active self-heal daemon runs in the background, diagnoses issues and automatically initiates self-healing when the brick comes on-line. You can view the list of files that need healing, the list of files which are recently healed, list of files which are in split-brain state, and you can manually trigger self-heal on the entire volume or only on the files which need healing. </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Network Lock Manager</emphasis>
+</para>
+ <para>GlusterFS 3.3 includes network lock manager (NLM) v4. NLM is a standard and an extension to NFSv3 which allows NFSv3 clients to lock on files across the network. NLM is required to make applications running on top of NFSv3 mount points to use the standard fcntl() (POSIX) and flock() (BSD) lock system calls to synchronize access across clients.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Volume Statedump</emphasis>
+</para>
+ <para>Statedump is a mechanism through which you can get details of all internal variables and state of the glusterfs process at the time of issuing the command.You can perform statedumps of the brick processes and nfs server process of a volume using the statedump command. The statedump information is useful while debugging.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Volume Status and Brick Information</emphasis>
+</para>
+ <para>You can display the status information about a specific volume, brick or all volumes, as needed. Volume status information includes memory usage, memory pool details of the bricks, inode tables of the volume, pending calls of the volume and other statistics. This information can be used to understand the current status of the brick, nfs processes, and overall file
+system. Status information can also be used to monitor and debug the volume information. </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Geo-replication Enhancements </emphasis></para>
+ <para>Now you can configure a secure slave using SSH so that master is granted a restricted access. You need not specify configuration parameters regarding the slave on the master-side configuration. You can also rotate the log file of a particular master-slave session, all sessions of a mater volume, and all geo-replication sessions, as needed. You can also set ignore-deletes option to 1 so that the file deleted on master will not trigger a delete operation on the slave. Hence, the slave will remain as a superset of the master and can be used to recover the master in case of crash and/or accidental delete.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Mount Server Fail-over </emphasis></para>
+ <para>Now there is an option to add backup volfile server while mounting fuse client. When the first volfile server fails, then the server specified in backupvolfile-server option is used as volfile server to mount the client. You can also specify the number of attempts to fetch while mounting glusterFS server. This option is useful when you mount a server with multiple IPs.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Debugging Locks</emphasis></para>
+ <para>You can use statedump command to list the locks held on files. The statedump output also provides information on each lock with its range, basename, PID of the application holding the lock, and so on. You can analyze and know which locks are valid and relevant at a point of time. After ensuring that the no application is using the file, you can clear the lock using the clear lock command.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Change in Working Directory </emphasis></para>
+ <para>The working directory of glusterd is changed to <emphasis role="italic">/var/lib/glusterd </emphasis>from <emphasis role="italic">/etc/glusterd</emphasis>.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Hadoop Compatible Storage </emphasis></para>
+ <para>GlusterFS provides compatibility for Apache Hadoop and it uses the standard file system APIs available in Hadoop to provide a new storage option for Hadoop deployments. Existing MapReduce based applications can use GlusterFS seamlessly. This new functionality opens up data within Hadoop deployments to any file-based or object-based application.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Granual Locking for Large Files </emphasis></para>
+ <para>Enables using GlusterFS as a backing store for preserving large files like virtual machine images. Granualar locking enables internal file operations (like self-heal) without blocking user level file operations. The latency for user I/O is reduced during self-heal operation.
+</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Configuration Enhancements</emphasis></para>
+ <para><itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Remove Brick Enhancements</emphasis></para>
+ <para>Previously, remove-bick command was used to remove a brick that is inaccessible due to hardware or network failure. And as a clean-up operation to remove dead server details from the volume configuration. Now remove-brick command can migrate data to existing bricks before deleting given brick.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Rebalance Enhancements </emphasis></para>
+ <para>GlusterFS 3.3 supports open file rebalance and files that have hardlinks. Rebalance has been enchanced to be more efficient with respect to network usage, completion time, and amount of data movement and starts migration of data immediately without waiting for directory layout to be fixed.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Dynamic Alteration of Volume Type </emphasis></para>
+ <para>You can now the change type of the volume from Distributed volume to Distributed Replicated Volume when performing add-brick and remove-brick operation. You must specify the replica count paramenter to increase the number of replicas to change it to distributed replicated volume.<note>
+ <para>Currently, changing of <emphasis role="italic">stripe</emphasis> count while changing volume configurations is not supported.</para>
+ </note></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Read-only Volume </emphasis></para>
+ <para>GlusterFS 3.3 enables you to mount volumes as read-only. While mounting the client, you can mount it as read-only for the volumes and you can also make the entire volume as read-only for all the clients (including NFS clients) using volume set option.
+</para>
+ </listitem>
+ </itemizedlist>
+</chapter>
diff --git a/doc/release-notes/en-US/gfs_introduction.xml b/doc/release-notes/en-US/gfs_introduction.xml
new file mode 100644
index 000000000..5fd887305
--- /dev/null
+++ b/doc/release-notes/en-US/gfs_introduction.xml
@@ -0,0 +1,54 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This document was created with Syntext Serna Free. --><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookV4.5/docbookx.dtd" []>
+<chapter>
+ <title>Introducing Gluster File System</title>
+ <para>GlusterFS is an open source, clustered file system capable of scaling to several petabytes and handling thousands of clients. GlusterFS can be flexibly combined with commodity physical, virtual, and cloud resources to deliver highly available and performant enterprise storage at a fraction of the cost of traditional solutions.</para>
+ <para>GlusterFS clusters together storage building blocks over Infiniband RDMA and/or TCP/IP interconnect, aggregating disk and memory resources and managing data in a single global namespace. GlusterFS is based on a stackable user space design, delivering exceptional performance for diverse workloads.
+</para>
+ <figure>
+ <title>Virtualized Cloud Environments</title>
+ <mediaobject>
+ <textobject>
+ <phrase>Virtualized Cloud Environments</phrase>
+ </textobject>
+ <imageobject>
+ <imagedata align="center" fileref="images/640px-GlusterFS_3.2_Architecture.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para>GlusterFS is designed for today&apos;s high-performance, virtualized cloud environments. Unlike traditional data centers, cloud environments require multi-tenancy along with the ability to grow or shrink resources on demand. Enterprises can scale capacity, performance, and availability on demand, with no vendor lock-in, across on-premise, public cloud, and hybrid environments. </para>
+ <para>GlusterFS is in production at thousands of enterprises spanning media, healthcare, government, education, web 2.0, and financial services. The following table lists the commercial offerings and its documentation location:
+</para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="16%"/>
+ <colspec colname="c2" colwidth="84%"/>
+ <thead>
+ <row>
+ <entry>Product</entry>
+ <entry>Documentation Location</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Red Hat Storage Software Appliance</entry>
+ <entry>
+ <ulink url="http://docs.redhat.com/docs/en-US/Red_Hat_Storage_Software_Appliance/index.html"/>
+ </entry>
+ </row>
+ <row>
+ <entry>Red Hat Virtual Storage Appliance</entry>
+ <entry>
+ <ulink url="http://docs.redhat.com/docs/en-US/Red_Hat_Virtual_Storage_Appliance/index.html"/>
+ </entry>
+ </row>
+ <row>
+ <entry>Red Hat Storage </entry>
+ <entry>
+ <ulink url="http://docs.redhat.com/docs/en-US/Red_Hat_Storage/index.html"/>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+</chapter>
diff --git a/doc/release-notes/en-US/images/640px-GlusterFS_3.2_Architecture.png b/doc/release-notes/en-US/images/640px-GlusterFS_3.2_Architecture.png
new file mode 100644
index 000000000..95f89ec82
--- /dev/null
+++ b/doc/release-notes/en-US/images/640px-GlusterFS_3.2_Architecture.png
Binary files differ
diff --git a/doc/release-notes/en-US/images/icon.svg b/doc/release-notes/en-US/images/icon.svg
new file mode 100644
index 000000000..b2f16d0f6
--- /dev/null
+++ b/doc/release-notes/en-US/images/icon.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="32" height="32" id="svg3017">
+ <defs id="defs3019">
+ <linearGradient id="linearGradient2381">
+ <stop id="stop2383" style="stop-color:#ffffff;stop-opacity:1" offset="0"/>
+ <stop id="stop2385" style="stop-color:#ffffff;stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <linearGradient x1="296.4996" y1="188.81061" x2="317.32471" y2="209.69398" id="linearGradient2371" xlink:href="#linearGradient2381" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.90776,0,0,0.90776,24.35648,49.24131)"/>
+ </defs>
+ <g transform="matrix(0.437808,-0.437808,0.437808,0.437808,-220.8237,43.55311)" id="g5089">
+ <path d="m 8.4382985,-6.28125 c -0.6073916,0 -4.3132985,5.94886271 -4.3132985,8.25 l 0,26.71875 c 0,0.846384 0.5818159,1.125 1.15625,1.125 l 25.5625,0 c 0.632342,0 1.125001,-0.492658 1.125,-1.125 l 0,-5.21875 0.28125,0 c 0.49684,0 0.906249,-0.409411 0.90625,-0.90625 l 0,-27.9375 c 0,-0.4968398 -0.40941,-0.90625 -0.90625,-0.90625 l -23.8117015,0 z" transform="translate(282.8327,227.1903)" id="path5091" style="fill:#5c5c4f;stroke:#000000;stroke-width:3.23021388;stroke-miterlimit:4;stroke-dasharray:none"/>
+ <rect width="27.85074" height="29.369793" rx="1.1414107" ry="1.1414107" x="286.96509" y="227.63805" id="rect5093" style="fill:#032c87"/>
+ <path d="m 288.43262,225.43675 25.2418,0 0,29.3698 -26.37615,0.0241 1.13435,-29.39394 z" id="rect5095" style="fill:#ffffff"/>
+ <path d="m 302.44536,251.73726 c 1.38691,7.85917 -0.69311,11.28365 -0.69311,11.28365 2.24384,-1.60762 3.96426,-3.47694 4.90522,-5.736 0.96708,2.19264 1.83294,4.42866 4.27443,5.98941 0,0 -1.59504,-7.2004 -1.71143,-11.53706 l -6.77511,0 z" id="path5097" style="fill:#a70000;fill-opacity:1;stroke-width:2"/>
+ <rect width="25.241802" height="29.736675" rx="0.89682275" ry="0.89682275" x="290.73544" y="220.92249" id="rect5099" style="fill:#809cc9"/>
+ <path d="m 576.47347,725.93939 6.37084,0.41502 0.4069,29.51809 c -1.89202,-1.31785 -6.85427,-3.7608 -8.26232,-1.68101 l 0,-26.76752 c 0,-0.82246 0.66212,-1.48458 1.48458,-1.48458 z" transform="matrix(0.499065,-0.866565,0,1,0,0)" id="rect5101" style="fill:#4573b3;fill-opacity:1"/>
+ <path d="m 293.2599,221.89363 20.73918,0 c 0.45101,0 0.8141,0.3631 0.8141,0.81411 0.21547,6.32836 -19.36824,21.7635 -22.36739,17.59717 l 0,-17.59717 c 0,-0.45101 0.3631,-0.81411 0.81411,-0.81411 z" id="path5103" style="opacity:0.65536726;fill:url(#linearGradient2371);fill-opacity:1"/>
+ </g>
+</svg>
diff --git a/doc/release-notes/publican.cfg b/doc/release-notes/publican.cfg
new file mode 100644
index 000000000..8afb0d03b
--- /dev/null
+++ b/doc/release-notes/publican.cfg
@@ -0,0 +1,12 @@
+# Config::Simple 4.59
+# Thu Apr 5 16:25:43 2012
+
+xml_lang: "en-US"
+type: Book
+brand: Gluster_Brand
+prod_url: http://www.gluster.org
+doc_url: http://www.gluster.com/community/documentation/index.php/Main_Page
+condition: gfs
+show_remarks: 1
+
+
diff --git a/doc/user-guide/Makefile.am b/doc/user-guide/legacy/Makefile.am
index 800e7321d..b2caabaa2 100644
--- a/doc/user-guide/Makefile.am
+++ b/doc/user-guide/legacy/Makefile.am
@@ -1,3 +1,3 @@
info_TEXINFOS = user-guide.texi
-CLEANFILES = *~
+CLEANFILES = *~
DISTCLEANFILES = .deps/*.P *.info *vti
diff --git a/doc/user-guide/advanced-stripe.odg b/doc/user-guide/legacy/advanced-stripe.odg
index 7686d7091..7686d7091 100644
--- a/doc/user-guide/advanced-stripe.odg
+++ b/doc/user-guide/legacy/advanced-stripe.odg
Binary files differ
diff --git a/doc/user-guide/advanced-stripe.pdf b/doc/user-guide/legacy/advanced-stripe.pdf
index ec8b03dcf..ec8b03dcf 100644
--- a/doc/user-guide/advanced-stripe.pdf
+++ b/doc/user-guide/legacy/advanced-stripe.pdf
Binary files differ
diff --git a/doc/user-guide/colonO-icon.jpg b/doc/user-guide/legacy/colonO-icon.jpg
index 3e66f7a27..3e66f7a27 100644
--- a/doc/user-guide/colonO-icon.jpg
+++ b/doc/user-guide/legacy/colonO-icon.jpg
Binary files differ
diff --git a/doc/user-guide/fdl.texi b/doc/user-guide/legacy/fdl.texi
index 92cfa81a7..e33c687cd 100644
--- a/doc/user-guide/fdl.texi
+++ b/doc/user-guide/legacy/fdl.texi
@@ -27,7 +27,7 @@ for modifications made by others.
This License is a kind of ``copyleft'', which means that derivative
works of the document must themselves be free in the same sense. It
-complements the GNU Affero General Public License, which is a copyleft
+complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for free
@@ -445,7 +445,7 @@ situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU Affero General Public License,
+free software license, such as the GNU General Public License,
to permit their use in free software.
@c Local Variables:
diff --git a/doc/user-guide/fuse.odg b/doc/user-guide/legacy/fuse.odg
index 61bd103c7..61bd103c7 100644
--- a/doc/user-guide/fuse.odg
+++ b/doc/user-guide/legacy/fuse.odg
Binary files differ
diff --git a/doc/user-guide/fuse.pdf b/doc/user-guide/legacy/fuse.pdf
index a7d13faff..a7d13faff 100644
--- a/doc/user-guide/fuse.pdf
+++ b/doc/user-guide/legacy/fuse.pdf
Binary files differ
diff --git a/doc/user-guide/ha.odg b/doc/user-guide/legacy/ha.odg
index e4b8b72d0..e4b8b72d0 100644
--- a/doc/user-guide/ha.odg
+++ b/doc/user-guide/legacy/ha.odg
Binary files differ
diff --git a/doc/user-guide/ha.pdf b/doc/user-guide/legacy/ha.pdf
index e372c0ab0..e372c0ab0 100644
--- a/doc/user-guide/ha.pdf
+++ b/doc/user-guide/legacy/ha.pdf
Binary files differ
diff --git a/doc/user-guide/stripe.odg b/doc/user-guide/legacy/stripe.odg
index 79441bf14..79441bf14 100644
--- a/doc/user-guide/stripe.odg
+++ b/doc/user-guide/legacy/stripe.odg
Binary files differ
diff --git a/doc/user-guide/stripe.pdf b/doc/user-guide/legacy/stripe.pdf
index b94446feb..b94446feb 100644
--- a/doc/user-guide/stripe.pdf
+++ b/doc/user-guide/legacy/stripe.pdf
Binary files differ
diff --git a/doc/user-guide/unify.odg b/doc/user-guide/legacy/unify.odg
index ccaa9bf16..ccaa9bf16 100644
--- a/doc/user-guide/unify.odg
+++ b/doc/user-guide/legacy/unify.odg
Binary files differ
diff --git a/doc/user-guide/unify.pdf b/doc/user-guide/legacy/unify.pdf
index c22027f66..c22027f66 100644
--- a/doc/user-guide/unify.pdf
+++ b/doc/user-guide/legacy/unify.pdf
Binary files differ
diff --git a/doc/user-guide/user-guide.info b/doc/user-guide/legacy/user-guide.info
index 494c0e94e..6a49d078d 100644
--- a/doc/user-guide/user-guide.info
+++ b/doc/user-guide/legacy/user-guide.info
@@ -6,7 +6,7 @@ END-INFO-DIR-ENTRY
This is the user manual for GlusterFS 2.0.
- Copyright (C) 2007-2010 Gluster, Inc. Permission is granted to
+ Copyright (c) 2007-2011 Gluster, Inc. Permission is granted to
copy, distribute and/or modify this document under the terms of the GNU
Free Documentation License, Version 1.2 or any later version published
by the Free Software Foundation; with no Invariant Sections, no
@@ -21,7 +21,7 @@ GlusterFS 2.0 User Guide
This is the user manual for GlusterFS 2.0.
- Copyright (C) 2007-2010 Gluster, Inc. Permission is granted to
+ Copyright (c) 2007-2011 Gluster, Inc. Permission is granted to
copy, distribute and/or modify this document under the terms of the GNU
Free Documentation License, Version 1.2 or any later version published
by the Free Software Foundation; with no Invariant Sections, no
@@ -130,7 +130,7 @@ suggestions. A huge thanks to them all.
Patrick Negri - for TCP non-blocking connect.
http://gluster.org/core-team.php (<list-hacking@gluster.com>)
- Gluster
+ Gluster

File: user-guide.info, Node: Introduction, Next: Installation and Invocation, Prev: Acknowledgements, Up: Top
@@ -160,15 +160,15 @@ makes them all appear to be a part of the same filesystem.
=================
You can reach us through the mailing list *gluster-devel*
-(<gluster-devel@nongnu.org>).
+(<gluster-devel@nongnu.org>).
You can also find many of the developers on IRC, on the `#gluster'
-channel on Freenode (<irc.freenode.net>).
+channel on Freenode (<irc.freenode.net>).
The GlusterFS documentation wiki is also useful:
<http://gluster.org/docs/index.php/GlusterFS>
- For commercial support, you can contact Gluster at:
+ For commercial support, you can contact Gluster at:
3194 Winding Vista Common
Fremont, CA 94539
@@ -907,7 +907,7 @@ and the client.
Whether to make the connection attempt asynchronous.
`remote-port <n> (24007)'
- Server port to connect to.
+ Server port to connect to.
`remote-host <hostname> *'
Hostname or IP address of the server. If the host name resolves to
@@ -952,7 +952,7 @@ always best to use `ib-verbs'. Use `ib-sdp' only if you cannot get
Whether to make the connection attempt asynchronous.
`remote-port <n> (24007)'
- Server port to connect to.
+ Server port to connect to.
`remote-host <hostname> *'
Hostname or IP address of the server. If the host name resolves to
@@ -2057,7 +2057,7 @@ the `--log-file' option (See *note Client::).
=======================
`modprobe fuse' fails with: "Unknown symbol in module, or unknown
-parameter".
+parameter".
If you are using fuse-2.6.x on Redhat Enterprise Linux Work Station 4
and Advanced Server 4 with 2.6.9-42.ELlargesmp, 2.6.9-42.ELsmp,
@@ -2188,7 +2188,7 @@ Appendix A GNU Free Documentation Licence
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense.
- It complements the GNU Affero General Public License, which is a copyleft
+ It complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for
@@ -2591,7 +2591,7 @@ situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU Affero General Public License, to
+free software license, such as the GNU General Public License, to
permit their use in free software.

diff --git a/doc/user-guide/user-guide.pdf b/doc/user-guide/legacy/user-guide.pdf
index ed7bd2a99..ed7bd2a99 100644
--- a/doc/user-guide/user-guide.pdf
+++ b/doc/user-guide/legacy/user-guide.pdf
Binary files differ
diff --git a/doc/user-guide/user-guide.texi b/doc/user-guide/legacy/user-guide.texi
index b679dee02..2d51da022 100644
--- a/doc/user-guide/user-guide.texi
+++ b/doc/user-guide/legacy/user-guide.texi
@@ -10,7 +10,7 @@
@copying
This is the user manual for GlusterFS 2.0.
-Copyright @copyright{} 2007-2010 @email{@b{Gluster}} , Inc. Permission is granted to
+Copyright @copyright{} 2007-2011 @email{@b{Gluster}} , Inc. Permission is granted to
copy, distribute and/or modify this document under the terms of the
@acronym{GNU} Free Documentation License, Version 1.2 or any later
version published by the Free Software Foundation; with no Invariant
@@ -23,7 +23,7 @@ Documentation License''.
@title GlusterFS 2.0 User Guide [DRAFT]
@subtitle January 15, 2008
@author http://gluster.org/core-team.php
-@author @email{@b{Gluster}}
+@author @email{@b{Gluster}}
@page
@vskip 0pt plus 1filll
@insertcopying
@@ -36,78 +36,78 @@ Documentation License''.
@insertcopying
@menu
-* Acknowledgements::
-* Introduction::
-* Installation and Invocation::
-* Concepts::
-* Translators::
-* Usage Scenarios::
-* Troubleshooting::
-* GNU Free Documentation Licence::
-* Index::
+* Acknowledgements::
+* Introduction::
+* Installation and Invocation::
+* Concepts::
+* Translators::
+* Usage Scenarios::
+* Troubleshooting::
+* GNU Free Documentation Licence::
+* Index::
@detailmenu
--- The Detailed Node Listing ---
Installation and Invocation
-* Pre requisites::
-* Getting GlusterFS::
-* Building::
-* Running GlusterFS::
-* A Tutorial Introduction::
+* Pre requisites::
+* Getting GlusterFS::
+* Building::
+* Running GlusterFS::
+* A Tutorial Introduction::
Running GlusterFS
-* Server::
-* Client::
+* Server::
+* Client::
Concepts
-* Filesystems in Userspace::
-* Translator::
-* Volume specification file::
+* Filesystems in Userspace::
+* Translator::
+* Volume specification file::
Translators
-* Storage Translators::
-* Client and Server Translators::
-* Clustering Translators::
-* Performance Translators::
-* Features Translators::
+* Storage Translators::
+* Client and Server Translators::
+* Clustering Translators::
+* Performance Translators::
+* Features Translators::
Storage Translators
-* POSIX::
+* POSIX::
Client and Server Translators
-* Transport modules::
-* Client protocol::
-* Server protocol::
+* Transport modules::
+* Client protocol::
+* Server protocol::
Clustering Translators
-* Unify::
-* Replicate::
-* Stripe::
+* Unify::
+* Replicate::
+* Stripe::
Performance Translators
-* Read Ahead::
-* Write Behind::
-* IO Threads::
-* IO Cache::
+* Read Ahead::
+* Write Behind::
+* IO Threads::
+* IO Cache::
-Features Translators
+Features Translators
-* POSIX Locks::
-* Fixed ID::
+* POSIX Locks::
+* Fixed ID::
Miscellaneous Translators
-* ROT-13::
-* Trace::
+* ROT-13::
+* Trace::
@end detailmenu
@end menu
@@ -120,7 +120,7 @@ Miscellaneous Translators
@node Acknowledgements
@unnumbered Acknowledgements
GlusterFS continues to be a wonderful and enriching experience for all
-of us involved.
+of us involved.
GlusterFS development would not have been possible at this pace if
not for our enthusiastic users. People from around the world have
@@ -142,7 +142,7 @@ Jacques Mattheij - for Europe mirror.
Patrick Negri - for TCP non-blocking connect.
@flushright
http://gluster.org/core-team.php (@email{list-hacking@@gluster.com})
-@email{@b{Gluster}}
+@email{@b{Gluster}}
@end flushright
@node Introduction
@@ -166,7 +166,7 @@ Need for distributed filesystems
@end itemize
@section Contacting us
-You can reach us through the mailing list @strong{gluster-devel}
+You can reach us through the mailing list @strong{gluster-devel}
(@email{gluster-devel@@nongnu.org}).
@cindex GlusterFS mailing list
@@ -197,11 +197,11 @@ You can also email us at @email{support@@gluster.com}.
@chapter Installation and Invocation
@menu
-* Pre requisites::
-* Getting GlusterFS::
-* Building::
-* Running GlusterFS::
-* A Tutorial Introduction::
+* Pre requisites::
+* Getting GlusterFS::
+* Building::
+* Running GlusterFS::
+* A Tutorial Introduction::
@end menu
@node Pre requisites
@@ -247,7 +247,7 @@ our patched version of the @acronym{FUSE} kernel module. See Patched FUSE for de
@subsection Patched FUSE
-The GlusterFS project maintains a patched version of @acronym{FUSE} meant to be used
+The GlusterFS project maintains a patched version of @acronym{FUSE} meant to be used
with GlusterFS. The patches increase GlusterFS performance. It is recommended that
all users use the patched @acronym{FUSE}.
@@ -311,7 +311,7 @@ $ cd glusterfs-<version>
If you checked out the source from the Arch repository, you'll need
to run @command{./autogen.sh} first. Note that you'll need to have
-Autoconf and Automake installed for this.
+Autoconf and Automake installed for this.
Run @command{configure}.
@@ -371,8 +371,8 @@ paths with the prefix.
@section Running GlusterFS
@menu
-* Server::
-* Client::
+* Server::
+* Client::
@end menu
@node Server
@@ -386,7 +386,7 @@ of the GlusterFS server program and all the command-line options accepted by it.
@cartouche
@table @code
Basic Options
-@item -f, --volfile=<path>
+@item -f, --volfile=<path>
Use the volume file as the volume specification.
@item -s, --volfile-server=<hostname>
@@ -396,7 +396,7 @@ Basic Options
Specify the path for the log file.
@item -L, --log-level=<level>
- Set the log level for the server. Log level should be one of @acronym{DEBUG},
+ Set the log level for the server. Log level should be one of @acronym{DEBUG},
@acronym{WARNING}, @acronym{ERROR}, @acronym{CRITICAL}, or @acronym{NONE}.
Advanced Options
@@ -404,10 +404,10 @@ Advanced Options
Run in debug mode. This option sets --no-daemon, --log-level to DEBUG and
--log-file to console.
-@item -N, --no-daemon
+@item -N, --no-daemon
Run glusterfsd as a foreground process.
-@item -p, --pid-file=<path>
+@item -p, --pid-file=<path>
Path for the @acronym{PID} file.
@item --volfile-id=<key>
@@ -423,13 +423,13 @@ Advanced Options
Add/override a translator option for a volume with specified value.
Miscellaneous Options
-@item -?, --help
+@item -?, --help
Show this help text.
-@item --usage
+@item --usage
Display a short usage message.
-@item -V, --version
+@item -V, --version
Show version information.
@end table
@end cartouche
@@ -464,7 +464,7 @@ The command-line options are detailed below.
@table @code
Basic Options
-@item -f, --volfile=<path>
+@item -f, --volfile=<path>
Use the volume file as the volume specification.
@item -s, --volfile-server=<hostname>
@@ -474,7 +474,7 @@ Basic Options
Specify the path for the log file.
@item -L, --log-level=<level>
- Set the log level for the server. Log level should be one of @acronym{DEBUG},
+ Set the log level for the server. Log level should be one of @acronym{DEBUG},
@acronym{WARNING}, @acronym{ERROR}, @acronym{CRITICAL}, or @acronym{NONE}.
Advanced Options
@@ -482,10 +482,10 @@ Advanced Options
Run in debug mode. This option sets --no-daemon, --log-level to DEBUG and
--log-file to console.
-@item -N, --no-daemon
+@item -N, --no-daemon
Run @command{glusterfs} as a foreground process.
-@item -p, --pid-file=<path>
+@item -p, --pid-file=<path>
Path for the @acronym{PID} file.
@item --volfile-id=<key>
@@ -512,14 +512,14 @@ Advanced Options
automatically if kernel supports big writes (>= 2.6.26).
@item -e, --entry-timeout=<n>
- Entry timeout for directory entries in the kernel, in seconds.
+ Entry timeout for directory entries in the kernel, in seconds.
Defaults to 1 second.
Missellaneous Options
-@item -?, --help
+@item -?, --help
Show this help information.
-@item -V, --version
+@item -V, --version
Show version information.
@end table
@end cartouche
@@ -527,7 +527,7 @@ Missellaneous Options
@node A Tutorial Introduction
@section A Tutorial Introduction
-This section will show you how to quickly get GlusterFS up and running. We'll
+This section will show you how to quickly get GlusterFS up and running. We'll
configure GlusterFS as a simple network filesystem, with one server and one client.
In this mode of usage, GlusterFS can serve as a replacement for NFS.
@@ -545,18 +545,18 @@ be run on the server will be shown with the prompt:
Our goal is to make a directory on the @emph{server} (say, @command{/export})
accessible to the @emph{client}.
-First of all, get GlusterFS installed on both the machines, as described in the
+First of all, get GlusterFS installed on both the machines, as described in the
previous sections. Make sure you have the @acronym{FUSE} kernel module loaded. You
-can ensure this by running:
+can ensure this by running:
@example
[root@@server]# modprobe fuse
@end example
Before we can run the GlusterFS client or server programs, we need to write
-two files called @emph{volume specifications} (equivalently refered to as @emph{volfiles}).
+two files called @emph{volume specifications} (equivalently refered to as @emph{volfiles}).
The volfile describes the @emph{translator tree} on a node. The next chapter will
-explain the concepts of `translator' and `volume specification' in detail. For now,
+explain the concepts of `translator' and `volume specification' in detail. For now,
just assume that the volfile is like an NFS @command{/etc/export} file.
On the server, create a text file somewhere (we'll assume the path
@@ -572,7 +572,7 @@ end-volume
volume server
type protocol/server
subvolumes colon-o
- option transport-type tcp
+ option transport-type tcp
option auth.addr.colon-o.allow *
end-volume
@end example
@@ -625,9 +625,9 @@ working as a network file system.
@chapter Concepts
@menu
-* Filesystems in Userspace::
-* Translator::
-* Volume specification file::
+* Filesystems in Userspace::
+* Translator::
+* Volume specification file::
@end menu
@node Filesystems in Userspace
@@ -639,16 +639,16 @@ is a kernel module/library that allows us to write a filesystem
completely in userspace.
@acronym{FUSE} consists of a kernel module which interacts with the userspace
-implementation using a device file @code{/dev/fuse}. When a process
+implementation using a device file @code{/dev/fuse}. When a process
makes a syscall on a @acronym{FUSE} filesystem, @acronym{VFS} hands the request to the
@acronym{FUSE} module, which writes the request to @code{/dev/fuse}. The
userspace implementation polls @code{/dev/fuse}, and when a request arrives,
processes it and writes the result back to @code{/dev/fuse}. The kernel then
-reads from the device file and returns the result to the user process.
+reads from the device file and returns the result to the user process.
In case of GlusterFS, the userspace program is the GlusterFS client.
The control flow is shown in the diagram below. The GlusterFS client
-services the request by sending it to the server, which in turn
+services the request by sending it to the server, which in turn
hands it to the local @acronym{POSIX} filesystem.
@center @image{fuse,44pc,,,.pdf}
@@ -752,7 +752,7 @@ or ``forty-two''.
line is considered the value; it is up to the translator to parse it.
@item @emph{subvolume1}, @emph{subvolume2}, @dots{}
- Volume names of sub-volumes. The sub-volumes must already have been defined earlier
+ Volume names of sub-volumes. The sub-volumes must already have been defined earlier
in the file.
@end table
@@ -797,11 +797,11 @@ end-volume
@chapter Translators
@menu
-* Storage Translators::
-* Client and Server Translators::
-* Clustering Translators::
-* Performance Translators::
-* Features Translators::
+* Storage Translators::
+* Client and Server Translators::
+* Clustering Translators::
+* Performance Translators::
+* Features Translators::
* Miscellaneous Translators::
@end menu
@@ -823,12 +823,12 @@ Other storage backends are planned for the future. One of the possibilities is a
Amazon S3 translator. Amazon S3 is an unlimited online storage service accessible
through a web services @acronym{API}. The S3 translator will allow you to access
the storage as a normal @acronym{POSIX} filesystem.
-@footnote{Some more discussion about this can be found at:
+@footnote{Some more discussion about this can be found at:
http://developer.amazonwebservices.com/connect/message.jspa?messageID=52873}
@menu
-* POSIX::
+* POSIX::
* BDB::
@end menu
@@ -843,14 +843,14 @@ filesystem as its ``backend'' to actually store files and
directories. This can be any filesystem that supports extended
attributes (@acronym{EXT3}, ReiserFS, @acronym{XFS}, ...). Extended
attributes are used by some translators to store metadata, for
-example, by the replicate and stripe translators. See
+example, by the replicate and stripe translators. See
@ref{Replicate} and @ref{Stripe}, respectively for details.
@cartouche
@table @code
@item directory <path>
The directory on the local filesystem which is to be used for storage.
-@end table
+@end table
@end cartouche
@node BDB
@@ -862,7 +862,7 @@ type storage/bdb
The @command{BDB} translator uses a @acronym{Berkeley DB} database as its
``backend'' to actually store files as key-value pair in the database and
directories as regular @acronym{POSIX} directories. Note that @acronym{BDB}
-does not provide extended attribute support for regular files. Do not use
+does not provide extended attribute support for regular files. Do not use
@acronym{BDB} as storage translator while using any translator that demands
extended attributes on ``backend''.
@@ -892,9 +892,9 @@ translator tree over the network or access a remote GlusterFS
server. These two translators implement GlusterFS's network protocol.
@menu
-* Transport modules::
-* Client protocol::
-* Server protocol::
+* Transport modules::
+* Client protocol::
+* Server protocol::
@end menu
@node Transport modules
@@ -962,7 +962,7 @@ This module accepts the same options as @command{tcp}
@cindex infiniband transport
-InfiniBand is a scalable switched fabric interconnect mechanism
+InfiniBand is a scalable switched fabric interconnect mechanism
primarily used in high-performance computing. InfiniBand can deliver
data throughput of the order of 10 Gbit/s, with latencies of 4-5 ms.
@@ -970,7 +970,7 @@ The @command{ib-verbs} transport accesses the InfiniBand hardware through
the ``verbs'' @acronym{API}, which is the lowest level of software access possible
and which gives the highest performance. On InfiniBand hardware, it is always
best to use @command{ib-verbs}. Use @command{ib-sdp} only if you cannot get
-@command{ib-verbs} working for some reason.
+@command{ib-verbs} working for some reason.
The @command{ib-verbs} client module accepts the following options:
@@ -1049,7 +1049,7 @@ translator tree.
@item transport-type [tcp,ib-sdp,ib-verbs] (tcp)
The transport type to use. You should use the client versions of all the
-transport modules (@command{tcp}, @command{ib-sdp},
+transport modules (@command{tcp}, @command{ib-sdp},
@command{ib-verbs}).
@item remote-subvolume <volume_name> *
The name of the volume on the remote host to attach to. Note that
@@ -1075,7 +1075,7 @@ remote GlusterFS clients.
@table @code
@item client-volume-filename <path> (<CONFDIR>/glusterfs-client.vol)
The volume specification file to use for the client. This is the file the
-client will receive when it is invoked with the @command{--server} option
+client will receive when it is invoked with the @command{--server} option
(@ref{Client}).
@item transport-type [tcp,ib-verbs,ib-sdp] (tcp)
@@ -1106,9 +1106,9 @@ translator allows a file to be spread across many server nodes. The following se
look at each of these translators in detail.
@menu
-* Unify::
-* Replicate::
-* Stripe::
+* Unify::
+* Replicate::
+* Stripe::
@end menu
@node Unify
@@ -1121,7 +1121,7 @@ type cluster/unify
The unify translator presents a `unified' view of all its sub-volumes. That is,
it makes the union of all its sub-volumes appear as a single volume. It is the
-unify translator that gives GlusterFS the ability to access an arbitrarily
+unify translator that gives GlusterFS the ability to access an arbitrarily
large amount of storage.
For unify to work correctly, certain invariants need to be maintained across
@@ -1144,7 +1144,7 @@ Looking at the second requirement, you might wonder how one can
accomplish storing redundant copies of a file, if no file can exist
multiple times. To answer, we must remember that these invariants are
from @emph{unify's perspective}. A translator such as replicate at a lower
-level in the translator tree than unify may subvert this picture.
+level in the translator tree than unify may subvert this picture.
The first invariant might seem quite tedious to ensure. We shall see
later that this is not so, since unify's @emph{self-heal} mechanism
@@ -1241,8 +1241,8 @@ are allowed. For example: @command{option alu.limits.min-free-disk 5GB}.
@item alu.read-usage.exit-threshold <%> (5)
@item alu.open-files-usage.entry-threshold <n> (1000)
@item alu.open-files-usage.exit-threshold <n> (100)
-@item alu.limits.min-free-disk <%>
-@item alu.limits.max-open-files <n>
+@item alu.limits.min-free-disk <%>
+@item alu.limits.max-open-files <n>
@end table
@end cartouche
@@ -1259,7 +1259,7 @@ files are mostly similar in size and I/O access pattern, this
scheduler is a good choice. RR scheduler checks for free disk space
on the server before scheduling, so you can know when to add
another server node. The default value of min-free-disk is 5% and is
-checked on file creation calls, with atleast 10 seconds (by default)
+checked on file creation calls, with atleast 10 seconds (by default)
elapsing between two checks.
Options:
@@ -1315,7 +1315,7 @@ than a specified amount (5% by default) then @acronym{NUFA} schedules files
among the other child volumes in a round-robin fashion.
@acronym{NUFA} is named after the similar strategy used for memory access,
-@acronym{NUMA}@footnote{Non-Uniform Memory Access:
+@acronym{NUMA}@footnote{Non-Uniform Memory Access:
@indicateurl{http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access}}.
@cartouche
@@ -1325,7 +1325,7 @@ Minimum disk space that must be free (local or remote) for @acronym{NUFA} to sch
file to it.
@item nufa.refresh-interval <t> (10 seconds)
Time between two successive free disk space checks.
-@item nufa.local-volume-name <volume>
+@item nufa.local-volume-name <volume>
The name of the volume corresponding to the local system. This volume must be
one of the children of the unify volume. This option is mandatory.
@end table
@@ -1397,13 +1397,13 @@ end-volume
@end example
This sample configuration will replicate all directories and files on
-brick1, brick2 and brick3.
+brick1, brick2 and brick3.
All the read operations happen from the first alive child. If all the
three sub-volumes are up, reads will be done from brick1; if brick1 is
down read will be done from brick2. In case read() was being done on
brick1 and it goes down, replicate transparently falls back to
-brick2.
+brick2.
The next release of GlusterFS will add the following features:
@itemize
@@ -1496,7 +1496,7 @@ type cluster/stripe
The stripe translator distributes the contents of a file over its
sub-volumes. It does this by creating a file equal in size to the
total size of the file on each of its sub-volumes. It then writes only
-a part of the file to each sub-volume, leaving the rest of it empty.
+a part of the file to each sub-volume, leaving the rest of it empty.
These empty regions are called `holes' in Unix terminology. The holes
do not consume any disk space.
@@ -1504,14 +1504,14 @@ The diagram below makes this clear.
@center @image{stripe,44pc,,,.pdf}
-You can configure stripe so that only filenames matching a pattern
-are striped. You can also configure the size of the data to be stored
+You can configure stripe so that only filenames matching a pattern
+are striped. You can also configure the size of the data to be stored
on each sub-volume.
@cartouche
@table @code
@item block-size <pattern>:<size> (*:0 no striping)
-Distribute files matching @command{<pattern>} over the sub-volumes,
+Distribute files matching @command{<pattern>} over the sub-volumes,
storing at least @command{<size>} on each sub-volume. For example,
@example
@@ -1530,9 +1530,9 @@ different sizes for different file name patterns.
@section Performance Translators
@menu
-* Read Ahead::
-* Write Behind::
-* IO Threads::
+* Read Ahead::
+* Write Behind::
+* IO Threads::
* IO Cache::
* Booster::
@end menu
@@ -1547,9 +1547,9 @@ type performance/read-ahead
The read-ahead translator pre-fetches data in advance on every read.
This benefits applications that mostly process files in sequential order,
since the next block of data will already be available by the time the
-application is done with the current one.
+application is done with the current one.
-Additionally, the read-ahead translator also behaves as a read-aggregator.
+Additionally, the read-ahead translator also behaves as a read-aggregator.
Many small read operations are combined and issued as fewer, larger read
requests to the server.
@@ -1557,7 +1557,7 @@ Read-ahead deals in ``pages'' as the unit of data fetched. The page size
is configurable, as is the ``page count'', which is the number of pages
that are pre-fetched.
-Read-ahead is best used with InfiniBand (using the ib-verbs transport).
+Read-ahead is best used with InfiniBand (using the ib-verbs transport).
On FastEthernet and Gigabit Ethernet networks,
GlusterFS can achieve the link-maximum throughput even without
read-ahead, making it quite superflous.
@@ -1577,7 +1577,7 @@ The unit of data that is pre-fetched.
The number of pages that are pre-fetched.
@item force-atime-update [on|off|yes|no] (off|no)
Whether to force an access time (atime) update on the file on every read. Without
-this, the atime will be slightly imprecise, as it will reflect the time when
+this, the atime will be slightly imprecise, as it will reflect the time when
the read-ahead translator read the data, not when the application actually read it.
@end table
@end cartouche
@@ -1596,7 +1596,7 @@ write-behind translator, successive write requests can be pipelined.
This mode of write-behind operation is best used on the client side, to
enable decreased write latency for the application.
-The write-behind translator can also aggregate write requests. If the
+The write-behind translator can also aggregate write requests. If the
@command{aggregate-size} option is specified, then successive writes upto that
size are accumulated and written in a single operation. This mode of operation
is best used on the server side, as this will decrease the disk's head movement
@@ -1659,7 +1659,7 @@ It caches data upto @command{cache-size} bytes. The cache is maintained as
a prioritized least-recently-used (@acronym{LRU}) list, with priorities determined
by user-specified patterns to match filenames.
-When the IO cache translator detects a write operation, the
+When the IO cache translator detects a write operation, the
cache for that file is flushed.
The IO cache translator periodically verifies the consistency of
@@ -1715,11 +1715,11 @@ can start your application as:
The booster translator accepts no options.
@node Features Translators
-@section Features Translators
+@section Features Translators
@menu
-* POSIX Locks::
-* Fixed ID::
+* POSIX Locks::
+* Fixed ID::
@end menu
@node POSIX Locks
@@ -1783,8 +1783,8 @@ The @acronym{GID} to send to the server
@section Miscellaneous Translators
@menu
-* ROT-13::
-* Trace::
+* ROT-13::
+* Trace::
@end menu
@node ROT-13
@@ -1799,7 +1799,7 @@ contents using the @acronym{ROT-13} algorithm. @acronym{ROT-13} is a trivial
algorithm that rotates each alphabet by thirteen places. Thus, 'A' becomes 'N',
'B' becomes 'O', and 'Z' becomes 'M'.
-It goes without saying that you shouldn't use this translator if you need
+It goes without saying that you shouldn't use this translator if you need
@emph{real} encryption (a future release of GlusterFS will have real encryption
translators).
@@ -1816,7 +1816,7 @@ Whether to decrypt on read
@subsection Trace
@cindex trace (translator)
@example
-type debug/trace
+type debug/trace
@end example
The trace translator is intended for debugging purposes. When loaded, it
@@ -1827,23 +1827,23 @@ level of DEBUG (See @ref{Running GlusterFS}) for trace to work.
Sample trace output (lines have been wrapped for readability):
@cartouche
@example
-2007-10-30 00:08:58 D [trace.c:1579:trace_opendir] trace: callid: 68
-(*this=0x8059e40, loc=0x8091984 @{path=/iozone3_283, inode=0x8091f00@},
+2007-10-30 00:08:58 D [trace.c:1579:trace_opendir] trace: callid: 68
+(*this=0x8059e40, loc=0x8091984 @{path=/iozone3_283, inode=0x8091f00@},
fd=0x8091d50)
-2007-10-30 00:08:58 D [trace.c:630:trace_opendir_cbk] trace:
+2007-10-30 00:08:58 D [trace.c:630:trace_opendir_cbk] trace:
(*this=0x8059e40, op_ret=4, op_errno=1, fd=0x8091d50)
-2007-10-30 00:08:58 D [trace.c:1602:trace_readdir] trace: callid: 69
+2007-10-30 00:08:58 D [trace.c:1602:trace_readdir] trace: callid: 69
(*this=0x8059e40, size=4096, offset=0 fd=0x8091d50)
-2007-10-30 00:08:58 D [trace.c:215:trace_readdir_cbk] trace:
+2007-10-30 00:08:58 D [trace.c:215:trace_readdir_cbk] trace:
(*this=0x8059e40, op_ret=0, op_errno=0, count=4)
-2007-10-30 00:08:58 D [trace.c:1624:trace_closedir] trace: callid: 71
+2007-10-30 00:08:58 D [trace.c:1624:trace_closedir] trace: callid: 71
(*this=0x8059e40, *fd=0x8091d50)
-2007-10-30 00:08:58 D [trace.c:809:trace_closedir_cbk] trace:
+2007-10-30 00:08:58 D [trace.c:809:trace_closedir_cbk] trace:
(*this=0x8059e40, op_ret=0, op_errno=1)
@end example
@end cartouche
@@ -1871,7 +1871,7 @@ scheduling on a single storage volume. Alternatively users can choose
to have two separate volumes and hence two mount points, but the
applications may demand a single storage system to host both.
-This document explains how to mix file level scheduling with stripe.
+This document explains how to mix file level scheduling with stripe.
@subsection Configuration Brief
@@ -1904,17 +1904,17 @@ addresses / access control fields to match your environment.
type storage/posix
option directory /export/for-unify
end-volume
-
+
volume posix-stripe
type storage/posix
option directory /export/for-stripe
end-volume
-
+
volume posix-namespace
type storage/posix
option directory /export/for-namespace
end-volume
-
+
volume server
type protocol/server
option transport-type tcp
@@ -1963,7 +1963,7 @@ addresses / access control fields to match your environment.
option remote-host 192.168.1.4
option remote-subvolume posix-unify
end-volume
-
+
volume client-stripe-1
type protocol/client
option transport-type tcp
@@ -1991,13 +1991,13 @@ addresses / access control fields to match your environment.
option remote-host 192.168.1.4
option remote-subvolume posix-stripe
end-volume
-
+
volume unify
type cluster/unify
option scheduler rr
subvolumes cluster-unify-1 cluster-unify-2 cluster-unify-3 cluster-unify-4
end-volume
-
+
volume stripe
type cluster/stripe
option block-size *.img:2MB # All files ending with .img are striped with 2MB stripe block size.
@@ -2046,13 +2046,13 @@ concludes with the suggested procedure to report bugs in GlusterFS.
@subsection Server errors
@example
-glusterfsd: FATAL: could not open specfile:
+glusterfsd: FATAL: could not open specfile:
'/etc/glusterfs/glusterfsd.vol'
@end example
-The GlusterFS server expects the volume specification file to be
+The GlusterFS server expects the volume specification file to be
at @command{/etc/glusterfs/glusterfsd.vol}. The example
-specification file will be installed as
+specification file will be installed as
@command{/etc/glusterfs/glusterfsd.vol.sample}. You need to edit
it and rename it, or provide a different specification file using
the @command{--spec-file} command line option (See @ref{Server}).
@@ -2060,7 +2060,7 @@ the @command{--spec-file} command line option (See @ref{Server}).
@vskip 4ex
@example
-gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfsd.log"
+gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfsd.log"
(Permission denied)
@end example
@@ -2072,7 +2072,7 @@ file using the @command{--log-file} option (See @ref{Server}).
@subsection Client errors
@example
-fusermount: failed to access mountpoint /mnt:
+fusermount: failed to access mountpoint /mnt:
Transport endpoint is not connected
@end example
@@ -2114,7 +2114,7 @@ port instead.
@vskip 4ex
@example
-gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfs.log"
+gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfs.log"
(Permission denied)
@end example
diff --git a/doc/user-guide/xlator.odg b/doc/user-guide/legacy/xlator.odg
index 179a65f6e..179a65f6e 100644
--- a/doc/user-guide/xlator.odg
+++ b/doc/user-guide/legacy/xlator.odg
Binary files differ
diff --git a/doc/user-guide/xlator.pdf b/doc/user-guide/legacy/xlator.pdf
index a07e14d67..a07e14d67 100644
--- a/doc/user-guide/xlator.pdf
+++ b/doc/user-guide/legacy/xlator.pdf
Binary files differ
diff --git a/extras/Makefile.am b/extras/Makefile.am
index 048227a12..f96105fdb 100644
--- a/extras/Makefile.am
+++ b/extras/Makefile.am
@@ -3,7 +3,9 @@ docdir = $(datadir)/doc/glusterfs/
EditorModedir = $(docdir)/
EditorMode_DATA = glusterfs-mode.el glusterfs.vim
-SUBDIRS = init.d benchmarking
-
-EXTRA_DIST = specgen.scm MacOSX/Portfile glusterfs-mode.el glusterfs.vim migrate-unify-to-distribute.sh backend-xattr-sanitize.sh backend-cleanup.sh disk_usage_sync.sh quota-remove-xattr.sh quota-metadata-cleanup.sh
+SUBDIRS = init.d benchmarking hook-scripts
+EXTRA_DIST = specgen.scm MacOSX/Portfile glusterfs-mode.el glusterfs.vim \
+ migrate-unify-to-distribute.sh backend-xattr-sanitize.sh \
+ backend-cleanup.sh disk_usage_sync.sh quota-remove-xattr.sh \
+ quota-metadata-cleanup.sh glusterfs-logrotate clear_xattrs.sh
diff --git a/extras/Solaris/README.solaris b/extras/Solaris/README.solaris
index ddb70c22c..5a4e4336d 100644
--- a/extras/Solaris/README.solaris
+++ b/extras/Solaris/README.solaris
@@ -10,7 +10,7 @@ $ which glusterfs
$ glusterfs --version
glusterfs 2.0.0rc1 built on Jan 16 2009 03:36:59
Repository revision: glusterfs--mainline--3.0--patch-844
-Copyright (c) 2006, 2007, 2008 Gluster Inc. <http://www.gluster.com>
+Copyright (c) 2006-2011 Gluster Inc. <http://www.gluster.com>
GlusterFS comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GlusterFS under the terms of the GNU General Public License.
diff --git a/extras/Ubuntu/README.Ubuntu b/extras/Ubuntu/README.Ubuntu
new file mode 100644
index 000000000..0c5b7828d
--- /dev/null
+++ b/extras/Ubuntu/README.Ubuntu
@@ -0,0 +1,24 @@
+Bug 765014 - Mounting from localhost in fstab fails at boot on ubuntu
+(https://bugzilla.redhat.com/show_bug.cgi?id=765014)
+(https://bugs.launchpad.net/ubuntu/+source/glusterfs/+bug/876648)
+
+Ubuntu uses upstart instead of init to bootstrap the system and it has a unique
+way of handling fstab, using a program called mountall(8). As a result of using
+a debian initscript to start glusterd, glusterfs mounts in fstab are tried before
+the glusterd service is running. In the case where the client is also a server
+and the volume is mounted from localhost, the mount fails at boot time. To
+correct this we need to launch glusterd using upstart and block the glusterfs
+mounting event until glusterd is started.
+
+The glusterd.conf file contains the necessary configuration for upstart to
+manage the glusterd service. It should be placed in /etc/init/glusterd.conf
+on Ubuntu systems, and then the old initscript /etc/init.d/glusterd can be
+removed. An additional upstart job, mounting-glusterfs.conf, is also required
+to block mounting glusterfs volumes until the glusterd service is available.
+Both of these upstart jobs need to be placed in /etc/init to resolve the issue.
+
+Starting with Ubuntu 12.04, Precise Pangolin, these upstart jobs will be
+included with the glusterfs-server package in the Ubuntu repository.
+
+This affects all versions of glusterfs on the Ubuntu platform since at least
+10.04, Lucid Lynx.
diff --git a/extras/Ubuntu/glusterd.conf b/extras/Ubuntu/glusterd.conf
new file mode 100644
index 000000000..aa99502b0
--- /dev/null
+++ b/extras/Ubuntu/glusterd.conf
@@ -0,0 +1,10 @@
+author "Louis Zuckerman <me@louiszuckerman.com>"
+description "GlusterFS Management Daemon"
+
+start on runlevel [2345]
+stop on runlevel [016]
+
+expect fork
+
+exec /usr/sbin/glusterd -p /var/run/glusterd.pid
+
diff --git a/extras/Ubuntu/mounting-glusterfs.conf b/extras/Ubuntu/mounting-glusterfs.conf
new file mode 100644
index 000000000..3c59c0f63
--- /dev/null
+++ b/extras/Ubuntu/mounting-glusterfs.conf
@@ -0,0 +1,7 @@
+author "Louis Zuckerman <me@louiszuckerman.com>"
+description "Block the mounting event for glusterfs filesystems until glusterd is running"
+
+start on mounting TYPE=glusterfs
+task
+exec start wait-for-state WAIT_FOR=glusterd WAITER=mounting-glusterfs
+
diff --git a/extras/benchmarking/glfs-bm.c b/extras/benchmarking/glfs-bm.c
index 7a4eabcae..035d055df 100644
--- a/extras/benchmarking/glfs-bm.c
+++ b/extras/benchmarking/glfs-bm.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
diff --git a/extras/benchmarking/rdd.c b/extras/benchmarking/rdd.c
index dc7aafa76..b06333370 100644
--- a/extras/benchmarking/rdd.c
+++ b/extras/benchmarking/rdd.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2008 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -36,172 +36,278 @@
#define UNIX_PATH_MAX 108
#endif
+#define UNIT_KB 1024ULL
+#define UNIT_MB UNIT_KB*1024ULL
+#define UNIT_GB UNIT_MB*1024ULL
+#define UNIT_TB UNIT_GB*1024ULL
+#define UNIT_PB UNIT_TB*1024ULL
+
+#define UNIT_KB_STRING "KB"
+#define UNIT_MB_STRING "MB"
+#define UNIT_GB_STRING "GB"
+#define UNIT_TB_STRING "TB"
+#define UNIT_PB_STRING "PB"
+
struct rdd_file {
- char path[UNIX_PATH_MAX];
- struct stat st;
- int fd;
+ char path[UNIX_PATH_MAX];
+ struct stat st;
+ int fd;
};
-
+
struct rdd_config {
- long iters;
- long max_ops_per_seq;
- size_t max_bs;
- size_t min_bs;
- int thread_count;
- pthread_t *threads;
- pthread_barrier_t barrier;
- pthread_mutex_t lock;
- struct rdd_file in_file;
- struct rdd_file out_file;
+ long iters;
+ long max_ops_per_seq;
+ size_t max_bs;
+ size_t min_bs;
+ int thread_count;
+ pthread_t *threads;
+ pthread_barrier_t barrier;
+ pthread_mutex_t lock;
+ struct rdd_file in_file;
+ struct rdd_file out_file;
+ ssize_t file_size;
};
static struct rdd_config rdd_config;
enum rdd_keys {
- RDD_MIN_BS_KEY = 1,
- RDD_MAX_BS_KEY,
+ RDD_MIN_BS_KEY = 1,
+ RDD_MAX_BS_KEY,
};
-
+
static error_t
rdd_parse_opts (int key, char *arg,
- struct argp_state *_state)
+ struct argp_state *_state)
{
- switch (key) {
- case 'o':
- {
- int len = 0;
- len = strlen (arg);
- if (len > UNIX_PATH_MAX) {
- fprintf (stderr, "output file name too long (%s)\n",
+ switch (key) {
+ case 'o':
+ {
+ int len = 0;
+ len = strlen (arg);
+ if (len > UNIX_PATH_MAX) {
+ fprintf (stderr, "output file name too long (%s)\n",
arg);
- return -1;
- }
-
- strncpy (rdd_config.out_file.path, arg, len);
- }
- break;
-
- case 'i':
- {
- int len = 0;
- len = strlen (arg);
- if (len > UNIX_PATH_MAX) {
- fprintf (stderr, "input file name too long (%s)\n",
+ return -1;
+ }
+
+ strncpy (rdd_config.out_file.path, arg, len);
+ }
+ break;
+
+ case 'i':
+ {
+ int len = 0;
+ len = strlen (arg);
+ if (len > UNIX_PATH_MAX) {
+ fprintf (stderr, "input file name too long (%s)\n",
arg);
- return -1;
- }
-
- strncpy (rdd_config.in_file.path, arg, len);
- }
- break;
-
- case RDD_MIN_BS_KEY:
- {
- char *tmp = NULL;
- long bs = 0;
- bs = strtol (arg, &tmp, 10);
- if ((bs == LONG_MAX) || (bs == LONG_MIN) || (tmp && *tmp)) {
- fprintf (stderr, "invalid argument for minimum block"
+ return -1;
+ }
+
+ strncpy (rdd_config.in_file.path, arg, len);
+ rdd_config.in_file.path[len] = '\0';
+ }
+ break;
+
+ case 'f':
+ {
+ char *tmp = NULL;
+ unsigned long long fs = 0;
+ if (string2bytesize (arg, &fs) == -1) {
+ fprintf (stderr, "invalid argument for file size "
+ "(%s)\n", arg);
+ return -1;
+ }
+
+ rdd_config.file_size = fs;
+ }
+ break;
+
+ case RDD_MIN_BS_KEY:
+ {
+ char *tmp = NULL;
+ long bs = 0;
+ bs = strtol (arg, &tmp, 10);
+ if ((bs == LONG_MAX) || (bs == LONG_MIN) || (tmp && *tmp)) {
+ fprintf (stderr, "invalid argument for minimum block"
"size (%s)\n", arg);
- return -1;
- }
-
- rdd_config.min_bs = bs;
- }
- break;
-
- case RDD_MAX_BS_KEY:
- {
- char *tmp = NULL;
- long bs = 0;
- bs = strtol (arg, &tmp, 10);
- if ((bs == LONG_MAX) || (bs == LONG_MIN) || (tmp && *tmp)) {
- fprintf (stderr, "invalid argument for maximum block"
+ return -1;
+ }
+
+ rdd_config.min_bs = bs;
+ }
+ break;
+
+ case RDD_MAX_BS_KEY:
+ {
+ char *tmp = NULL;
+ long bs = 0;
+ bs = strtol (arg, &tmp, 10);
+ if ((bs == LONG_MAX) || (bs == LONG_MIN) || (tmp && *tmp)) {
+ fprintf (stderr, "invalid argument for maximum block"
"size (%s)\n", arg);
- return -1;
- }
-
- rdd_config.max_bs = bs;
- }
- break;
-
- case 'r':
- {
- char *tmp = NULL;
- long iters = 0;
- iters = strtol (arg, &tmp, 10);
- if ((iters == LONG_MAX) ||
- (iters == LONG_MIN) ||
+ return -1;
+ }
+
+ rdd_config.max_bs = bs;
+ }
+ break;
+
+ case 'r':
+ {
+ char *tmp = NULL;
+ long iters = 0;
+ iters = strtol (arg, &tmp, 10);
+ if ((iters == LONG_MAX) ||
+ (iters == LONG_MIN) ||
(tmp && *tmp)) {
- fprintf (stderr, "invalid argument for iterations"
+ fprintf (stderr, "invalid argument for iterations"
"(%s)\n", arg);
- return -1;
- }
-
- rdd_config.iters = iters;
- }
- break;
-
- case 'm':
- {
- char *tmp = NULL;
- long max_ops = 0;
- max_ops = strtol (arg, &tmp, 10);
- if ((max_ops == LONG_MAX) ||
- (max_ops == LONG_MIN) ||
+ return -1;
+ }
+
+ rdd_config.iters = iters;
+ }
+ break;
+
+ case 'm':
+ {
+ char *tmp = NULL;
+ long max_ops = 0;
+ max_ops = strtol (arg, &tmp, 10);
+ if ((max_ops == LONG_MAX) ||
+ (max_ops == LONG_MIN) ||
(tmp && *tmp)) {
- fprintf (stderr, "invalid argument for max-ops"
+ fprintf (stderr, "invalid argument for max-ops"
"(%s)\n", arg);
- return -1;
- }
-
- rdd_config.max_ops_per_seq = max_ops;
- }
- break;
-
- case 't':
- {
- char *tmp = NULL;
- long threads = 0;
- threads = strtol (arg, &tmp, 10);
- if ((threads == LONG_MAX) ||
- (threads == LONG_MIN) ||
+ return -1;
+ }
+
+ rdd_config.max_ops_per_seq = max_ops;
+ }
+ break;
+
+ case 't':
+ {
+ char *tmp = NULL;
+ long threads = 0;
+ threads = strtol (arg, &tmp, 10);
+ if ((threads == LONG_MAX) ||
+ (threads == LONG_MIN) ||
(tmp && *tmp)) {
- fprintf (stderr, "invalid argument for thread count"
+ fprintf (stderr, "invalid argument for thread count"
"(%s)\n", arg);
- return -1;
- }
+ return -1;
+ }
- rdd_config.thread_count = threads;
- }
- break;
+ rdd_config.thread_count = threads;
+ }
+ break;
- case ARGP_KEY_NO_ARGS:
- break;
- case ARGP_KEY_ARG:
- break;
- case ARGP_KEY_END:
- if (_state->argc == 1) {
- argp_usage (_state);
- }
+ case ARGP_KEY_NO_ARGS:
+ break;
+ case ARGP_KEY_ARG:
+ break;
+ case ARGP_KEY_END:
+ if (_state->argc == 1) {
+ argp_usage (_state);
+ }
- }
+ }
- return 0;
+ return 0;
+}
+
+int
+string2bytesize (const char *str, unsigned long long *n)
+{
+ unsigned long long value = 0ULL;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++)
+ {
+ if (isspace (*s))
+ {
+ continue;
+ }
+ if (*s == '-')
+ {
+ return -1;
+ }
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtoull (str, &tail, 10);
+
+ if (errno == ERANGE || errno == EINVAL)
+ {
+ return -1;
+ }
+
+ if (errno == 0)
+ {
+ errno = old_errno;
+ }
+
+ if (tail[0] != '\0')
+ {
+ if (strcasecmp (tail, UNIT_KB_STRING) == 0)
+ {
+ value *= UNIT_KB;
+ }
+ else if (strcasecmp (tail, UNIT_MB_STRING) == 0)
+ {
+ value *= UNIT_MB;
+ }
+ else if (strcasecmp (tail, UNIT_GB_STRING) == 0)
+ {
+ value *= UNIT_GB;
+ }
+ else if (strcasecmp (tail, UNIT_TB_STRING) == 0)
+ {
+ value *= UNIT_TB;
+ }
+ else if (strcasecmp (tail, UNIT_PB_STRING) == 0)
+ {
+ value *= UNIT_PB;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+
+ *n = value;
+
+ return 0;
}
static struct argp_option rdd_options[] = {
- {"if", 'i', "INPUT_FILE", 0, "input-file"},
- {"of", 'o', "OUTPUT_FILE", 0, "output-file"},
- {"threads", 't', "COUNT", 0, "number of threads to spawn (defaults to 2)"},
- {"min-bs", RDD_MIN_BS_KEY, "MIN_BLOCK_SIZE", 0,
- "Minimum block size in bytes (defaults to 1024)"},
- {"max-bs", RDD_MAX_BS_KEY, "MAX_BLOCK_SIZE", 0,
- "Maximum block size in bytes (defaults to 4096)"},
- {"iters", 'r', "ITERS", 0,
- "Number of read-write sequences (defaults to 1000000)"},
- {"max-ops", 'm', "MAXOPS", 0,
- "maximum number of read-writes to be performed in a sequence (defaults to 1)"},
- {0, 0, 0, 0, 0}
+ {"if", 'i', "INPUT_FILE", 0, "input-file"},
+ {"of", 'o', "OUTPUT_FILE", 0, "output-file"},
+ {"threads", 't', "COUNT", 0, "number of threads to spawn (defaults to 2)"},
+ {"min-bs", RDD_MIN_BS_KEY, "MIN_BLOCK_SIZE", 0,
+ "Minimum block size in bytes (defaults to 1024)"},
+ {"max-bs", RDD_MAX_BS_KEY, "MAX_BLOCK_SIZE", 0,
+ "Maximum block size in bytes (defaults to 4096)"},
+ {"iters", 'r', "ITERS", 0,
+ "Number of read-write sequences (defaults to 1000000)"},
+ {"max-ops", 'm', "MAXOPS", 0,
+ "maximum number of read-writes to be performed in a sequence (defaults to 1)"},
+ {"file-size", 'f', "FILESIZE", 0,
+ "the size of the file which will be created and upon it I/O will be done"
+ " (defaults to 100MB"},
+ {0, 0, 0, 0, 0}
};
static struct argp argp = {
@@ -216,277 +322,341 @@ static struct argp argp = {
static void
rdd_default_config (void)
{
- rdd_config.thread_count = 2;
- rdd_config.iters = 1000000;
- rdd_config.max_bs = 4096;
- rdd_config.min_bs = 1024;
- rdd_config.in_file.fd = rdd_config.out_file.fd = -1;
- rdd_config.max_ops_per_seq = 1;
-
- return;
+ char *tmp_path = "rdd.in";
+
+ rdd_config.thread_count = 2;
+ rdd_config.iters = 1000000;
+ rdd_config.max_bs = 4096;
+ rdd_config.min_bs = 1024;
+ rdd_config.in_file.fd = rdd_config.out_file.fd = -1;
+ rdd_config.max_ops_per_seq = 1;
+ strncpy (rdd_config.in_file.path, tmp_path, strlen (tmp_path));
+ rdd_config.file_size = 104857600;
+
+ return;
}
static char
rdd_valid_config (void)
{
- char ret = 1;
- int fd = -1;
-
- fd = open (rdd_config.in_file.path, O_RDONLY);
- if (fd == -1) {
- ret = 0;
- goto out;
- }
- close (fd);
-
- if (rdd_config.min_bs > rdd_config.max_bs) {
- ret = 0;
- goto out;
- }
-
- if (strlen (rdd_config.out_file.path) == 0) {
- sprintf (rdd_config.out_file.path, "%s.rddout",
+ char ret = 1;
+ int fd = -1;
+
+ fd = open (rdd_config.in_file.path, O_RDONLY);
+ if (fd == -1 && (errno != ENOENT)) {
+ fprintf (stderr, "open: (%s)", strerror (errno));
+ ret = 0;
+ goto out;
+ }
+ close (fd);
+
+ if (rdd_config.min_bs > rdd_config.max_bs) {
+ fprintf (stderr, "minimum blocksize %ld is greater than the "
+ "maximum blocksize %ld", rdd_config.min_bs,
+ rdd_config.max_bs);
+ ret = 0;
+ goto out;
+ }
+
+ if (strlen (rdd_config.out_file.path) == 0) {
+ sprintf (rdd_config.out_file.path, "%s.rddout",
rdd_config.in_file.path);
- }
+ }
out:
- return ret;
+ return ret;
}
static void *
rdd_read_write (void *arg)
{
- int i = 0, ret = 0;
- size_t bs = 0;
- off_t offset = 0;
- long rand = 0;
- long max_ops = 0;
- char *buf = NULL;
-
- buf = calloc (1, rdd_config.max_bs);
- if (!buf) {
- fprintf (stderr, "calloc failed (%s)\n", strerror (errno));
- ret = -1;
- goto out;
- }
-
- for (i = 0; i < rdd_config.iters; i++)
- {
- pthread_mutex_lock (&rdd_config.lock);
- {
- int bytes = 0;
- rand = random ();
-
- if (rdd_config.min_bs == rdd_config.max_bs) {
- bs = rdd_config.max_bs;
- } else {
- bs = rdd_config.min_bs +
- (rand %
- (rdd_config.max_bs -
+ int i = 0, ret = 0;
+ size_t bs = 0;
+ off_t offset = 0;
+ long rand = 0;
+ long max_ops = 0;
+ char *buf = NULL;
+
+ buf = calloc (1, rdd_config.max_bs);
+ if (!buf) {
+ fprintf (stderr, "calloc failed (%s)\n", strerror (errno));
+ ret = -1;
+ goto out;
+ }
+
+ for (i = 0; i < rdd_config.iters; i++)
+ {
+ pthread_mutex_lock (&rdd_config.lock);
+ {
+ int bytes = 0;
+ rand = random ();
+
+ if (rdd_config.min_bs == rdd_config.max_bs) {
+ bs = rdd_config.max_bs;
+ } else {
+ bs = rdd_config.min_bs +
+ (rand %
+ (rdd_config.max_bs -
rdd_config.min_bs));
- }
-
- offset = rand % rdd_config.in_file.st.st_size;
- max_ops = rand % rdd_config.max_ops_per_seq;
- if (!max_ops) {
- max_ops ++;
- }
-
- ret = lseek (rdd_config.in_file.fd, offset, SEEK_SET);
- if (ret != offset) {
- fprintf (stderr, "lseek failed (%s)\n",
+ }
+
+ offset = rand % rdd_config.in_file.st.st_size;
+ max_ops = rand % rdd_config.max_ops_per_seq;
+ if (!max_ops) {
+ max_ops ++;
+ }
+
+ ret = lseek (rdd_config.in_file.fd, offset, SEEK_SET);
+ if (ret != offset) {
+ fprintf (stderr, "lseek failed (%s)\n",
strerror (errno));
- ret = -1;
- goto unlock;
- }
+ ret = -1;
+ goto unlock;
+ }
- ret = lseek (rdd_config.out_file.fd, offset, SEEK_SET);
- if (ret != offset) {
- fprintf (stderr, "lseek failed (%s)\n",
+ ret = lseek (rdd_config.out_file.fd, offset, SEEK_SET);
+ if (ret != offset) {
+ fprintf (stderr, "lseek failed (%s)\n",
strerror (errno));
- ret = -1;
- goto unlock;
- }
-
- while (max_ops--)
- {
- bytes = read (rdd_config.in_file.fd, buf, bs);
- if (!bytes) {
- break;
- }
-
- if (bytes == -1) {
- fprintf (stderr, "read failed (%s)\n",
+ ret = -1;
+ goto unlock;
+ }
+
+ while (max_ops--)
+ {
+ bytes = read (rdd_config.in_file.fd, buf, bs);
+ if (!bytes) {
+ break;
+ }
+
+ if (bytes == -1) {
+ fprintf (stderr, "read failed (%s)\n",
strerror (errno));
- ret = -1;
- goto unlock;
- }
+ ret = -1;
+ goto unlock;
+ }
- if (write (rdd_config.out_file.fd, buf, bytes)
+ if (write (rdd_config.out_file.fd, buf, bytes)
!= bytes) {
- fprintf (stderr, "write failed (%s)\n",
+ fprintf (stderr, "write failed (%s)\n",
strerror (errno));
- ret = -1;
- goto unlock;
- }
- }
- }
- unlock:
- pthread_mutex_unlock (&rdd_config.lock);
- if (ret == -1) {
- goto out;
- }
- ret = 0;
- }
+ ret = -1;
+ goto unlock;
+ }
+ }
+ }
+ unlock:
+ pthread_mutex_unlock (&rdd_config.lock);
+ if (ret == -1) {
+ goto out;
+ }
+ ret = 0;
+ }
out:
- free (buf);
- pthread_barrier_wait (&rdd_config.barrier);
+ free (buf);
+ pthread_barrier_wait (&rdd_config.barrier);
- return NULL;
+ return NULL;
}
+static void
+cleanup (void)
+{
+ close (rdd_config.in_file.fd);
+ close (rdd_config.out_file.fd);
+ rdd_config.in_file.fd = rdd_config.out_file.fd = -1;
+}
+
+static int
+check_and_create (void)
+{
+ int ret = -1;
+ char buf[4096] = {0,};
+ struct stat stbuf = {0,};
+ int fd[2] = {-1,};
+ size_t total_size = -1;
+
+ total_size = rdd_config.file_size;
+
+ ret = stat (rdd_config.in_file.path, &stbuf);
+ if (ret == -1 && (errno != ENOENT))
+ goto out;
+
+ fd[1] = open (rdd_config.in_file.path, O_CREAT | O_WRONLY | O_TRUNC);
+ if (fd[1] == -1)
+ goto out;
+
+ fd[0] = open ("/dev/urandom", O_RDONLY);
+ if (fd[0] == -1)
+ goto out;
+
+ while (total_size > 0) {
+ if (total_size >= 4096) {
+ ret = read (fd[0], buf, 4096);
+ if (ret == -1)
+ goto out;
+ ret = write (fd[1], buf, 4096);
+ if (ret == -1)
+ goto out;
+ total_size = total_size - 4096;
+ } else {
+ ret = read (fd[0], buf, total_size);
+ if (ret == -1)
+ goto out;
+ ret = write (fd[1], buf, total_size);
+ if (ret == -1)
+ goto out;
+ total_size = total_size - total_size;
+ }
+
+ }
+
+ ret = 0;
+
+out:
+ if (fd[0] > 0)
+ close (fd[0]);
+ if (fd[1] > 0)
+ close (fd[1]);
+ return ret;
+}
static int
rdd_spawn_threads (void)
{
- int i = 0, ret = -1, fd = -1;
- char buf[4096];
+ int i = 0, ret = -1, fd = -1;
+ char buf[4096];
- fd = open (rdd_config.in_file.path, O_RDONLY);
- if (fd < 0) {
- fprintf (stderr, "cannot open %s (%s)\n",
+ ret = check_and_create ();
+ if (ret == -1)
+ goto out;
+
+ fd = open (rdd_config.in_file.path, O_RDONLY);
+ if (fd < 0) {
+ fprintf (stderr, "cannot open %s (%s)\n",
rdd_config.in_file.path, strerror (errno));
- ret = -1;
- goto out;
- }
- ret = fstat (fd, &rdd_config.in_file.st);
- if (ret != 0) {
- close (fd);
- fprintf (stderr, "cannot stat %s (%s)\n",
+ ret = -1;
+ goto out;
+ }
+ ret = fstat (fd, &rdd_config.in_file.st);
+ if (ret != 0) {
+ close (fd);
+ fprintf (stderr, "cannot stat %s (%s)\n",
rdd_config.in_file.path, strerror (errno));
- ret = -1;
- goto out;
- }
- rdd_config.in_file.fd = fd;
+ ret = -1;
+ goto out;
+ }
+ rdd_config.in_file.fd = fd;
- fd = open (rdd_config.out_file.path, O_WRONLY | O_CREAT,
+ fd = open (rdd_config.out_file.path, O_WRONLY | O_CREAT | O_TRUNC,
S_IRWXU | S_IROTH);
- if (fd < 0) {
- close (rdd_config.in_file.fd);
- rdd_config.in_file.fd = -1;
- fprintf (stderr, "cannot open %s (%s)\n",
+ if (fd < 0) {
+ close (rdd_config.in_file.fd);
+ rdd_config.in_file.fd = -1;
+ fprintf (stderr, "cannot open %s (%s)\n",
rdd_config.out_file.path, strerror (errno));
- ret = -1;
- goto out;
- }
- rdd_config.out_file.fd = fd;
-
- while ((ret = read (rdd_config.in_file.fd, buf, 4096)) > 0) {
- if (write (rdd_config.out_file.fd, buf, ret) != ret) {
- fprintf (stderr, "write failed (%s)\n",
+ ret = -1;
+ goto out;
+ }
+ rdd_config.out_file.fd = fd;
+
+ while ((ret = read (rdd_config.in_file.fd, buf, 4096)) > 0) {
+ if (write (rdd_config.out_file.fd, buf, ret) != ret) {
+ fprintf (stderr, "write failed (%s)\n",
strerror (errno));
- close (rdd_config.in_file.fd);
- close (rdd_config.out_file.fd);
- rdd_config.in_file.fd = rdd_config.out_file.fd = -1;
- ret = -1;
- goto out;
- }
- }
-
- rdd_config.threads = calloc (rdd_config.thread_count,
+ cleanup ();
+ ret = -1;
+ goto out;
+ }
+ }
+
+ rdd_config.threads = calloc (rdd_config.thread_count,
sizeof (pthread_t));
- if (rdd_config.threads == NULL) {
- fprintf (stderr, "calloc() failed (%s)\n", strerror (errno));
+ if (rdd_config.threads == NULL) {
+ fprintf (stderr, "calloc() failed (%s)\n", strerror (errno));
- ret = -1;
- close (rdd_config.in_file.fd);
- close (rdd_config.out_file.fd);
- rdd_config.in_file.fd = rdd_config.out_file.fd = -1;
- goto out;
- }
+ ret = -1;
+ cleanup ();
+ goto out;
+ }
- ret = pthread_barrier_init (&rdd_config.barrier, NULL,
+ ret = pthread_barrier_init (&rdd_config.barrier, NULL,
rdd_config.thread_count + 1);
- if (ret != 0) {
- fprintf (stderr, "pthread_barrier_init() failed (%s)\n",
+ if (ret != 0) {
+ fprintf (stderr, "pthread_barrier_init() failed (%s)\n",
strerror (ret));
- free (rdd_config.threads);
- close (rdd_config.in_file.fd);
- close (rdd_config.out_file.fd);
- rdd_config.in_file.fd = rdd_config.out_file.fd = -1;
- ret = -1;
- goto out;
- }
-
- ret = pthread_mutex_init (&rdd_config.lock, NULL);
- if (ret != 0) {
- fprintf (stderr, "pthread_mutex_init() failed (%s)\n",
+ free (rdd_config.threads);
+ cleanup ();
+ ret = -1;
+ goto out;
+ }
+
+ ret = pthread_mutex_init (&rdd_config.lock, NULL);
+ if (ret != 0) {
+ fprintf (stderr, "pthread_mutex_init() failed (%s)\n",
strerror (ret));
- free (rdd_config.threads);
- pthread_barrier_destroy (&rdd_config.barrier);
- close (rdd_config.in_file.fd);
- close (rdd_config.out_file.fd);
- rdd_config.in_file.fd = rdd_config.out_file.fd = -1;
- ret = -1;
- goto out;
- }
-
- for (i = 0; i < rdd_config.thread_count; i++)
- {
- ret = pthread_create (&rdd_config.threads[i], NULL,
+ free (rdd_config.threads);
+ pthread_barrier_destroy (&rdd_config.barrier);
+ cleanup ();
+ ret = -1;
+ goto out;
+ }
+
+ for (i = 0; i < rdd_config.thread_count; i++)
+ {
+ ret = pthread_create (&rdd_config.threads[i], NULL,
rdd_read_write, NULL);
- if (ret != 0) {
- fprintf (stderr, "pthread_create failed (%s)\n",
+ if (ret != 0) {
+ fprintf (stderr, "pthread_create failed (%s)\n",
strerror (errno));
- exit (1);
- }
- }
+ exit (1);
+ }
+ }
out:
- return ret;
+ return ret;
}
-
static void
rdd_wait_for_completion (void)
{
- pthread_barrier_wait (&rdd_config.barrier);
+ pthread_barrier_wait (&rdd_config.barrier);
}
-int
+int
main (int argc, char *argv[])
{
- int ret = -1;
+ int ret = -1;
- rdd_default_config ();
+ rdd_default_config ();
- ret = argp_parse (&argp, argc, argv, 0, 0, NULL);
- if (ret != 0) {
- ret = -1;
- fprintf (stderr, "%s: argp_parse() failed\n", argv[0]);
- goto err;
- }
+ ret = argp_parse (&argp, argc, argv, 0, 0, NULL);
+ if (ret != 0) {
+ ret = -1;
+ fprintf (stderr, "%s: argp_parse() failed\n", argv[0]);
+ goto err;
+ }
- if (!rdd_valid_config ()) {
- ret = -1;
- fprintf (stderr, "%s: configuration validation failed\n",
+ if (!rdd_valid_config ()) {
+ ret = -1;
+ fprintf (stderr, "%s: configuration validation failed\n",
argv[0]);
- goto err;
- }
+ goto err;
+ }
- ret = rdd_spawn_threads ();
- if (ret != 0) {
- fprintf (stderr, "%s: spawning threads failed\n", argv[0]);
- goto err;
- }
+ ret = rdd_spawn_threads ();
+ if (ret != 0) {
+ fprintf (stderr, "%s: spawning threads failed\n", argv[0]);
+ goto err;
+ }
- rdd_wait_for_completion ();
+ rdd_wait_for_completion ();
err:
- return ret;
-}
+ return ret;
+}
diff --git a/extras/clear_xattrs.sh b/extras/clear_xattrs.sh
new file mode 100755
index 000000000..dd04731e8
--- /dev/null
+++ b/extras/clear_xattrs.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Clear the trusted.gfid xattr in the brick tree
+
+# This script must be run only on a stopped brick/volume
+# Stop the volume to make sure no rebalance/replace-brick
+# operations are on-going
+
+# Not much error checking
+remove_xattrs ()
+{
+ find "$1" -exec setfattr -h -x "trusted.gfid" '{}' \; > /dev/null 2>&1;
+ find "$1" -exec setfattr -h -x "trusted.glusterfs.volume-id" '{}' \; > /dev/null 2>&1;
+}
+
+main ()
+{
+ if [ -z "$1" ]; then
+ echo "Usage: $0 <brick_path(s)>";
+ exit 1;
+ fi
+
+ export PATH;
+ which getfattr > /dev/null 2>&1;
+ if [ $? -ne 0 ]; then
+ echo "attr package missing";
+ exit 2;
+ fi
+
+ which setfattr > /dev/null 2>&1;
+ if [ $? -ne 0 ]; then
+ echo "attr package missing";
+ exit 2;
+ fi
+
+ for brick in "$@";
+ do
+ stat "$brick" > /dev/null 2>&1;
+ if [ $? -ne 0 ]; then
+ echo "brick: $brick does not exist";
+ exit 3;
+ fi
+ if [ ! -d "$brick" ]; then
+ echo "$brick: not a directory";
+ exit 4;
+ fi
+ echo "xattr clean-up in progress: $brick";
+ remove_xattrs "$brick";
+ echo "$brick ready to be used as a glusterfs brick";
+ done;
+}
+
+main "$@"; \ No newline at end of file
diff --git a/extras/contri-add.sh b/extras/contri-add.sh
new file mode 100755
index 000000000..7db5edd5d
--- /dev/null
+++ b/extras/contri-add.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+# This script adds contributions of files/directories in backend to volume
+# size.
+# It can also be used to debug by passing dir as first argument, in which case
+# it will just add contributions from immediate children of a directory and
+# displays only if added contributions from immediate children is different
+# from size stored in directory.
+# For Eg., find <backend-directory> -type d -exec ./contri-add.sh dir \{} \;
+# will list all the directories which have descrepancies in their
+# size/contributions.
+
+usage ()
+{
+ echo >&2 "usage: $0 <file|dir> <list-of-backend-directories>"
+}
+
+add_contributions ()
+{
+ local var=0
+ local count=0
+
+ SIZE=`getfattr -h -e hex -n trusted.glusterfs.quota.size $2 2>&1 | sed -e '/^#/d' | sed -e '/^getfattr/d' | sed -e '/^$/d' | cut -d'=' -f 2`
+ CONTRI=`getfattr -h -e hex -d -m trusted.glusterfs.quota.*.contri $2 2>&1 | sed -e '/^#/d' | sed -e '/^getfattr/d' | sed -e '/^$/d' | cut -d'=' -f 2`
+
+ if [ $1 == "file" ]; then
+ PATHS=`find $2 ! -type d | sed -e "\|^$2$|d" | sed -e '/^[ \t]*$/d'`
+ else
+ PATHS=`find $2 -maxdepth 1 | sed -e "\|^$2$|d" | sed -e '/^[ \t]*$/d'`
+ fi
+
+ if [ -z "$PATHS" ]; then
+ return 0
+ fi
+
+ CONTRIBUTIONS=`echo $PATHS | xargs getfattr -h -e hex -d -m trusted.glusterfs.quota.*.contri 2>&1 | sed -e '/^#/d' | sed -e '/^getfattr/d' | sed -e '/^$/d' | cut -d'=' -f 2 | sed -e 's/^[ \t]*\([^ \t]*\)/\1/g'`
+
+ if [ -n "$CONTRIBUTIONS" ]; then
+ for i in $CONTRIBUTIONS; do
+ count=$(($count + 1))
+ var=$(($var + $i))
+ done
+ fi
+
+ if [ $1 == "file" ] || [ $var -ne $(($SIZE)) ] || [ $(($SIZE)) -ne $(($CONTRI)) ]; then
+ if [ $1 == "dir" ]; then
+ TMP_PATH=`echo $2 | sed -e "s/\/home\/export\/[0-9]*/\/mnt\/raghu/g"`
+ stat $TMP_PATH > /dev/null
+ fi
+
+ echo "file count $count"
+ echo "added contribution of $2=$var"
+ echo "size stored in xattrs on $2=$(($SIZE))"
+ echo "contribution of $2 to its parent directory=$(($CONTRI))"
+ echo "=============================================================="
+ fi
+}
+
+
+main ()
+{
+ [ $# -lt 1 ] && usage
+
+ TYPE=$1
+
+ shift 1
+
+ for i in $@; do
+ add_contributions $TYPE $i
+ done
+}
+
+main $@ \ No newline at end of file
diff --git a/extras/file_size_contri.sh b/extras/file_size_contri.sh
new file mode 100755
index 000000000..4f52a9a89
--- /dev/null
+++ b/extras/file_size_contri.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# This script checks whether the contribution and disk-usage of a file is same.
+
+CONTRIBUTION_HEX=`getfattr -h -e hex -d -m trusted.glusterfs.quota.*.contri $1 2>&1 | sed -e '/^#/d' | sed -e '/^getfattr/d' | sed -e '/^$/d' | cut -d'=' -f 2`
+
+BLOCKS=`stat -c %b $1`
+SIZE=$(($BLOCKS * 512))
+
+CONTRIBUTION=`printf "%d" $CONTRIBUTION_HEX`
+
+if [ $CONTRIBUTION -ne $SIZE ]; then
+ printf "contribution of %s:%d\n" $1 $CONTRIBUTION
+ echo "size of $1: $SIZE"
+ echo "==================================================="
+fi
+
diff --git a/extras/generate-xdr-files.sh b/extras/generate-xdr-files.sh
new file mode 100755
index 000000000..e52321cd3
--- /dev/null
+++ b/extras/generate-xdr-files.sh
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+_init ()
+{
+ xfile="$1";
+ # TODO: check the validity of .x file
+
+ cfile="${1%.x}.c";
+ hfile="${1%.x}.h";
+
+ tmp_cfile="$1.c";
+
+ tmp1_hfile="$1.h.tmp";
+ tmp1_cfile="$1.c.tmp";
+
+}
+
+append_licence_header ()
+{
+ src_file=$1;
+ dst_file=$2;
+
+ cat >$dst_file <<EOF
+/*
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
+
+EOF
+
+ cat $src_file >> $dst_file;
+
+}
+
+main ()
+{
+ if [ $# -ne 1 ]; then
+ echo "wrong number of arguments given"
+ echo " $0 <XDR-definition-file>.x"
+ exit 1;
+ fi
+
+
+ echo -n "writing the XDR routine file ($tmp_cfile) ... ";
+ rm -f $tmp_cfile;
+ rpcgen -c -o $tmp_cfile $xfile;
+
+ # get rid of warnings in xdr .c file due to "unused variable 'buf'"
+ sed -i -e 's:buf;$:buf;\
+ buf = NULL;:' $tmp_cfile;
+
+ sed -i '/int i;/d' $tmp_cfile;
+
+ echo "OK";
+
+ # no need for a temporary file here as there are no changes from glusterfs
+ echo -n "writing the XDR header file ($hfile) ... ";
+ rm -f $hfile;
+ rpcgen -h -o $hfile $xfile;
+
+ # the '#ifdef' part of file should be fixed
+ sed -i -e 's/-/_/g' $hfile;
+
+ echo "OK";
+
+ echo -n "writing licence header to the generated files ... ";
+ # Write header to temp file and append generated file
+ append_licence_header $hfile $tmp1_hfile;
+ append_licence_header $tmp_cfile $tmp1_cfile;
+ echo "OK"
+
+ # now move the destination file to actual original file
+ echo -n "updating existing files ... ";
+ mv $tmp1_hfile $hfile;
+ mv $tmp1_cfile $cfile;
+
+ # remove unwanted temporary files (if any)
+ rm -f $tmp_cfile $tmp1_cfile $tmp1_hfile
+
+ echo "OK"
+
+}
+
+_init "$@" && main "$@";
diff --git a/extras/glusterfs-logrotate b/extras/glusterfs-logrotate
new file mode 100644
index 000000000..373ec2e0b
--- /dev/null
+++ b/extras/glusterfs-logrotate
@@ -0,0 +1,27 @@
+# perform the log rotate every week
+weekly
+# keep the backup of 52 weeks
+rotate 52
+missingok
+
+# compress the logs, but from the .2 onwards
+compress
+delaycompress
+notifempty
+
+# Rotate client logs
+/var/log/glusterfs/*.log {
+ sharedscripts
+ postrotate
+ /usr/bin/killall -HUP glusterfs > /dev/null 2>&1 || true
+ /usr/bin/killall -HUP glusterd > /dev/null 2>&1 || true
+ endscript
+}
+
+# Rotate server logs
+/var/log/glusterfs/bricks/*.log {
+ sharedscripts
+ postrotate
+ /usr/bin/killall -HUP glusterfsd > /dev/null 2>&1 || true
+ endscript
+}
diff --git a/extras/glusterfs-mode.el b/extras/glusterfs-mode.el
index 2f4b40c4e..d4f6dc568 100644
--- a/extras/glusterfs-mode.el
+++ b/extras/glusterfs-mode.el
@@ -1,4 +1,4 @@
-;;; Copyright (C) 2007-2009 Gluster Inc. <http://www.gluster.com>
+;;; Copyright (C) 2007-2011 Gluster Inc. <http://www.gluster.com>
;;;
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
diff --git a/extras/glusterfs.vim b/extras/glusterfs.vim
index eb5b2c98b..62102c1ee 100644
--- a/extras/glusterfs.vim
+++ b/extras/glusterfs.vim
@@ -1,5 +1,5 @@
" glusterfs.vim: GNU Vim Syntax file for GlusterFS .vol specification
-" Copyright (C) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+" Copyright (c) 2017-2011 Gluster, Inc. <http://www.gluster.com>
" This file is part of GlusterFS.
"
" GlusterFS is free software; you can redistribute it and/or modify
diff --git a/extras/gnfs-loganalyse.py b/extras/gnfs-loganalyse.py
index 1e0fde7f2..6b24e5a71 100644
--- a/extras/gnfs-loganalyse.py
+++ b/extras/gnfs-loganalyse.py
@@ -1,6 +1,6 @@
#!/bin/python
"""
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -24,6 +24,13 @@ import sys
class NFSRequest:
+ def requestIsEntryOp (self):
+ op = self.op
+ if op == "CREATE" or op == "LOOKUP" or op == "REMOVE" or op == "LINK" or op == "RENAME" or op == "MKDIR" or op == "RMDIR" or op == "SYMLINK" or op == "MKNOD":
+ return 1
+ else:
+ return 0
+
def __init__ (self, logline, linecount):
self.calllinecount = 0
self.xid = ""
@@ -31,8 +38,13 @@ class NFSRequest:
self.opdata = ""
self.replydata = ""
self.replylinecount = 0
+ self.timestamp = ""
+ self.entryname = ""
+ self.gfid = ""
+ self.replygfid = ""
tokens = logline.strip ().split (" ")
+ self.timestamp = tokens[0] + " " + tokens[1]
if "XID:" not in tokens:
return None
@@ -47,6 +59,11 @@ class NFSRequest:
opidx = tokens.index ("args:")
self.op = tokens [opidx-1].strip (":")
self.opdata = " ".join(tokens [opidx+1:])
+ if self.requestIsEntryOp ():
+ nameidx = tokens.index ("name:")
+ self.entryname = tokens[nameidx + 1].strip (",")
+ gfididx = tokens.index ("gfid")
+ self.gfid = tokens[gfididx +1].strip(",")
def getXID (self):
@@ -54,25 +71,56 @@ class NFSRequest:
def setReply (self, logline, linecount):
tokens = logline.strip ().split (" ")
+ timestamp = tokens[0] + " " + tokens[1]
statidx = tokens.index ("NFS:")
- self.replydata = " ".join (tokens [statidx+1:])
+ self.replydata = " TimeStamp: " + timestamp + " " + " ".join (tokens [statidx+1:])
self.replylinecount = linecount
+ if "gfid" in tokens:
+ gfididx = tokens.index ("gfid")
+ self.replygfid = tokens [gfididx + 1].strip(",")
def dump (self):
- print "ReqLine: " + str(self.calllinecount) + " XID: " + self.xid + " " + self.op + " ARGS: " + self.opdata + " RepLine: " + str(self.replylinecount) + " " + self.replydata
+ print "ReqLine: " + str(self.calllinecount) + " TimeStamp: " + self.timestamp + ", XID: " + self.xid + " " + self.op + " ARGS: " + self.opdata + " RepLine: " + str(self.replylinecount) + " " + self.replydata
class NFSLogAnalyzer:
- def __init__ (self):
+ def __init__ (self, optn, trackfilename, tracknamefh, stats):
+ self.stats = stats
self.xid_request_map = {}
self.orphan_replies = {}
+ self.rqlist = []
self.CALL = 1
self.REPLY = 2
+ self.optn = optn
+ self.trackfilename = trackfilename
+ self.tracknamefh = tracknamefh
+ self.trackedfilehandles = []
def handle_call_line (self, logline, linecount):
newreq = NFSRequest (logline, linecount)
xid = newreq.getXID ()
- self.xid_request_map [xid] = newreq
+ if (self.optn == SYNTHESIZE):
+ self.xid_request_map [xid] = newreq
+ self.rqlist.append(newreq)
+ elif self.optn == TRACKFILENAME:
+ if newreq.requestIsEntryOp():
+ if newreq.entryname == self.trackfilename:
+ self.xid_request_map [xid] = newreq
+ self.rqlist.append(newreq)
+ else:
+ del newreq
+ elif self.tracknamefh == ENABLE_TRACKNAME_FH:
+ if len (self.trackedfilehandles) > 0:
+ if newreq.gfid in self.trackedfilehandles:
+ self.xid_request_map [xid] = newreq
+ self.rqlist.append(newreq)
+ else:
+ del newreq
+ else:
+ del newreq
+ else:
+ del newreq
+
def handle_reply_line (self, logline, linecount):
tokens = logline.strip ().split (" ")
@@ -82,7 +130,10 @@ class NFSLogAnalyzer:
if xid not in self.xid_request_map.keys ():
self.orphan_replies [xid] = logline
else:
- self.xid_request_map [xid].setReply (logline, linecount)
+ rq = self.xid_request_map [xid]
+ rq.setReply (logline, linecount)
+ if rq.requestIsEntryOp() and rq.entryname == self.trackfilename:
+ self.trackedfilehandles.append (rq.replygfid)
def analyzeLine (self, logline, linecount):
tokens = logline.strip ().split (" ")
@@ -102,43 +153,116 @@ class NFSLogAnalyzer:
self.handle_reply_line (logline, linecount)
def getStats (self):
+ if self.stats == 0:
+ return
rcount = len (self.xid_request_map.keys ())
orphancount = len (self.orphan_replies.keys ())
print "Requests: " + str(rcount) + ", Orphans: " + str(orphancount)
def dump (self):
self.getStats ()
- for rq in self.xid_request_map.values ():
+ for rq in self.rqlist:
rq.dump ()
+ del rq
-
+ self.rqlist = []
+ self.orphan_replies = {}
+ self.xid_request_map = {}
linecount = 0
-la = NFSLogAnalyzer ()
+
+SYNTHESIZE = 1
+TRACKFILENAME = 2
+
+ENABLESTATS = 1
+DISABLESTATS = 0
+
+ENABLE_TRACKNAME_FH = 1
+DISABLE_TRACKNAME_FH = 0
progmsgcount = 1000
-dumpinterval = 2000000
+dumpinterval = 200000
+operation = SYNTHESIZE
+stats = ENABLESTATS
+tracknamefh = DISABLE_TRACKNAME_FH
+trackfilename = ""
+
+"""
+Print the progress of the analysing operations every X number of lines read from
+the logs, where X is the argument provided to this option.
+Use this to print a status message every say 10000 lines processed or 100000
+lines processed to know how much longer the processing will go on for.
+
+
+USAGE: --progress <NUMLINES>
+"""
if "--progress" in sys.argv:
idx = sys.argv.index ("--progress")
progmsgcount = int(sys.argv[idx+1])
-
+"""
+The replies for a NFS request can be separated by hundreds and even thousands
+of other NFS requests and replies. These can be spread over many hundreds and
+thousands of log lines. This script maintains a memory dict to map each request
+to its reply using the XID. Because this is in-core, there is a limit to the
+number of entries in the dict. At regular intervals, it dumps the mapped
+requests and the replies into the stdout. The requests whose replies were not
+found at the point of dumping are left as orphans, i.e. without info about the
+replies. Use this option to tune the number of lines to maximize the number of
+requests whose replies are found while balancing the dict size with memory
+on the machine. The default works fine for most cases.
+
+USAGE: --dump <NUMLINES>
+"""
if "--dump" in sys.argv:
idx = sys.argv.index ("--dump")
dumpinterval = int(sys.argv[idx+1])
+"""
+The default operation of the script is to output all the requests mapped to
+their replies in a single line. This operation mode can be changed by this
+argument. It is used to print only those operations that were performed on the
+filename given as the argument to this option. Only those entry operations are
+printed which contain this filename.
+
+USAGE: --trackfilename <filename>
+"""
+if "--trackfilename" in sys.argv:
+ idx = sys.argv.index ("--trackfilename")
+ trackfilename = sys.argv[idx + 1]
+ operation = TRACKFILENAME
+
+"""
+At every dump interval, some stats are printed about the dumped lines.
+Use this option to disable printing that to avoid cluttering the
+output.
+"""
+if "--nostats" in sys.argv:
+ stats = DISABLESTATS
+
+"""
+While tracking a file using --trackfilename, we're only given those
+operations which contain the filename. This excludes a large number
+of operations which operate on that file using its filehandle instead of
+the filename. This option enables outputting those operations also. It
+tracks every single file handle that was ever seen in the log for a given
+filename.
+
+USAGE: --trackfilename
+"""
+if "--tracknamefh" in sys.argv:
+ tracknamefh = ENABLE_TRACKNAME_FH
+
+la = NFSLogAnalyzer (operation, trackfilename, tracknamefh, stats)
+
for line in sys.stdin:
linecount = linecount + 1
if linecount % dumpinterval == 0:
sys.stderr.write ("Dumping data..\n")
la.dump ()
- del la
- la = NFSLogAnalyzer ()
if linecount % progmsgcount == 0:
sys.stderr.write ("Integrating line: "+ str(linecount) + "\n")
la.analyzeLine (line, linecount)
-
-la.dump ()
diff --git a/extras/hook-scripts/Makefile.am b/extras/hook-scripts/Makefile.am
new file mode 100644
index 000000000..5c6249de7
--- /dev/null
+++ b/extras/hook-scripts/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = S29CTDBsetup.sh S30samba-start.sh S30samba-stop.sh
diff --git a/extras/hook-scripts/S29CTDBsetup.sh b/extras/hook-scripts/S29CTDBsetup.sh
new file mode 100644
index 000000000..e256be1f3
--- /dev/null
+++ b/extras/hook-scripts/S29CTDBsetup.sh
@@ -0,0 +1,69 @@
+#! /bin/bash
+#non-portable - RHS-2.0 only
+# - The script mounts the 'meta-vol' on start 'event' on a known
+# directory (eg. /gluster/lock)
+# - Adds the necessary configuration changes for ctdb in smb.conf and
+# restarts smb service.
+# - P.S: There are other 'tasks' that need to be done outside this script
+# to get CTDB based failover up and running.
+
+SMB_CONF=/etc/samba/smb.conf
+
+CTDB_MNT=/gluster/lock
+PROGNAME="ctdb"
+OPTSPEC="volname:"
+VOL=
+# $META is the volume that will be used by CTDB as a shared filesystem.
+# It is not desirable to use this volume for storing 'data' as well.
+# META is set to 'all' (viz. a keyword and hence not a legal volume name)
+# to prevent the script from running for volumes it was not intended.
+# User needs to set META to the volume that serves CTDB lockfile.
+META="all"
+
+function sighup_samba () {
+ pid=`cat /var/run/smbd.pid`
+ if [ $pid != " " ]
+ then
+ kill -HUP $pid;
+ else
+ /etc/init.d/smb start
+ fi
+}
+
+function parse_args () {
+ ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+ eval set -- "$ARGS"
+
+ while true; do
+ case $1 in
+ --volname)
+ shift
+ VOL=$1
+ ;;
+
+ *)
+ shift
+ break
+ ;;
+
+ esac
+
+ shift
+ done
+}
+
+function add_glusterfs_ctdb_options () {
+ PAT="Share Definitions"
+ GLUSTER_CTDB_CONFIG="# ctdb config for glusterfs\n\tclustering = yes\n\tidmap backend = tdb2\n\tprivate dir = "$CTDB_MNT"\n"
+
+ sed -i /"$PAT"/i\ "$GLUSTER_CTDB_CONFIG" $SMB_CONF
+}
+
+parse_args $@
+if [ "$META" = "$VOL" ]
+then
+ add_glusterfs_ctdb_options
+ sighup_samba
+ mount -t glusterfs `hostname`:$VOL "$CTDB_MNT" &
+fi
+
diff --git a/extras/hook-scripts/S30samba-start.sh b/extras/hook-scripts/S30samba-start.sh
new file mode 100755
index 000000000..a42bb07eb
--- /dev/null
+++ b/extras/hook-scripts/S30samba-start.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#Need to be copied to hooks/<HOOKS_VER>/start/post
+
+PROGNAME="Ssamba-start"
+OPTSPEC="volname:,mnt:"
+VOL=
+#FIXME: glusterd hook interface will eventually provide mntpt prefix as
+# command line arg
+MNT_PRE="/mnt/samba"
+
+function parse_args () {
+ ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+ eval set -- "$ARGS"
+
+ while true; do
+ case $1 in
+ --volname)
+ shift
+ VOL=$1
+ ;;
+ --mnt)
+ shift
+ MNT_PRE=$1
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+ shift
+ done
+}
+
+function add_samba_export () {
+ volname=$1
+ mnt_pre=$2
+ mkdir -p $mnt_pre/$volname && \
+ printf "\n[gluster-$volname]\ncomment=For samba export of volume $volname\npath=$mnt_pre/$volname\nread only=no\nguest ok=yes\n" >> /etc/samba/smb.conf
+}
+
+function mount_volume () {
+ volname=$1
+ mnt_pre=$2
+ #Mount shouldn't block on glusterd to fetch volfile, hence the 'bg'
+ mount -t glusterfs `hostname`:$volname $mnt_pre/$volname &
+}
+
+function sighup_samba () {
+ pid=`cat /var/run/smbd.pid`
+ if [ $pid != "" ]
+ then
+ kill -HUP $pid;
+ else
+ /etc/init.d/smb start
+ fi
+}
+
+
+parse_args $@
+add_samba_export $VOL $MNT_PRE
+mount_volume $VOL $MNT_PRE
+sighup_samba
diff --git a/extras/hook-scripts/S30samba-stop.sh b/extras/hook-scripts/S30samba-stop.sh
new file mode 100755
index 000000000..0e483bff8
--- /dev/null
+++ b/extras/hook-scripts/S30samba-stop.sh
@@ -0,0 +1,60 @@
+#! /bin/bash
+#Need to be copied to hooks/<HOOKS_VER>/stop/post
+
+PROGNAME="Ssamba-stop"
+OPTSPEC="volname:,mnt:"
+VOL=
+#FIXME: gluster will eventually pass mnt prefix as command line argument
+MNT_PRE="/mnt/samba"
+
+function parse_args () {
+ ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+ eval set -- "$ARGS"
+
+ while true; do
+ case $1 in
+ --volname)
+ shift
+ VOL=$1
+ ;;
+ --mnt)
+ shift
+ MNT_PRE=$1
+ echo $1
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+ shift
+ done
+}
+
+function del_samba_export () {
+ volname=$1
+ cp /etc/samba/smb.conf /tmp/smb.conf
+ sed -i "/gluster-$volname/,/^$/d" /tmp/smb.conf &&\
+ mv /tmp/smb.conf /etc/samba/smb.conf
+}
+
+function umount_volume () {
+ volname=$1
+ mnt_pre=$2
+ umount -l $mnt_pre/$volname
+}
+
+function sighup_samba () {
+ pid=`cat /var/run/smbd.pid`
+ if [ $pid != "" ]
+ then
+ kill -HUP $pid;
+ else
+ /etc/init.d/smb start
+ fi
+}
+
+parse_args $@
+del_samba_export $VOL
+umount_volume $VOL $MNT_PRE
+sighup_samba
diff --git a/extras/init.d/glusterd-Redhat.in b/extras/init.d/glusterd-Redhat.in
index 0c39ff139..cf9d390f0 100755
--- a/extras/init.d/glusterd-Redhat.in
+++ b/extras/init.d/glusterd-Redhat.in
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# chkconfig: 35 90 12
+# chkconfig: 35 20 80
# description: Gluster File System service for volume management
#
@@ -8,55 +8,82 @@
. /etc/rc.d/init.d/functions
BASE=glusterd
+PIDFILE=/var/run/$BASE.pid
+PID=`test -f $PIDFILE && cat $PIDFILE`
GLUSTERFSD=glusterfsd
GLUSTERFS=glusterfs
GLUSTERD_BIN=@prefix@/sbin/$BASE
-GLUSTERD_OPTS=""
+GLUSTERD_OPTS="--pid-file=$PIDFILE"
GLUSTERD="$GLUSTERD_BIN $GLUSTERD_OPTS"
RETVAL=0
# Start the service $BASE
start()
{
- echo -n $"Starting $BASE:"
- daemon $GLUSTERD
- RETVAL=$?
- echo
- [ $RETVAL -ne 0 ] && exit $RETVAL
+ pidofproc -p $PIDFILE $GLUSTERD_BIN &> /dev/null
+ status=$?
+ if [ $status -eq 0 ]; then
+ echo "glusterd service is already running with pid $PID"
+ exit 1
+ else
+ echo -n $"Starting $BASE:"
+ daemon $GLUSTERD
+ RETVAL=$?
+ echo
+ [ $RETVAL -ne 0 ] && exit $RETVAL
+ fi
+
}
# Stop the service $BASE
stop()
{
- echo -n $"Stopping $BASE:"
- killproc $BASE
- echo
- pidof -c -o %PPID -x $GLUSTERFSD &> /dev/null
- [ $? -eq 0 ] && killproc $GLUSTERFSD &> /dev/null
-
- pidof -c -o %PPID -x $GLUSTERFS &> /dev/null
- [ $? -eq 0 ] && killproc $GLUSTERFS &> /dev/null
+ echo -n $"Stopping $BASE:"
+ pidofproc -p $PIDFILE $GLUSTERD_BIN &> /dev/null
+ status=$?
+ if [ $status -eq 0 ]; then
+ killproc -p $PIDFILE $BASE
+ [ -w $PIDFILE ] && rm -f $PIDFILE
+ else
+ killproc $BASE
+ fi
+
+ echo
+ pidof -c -o %PPID -x $GLUSTERFSD &> /dev/null
+ [ $? -eq 0 ] && killproc $GLUSTERFSD &> /dev/null
+
+ #pidof -c -o %PPID -x $GLUSTERFS &> /dev/null
+ #[ $? -eq 0 ] && killproc $GLUSTERFS &> /dev/null
+
+ if [ -f /etc/glusterd/nfs/run/nfs.pid ] ;then
+ pid=`cat /etc/glusterd/nfs/run/nfs.pid`;
+ cmd=`ps -p $pid -o comm=`
+
+ if [ $cmd == "glusterfs" ]; then
+ kill `cat /etc/glusterd/nfs/run/nfs.pid`
+ fi
+ fi
}
### service arguments ###
case $1 in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- status $BASE
- ;;
- restart)
- $0 stop
- $0 start
- ;;
- *)
- echo $"Usage: $0 {start|stop|status|restart}."
- exit 1
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ status $BASE
+ ;;
+ restart)
+ $0 stop
+ $0 start
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|status|restart}."
+ exit 1
esac
exit 0
diff --git a/extras/profiler/glusterfs-profiler b/extras/profiler/glusterfs-profiler
index f70db5228..042eadcf2 100755
--- a/extras/profiler/glusterfs-profiler
+++ b/extras/profiler/glusterfs-profiler
@@ -420,7 +420,7 @@ class Texttable:
return line_wrapped
-# Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+# Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
# This file is part of GlusterFS.
# GlusterFS is free software; you can redistribute it and/or modify
diff --git a/extras/rhel_install.sh b/extras/rhel_install.sh
new file mode 100644
index 000000000..3e10e6c2f
--- /dev/null
+++ b/extras/rhel_install.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+rpm -ivh http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/UFO/gluster-swift-1.4.8-4.el6.noarch.rpm
+rpm -ivh http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/UFO/gluster-swift-account-1.4.8-4.el6.noarch.rpm
+rpm -ivh http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/UFO/gluster-swift-container-1.4.8-4.el6.noarch.rpm
+rpm -ivh http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/UFO/gluster-swift-object-1.4.8-4.el6.noarch.rpm
+rpm -ivh http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/UFO/gluster-swift-proxy-1.4.8-4.el6.noarch.rpm
+rpm -ivh http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/UFO/gluster-swift-plugin-1.0-2.noarch.rpm
+rpm -ivh http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/UFO/gluster-swift-doc-1.4.8-4.el6.noarch.rpm
diff --git a/extras/rpc-coverage.sh b/extras/rpc-coverage.sh
index ebb92a2a1..9148a73e2 100755
--- a/extras/rpc-coverage.sh
+++ b/extras/rpc-coverage.sh
@@ -398,8 +398,7 @@ function test_getxattr()
function test_removexattr()
{
setfattr -x trusted.testing $PFX/dir/file || fail "setfattr remove"
- getfattr -n trusted.testing $PFX/dir/file 2>&1 | grep -q 'No such attribute' \
- || fail "getfattr"
+ getfattr -n trusted.testing $PFXf/dir/file 2>&1 | grep -q "No such attribute"
}
diff --git a/extras/specgen.scm b/extras/specgen.scm
index 57640705f..0edbb6f62 100755
--- a/extras/specgen.scm
+++ b/extras/specgen.scm
@@ -1,7 +1,7 @@
#!/usr/bin/guile -s
!#
-;;; Copyright (C) 2007-2010 Gluster Inc. <http://www.gluster.com>
+;;; Copyright (c) 2007-2011 Gluster Inc. <http://www.gluster.com>
;;;
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
diff --git a/extras/stripe-merge.c b/extras/stripe-merge.c
index 3f8e4b124..32768badd 100644
--- a/extras/stripe-merge.c
+++ b/extras/stripe-merge.c
@@ -1,48 +1,498 @@
+/*
+ Copyright (c) 2008-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.
+*/
+
+/*
+ * stripe-merge.c
+ *
+ * This program recovers an original file based on the striped files stored on
+ * the individual bricks of a striped volume. The file format and stripe
+ * geometry is validated through the extended attributes stored in the file.
+ *
+ * TODO: Support optional xattr recovery (i.e., user xattrs). Perhaps provide a
+ * command-line flag to toggle this behavior.
+ */
+
#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+#include <attr/xattr.h>
+#include <fnmatch.h>
-int
-main (int argc, char *argv[])
+#define ATTRNAME_STRIPE_INDEX "trusted.*.stripe-index"
+#define ATTRNAME_STRIPE_COUNT "trusted.*.stripe-count"
+#define ATTRNAME_STRIPE_SIZE "trusted.*.stripe-size"
+#define ATTRNAME_STRIPE_COALESCE "trusted.*.stripe-coalesce"
+
+#define INVALID_FD -1
+#define INVALID_MODE UINT32_MAX
+
+struct file_stripe_info {
+ int stripe_count;
+ int stripe_size;
+ int coalesce;
+ mode_t mode;
+ int fd[0];
+};
+
+static int close_files(struct file_stripe_info *);
+
+static struct
+file_stripe_info *alloc_file_stripe_info(int count)
{
- int fds[argc-1];
- char buf[argc-1][4096];
int i;
- int max_ret, ret;
+ struct file_stripe_info *finfo;
- if (argc < 2) {
- printf ("Usage: %s file1 file2 ... >file\n", argv[0]);
- return 1;
+ finfo = calloc(1, sizeof(struct file_stripe_info) +
+ (sizeof(int) * count));
+ if (!finfo)
+ return NULL;
+
+ for (i = 0; i < count; i++)
+ finfo->fd[i] = INVALID_FD;
+
+ finfo->mode = INVALID_MODE;
+ finfo->coalesce = INVALID_FD;
+
+ return finfo;
+}
+
+/*
+ * Search for an attribute matching the provided pattern. Return a count for
+ * the total number of matching entries (including 0). Allocate a buffer for
+ * the first matching entry found.
+ */
+static int
+get_stripe_attr_name(const char *path, const char *pattern, char **attrname)
+{
+ char attrbuf[4096];
+ char *ptr, *match = NULL;
+ int len, r, match_count = 0;
+
+ if (!path || !pattern || !attrname)
+ return -1;
+
+ len = listxattr(path, attrbuf, sizeof(attrbuf));
+ if (len < 0)
+ return len;
+
+ ptr = attrbuf;
+ while (ptr) {
+ r = fnmatch(pattern, ptr, 0);
+ if (!r) {
+ if (!match)
+ match = ptr;
+ match_count++;
+ } else if (r != FNM_NOMATCH) {
+ return -1;
+ }
+
+ len -= strlen(ptr) + 1;
+ if (len > 0)
+ ptr += strlen(ptr) + 1;
+ else
+ ptr = NULL;
}
- for (i=0; i<argc-1; i++) {
- fds[i] = open (argv[i+1], O_RDONLY);
- if (fds[i] == -1) {
- perror (argv[i+1]);
- return 1;
+ if (match)
+ *attrname = strdup(match);
+
+ return match_count;
+}
+
+/*
+ * Get the integer representation of a named attribute.
+ */
+static int
+get_stripe_attr_val(const char *path, const char *attr, int *val)
+{
+ char attrbuf[4096];
+ int len;
+
+ if (!path || !attr || !val)
+ return -1;
+
+ len = getxattr(path, attr, attrbuf, sizeof(attrbuf));
+ if (len < 0)
+ return len;
+
+ *val = atoi(attrbuf);
+
+ return 0;
+}
+
+/*
+ * Get an attribute name/value (assumed to be an integer) pair based on a
+ * specified search pattern. A buffer is allocated for the exact attr name
+ * returned. Optionally, skip the pattern search if a buffer is provided
+ * (which should contain an attribute name).
+ *
+ * Returns the attribute count or -1 on error. The value parameter is set only
+ * when a single attribute is found.
+ */
+static int
+get_attr(const char *path, const char *pattern, char **buf, int *val)
+{
+ int count = 1;
+
+ if (!buf)
+ return -1;
+
+ if (!*buf) {
+ count = get_stripe_attr_name(path, pattern, buf);
+ if (count > 1) {
+ /* pattern isn't good enough */
+ fprintf(stderr, "ERROR: duplicate attributes found "
+ "matching pattern: %s\n", pattern);
+ free(*buf);
+ *buf = NULL;
+ return count;
+ } else if (count < 1) {
+ return count;
}
}
- max_ret = 0;
+ if (get_stripe_attr_val(path, *buf, val) < 0)
+ return -1;
+
+ return count;
+}
+
+/*
+ * validate_and_open_files()
+ *
+ * Open the provided source files and validate the extended attributes. Verify
+ * that the geometric attributes are consistent across all of the files and
+ * print a warning if any files are missing. We proceed without error in the
+ * latter case to support partial recovery.
+ */
+static struct
+file_stripe_info *validate_and_open_files(char *paths[], int count)
+{
+ int i, val, tmp;
+ struct stat sbuf;
+ char *stripe_count_attr = NULL;
+ char *stripe_size_attr = NULL;
+ char *stripe_index_attr = NULL;
+ char *stripe_coalesce_attr = NULL;
+ struct file_stripe_info *finfo = NULL;
+
+ for (i = 0; i < count; i++) {
+ if (!paths[i])
+ goto err;
+
+ /*
+ * Check the stripe count first so we can allocate the info
+ * struct with the appropriate number of fds.
+ */
+ if (get_attr(paths[i], ATTRNAME_STRIPE_COUNT,
+ &stripe_count_attr, &val) != 1) {
+ fprintf(stderr, "ERROR: %s: attribute: '%s'\n",
+ paths[i], ATTRNAME_STRIPE_COUNT);
+ goto err;
+ }
+ if (!finfo) {
+ finfo = alloc_file_stripe_info(val);
+ if (!finfo)
+ goto err;
+
+ if (val != count)
+ fprintf(stderr, "WARNING: %s: stripe-count "
+ "(%d) != file count (%d). Result may "
+ "be incomplete.\n", paths[i], val,
+ count);
+
+ finfo->stripe_count = val;
+ } else if (val != finfo->stripe_count) {
+ fprintf(stderr, "ERROR %s: invalid stripe count: %d "
+ "(expected %d)\n", paths[i], val,
+ finfo->stripe_count);
+ goto err;
+ }
+
+ /*
+ * Get and validate the chunk size.
+ */
+ if (get_attr(paths[i], ATTRNAME_STRIPE_SIZE, &stripe_size_attr,
+ &val) != 1) {
+ fprintf(stderr, "ERROR: %s: attribute: '%s'\n",
+ paths[i], ATTRNAME_STRIPE_SIZE);
+ goto err;
+ }
+
+ if (!finfo->stripe_size) {
+ finfo->stripe_size = val;
+ } else if (val != finfo->stripe_size) {
+ fprintf(stderr, "ERROR: %s: invalid stripe size: %d "
+ "(expected %d)\n", paths[i], val,
+ finfo->stripe_size);
+ goto err;
+ }
+
+ /*
+ * stripe-coalesce is a backward compatible attribute. If the
+ * attribute does not exist, assume a value of zero for the
+ * traditional stripe format.
+ */
+ tmp = get_attr(paths[i], ATTRNAME_STRIPE_COALESCE,
+ &stripe_coalesce_attr, &val);
+ if (!tmp) {
+ val = 0;
+ } else if (tmp != 1) {
+ fprintf(stderr, "ERROR: %s: attribute: '%s'\n",
+ paths[i], ATTRNAME_STRIPE_COALESCE);
+ goto err;
+ }
+
+ if (finfo->coalesce == INVALID_FD) {
+ finfo->coalesce = val;
+ } else if (val != finfo->coalesce) {
+ fprintf(stderr, "ERROR: %s: invalid coalesce flag\n",
+ paths[i]);
+ goto err;
+ }
+
+ /*
+ * Get/validate the stripe index and open the file in the
+ * appropriate fd slot.
+ */
+ if (get_attr(paths[i], ATTRNAME_STRIPE_INDEX,
+ &stripe_index_attr, &val) != 1) {
+ fprintf(stderr, "ERROR: %s: attribute: '%s'\n",
+ paths[i], ATTRNAME_STRIPE_INDEX);
+ goto err;
+ }
+ if (finfo->fd[val] != INVALID_FD) {
+ fprintf(stderr, "ERROR: %s: duplicate stripe index: "
+ "%d\n", paths[i], val);
+ goto err;
+ }
+
+ finfo->fd[val] = open(paths[i], O_RDONLY);
+ if (finfo->fd[val] < 0)
+ goto err;
+
+ /*
+ * Get the creation mode for the file.
+ */
+ if (fstat(finfo->fd[val], &sbuf) < 0)
+ goto err;
+ if (finfo->mode == INVALID_MODE) {
+ finfo->mode = sbuf.st_mode;
+ } else if (sbuf.st_mode != finfo->mode) {
+ fprintf(stderr, "ERROR: %s: invalid mode\n", paths[i]);
+ goto err;
+ }
+ }
+
+ free(stripe_count_attr);
+ free(stripe_size_attr);
+ free(stripe_index_attr);
+ free(stripe_coalesce_attr);
+
+ return finfo;
+err:
+
+ if (stripe_count_attr)
+ free(stripe_count_attr);
+ if (stripe_size_attr)
+ free(stripe_size_attr);
+ if (stripe_index_attr)
+ free(stripe_index_attr);
+ if (stripe_coalesce_attr)
+ free(stripe_coalesce_attr);
+
+ if (finfo) {
+ close_files(finfo);
+ free(finfo);
+ }
+
+ return NULL;
+}
+
+static int
+close_files(struct file_stripe_info *finfo)
+{
+ int i, ret;
+
+ if (!finfo)
+ return -1;
+
+ for (i = 0; i < finfo->stripe_count; i++) {
+ if (finfo->fd[i] == INVALID_FD)
+ continue;
+
+ ret = close(finfo->fd[i]);
+ if (ret < 0)
+ return ret;
+ }
+
+ return ret;
+}
+
+/*
+ * Generate the original file using files striped in the coalesced format.
+ * Data in the striped files is stored at a coalesced offset based on the
+ * stripe number.
+ *
+ * Walk through the finfo fds (which are already ordered) and and iteratively
+ * copy stripe_size bytes from the source files to the target file. If a source
+ * file is missing, seek past the associated stripe_size bytes in the target
+ * file.
+ */
+static int
+generate_file_coalesce(int target, struct file_stripe_info *finfo)
+{
+ char *buf;
+ int ret = 0;
+ int r, w, i;
+
+ buf = malloc(finfo->stripe_size);
+ if (!buf)
+ return -1;
+
+ i = 0;
+ while (1) {
+ if (finfo->fd[i] == INVALID_FD) {
+ if (lseek(target, finfo->stripe_size, SEEK_CUR) < 0)
+ break;
+
+ i = (i + 1) % finfo->stripe_count;
+ continue;
+ }
+
+ r = read(finfo->fd[i], buf, finfo->stripe_size);
+ if (r < 0) {
+ ret = r;
+ break;
+ }
+ if (!r)
+ break;
+
+ w = write(target, buf, r);
+ if (w < 0) {
+ ret = w;
+ break;
+ }
+
+ i = (i + 1) % finfo->stripe_count;
+ }
+
+ free(buf);
+ return ret;
+}
+
+/*
+ * Generate the original file using files striped with the traditional stripe
+ * format. Data in the striped files is stored at the equivalent offset from
+ * the source file.
+ */
+static int
+generate_file_traditional(int target, struct file_stripe_info *finfo)
+{
+ int i, j, max_ret, ret;
+ char buf[finfo->stripe_count][4096];
+
do {
char newbuf[4096] = {0, };
- int j;
max_ret = 0;
- for (i=0; i<argc-1; i++) {
- memset (buf[i], 0, 4096);
- ret = read (fds[i], buf[i], 4096);
+ for (i = 0; i < finfo->stripe_count; i++) {
+ memset(buf[i], 0, 4096);
+ ret = read(finfo->fd[i], buf[i], 4096);
if (ret > max_ret)
max_ret = ret;
}
- for (i=0; i<max_ret;i++)
- for (j=0; j<argc-1; j++)
+ for (i = 0; i < max_ret; i++)
+ for (j = 0; j < finfo->stripe_count; j++)
newbuf[i] |= buf[j][i];
- write (1, newbuf, max_ret);
+ write(target, newbuf, max_ret);
} while (max_ret);
return 0;
}
+static int
+generate_file(int target, struct file_stripe_info *finfo)
+{
+ if (finfo->coalesce)
+ return generate_file_coalesce(target, finfo);
+
+ return generate_file_traditional(target, finfo);
+}
+
+static void
+usage(char *name)
+{
+ fprintf(stderr, "Usage: %s [-o <outputfile>] <inputfile1> "
+ "<inputfile2> ...\n", name);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int file_count, opt;
+ char *opath = NULL;
+ int targetfd;
+ struct file_stripe_info *finfo;
+
+ while ((opt = getopt(argc, argv, "o:")) != -1) {
+ switch (opt) {
+ case 'o':
+ opath = optarg;
+ break;
+ default:
+ usage(argv[0]);
+ return -1;
+ }
+ }
+
+ file_count = argc - optind;
+
+ if (!opath || !file_count) {
+ usage(argv[0]);
+ return -1;
+ }
+
+ finfo = validate_and_open_files(&argv[optind], file_count);
+ if (!finfo)
+ goto err;
+
+ targetfd = open(opath, O_RDWR|O_CREAT, finfo->mode);
+ if (targetfd < 0)
+ goto err;
+
+ if (generate_file(targetfd, finfo) < 0)
+ goto err;
+
+ if (fsync(targetfd) < 0)
+ fprintf(stderr, "ERROR: %s\n", strerror(errno));
+ if (close(targetfd) < 0)
+ fprintf(stderr, "ERROR: %s\n", strerror(errno));
+
+ close_files(finfo);
+ free(finfo);
+
+ return 0;
+
+err:
+ if (finfo) {
+ close_files(finfo);
+ free(finfo);
+ }
+
+ return -1;
+}
+
diff --git a/extras/test/gluster_commands.sh b/extras/test/gluster_commands.sh
index 27acb1b4f..e1e396020 100755
--- a/extras/test/gluster_commands.sh
+++ b/extras/test/gluster_commands.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+# Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
# This file is part of GlusterFS.
# GlusterFS is free software; you can redistribute it and/or modify
diff --git a/extras/test/ld-preload-test/ld-preload-lib.c b/extras/test/ld-preload-test/ld-preload-lib.c
index 900d967a0..e17305a4a 100644
--- a/extras/test/ld-preload-test/ld-preload-lib.c
+++ b/extras/test/ld-preload-test/ld-preload-lib.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
diff --git a/extras/test/ld-preload-test/ld-preload-test.c b/extras/test/ld-preload-test/ld-preload-test.c
index b67dad23c..55dd98805 100644
--- a/extras/test/ld-preload-test/ld-preload-test.c
+++ b/extras/test/ld-preload-test/ld-preload-test.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
diff --git a/extras/test/open-fd-tests.c b/extras/test/open-fd-tests.c
new file mode 100644
index 000000000..4184079d0
--- /dev/null
+++ b/extras/test/open-fd-tests.c
@@ -0,0 +1,64 @@
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <attr/xattr.h>
+#include <errno.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+ int ret = -1;
+ int fd = 0;
+ char *filename = NULL;
+ int loop = 0;
+ struct stat stbuf = {0,};
+ char string[1024] = {0,};
+
+ if (argc > 1)
+ filename = argv[1];
+
+ if (!filename)
+ filename = "temp-fd-test-file";
+
+ fd = open (filename, O_RDWR|O_CREAT|O_TRUNC);
+ if (fd < 0) {
+ fd = 0;
+ fprintf (stderr, "open failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ while (loop < 1000) {
+ /* Use it as a mechanism to test time delays */
+ memset (string, 0, 1024);
+ scanf ("%s", string);
+
+ ret = write (fd, string, strlen (string));
+ if (ret != strlen (string)) {
+ fprintf (stderr, "write failed : %s (%s %d)\n",
+ strerror (errno), string, loop);
+ goto out;
+ }
+
+ ret = write (fd, "\n", 1);
+ if (ret != 1) {
+ fprintf (stderr, "write failed : %s (%d)\n",
+ strerror (errno), loop);
+ goto out;
+ }
+
+ loop++;
+ }
+
+ fprintf (stdout, "finishing the test after %d loops\n", loop);
+
+ ret = 0;
+out:
+ if (fd)
+ close (fd);
+
+ return ret;
+}
diff --git a/extras/test/run.sh b/extras/test/run.sh
index e014a1033..2440af237 100755
--- a/extras/test/run.sh
+++ b/extras/test/run.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+# Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
# This file is part of GlusterFS.
# GlusterFS is free software; you can redistribute it and/or modify
diff --git a/extras/test/stop_glusterd.sh b/extras/test/stop_glusterd.sh
index 7dfc8686c..a84689beb 100755
--- a/extras/test/stop_glusterd.sh
+++ b/extras/test/stop_glusterd.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+# Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
# This file is part of GlusterFS.
# GlusterFS is free software; you can redistribute it and/or modify
diff --git a/extras/test/test-ffop.c b/extras/test/test-ffop.c
new file mode 100644
index 000000000..2c47ab004
--- /dev/null
+++ b/extras/test/test-ffop.c
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <attr/xattr.h>
+#include <errno.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+ int ret = -1;
+ int fd = 0;
+ char *filename = NULL;
+ struct stat stbuf = {0,};
+
+ if (argc > 1)
+ filename = argv[1];
+
+ if (!filename)
+ filename = "temp-xattr-test-file";
+
+ fd = open (filename, O_RDWR|O_CREAT);
+ if (fd < 0) {
+ fd = 0;
+ fprintf (stderr, "open failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = unlink (filename);
+ if (ret < 0) {
+ fprintf (stderr, "unlink failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = ftruncate (fd, 0);
+ if (ret < 0) {
+ fprintf (stderr, "ftruncate failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = fstat (fd, &stbuf);
+ if (ret < 0) {
+ fprintf (stderr, "fstat failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = fchmod (fd, 0640);
+ if (ret < 0) {
+ fprintf (stderr, "fchmod failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = fchown (fd, 10001, 10001);
+ if (ret < 0) {
+ fprintf (stderr, "fchown failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = fsync (fd);
+ if (ret < 0) {
+ fprintf (stderr, "fsync failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = fsetxattr (fd, "trusted.xattr-test", "working", 8, 0);
+ if (ret < 0) {
+ fprintf (stderr, "fsetxattr failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = fdatasync (fd);
+ if (ret < 0) {
+ fprintf (stderr, "fdatasync failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = flistxattr (fd, NULL, 0);
+ if (ret <= 0) {
+ ret = -1;
+ fprintf (stderr, "flistxattr failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = fgetxattr (fd, "trusted.xattr-test", NULL, 0);
+ if (ret <= 0) {
+ ret = -1;
+ fprintf (stderr, "fgetxattr failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = fremovexattr (fd, "trusted.xattr-test");
+ if (ret < 0) {
+ fprintf (stderr, "fremovexattr failed : %s\n", strerror (errno));
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (fd)
+ close (fd);
+
+ return ret;
+}
diff --git a/format-patch.sh b/format-patch.sh
deleted file mode 100755
index e7cb4c7c1..000000000
--- a/format-patch.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/bash
-
-
-function is_num()
-{
- local num;
-
- num="$1";
-
- [ -z "$(echo $num | sed -e 's/[0-9]//g')" ]
-}
-
-
-function guess_branch()
-{
- local branch;
- local src_branch;
-
- branch=$(git branch | grep '*' | cut -f2 -d' ');
-
- if [ $branch = "master" ] ; then
- src_branch="master";
- else
- src_branch=$(cat .git/logs/refs/heads/$branch | head -n 1 \
- | sed -r -e 's/.*( [^ ]*)$/\1/g' | cut -f2 -d/);
- fi
-
- echo $src_branch
-}
-
-
-function main()
-{
- local branch;
- local bug;
-
- branch=$(guess_branch);
- echo
- echo "Patches are always to be associated with a bug ID. If there is no "
- echo "bug filed in bugzilla for this patch, it is highly suggested to file"
- echo "a new bug with a description and reasoning of this patchset. If this"
- echo "is a new feature, then file a new enhancement bug with a brief "
- echo "summary of the feature as the description."
- echo
- echo -n "Enter bug ID (from http://bugs.gluster.com/): "
- read bug;
-
- [ -z "$bug" ] || is_num $bug || {
- log "bug ID should be a valid bug number";
- exit;
- }
-
- if [ -z "$bug" ]; then
- git format-patch -s "$@";
- else
- git format-patch -s --subject-prefix="PATCH BRANCH:release-3.2 BUG:$bug" "$@";
- fi
-}
-
-main "$@"
diff --git a/glusterfs-hadoop/0.20.2/conf/core-site.xml b/glusterfs-hadoop/0.20.2/conf/core-site.xml
new file mode 100644
index 000000000..d7f75fca7
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/conf/core-site.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+
+<!-- Put site-specific property overrides in this file. -->
+
+<configuration>
+
+ <property>
+ <name>fs.glusterfs.impl</name>
+ <value>org.apache.hadoop.fs.glusterfs.GlusterFileSystem</value>
+ </property>
+
+ <property>
+ <name>fs.default.name</name>
+ <value>glusterfs://192.168.1.36:9000</value>
+ </property>
+
+ <property>
+ <name>fs.glusterfs.volname</name>
+ <value>volume-dist-rep</value>
+ </property>
+
+ <property>
+ <name>fs.glusterfs.mount</name>
+ <value>/mnt/glusterfs</value>
+ </property>
+
+ <property>
+ <name>fs.glusterfs.server</name>
+ <value>192.168.1.36</value>
+ </property>
+
+ <property>
+ <name>quick.slave.io</name>
+ <value>Off</value>
+ </property>
+
+</configuration>
diff --git a/glusterfs-hadoop/0.20.2/pom.xml b/glusterfs-hadoop/0.20.2/pom.xml
new file mode 100644
index 000000000..fe661d40f
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/pom.xml
@@ -0,0 +1,36 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.hadoop.fs.glusterfs</groupId>
+ <artifactId>glusterfs</artifactId>
+ <packaging>jar</packaging>
+ <version>0.20.2-0.1</version>
+ <name>glusterfs</name>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-core</artifactId>
+ <version>0.20.2</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickClass.java b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickClass.java
new file mode 100644
index 000000000..e633b8aae
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickClass.java
@@ -0,0 +1,109 @@
+/**
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of GlusterFS.
+ *
+ * Licensed under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+package org.apache.hadoop.fs.glusterfs;
+
+import java.io.*;
+
+public class GlusterFSBrickClass {
+ String host;
+ String exportedFile;
+ long start;
+ long end;
+ boolean isChunked;
+ int stripeSize; // Stripe size in bytes
+ int nrStripes; // number of stripes
+ int switchCount; // for SR, DSR - number of replicas of each stripe
+ // -1 for others
+
+ public GlusterFSBrickClass (String brick, long start, long len, boolean flag,
+ int stripeSize, int nrStripes, int switchCount)
+ throws IOException {
+ this.host = brick2host(brick);
+ this.exportedFile = brick2file(brick);
+ this.start = start;
+ this.end = start + len;
+ this.isChunked = flag;
+ this.stripeSize = stripeSize;
+ this.nrStripes = nrStripes;
+ this.switchCount = switchCount;
+ }
+
+ public boolean isChunked () {
+ return isChunked;
+ }
+
+ public String brickIsLocal(String hostname) {
+ String path = null;
+ File f = null;
+ if (host.equals(hostname))
+ path = exportedFile;
+
+ return path;
+ }
+
+ public int[] getBrickNumberInTree(long start, int len) {
+ long end = len;
+ int startNodeInTree = ((int) (start / stripeSize)) % nrStripes;
+ int endNodeInTree = ((int) ((start + len) / stripeSize)) % nrStripes;
+
+ if (startNodeInTree != endNodeInTree) {
+ end = (start - (start % stripeSize)) + stripeSize;
+ end -= start;
+ }
+
+ return new int[] {startNodeInTree, endNodeInTree, (int) end};
+ }
+
+ public boolean brickHasFilePart(int nodeInTree, int nodeLoc) {
+ if (switchCount == -1)
+ return (nodeInTree == nodeLoc);
+
+ nodeInTree *= switchCount;
+ for (int i = nodeInTree; i < (nodeInTree + switchCount); i++) {
+ if (i == nodeLoc)
+ return true;
+ }
+
+ return false;
+ }
+
+ public String brick2host (String brick)
+ throws IOException {
+ String[] hf = null;
+
+ hf = brick.split(":");
+ if (hf.length != 2)
+ throw new IOException("Error getting hostname from brick");
+
+ return hf[0];
+ }
+
+ public String brick2file (String brick)
+ throws IOException {
+ String[] hf = null;
+
+ hf = brick.split(":");
+ if (hf.length != 2)
+ throw new IOException("Error getting hostname from brick");
+
+ return hf[1];
+ }
+
+}
diff --git a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickRepl.java b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickRepl.java
new file mode 100644
index 000000000..11454e636
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickRepl.java
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of GlusterFS.
+ *
+ * Licensed under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+package org.apache.hadoop.fs.glusterfs;
+
+import java.io.*;
+
+public class GlusterFSBrickRepl {
+ private String[] replHost;
+ private long start;
+ private long len;
+ private int cnt;
+
+ GlusterFSBrickRepl(int replCount, long start, long len) {
+ this.replHost = new String[replCount];
+ this.start = start;
+ this.len = len;
+ this.cnt = 0;
+ }
+
+ public void addHost (String host) {
+ this.replHost[cnt++] = host;
+ }
+
+ public String[] getReplHosts () {
+ return this.replHost;
+ }
+
+ public long getStartLen () {
+ return this.start;
+ }
+
+ public long getOffLen () {
+ return this.len;
+ }
+}
diff --git a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSXattr.java b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSXattr.java
new file mode 100644
index 000000000..455dda97e
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSXattr.java
@@ -0,0 +1,472 @@
+/**
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of GlusterFS.
+ *
+ * Licensed under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+package org.apache.hadoop.fs.glusterfs;
+
+import java.net.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.io.*;
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.hadoop.fs.BlockLocation;
+
+public class GlusterFSXattr {
+
+ public enum LAYOUT { D, S, R, DS, DR, SR, DSR }
+ public enum CMD { GET_HINTS, GET_REPLICATION, GET_BLOCK_SIZE, CHECK_FOR_QUICK_IO }
+
+ private static String hostname;
+
+ public GlusterFSXattr() { }
+
+ public static String brick2host (String brick)
+ throws IOException {
+ String[] hf = null;
+
+ hf = brick.split(":");
+ if (hf.length != 2) {
+ System.out.println("brick not of format hostname:path");
+ throw new IOException("Error getting hostname from brick");
+ }
+
+ return hf[0];
+ }
+
+ public static String brick2file (String brick)
+ throws IOException {
+ String[] hf = null;
+
+ hf = brick.split(":");
+ if (hf.length != 2) {
+ System.out.println("brick not of format hostname:path");
+ throw new IOException("Error getting hostname from brick");
+ }
+
+ return hf[1];
+ }
+
+ public static BlockLocation[] getPathInfo (String filename, long start, long len)
+ throws IOException {
+ HashMap<String, ArrayList<String>> vol = null;
+ HashMap<String, Integer> meta = new HashMap<String, Integer>();
+
+ vol = execGetFattr(filename, meta, CMD.GET_HINTS);
+
+ return getHints(vol, meta, start, len, null);
+ }
+
+ public static long getBlockSize (String filename)
+ throws IOException {
+ HashMap<String, ArrayList<String>> vol = null;
+ HashMap<String, Integer> meta = new HashMap<String, Integer>();
+
+ vol = execGetFattr(filename, meta, CMD.GET_BLOCK_SIZE);
+
+ if (!meta.containsKey("block-size"))
+ return 0;
+
+ return (long) meta.get("block-size");
+
+ }
+
+ public static short getReplication (String filename)
+ throws IOException {
+ HashMap<String, ArrayList<String>> vol = null;
+ HashMap<String, Integer> meta = new HashMap<String, Integer>();
+
+ vol = execGetFattr(filename, meta, CMD.GET_REPLICATION);
+
+ return (short) getReplicationFromLayout(vol, meta);
+
+ }
+
+ public static TreeMap<Integer, GlusterFSBrickClass> quickIOPossible (String filename, long start,
+ long len)
+ throws IOException {
+ String realpath = null;
+ HashMap<String, ArrayList<String>> vol = null;
+ HashMap<String, Integer> meta = new HashMap<String, Integer>();
+ TreeMap<Integer, GlusterFSBrickClass> hnts = new TreeMap<Integer, GlusterFSBrickClass>();
+
+ vol = execGetFattr(filename, meta, CMD.GET_HINTS);
+ getHints(vol, meta, start, len, hnts);
+
+ if (hnts.size() == 0)
+ return null; // BOOM !!
+
+ // DEBUG - dump hnts here
+ return hnts;
+ }
+
+ public static HashMap<String, ArrayList<String>> execGetFattr (String filename,
+ HashMap<String, Integer> meta,
+ CMD cmd)
+ throws IOException {
+ Process p = null;
+ BufferedReader brInput = null;
+ String s = null;
+ String cmdOut = null;
+ String getfattrCmd = null;
+ String xlator = null;
+ String enclosingXl = null;
+ String enclosingXlVol = null;
+ String key = null;
+ String layout = "";
+ int rcount = 0;
+ int scount = 0;
+ int dcount = 0;
+ int count = 0;
+
+ HashMap<String, ArrayList<String>> vol = new HashMap<String, ArrayList<String>>();
+
+ getfattrCmd = "getfattr -m . -n trusted.glusterfs.pathinfo " + filename;
+
+ p = Runtime.getRuntime().exec(getfattrCmd);
+ brInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
+
+ cmdOut = "";
+ while ( (s = brInput.readLine()) != null )
+ cmdOut += s;
+
+ /**
+ * TODO: Use a single regex for extracting posix paths as well
+ * as xlator counts for layout matching.
+ */
+
+ Pattern pattern = Pattern.compile("<(.*?)[:\\(](.*?)>");
+ Matcher matcher = pattern.matcher(cmdOut);
+
+ Pattern p_px = Pattern.compile(".*?:(.*)");
+ Matcher m_px;
+ String gibberish_path;
+
+ s = null;
+ while (matcher.find()) {
+ xlator = matcher.group(1);
+ if (xlator.equalsIgnoreCase("posix")) {
+ if (enclosingXl.equalsIgnoreCase("replicate"))
+ count = rcount;
+ else if (enclosingXl.equalsIgnoreCase("stripe"))
+ count = scount;
+ else if (enclosingXl.equalsIgnoreCase("distribute"))
+ count = dcount;
+ else
+ throw new IOException("Unknown Translator: " + enclosingXl);
+
+ key = enclosingXl + "-" + count;
+
+ if (vol.get(key) == null)
+ vol.put(key, new ArrayList<String>());
+
+ gibberish_path = matcher.group(2);
+
+ /* extract posix path from the gibberish string */
+ m_px = p_px.matcher(gibberish_path);
+ if (!m_px.find())
+ throw new IOException("Cannot extract posix path");
+
+ vol.get(key).add(m_px.group(1));
+ continue;
+ }
+
+ enclosingXl = xlator;
+ enclosingXlVol = matcher.group(2);
+
+ if (xlator.equalsIgnoreCase("replicate"))
+ if (rcount++ != 0)
+ continue;
+
+ if (xlator.equalsIgnoreCase("stripe")) {
+ if (scount++ != 0)
+ continue;
+
+
+ Pattern ps = Pattern.compile("\\[(\\d+)\\]");
+ Matcher ms = ps.matcher(enclosingXlVol);
+
+ if (ms.find()) {
+ if (((cmd == CMD.GET_BLOCK_SIZE) || (cmd == CMD.GET_HINTS))
+ && (meta != null))
+ meta.put("block-size", Integer.parseInt(ms.group(1)));
+ } else
+ throw new IOException("Cannot get stripe size");
+ }
+
+ if (xlator.equalsIgnoreCase("distribute"))
+ if (dcount++ != 0)
+ continue;
+
+ layout += xlator.substring(0, 1);
+ }
+
+ if ((dcount == 0) && (scount == 0) && (rcount == 0))
+ throw new IOException("Cannot get layout");
+
+ if (meta != null) {
+ meta.put("dcount", dcount);
+ meta.put("scount", scount);
+ meta.put("rcount", rcount);
+ }
+
+ vol.put("layout", new ArrayList<String>(1));
+ vol.get("layout").add(layout);
+
+ return vol;
+ }
+
+ static BlockLocation[] getHints (HashMap<String, ArrayList<String>> vol,
+ HashMap<String, Integer> meta,
+ long start, long len,
+ TreeMap<Integer, GlusterFSBrickClass> hnts)
+ throws IOException {
+ String brick = null;
+ String key = null;
+ boolean done = false;
+ int i = 0;
+ int counter = 0;
+ int stripeSize = 0;
+ long stripeStart = 0;
+ long stripeEnd = 0;
+ int nrAllocs = 0;
+ int allocCtr = 0;
+ BlockLocation[] result = null;
+ ArrayList<String> brickList = null;
+ ArrayList<String> stripedBricks = null;
+ Iterator<String> it = null;
+
+ String[] blks = null;
+ GlusterFSBrickRepl[] repl = null;
+ int dcount, scount, rcount;
+
+ LAYOUT l = LAYOUT.valueOf(vol.get("layout").get(0));
+ dcount = meta.get("dcount");
+ scount = meta.get("scount");
+ rcount = meta.get("rcount");
+
+ switch (l) {
+ case D:
+ key = "DISTRIBUTE-" + dcount;
+ brick = vol.get(key).get(0);
+
+ if (hnts == null) {
+ result = new BlockLocation[1];
+ result[0] = new BlockLocation(null, new String[] {brick2host(brick)}, start, len);
+ } else
+ hnts.put(0, new GlusterFSBrickClass(brick, start, len, false, -1, -1, -1));
+ break;
+
+ case R:
+ case DR:
+ /* just the name says it's striped - the volume isn't */
+ stripedBricks = new ArrayList<String>();
+
+ for (i = 1; i <= rcount; i++) {
+ key = "REPLICATE-" + i;
+ brickList = vol.get(key);
+ it = brickList.iterator();
+ while (it.hasNext()) {
+ stripedBricks.add(it.next());
+ }
+ }
+
+ nrAllocs = stripedBricks.size();
+ if (hnts == null) {
+ result = new BlockLocation[1];
+ blks = new String[nrAllocs];
+ }
+
+ for (i = 0; i < nrAllocs; i++) {
+ if (hnts == null)
+ blks[i] = brick2host(stripedBricks.get(i));
+ else
+ hnts.put(i, new GlusterFSBrickClass(stripedBricks.get(i), start, len, false, -1, -1, -1));
+ }
+
+ if (hnts == null)
+ result[0] = new BlockLocation(null, blks, start, len);
+
+ break;
+
+ case SR:
+ case DSR:
+ int rsize = 0;
+ ArrayList<ArrayList<String>> replicas = new ArrayList<ArrayList<String>>();
+
+ stripedBricks = new ArrayList<String>();
+
+ if (rcount == 0)
+ throw new IOException("got replicated volume with replication count 0");
+
+ for (i = 1; i <= rcount; i++) {
+ key = "REPLICATE-" + i;
+ brickList = vol.get(key);
+ it = brickList.iterator();
+ replicas.add(i - 1, new ArrayList<String>());
+ while (it.hasNext()) {
+ replicas.get(i - 1).add(it.next());
+ }
+ }
+
+ stripeSize = meta.get("block-size");
+
+ nrAllocs = (int) (((len - start) / stripeSize) + 1);
+ if (hnts == null) {
+ result = new BlockLocation[nrAllocs];
+ repl = new GlusterFSBrickRepl[nrAllocs];
+ }
+
+ // starting stripe position
+ counter = (int) ((start / stripeSize) % rcount);
+ stripeStart = start;
+
+ key = null;
+ int currAlloc = 0;
+ boolean hntsDone = false;
+ while ((stripeStart < len) && !done) {
+ stripeEnd = (stripeStart - (stripeStart % stripeSize)) + stripeSize - 1;
+ if (stripeEnd > start + len) {
+ stripeEnd = start + len - 1;
+ done = true;
+ }
+
+ rsize = replicas.get(counter).size();
+
+ if (hnts == null)
+ repl[allocCtr] = new GlusterFSBrickRepl(rsize, stripeStart, (stripeEnd - stripeStart));
+
+ for (i = 0; i < rsize; i++) {
+ brick = replicas.get(counter).get(i);
+ currAlloc = (allocCtr * rsize) + i;
+
+ if (hnts == null)
+ repl[allocCtr].addHost(brick2host(brick));
+ else
+ if (currAlloc <= (rsize * rcount) - 1) {
+ hnts.put(currAlloc, new GlusterFSBrickClass(brick, stripeStart,
+ (stripeEnd - stripeStart),
+ true, stripeSize, rcount, rsize));
+ } else
+ hntsDone = true;
+ }
+
+ if (hntsDone)
+ break;
+
+ stripeStart = stripeEnd + 1;
+
+ allocCtr++;
+ counter++;
+
+ if (counter >= replicas.size())
+ counter = 0;
+ }
+
+ if (hnts == null)
+ for (int k = 0; k < nrAllocs; k++)
+ result[k] = new BlockLocation(null, repl[k].getReplHosts(), repl[k].getStartLen(), repl[k].getOffLen());
+
+ break;
+
+ case S:
+ case DS:
+ if (scount == 0)
+ throw new IOException("got striped volume with stripe count 0");
+
+ stripedBricks = new ArrayList<String>();
+ stripeSize = meta.get("block-size");
+
+ key = "STRIPE-" + scount;
+ brickList = vol.get(key);
+ it = brickList.iterator();
+ while (it.hasNext()) {
+ stripedBricks.add(it.next());
+ }
+
+ nrAllocs = (int) ((len - start) / stripeSize) + 1;
+ if (hnts == null)
+ result = new BlockLocation[nrAllocs];
+
+ // starting stripe position
+ counter = (int) ((start / stripeSize) % stripedBricks.size());
+ stripeStart = start;
+
+ key = null;
+ while ((stripeStart < len) && !done) {
+ brick = stripedBricks.get(counter);
+
+ stripeEnd = (stripeStart - (stripeStart % stripeSize)) + stripeSize - 1;
+ if (stripeEnd > start + len) {
+ stripeEnd = start + len - 1;
+ done = true;
+ }
+
+ if (hnts == null)
+ result[allocCtr] = new BlockLocation(null, new String[] {brick2host(brick)},
+ stripeStart, (stripeEnd - stripeStart));
+ else
+ if (allocCtr <= stripedBricks.size()) {
+ hnts.put(allocCtr, new GlusterFSBrickClass(brick, stripeStart, (stripeEnd - stripeStart),
+ true, stripeSize, stripedBricks.size(), -1));
+ } else
+ break;
+
+ stripeStart = stripeEnd + 1;
+
+ counter++;
+ allocCtr++;
+
+ if (counter >= stripedBricks.size())
+ counter = 0;
+ }
+
+ break;
+ }
+
+ return result;
+ }
+
+ /* TODO: use meta{dcount,scount,rcount} for checking */
+ public static int getReplicationFromLayout (HashMap<String, ArrayList<String>> vol,
+ HashMap<String, Integer> meta)
+ throws IOException {
+ int replication = 0;
+ LAYOUT l = LAYOUT.valueOf(vol.get("layout").get(0));
+
+ switch (l) {
+ case D:
+ case S:
+ case DS:
+ replication = 1;
+ break;
+
+ case R:
+ case DR:
+ case SR:
+ case DSR:
+ final String key = "REPLICATION-1";
+ replication = vol.get(key).size();
+ }
+
+ return replication;
+ }
+}
diff --git a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEInputStream.java b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEInputStream.java
new file mode 100644
index 000000000..e92237aee
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEInputStream.java
@@ -0,0 +1,205 @@
+/**
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of GlusterFS.
+ *
+ * Licensed under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+package org.apache.hadoop.fs.glusterfs;
+
+import java.io.*;
+import java.util.TreeMap;
+
+import org.apache.hadoop.fs.FSInputStream;
+import org.apache.hadoop.fs.FileSystem;
+
+
+public class GlusterFUSEInputStream extends FSInputStream {
+ File f;
+ boolean lastActive;
+ long pos;
+ boolean closed;
+ String thisHost;
+ RandomAccessFile fuseInputStream;
+ RandomAccessFile fsInputStream;
+ GlusterFSBrickClass thisBrick;
+ int nodeLocation;
+ TreeMap<Integer, GlusterFSBrickClass> hnts;
+
+ public GlusterFUSEInputStream (File f, TreeMap<Integer, GlusterFSBrickClass> hnts,
+ String hostname) throws IOException {
+ this.f = f;
+ this.pos = 0;
+ this.closed = false;
+ this.hnts = hnts;
+ this.thisHost = hostname;
+ this.fsInputStream = null;
+ this.fuseInputStream = new RandomAccessFile(f.getPath(), "r");
+
+ this.lastActive = true; // true == FUSE, false == backed file
+
+ String directFilePath = null;
+ if (this.hnts != null) {
+ directFilePath = findLocalFile(f.getPath(), this.hnts);
+ if (directFilePath != null) {
+ this.fsInputStream = new RandomAccessFile(directFilePath, "r");
+ this.lastActive = !this.lastActive;
+ }
+ }
+ }
+
+ public String findLocalFile (String path, TreeMap<Integer, GlusterFSBrickClass> hnts) {
+ int i = 0;
+ String actFilePath = null;
+ GlusterFSBrickClass gfsBrick = null;
+
+ gfsBrick = hnts.get(0);
+
+ /* do a linear search for the matching host not worrying
+ about file stripes */
+ for (i = 0; i < hnts.size(); i++) {
+ gfsBrick = hnts.get(i);
+ actFilePath = gfsBrick.brickIsLocal(this.thisHost);
+ if (actFilePath != null) {
+ this.thisBrick = gfsBrick;
+ this.nodeLocation = i;
+ break;
+ }
+ }
+
+ return actFilePath;
+ }
+
+ public long getPos () throws IOException {
+ return pos;
+ }
+
+ public synchronized int available () throws IOException {
+ return (int) ((f.length()) - getPos());
+ }
+
+ public void seek (long pos) throws IOException {
+ fuseInputStream.seek(pos);
+ if (fsInputStream != null)
+ fsInputStream.seek(pos);
+ }
+
+ public boolean seekToNewSource (long pos) throws IOException {
+ return false;
+ }
+
+ public RandomAccessFile chooseStream (long start, int[] nlen)
+ throws IOException {
+ GlusterFSBrickClass gfsBrick = null;
+ RandomAccessFile in = fuseInputStream;
+ boolean oldActiveStream = lastActive;
+ lastActive = true;
+
+ if ((hnts != null) && (fsInputStream != null)) {
+ gfsBrick = hnts.get(0);
+ if (!gfsBrick.isChunked()) {
+ in = fsInputStream;
+ lastActive = false;
+ } else {
+ // find the current location in the tree and the amount of data it can serve
+ int[] nodeInTree = thisBrick.getBrickNumberInTree(start, nlen[0]);
+
+ // does this node hold the byte ranges we have been requested for ?
+ if ((nodeInTree[2] != 0) && thisBrick.brickHasFilePart(nodeInTree[0], nodeLocation)) {
+ in = fsInputStream;
+ nlen[0] = nodeInTree[2]; // the amount of data that can be read from the stripe
+ lastActive = false;
+ }
+ }
+ }
+
+ return in;
+ }
+
+ public synchronized int read () throws IOException {
+ int byteRead = 0;
+ RandomAccessFile in = null;
+
+ if (closed)
+ throw new IOException("Stream Closed.");
+
+ int[] nlen = { 1 };
+
+ in = chooseStream(getPos(), nlen);
+
+ byteRead = in.read();
+ if (byteRead >= 0) {
+ pos++;
+ syncStreams(1);
+ }
+
+ return byteRead;
+ }
+
+ public synchronized int read (byte buff[], int off, int len) throws
+ IOException {
+ int result = 0;
+ RandomAccessFile in = null;
+
+ if (closed)
+ throw new IOException("Stream Closed.");
+
+ int[] nlen = {len}; // hack to make len mutable
+ in = chooseStream(pos, nlen);
+
+ result = in.read(buff, off, nlen[0]);
+ if (result > 0) {
+ pos += result;
+ syncStreams(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * TODO: use seek() insted of skipBytes(); skipBytes does I/O
+ */
+ public void syncStreams (int bytes) throws IOException {
+ if ((hnts != null) && (hnts.get(0).isChunked()) && (fsInputStream != null))
+ if (!this.lastActive)
+ fuseInputStream.skipBytes(bytes);
+ else
+ fsInputStream.skipBytes(bytes);
+ }
+
+ public synchronized void close () throws IOException {
+ if (closed)
+ throw new IOException("Stream closed.");
+
+ super.close();
+ if (fsInputStream != null)
+ fsInputStream.close();
+ fuseInputStream.close();
+
+ closed = true;
+ }
+
+ // Not supported - mark () and reset ()
+
+ public boolean markSupported () {
+ return false;
+ }
+
+ public void mark (int readLimit) {}
+
+ public void reset () throws IOException {
+ throw new IOException("Mark/Reset not supported.");
+ }
+}
diff --git a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEOutputStream.java b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEOutputStream.java
new file mode 100644
index 000000000..5192a0a56
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEOutputStream.java
@@ -0,0 +1,86 @@
+/**
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of GlusterFS.
+ *
+ * Licensed under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+package org.apache.hadoop.fs.glusterfs;
+
+import java.io.*;
+
+import org.apache.hadoop.fs.FSOutputSummer;
+import org.apache.hadoop.fs.FileSystem;
+
+public class GlusterFUSEOutputStream extends OutputStream {
+ File f;
+ long pos;
+ boolean closed;
+ OutputStream fuseOutputStream;
+
+ public GlusterFUSEOutputStream (String file, boolean append) throws
+ IOException {
+ this.f = new File(file); /* not needed ? */
+ this.pos = 0;
+ this.fuseOutputStream = new FileOutputStream(file, append);
+ this.closed = false;
+ }
+
+ public long getPos () throws IOException {
+ return pos;
+ }
+
+ public void write (int v) throws IOException {
+ if (closed)
+ throw new IOException("Stream closed.");
+
+ byte[] b = new byte[1];
+ b[0] = (byte) v;
+
+ write(b, 0, 1);
+ }
+
+ public void write (byte b[]) throws IOException {
+ if (closed)
+ throw new IOException("Stream closed.");
+
+ fuseOutputStream.write(b, 0, b.length);
+ pos += (long) b.length;
+ }
+
+ public void write (byte b[], int off, int len) throws IOException {
+ if (closed)
+ throw new IOException("Stream closed.");
+
+ fuseOutputStream.write(b, off, len);
+ pos += (long) len;
+ }
+
+ public void flush () throws IOException {
+ if (closed)
+ throw new IOException("Stream closed.");
+
+ fuseOutputStream.flush();
+ }
+
+ public void close () throws IOException {
+ if (closed)
+ throw new IOException("Stream closed.");
+
+ flush();
+ fuseOutputStream.close();
+ closed = true;
+ }
+}
diff --git a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFileSystem.java b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFileSystem.java
new file mode 100644
index 000000000..b0501cced
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFileSystem.java
@@ -0,0 +1,492 @@
+/**
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of GlusterFS.
+ *
+ * Licensed under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+/**
+ * Implements the Hadoop FileSystem Interface to allow applications to store
+ * files on GlusterFS and run Map/Reduce jobs on the data.
+ */
+
+package org.apache.hadoop.fs.glusterfs;
+
+import java.io.*;
+import java.net.*;
+
+import java.util.regex.*;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.BlockLocation;
+import org.apache.hadoop.fs.permission.FsPermission;
+import org.apache.hadoop.util.Progressable;
+
+import java.util.TreeMap;
+
+/*
+ * This package provides interface for hadoop jobs (incl. Map/Reduce)
+ * to access files in GlusterFS backed file system via FUSE mount
+ */
+public class GlusterFileSystem extends FileSystem {
+
+ private FileSystem glusterFs = null;
+ private URI uri = null;
+ private Path workingDir = null;
+ private String glusterMount = null;
+ private boolean mounted = false;
+
+ /* for quick IO */
+ private boolean quickSlaveIO = false;
+
+ /* extended attribute class */
+ private GlusterFSXattr xattr = null;
+
+ /* hostname of this machine */
+ private static String hostname;
+
+ public GlusterFileSystem () {
+
+ }
+
+ public URI getUri () {
+ return uri;
+ }
+
+ public boolean FUSEMount (String volname, String server, String mount)
+ throws IOException, InterruptedException {
+ boolean ret = true;
+ int retVal = 0;
+ Process p = null;
+ String s = null;
+ String mountCmd = null;
+
+ mountCmd = "mount -t glusterfs " + server + ":" + "/" + volname + " " + mount;
+
+ try {
+ p = Runtime.getRuntime().exec(mountCmd);
+
+ retVal = p.waitFor();
+ if (retVal != 0)
+ ret = false;
+
+ } catch (IOException e) {
+ System.out.println ("Problem mounting FUSE mount on: " + mount);
+ e.printStackTrace();
+ System.exit(-1);
+ }
+
+ return ret;
+ }
+
+ public void initialize (URI uri, Configuration conf) throws IOException {
+ boolean ret = false;
+ String volName = null;
+ String remoteGFSServer = null;
+ String needQuickRead = null;
+
+ if (this.mounted)
+ return;
+
+ System.out.println("Initializing GlusterFS");
+
+ try {
+ volName = conf.get("fs.glusterfs.volname", "");
+ glusterMount = conf.get("fs.glusterfs.mount", "");
+ remoteGFSServer = conf.get("fs.glusterfs.server", "");
+ needQuickRead = conf.get("quick.slave.io", "");
+
+ /*
+ * bail out if we do not have enough information to do a FUSE
+ * mount
+ */
+ if ( (volName.length() == 0) || (remoteGFSServer.length() == 0) ||
+ (glusterMount.length() == 0) )
+ System.exit (-1);
+
+ ret = FUSEMount(volName, remoteGFSServer, glusterMount);
+ if (!ret) {
+ System.out.println("Failed to initialize GlusterFS");
+ System.exit(-1);
+ }
+
+ if ((needQuickRead.length() != 0)
+ && (needQuickRead.equalsIgnoreCase("yes")
+ || needQuickRead.equalsIgnoreCase("on")
+ || needQuickRead.equals("1")))
+ this.quickSlaveIO = true;
+
+ this.mounted = true;
+ this.glusterFs = FileSystem.getLocal(conf);
+ this.workingDir = new Path(glusterMount);
+ this.uri = URI.create(uri.getScheme() + "://" + uri.getAuthority());
+
+ this.xattr = new GlusterFSXattr();
+
+ InetAddress addr = InetAddress.getLocalHost();
+ this.hostname = addr.getHostName();
+
+ setConf(conf);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Unable to initialize GlusterFS");
+ System.exit(-1);
+ }
+ }
+
+ @Deprecated
+ public String getName () {
+ return getUri().toString();
+ }
+
+ public Path getWorkingDirectory () {
+ return this.workingDir;
+ }
+
+ public Path getHomeDirectory () {
+ return this.workingDir;
+ }
+
+ public Path makeAbsolute (Path path) {
+ String pth = path.toUri().getPath();
+ if (pth.startsWith(workingDir.toUri().getPath())) {
+ return path;
+ }
+
+ return new Path(workingDir + "/" + pth);
+ }
+
+ public void setWorkingDirectory (Path dir) {
+ this.workingDir = makeAbsolute(dir);
+ }
+
+ public boolean exists (Path path) throws IOException {
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+
+ return f.exists();
+ }
+
+ public boolean mkdirs (Path path, FsPermission permission
+ ) throws IOException {
+ boolean created = false;
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+
+ if (f.exists()) {
+ System.out.println("Directory " + f.getPath() + " already exist");
+ return true;
+ }
+
+ return f.mkdirs();
+ }
+
+ @Deprecated
+ public boolean isDirectory (Path path) throws IOException {
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+
+ return f.isDirectory();
+ }
+
+ public boolean isFile (Path path) throws IOException {
+ return !isDirectory(path);
+ }
+
+ public Path[] listPaths (Path path) throws IOException {
+ Path absolute = makeAbsolute(path);
+ File f = new File (absolute.toUri().getPath());
+ String relPath = path.toUri().getPath();
+ String[] fileList = null;
+ Path[] filePath = null;
+ int fileCnt = 0;
+
+ fileList = f.list();
+
+ filePath = new Path[fileList.length];
+
+ for (; fileCnt < fileList.length; fileCnt++) {
+ filePath[fileCnt] = new Path(relPath + "/" + fileList[fileCnt]);
+ }
+
+ return filePath;
+ }
+
+ public FileStatus[] listStatus (Path path) throws IOException {
+ int fileCnt = 0;
+ Path absolute = makeAbsolute(path);
+ String relpath = path.toUri().getPath();
+ String[] strFileList = null;
+ FileStatus[] fileStatus = null;
+ File f = new File(absolute.toUri().getPath());
+
+ if (!f.exists()) {
+ return null;
+ }
+
+ if (f.isFile())
+ return new FileStatus[] {
+ getFileStatus(path)
+ };
+
+ if (relpath.charAt(relpath.length() - 1) != '/')
+ relpath += "/";
+
+ strFileList = f.list();
+
+ fileStatus = new FileStatus[strFileList.length];
+
+ for (; fileCnt < strFileList.length; fileCnt++) {
+ fileStatus[fileCnt] = getFileStatusFromFileString(relpath + strFileList[fileCnt]);
+ }
+
+ return fileStatus;
+ }
+
+ public FileStatus getFileStatusFromFileString (String path)
+ throws IOException {
+ Path nPath = new Path(path);
+ return getFileStatus(nPath);
+ }
+
+ public FileStatus getFileStatus (Path path) throws IOException {
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+
+ if (!f.exists ())
+ throw new FileNotFoundException("File " + f.getPath() + " does not exist.");
+
+ if (f.isDirectory ())
+ return new FileStatus(0, true, 1, 0, f.lastModified(), path.makeQualified(this));
+ else
+ return new FileStatus(f.length(), false, 0, getDefaultBlockSize(),
+ f.lastModified(), path.makeQualified(this));
+
+ }
+
+ /*
+ * creates a new file in glusterfs namespace. internally the file
+ * descriptor is an instance of OutputStream class.
+ */
+ public FSDataOutputStream create (Path path, FsPermission permission,
+ boolean overwrite, int bufferSize,
+ short replication, long blockSize,
+ Progressable progress)
+ throws IOException {
+ Path absolute = makeAbsolute(path);
+ Path parent = null;
+ File f = null;
+ File fParent = null;
+ FSDataOutputStream glusterFileStream = null;
+
+ f = new File(absolute.toUri().getPath());
+
+ if (f.exists ()) {
+ if (overwrite)
+ f.delete ();
+ else
+ throw new IOException(f.getPath() + " already exist");
+ }
+
+ parent = path.getParent();
+ fParent = new File ((makeAbsolute(parent)).toUri().getPath());
+ if ((parent != null) && (fParent != null) && (!fParent.exists()))
+ if (!fParent.mkdirs())
+ throw new IOException("cannot create parent directory: " + fParent.getPath());
+
+ glusterFileStream = new FSDataOutputStream(new GlusterFUSEOutputStream
+ (f.getPath(), false));
+
+ return glusterFileStream;
+ }
+
+ /*
+ * open the file in read mode (internally the file descriptor is an
+ * instance of InputStream class).
+ *
+ * if quick read mode is set then read the file by by-passing FUSE
+ * if we are on same slave where the file exist
+ */
+ public FSDataInputStream open (Path path) throws IOException {
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+ FSDataInputStream glusterFileStream = null;
+ TreeMap<Integer, GlusterFSBrickClass> hnts = null;
+
+ if (!f.exists())
+ throw new IOException("File " + f.getPath() + " does not exist.");
+
+ if (quickSlaveIO)
+ hnts = xattr.quickIOPossible(f.getPath(), 0, f.length());
+
+ glusterFileStream = new FSDataInputStream(new GlusterFUSEInputStream(f, hnts, hostname));
+ return glusterFileStream;
+ }
+
+ public FSDataInputStream open (Path path, int bufferSize) throws IOException {
+ return open(path);
+ }
+
+ public FSDataOutputStream append (Path f, int bufferSize, Progressable progress)
+ throws IOException {
+ throw new IOException ("append not supported (as yet).");
+ }
+
+ public boolean rename (Path src, Path dst) throws IOException {
+ Path absoluteSrc = makeAbsolute(src);
+ Path absoluteDst = makeAbsolute(dst);
+
+ File fSrc = new File(absoluteSrc.toUri().getPath());
+ File fDst = new File(absoluteDst.toUri().getPath());
+
+ if (fDst.isDirectory()) {
+ fDst = null;
+ String newPath = absoluteDst.toUri().getPath() + "/" + fSrc.getName();
+ fDst = new File(newPath);
+ }
+ return fSrc.renameTo(fDst);
+ }
+
+ @Deprecated
+ public boolean delete (Path path) throws IOException {
+ return delete(path, true);
+ }
+
+ public boolean delete (Path path, boolean recursive) throws IOException {
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+
+ if (f.isFile())
+ return f.delete();
+
+ FileStatus[] dirEntries = listStatus(absolute);
+ if ((!recursive) && (dirEntries != null) && (dirEntries.length != 0))
+ throw new IOException ("Directory " + path.toString() + " is not empty");
+
+ if (dirEntries != null)
+ for (int i = 0; i < dirEntries.length; i++)
+ delete(new Path(absolute, dirEntries[i].getPath()), recursive);
+
+ return f.delete();
+ }
+
+ @Deprecated
+ public long getLength (Path path) throws IOException {
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+
+ if (!f.exists())
+ throw new IOException(f.getPath() + " does not exist.");
+
+ return f.length();
+ }
+
+ @Deprecated
+ public short getReplication (Path path) throws IOException {
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+
+ if (!f.exists())
+ throw new IOException(f.getPath() + " does not exist.");
+
+ return xattr.getReplication(f.getPath());
+ }
+
+ public short getDefaultReplication (Path path) throws IOException {
+ return getReplication(path);
+ }
+
+ public boolean setReplication (Path path, short replication)
+ throws IOException {
+ return true;
+ }
+
+ public long getBlockSize (Path path) throws IOException {
+ long blkSz;
+ Path absolute = makeAbsolute(path);
+ File f = new File(absolute.toUri().getPath());
+
+ blkSz = xattr.getBlockSize(f.getPath());
+ if (blkSz == 0)
+ blkSz = getLength(path);
+
+ return blkSz;
+ }
+
+ public long getDefaultBlockSize () {
+ return 1 << 26; /* default's from hdfs, kfs */
+ }
+
+ @Deprecated
+ public void lock (Path path, boolean shared) throws IOException {
+ }
+
+ @Deprecated
+ public void release (Path path) throws IOException {
+ }
+
+ public BlockLocation[] getFileBlockLocations (FileStatus file, long start, long len)
+ throws IOException {
+
+ Path absolute = makeAbsolute(file.getPath());
+ File f = new File(absolute.toUri().getPath());
+ BlockLocation[] result = null;
+
+ if (file == null)
+ return null;
+
+ result = xattr.getPathInfo(f.getPath(), start, len);
+ if (result == null) {
+ System.out.println("Problem getting destination host for file "
+ + f.getPath());
+ return null;
+ }
+
+ return result;
+ }
+
+ // getFileBlockLocations (FileStatus, long, long) is called by hadoop
+ public BlockLocation[] getFileBlockLocations (Path p, long start, long len)
+ throws IOException {
+ return null;
+ }
+
+ public void copyFromLocalFile (boolean delSrc, Path src, Path dst)
+ throws IOException {
+ FileUtil.copy(glusterFs, src, this, dst, delSrc, getConf());
+ }
+
+ public void copyToLocalFile (boolean delSrc, Path src, Path dst)
+ throws IOException {
+ FileUtil.copy(this, src, glusterFs, dst, delSrc, getConf());
+ }
+
+ public Path startLocalOutput (Path fsOutputFile, Path tmpLocalFile)
+ throws IOException {
+ return tmpLocalFile;
+ }
+
+ public void completeLocalOutput (Path fsOutputFile, Path tmpLocalFile)
+ throws IOException {
+ moveFromLocalFile(tmpLocalFile, fsOutputFile);
+ }
+}
diff --git a/glusterfs-hadoop/0.20.2/src/test/java/org/apache/hadoop/fs/glusterfs/AppTest.java b/glusterfs-hadoop/0.20.2/src/test/java/org/apache/hadoop/fs/glusterfs/AppTest.java
new file mode 100644
index 000000000..21e188c52
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/src/test/java/org/apache/hadoop/fs/glusterfs/AppTest.java
@@ -0,0 +1,38 @@
+package org.apache.hadoop.fs.glusterfs;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/glusterfs-hadoop/0.20.2/tools/build-deploy-jar.py b/glusterfs-hadoop/0.20.2/tools/build-deploy-jar.py
new file mode 100755
index 000000000..c20e53b39
--- /dev/null
+++ b/glusterfs-hadoop/0.20.2/tools/build-deploy-jar.py
@@ -0,0 +1,212 @@
+#!/usr/bin/python
+
+##
+ #
+ # Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ # This file is part of GlusterFS.
+ #
+ # Licensed under the Apache License, Version 2.0
+ # (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # permissions and limitations under the License.
+ #
+ ##
+
+import getopt
+import glob
+import sys, os
+import shutil
+import subprocess, shlex
+
+def usage():
+ print "usage: python build-deploy-jar.py [-b/--build] -d/--dir <hadoop-home> [-c/--core] [-m/--mapred] [-h/--henv]"
+
+def addSlash(s):
+ if not (s[-1] == '/'):
+ s = s + '/'
+
+ return s
+
+def whereis(program):
+ abspath = None
+ for path in (os.environ.get('PATH', '')).split(':'):
+ abspath = os.path.join(path, program)
+ if os.path.exists(abspath) and not os.path.isdir(abspath):
+ return abspath
+
+ return None
+
+def getLatestJar(targetdir):
+ glusterfsJar = glob.glob(targetdir + "*.jar")
+ if len(glusterfsJar) == 0:
+ print "No GlusterFS jar file found in %s ... exiting" % (targetdir)
+ return None
+
+ # pick up the latest jar file - just in case ...
+ stat = latestJar = None
+ ctime = 0
+
+ for jar in glusterfsJar:
+ stat = os.stat(jar)
+ if stat.st_ctime > ctime:
+ latestJar = jar
+ ctime = stat.st_ctime
+
+ return latestJar
+
+# build the glusterfs hadoop plugin using maven
+def build_jar(targetdir):
+ location = whereis('mvn')
+
+ if location == None:
+ print "Cannot find maven to build glusterfs hadoop jar"
+ print "please install maven or if it's already installed then fix your PATH environ"
+ return None
+
+ # do a clean packaging
+ if os.path.exists(targetdir) and os.path.isdir(targetdir):
+ print "Cleaning up directories ... [ " + targetdir + " ]"
+ shutil.rmtree(targetdir)
+
+ print "Building glusterfs jar ..."
+ process = subprocess.Popen(['package'], shell=True,
+ executable=location, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ process.wait()
+ if not process.returncode == 0:
+ print "Building glusterfs jar failed ... exiting"
+ return None
+
+ latestJar = getLatestJar(targetdir)
+ return latestJar
+
+def rcopy(f, host, libdir):
+ print " * doing remote copy to host %s" % (host)
+ scpCmd = "scp %s %s:%s" % (f, host, libdir)
+
+ os.system(scpCmd);
+
+def deployInSlave(f, confdir, libdir, cc, cm, he):
+ slavefile = confdir + "slaves"
+
+ ccFile = confdir + "core-site.xml"
+ cmFile = confdir + "mapred-site.xml"
+ heFile = confdir + "hadoop-env.sh"
+
+ sf = open(slavefile, 'r')
+ for host in sf:
+ host = host.rstrip('\n')
+ print " >>> Deploying %s on %s ..." % (os.path.basename(f), host)
+ rcopy(f, host, libdir)
+
+ if cc:
+ print " >>> Deploying [%s] on %s ..." % (os.path.basename(ccFile), host)
+ rcopy(ccFile, host, confdir)
+
+ if cm:
+ print " >>> Deploying [%s] on %s ..." % (os.path.basename(cmFile), host)
+ rcopy(cmFile, host, confdir)
+
+ if he:
+ print " >>> Deploying [%s] on %s ..." % (os.path.basename(heFile), host)
+ rcopy(heFile, host, confdir);
+
+ print "<<< Done\n"
+
+ sf.close()
+
+def deployInMaster(f, confdir, libdir):
+ import socket
+ masterfile = confdir + "masters"
+
+ mf = open(masterfile, 'r')
+ for host in mf:
+ host = host.rstrip('\n')
+ print " >>> Deploying %s on %s ..." % (os.path.basename(f), host)
+ h = host
+ try:
+ socket.inet_aton(host)
+ h = socket.getfqdn(host)
+ except socket.error:
+ pass
+
+ if h == socket.gethostname() or h == 'localhost':
+ # local cp
+ print " * doing local copy"
+ shutil.copy(f, libdir)
+ else:
+ # scp the file
+ rcopy(f, h, libdir)
+
+ print "<<< Done\n"
+
+ mf.close()
+
+if __name__ == '__main__':
+ opt = args = []
+ try:
+ opt, args = getopt.getopt(sys.argv[1:], "bd:cmh", ["build", "dir=", "core", "mapred", "henv"]);
+ except getopt.GetoptError, err:
+ print str(err)
+ usage()
+ sys.exit(1)
+
+ needbuild = hadoop_dir = copyCore = copyMapred = copyHadoopEnv = None
+
+ for k, v in opt:
+ if k in ("-b", "--build"):
+ needbuild = True
+ elif k in ("-d", "--dir"):
+ hadoop_dir = v
+ elif k in ("-c", "--core"):
+ copyCore = True
+ elif k in ("-m", "--mapred"):
+ copyMapred = True
+ elif k in ("-h", "--henv"):
+ copyHadoopEnv = True
+ else:
+ pass
+
+ if hadoop_dir == None:
+ print 'hadoop directory missing'
+ usage()
+ sys.exit(1)
+
+ os.chdir(os.path.dirname(sys.argv[0]) + '/..')
+ targetdir = './target/'
+
+ if needbuild:
+ jar = build_jar(targetdir)
+ if jar == None:
+ sys.exit(1)
+ else:
+ jar = getLatestJar(targetdir)
+ if jar == None:
+ print "Maybe you want to build it ? with -b option"
+ sys.exit(1)
+
+ print ""
+ print "*** Deploying %s *** " % (jar)
+
+ # copy jar to local hadoop distribution (master)
+ hadoop_home = addSlash(hadoop_dir)
+ if not (os.path.exists(hadoop_home) and os.path.isdir(hadoop_home)):
+ print "path " + hadoop_home + " does not exist or is not adiretory";
+ sys.exit(1);
+
+ hadoop_conf = hadoop_home + "conf/"
+ hadoop_lib = hadoop_home + "lib/"
+
+ print " >>> Scanning hadoop master file for host(s) to deploy"
+ deployInMaster(jar, hadoop_conf, hadoop_lib)
+
+ print ""
+ print " >>> Scanning hadoop slave file for host(s) to deploy"
+ deployInSlave(jar, hadoop_conf, hadoop_lib, copyCore, copyMapred, copyHadoopEnv)
diff --git a/glusterfs-hadoop/COPYING b/glusterfs-hadoop/COPYING
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/glusterfs-hadoop/COPYING
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/glusterfs-hadoop/README b/glusterfs-hadoop/README
new file mode 100644
index 000000000..3026f11c0
--- /dev/null
+++ b/glusterfs-hadoop/README
@@ -0,0 +1,182 @@
+GlusterFS Hadoop Plugin
+=======================
+
+INTRODUCTION
+------------
+
+This document describes how to use GlusterFS (http://www.gluster.org/) as a backing store with Hadoop.
+
+
+REQUIREMENTS
+------------
+
+* Supported OS is GNU/Linux
+* GlusterFS and Hadoop installed on all machines in the cluster
+* Java Runtime Environment (JRE)
+* Maven (needed if you are building the plugin from source)
+* JDK (needed if you are building the plugin from source)
+
+NOTE: Plugin relies on two *nix command line utilities to function properly. They are:
+
+* mount: Used to mount GlusterFS volumes.
+* getfattr: Used to fetch Extended Attributes of a file
+
+Make sure they are installed on all hosts in the cluster and their locations are in $PATH
+environment variable.
+
+
+INSTALLATION
+------------
+
+** NOTE: Example below is for Hadoop version 0.20.2 ($GLUSTER_HOME/hdfs/0.20.2) **
+
+* Building the plugin from source [Maven (http://maven.apache.org/) and JDK is required to build the plugin]
+
+ Change to glusterfs-hadoop directory in the GlusterFS source tree and build the plugin.
+
+ # cd $GLUSTER_HOME/hdfs/0.20.2
+ # mvn package
+
+ On a successful build the plugin will be present in the `target` directory.
+ (NOTE: version number will be a part of the plugin)
+
+ # ls target/
+ classes glusterfs-0.20.2-0.1.jar maven-archiver surefire-reports test-classes
+ ^^^^^^^^^^^^^^^^^^
+
+ Copy the plugin to lib/ directory in your $HADOOP_HOME dir.
+
+ # cp target/glusterfs-0.20.2-0.1.jar $HADOOP_HOME/lib
+
+ Copy the sample configuration file that ships with this source (conf/core-site.xml) to conf
+ directory in your $HADOOP_HOME dir.
+
+ # cp conf/core-site.xml $HADOOP_HOME/conf
+
+* Installing the plugin from RPM
+
+ See the plugin documentation for installing from RPM.
+
+
+CLUSTER INSTALLATION
+--------------------
+
+ In case it is tedious to do the above steps(s) on all hosts in the cluster; use the build-and-deploy.py script to
+ build the plugin in one place and deploy it (along with the configuration file on all other hosts).
+
+ This should be run on the host which is that hadoop master [Job Tracker].
+
+* STEPS (You would have done Step 1 and 2 anyway while deploying Hadoop)
+
+ 1. Edit conf/slaves file in your hadoop distribution; one line for each slave.
+ 2. Setup password-less ssh b/w hadoop master and slave(s).
+ 3. Edit conf/core-site.xml with all glusterfs related configurations (see CONFIGURATION)
+ 4. Run the following
+ # cd $GLUSTER_HOME/hdfs/0.20.2/tools
+ # python ./build-and-deploy.py -b -d /path/to/hadoop/home -c
+
+ This will build the plugin and copy it (and the config file) to all slaves (mentioned in $HADOOP_HOME/conf/slaves).
+
+ Script options:
+ -b : build the plugin
+ -d : location of hadoop directory
+ -c : deploy core-site.xml
+ -m : deploy mapred-site.xml
+ -h : deploy hadoop-env.sh
+
+
+CONFIGURATION
+-------------
+
+ All plugin configuration is done in a single XML file (core-site.xml) with <name><value> tags in each <property>
+ block.
+
+ Brief explanation of the tunables and the values they accept (change them where-ever needed) are mentioned below
+
+ name: fs.glusterfs.impl
+ value: org.apache.hadoop.fs.glusterfs.GlusterFileSystem
+
+ The default FileSystem API to use (there is little reason to modify this).
+
+ name: fs.default.name
+ value: glusterfs://server:port
+
+ The default name that hadoop uses to represent file as a URI (typically a server:port tuple). Use any host
+ in the cluster as the server and any port number. This option has to be in server:port format for hadoop
+ to create file URI; but is not used by plugin.
+
+ name: fs.glusterfs.volname
+ value: volume-dist-rep
+
+ The volume to mount.
+
+
+ name: fs.glusterfs.mount
+ value: /mnt/glusterfs
+
+ This is the directory that the plugin will use to mount (FUSE mount) the volume.
+
+ name: fs.glusterfs.server
+ value: 192.168.1.36, hackme.zugzug.org
+
+ To mount a volume the plugin needs to know the hostname or the IP of a GlusterFS server in the cluster.
+ Mention it here.
+
+ name: quick.slave.io
+ value: [On/Off], [Yes/No], [1/0]
+
+ NOTE: This option is not tested as of now.
+
+ This is a performance tunable option. Hadoop schedules jobs to hosts that contain the file data part. The job
+ then does I/O on the file (via FUSE in case of GlusterFS). When this option is set, the plugin will try to
+ do I/O directly from the backed filesystem (ext3, ext4 etc..) the file resides on. Hence read performance
+ will improve and job would run faster.
+
+
+USAGE
+-----
+
+ Once configured, start Hadoop Map/Reduce daemons
+
+ # cd $HADOOP_HOME
+ # ./bin/start-mapred.sh
+
+ If the map/reduce job/task trackers are up, all I/O will be done to GlusterFS.
+
+
+FOR HACKERS
+-----------
+
+* Source Layout
+
+** version specific: hdfs/<version> **
+./src
+./src/main
+./src/main/java
+./src/main/java/org
+./src/main/java/org/apache
+./src/main/java/org/apache/hadoop
+./src/main/java/org/apache/hadoop/fs
+./src/main/java/org/apache/hadoop/fs/glusterfs
+./src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickClass.java
+./src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSXattr.java <--- Fetch/Parse Extended Attributes of a file
+./src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEInputStream.java <--- Input Stream (instantiated during open() calls; quick read from backed FS)
+./src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickRepl.java
+./src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEOutputStream.java <--- Output Stream (instantiated during creat() calls)
+./src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFileSystem.java <--- Entry Point for the plugin (extends Hadoop FileSystem class)
+./src/test
+./src/test/java
+./src/test/java/org
+./src/test/java/org/apache
+./src/test/java/org/apache/hadoop
+./src/test/java/org/apache/hadoop/fs
+./src/test/java/org/apache/hadoop/fs/glusterfs
+./src/test/java/org/apache/hadoop/fs/glusterfs/AppTest.java <--- Your test cases go here (if any :-))
+./tools/build-deploy-jar.py <--- Build and Deployment Script
+./conf
+./conf/core-site.xml <--- Sample configuration file
+./pom.xml <--- build XML file (used by maven)
+
+** toplevel: hdfs/ **
+./COPYING <--- License
+./README <--- This file
diff --git a/glusterfs.spec.in b/glusterfs.spec.in
index c07666f7a..c5ab0fc16 100644
--- a/glusterfs.spec.in
+++ b/glusterfs.spec.in
@@ -1,60 +1,69 @@
-# if you make changes, the it is advised to increment this number, and provide
+# if you make changes, the it is advised to increment this number, and provide
# a descriptive suffix to identify who owns or what the change represents
# e.g. release_version 2.MSW
-%define release 1%{?dist}
-%define _libexecdir %{_prefix}/local/libexec/
+%global release 1%{?dist}
+%global _sharedstatedir /var/lib
+
# if you wish to compile an rpm without rdma support, compile like this...
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without rdma
-%{?_without_rdma:%define _without_rdma --disable-ibverbs}
+%{?_without_rdma:%global _without_rdma --disable-ibverbs}
+
+# No RDMA Support on x390(x)
+%ifarch s390 s390x
+%global _without_rdma --disable-ibverbs
+%endif
# if you wish to compile an rpm without epoll...
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without epoll
-%{?_without_epoll:%define _without_epoll --disable-epoll}
+%{?_without_epoll:%global _without_epoll --disable-epoll}
# if you wish to compile an rpm with fusermount...
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with fusermount
-%{?_with_fusermount:%define _with_fusermount --enable-fusermount}
+%{?_with_fusermount:%global _with_fusermount --enable-fusermount}
+
+%global version @PACKAGE_VERSION@
+%if "%{version}" >= "3.2"
+%global _can_georeplicate 1
# if you wish to compile an rpm without geo-replication support, compile like this...
-# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without geo-replication
-%{?_without_geo-replication:%define _without_geo-replication --disable-geo-replication}
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without georeplication
+%{?_without_georeplication:%global _without_georeplication --disable-geo-replication}
+%endif
Summary: Cluster File System
Name: @PACKAGE_NAME@
-Version: @PACKAGE_VERSION@
+Version: %{version}
Release: %{release}
-License: AGPLv3+
+License: GPLv2 or LGPLv3+
Group: System Environment/Base
Vendor: Gluster Inc
Packager: @PACKAGE_BUGREPORT@
URL: http://www.gluster.org/docs/index.php/GlusterFS
-Source0: ftp://ftp.gluster.com/pub/gluster/glusterfs/@PACKAGE_VERSION@/@PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+Source0: @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz
+BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
Requires(post): /sbin/chkconfig
Requires(preun): /sbin/service, /sbin/chkconfig
Requires(postun): /sbin/service
-BuildRequires: bison flex
-BuildRequires: gcc make
-%define _prefix /opt/%{name}/%{version}
-
-%description
-GlusterFS is a clustered file-system capable of scaling to several
-peta-bytes. It aggregates various storage bricks over Infiniband RDMA
-or TCP/IP interconnect into one large parallel network file
-system. GlusterFS is one of the most sophisticated file system in
-terms of features and extensibility. It borrows a powerful concept
-called Translators from GNU Hurd kernel. Much of the code in GlusterFS
-is in userspace and easily manageable.
+BuildRequires: bison flex
+BuildRequires: gcc make automake libtool
+BuildRequires: ncurses-devel readline-devel openssl-devel
+BuildRequires: libxml2-devel
+BuildRequires: python-ctypes
+%if 0%{?suse_version}
+BuildRequires: python-devel
+%endif
+Requires: openssl
-%package core
-Summary: GlusterFS common files for both the client and the server
-Group: System Environment/Libraries
-Obsoletes: glusterfs-libs <= 2.0.0 glusterfs-common < 3.1.0 glusterfs-server < 3.1.0
-Provides: glusterfs-libs = %{version}-%{release}
+Obsoletes: %{name}-libs <= 2.0.0
+Obsoletes: %{name}-common < %{version}-%{release}
+Obsoletes: %{name}-core < %{version}-%{release}
+Provides: %{name}-libs = %{version}-%{release}
+Provides: %{name}-common = %{version}-%{release}
+Provides: %{name}-core = %{version}-%{release}
-%description core
+%description
GlusterFS is a clustered file-system capable of scaling to several
peta-bytes. It aggregates various storage bricks over Infiniband RDMA
or TCP/IP interconnect into one large parallel network file
@@ -63,17 +72,17 @@ terms of features and extensibility. It borrows a powerful concept
called Translators from GNU Hurd kernel. Much of the code in GlusterFS
is in userspace and easily manageable.
-This package includes the glusterfs binary, the glusterd daemon and the gluster
-command line, libglusterfs and glusterfs translator modules common to both
-GlusterFS server and client framework.
+This package includes libraries and utility scripts.
%if 0%{!?_without_rdma:1}
%package rdma
-Summary: GlusterFS rdma
+Summary: GlusterFS rdma support for ib-verbs
+License: GPLv2 or LGPLv3+
Group: Applications/File
-Requires: glusterfs-core >= %{version}-%{release}
BuildRequires: libibverbs-devel
+Requires: %{name} = %{version}-%{release}
+
%description rdma
GlusterFS is a clustered file-system capable of scaling to several
peta-bytes. It aggregates various storage bricks over Infiniband RDMA
@@ -86,11 +95,13 @@ is in userspace and easily manageable.
This package provides support to ib-verbs library.
%endif
-%if 0%{!?_without_geo-replication:1}
+%if 0%{?_can_georeplicate}
+%if 0%{!?_without_georeplication:1}
%package geo-replication
Summary: GlusterFS Geo-replication
+License: GPLv3+
Group: Applications/File
-Requires: glusterfs-core >= %{version}-%{release} , python-ctypes , rsync >= 3.0.7
+Requires: %{name} = %{version}-%{release} , python-ctypes , rsync >= 3.0.0
%description geo-replication
GlusterFS is a clustered file-system capable of scaling to several
@@ -103,12 +114,17 @@ is in userspace and easily manageable.
This package provides support to geo-replication.
%endif
+%endif
%package fuse
-Summary: GlusterFS Fuse
+Summary: GlusterFS Fuse client
+License: GPLv2 or LGPLv3+
Group: Applications/File
-Requires: glusterfs-core >= %{version}-%{release}
-Obsoletes: glusterfs-client < 3.1.0
+
+Requires: %{name} >= %{version}-%{release}
+
+Obsoletes: %{name}-client < %{version}-%{release}
+Provides: %{name}-client = %{version}-%{release}
%description fuse
GlusterFS is a clustered file-system capable of scaling to several
@@ -121,95 +137,157 @@ is in userspace and easily manageable.
This package provides support to FUSE based clients.
+%package server
+Summary: Clustered file-system server
+License: GPLv3+
+Group: System Environment/Daemons
+Requires: %{name} = %{version}-%{release}
+Requires: %{name}-fuse = %{version}-%{release}
+Requires: openssl
+
+%description server
+GlusterFS is a clustered file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over Infiniband RDMA
+or TCP/IP interconnect into one large parallel network file
+system. GlusterFS is one of the most sophisticated file systems in
+terms of features and extensibility. It borrows a powerful concept
+called Translators from GNU Hurd kernel. Much of the code in GlusterFS
+is in user space and easily manageable.
+
+This package provides the glusterfs server daemon and translators that
+are loaded on the server.
+
+%package devel
+Summary: Development Libraries
+License: GPLv2 or LGPLv3+
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+GlusterFS is a clustered file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over Infiniband RDMA
+or TCP/IP interconnect into one large parallel network file
+system. GlusterFS is one of the most sophisticated file systems in
+terms of features and extensibility. It borrows a powerful concept
+called Translators from GNU Hurd kernel. Much of the code in GlusterFS
+is in user space and easily manageable.
+
+This package provides the development libraries.
+
%prep
%setup -q -n %{name}-%{version}
%build
-
-%configure %{?_without_rdma} %{?_without_epoll} %{?_with_fusermount} %{?_without_geo-replication}
+./autogen.sh
+%configure %{?_without_rdma} %{?_without_epoll} %{?_with_fusermount} %{?_without_georeplication}
# Remove rpath
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
+
%{__make} %{?_smp_mflags}
%install
-%{__rm} -rf %{buildroot}
+%{__rm} -rf %{buildroot}
%{__make} install DESTDIR=%{buildroot}
-%{__mkdir_p} %{buildroot}/usr/sbin
-%{__mkdir_p} %{buildroot}/usr/local/libexec/glusterfs
-%{__ln_s} ../..%{_sbindir}/glusterd %{buildroot}/usr/sbin/glusterd
-%{__ln_s} ../..%{_sbindir}/glusterfsd %{buildroot}/usr/sbin/glusterfsd
-%{__ln_s} ../..%{_sbindir}/gluster %{buildroot}/usr/sbin/gluster
-%{__ln_s} ../..%{_sbindir}/glusterfs %{buildroot}/usr/sbin/glusterfs
-%{__ln_s} %{_libexecdir}/glusterfs/gsyncd %{buildroot}/usr/local/libexec/glusterfs/gsyncd
+# Install include directory
%{__mkdir_p} %{buildroot}%{_includedir}/glusterfs
-%{__mkdir_p} %{buildroot}/var/log/glusterfs
%{__install} -p -m 0644 libglusterfs/src/*.h \
%{buildroot}%{_includedir}/glusterfs/
+%{__install} -p -m 0644 contrib/uuid/*.h \
+ %{buildroot}%{_includedir}/glusterfs/
+# Following needed by hekafs multi-tenant translator
+%{__mkdir_p} %{buildroot}%{_includedir}/glusterfs/rpc
+%{__install} -p -m 0644 rpc/rpc-lib/src/*.h \
+ %{buildroot}%{_includedir}/glusterfs/rpc/
+%{__install} -p -m 0644 rpc/xdr/src/*.h \
+ %{buildroot}%{_includedir}/glusterfs/rpc/
+%{__mkdir_p} %{buildroot}%{_includedir}/glusterfs/server
+%{__install} -p -m 0644 xlators/protocol/server/src/*.h \
+ %{buildroot}%{_includedir}/glusterfs/server/
+
+%{__mkdir_p} %{buildroot}%{_localstatedir}/run/gluster
# Remove unwanted files from all the shared libraries
-find %{buildroot}%{_libdir} -name '*.la' | xargs rm -f
-find %{buildroot}%{_libdir} -name '*.a' | xargs rm -f
+find %{buildroot}%{_libdir} -name '*.a' -delete
+find %{buildroot}%{_libdir} -name '*.la' -delete
+
+# Remove installed docs, we include them ourselves as %%doc
+%{__rm} -rf %{buildroot}%{_datadir}/doc/glusterfs/
+
+# Rename the samples, so we can include them as %%config
+#for file in %{buildroot}%{_sysconfdir}/glusterfs/*.sample; do
+# %{__mv} ${file} `dirname ${file}`/`basename ${file} .sample`
+#done
+
+# Create working directory
+%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd
+
+# Update configuration file to /var/lib working directory
+sed -i 's|option working-directory /etc/glusterd|option working-directory %{_sharedstatedir}/glusterd|g' \
+ %{buildroot}%{_sysconfdir}/glusterfs/glusterd.vol
+
+# Following needed by the hooks interface
+%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/hook-scripts
+%{__install} -p -m 0644 extras/hook-scripts/*.sh \
+ %{buildroot}%{_sharedstatedir}/glusterd/hook-scripts/
+
+# Create directories and files that get created during runtime. This should
+# not be needed for files marged as "ghost", but rpm-4.9 is broken in this
+# respect :-(
+# - see also https://bugzilla.redhat.com/show_bug.cgi?id=839656
+touch %{buildroot}%{_sharedstatedir}/glusterd/glusterd.info
+%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/glustershd
+%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/{add-brick,create,delete,set,start,stop,remove,remove-brick}/{pre,post}
+%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/nfs
+%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/peers
+%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/vols
+%if 0%{?_can_georeplicate}
+%if 0%{!?_without_georeplication:1}
+%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/geo-replication
+touch %{buildroot}%{_sharedstatedir}/glusterd/geo-replication/gsyncd.conf
+%endif
+%endif
+
+# Clean up the examples we want to include as %%doc
+#%{__cp} -a doc/examples examples
+#%{__rm} -f examples/Makefile*
%clean
%{__rm} -rf %{buildroot}
-%post core
-/sbin/ldconfig
-/sbin/chkconfig --add glusterd
-
-
-#update /etc/ld.so.conf.d
-echo "%{_prefix}/lib64" > /etc/ld.so.conf.d/glusterfs.conf
+%post
/sbin/ldconfig
-pidof -c -o %PPID -x glusterd &> /dev/null
-if [ $? -eq 0 ];
-then
-kill -9 `pgrep -f gsyncd.py` &> /dev/null
-/etc/init.d/glusterd restart &> /dev/null
+# Copy the 'glusterfs-logrotate' file at the right place
+if [ -d /etc/logrotate.d ]; then
+ cp %{_docdir}/%{name}-%{version}/glusterfs-logrotate /etc/logrotate.d/glusterfs
fi
-%postun core
-/sbin/ldconfig -n %{_libdir}
-
-%preun core
-if [ $1 -eq 0 ]; then
- /sbin/chkconfig --del glusterd
-fi
+%postun
+/sbin/ldconfig
-%files core
+%files
%defattr(-,root,root)
-%doc AUTHORS ChangeLog COPYING INSTALL NEWS README THANKS
-%doc %{_datadir}/doc/glusterfs
-%if 0%{?_with_fusermount:1}
-%{_bindir}/fusermount-glusterfs
-%endif
+%doc AUTHORS ChangeLog COPYING-GPLV2 COPYING-LGPLV3 INSTALL NEWS README THANKS
+%doc extras/glusterfs-logrotate
%{_libdir}/glusterfs
%{_libdir}/*.so.*
%{_sbindir}/glusterfs*
-%{_sbindir}/gluster
-%{_sbindir}/glusterd
-/usr/sbin
-%{_mandir}/man8/*glusterfs.8*
-%{_mandir}/man8/*glusterfsd.8*
-%{_mandir}/man8/*gluster.8*
-%{_mandir}/man8/*glusterd.8*
-%dir /var/log/glusterfs
+%{_mandir}/man8/*gluster*.8*
+%dir %{_localstatedir}/log/glusterfs
+%dir %{_localstatedir}/run/gluster
+%dir %{_sharedstatedir}/glusterd
%if 0%{!?_without_rdma:1}
%exclude %{_libdir}/glusterfs/%{version}/rpc-transport/rdma*
%endif
%exclude %{_libdir}/glusterfs/%{version}/xlator/mount/fuse*
-%config %{_sysconfdir}/glusterfs
-%{_sysconfdir}/init.d/glusterd
-%{_includedir}/glusterfs
-%exclude %{_includedir}/glusterfs/y.tab.h
-%{_libdir}/*.so
-%exclude %{_libexecdir}/glusterfs/gsyncd
-%exclude %{_libexecdir}/glusterfs/python/syncdaemon/*
-%exclude /usr/local/libexec/glusterfs/gsyncd
+%exclude %{_libdir}/glusterfs/%{version}/xlator/storage*
+%exclude %{_libdir}/glusterfs/%{version}/xlator/features/posix*
+%exclude %{_libdir}/glusterfs/%{version}/xlator/protocol/server*
+%exclude %{_libdir}/glusterfs/%{version}/xlator/mgmt*
+%exclude %{_libdir}/glusterfs/%{version}/xlator/nfs*
%if 0%{!?_without_rdma:1}
%files rdma
@@ -217,28 +295,363 @@ fi
%{_libdir}/glusterfs/%{version}/rpc-transport/rdma*
%endif
-%if 0%{!?_without_geo-replication:1}
+%if 0%{?_can_georeplicate}
+%if 0%{!?_without_georeplication:1}
+%post geo-replication
+#restart glusterd.
+%{_sysconfdir}/init.d/glusterd restart &> /dev/null
+%endif
+
+%if 0%{!?_without_georeplication:1}
%files geo-replication
%defattr(-,root,root)
%{_libexecdir}/glusterfs/gsyncd
%{_libexecdir}/glusterfs/python/syncdaemon/*
-/usr/local/libexec/glusterfs/gsyncd
+%ghost %attr(0755,-,-) %dir %{_sharedstatedir}/glusterd/geo-replication
+%ghost %attr(0644,-,-) %{_sharedstatedir}/glusterd/geo-replication/gsyncd.conf
+%endif
%endif
-
%files fuse
%defattr(-,root,root)
%{_libdir}/glusterfs/%{version}/xlator/mount/fuse*
+#%{_mandir}/man8/mount.glusterfs.8*
/sbin/mount.glusterfs
+%if 0%{?_with_fusermount:1}
+%{_bindir}/fusermount-glusterfs
+%endif
+
+%post server
+/sbin/chkconfig --add glusterd
+
+# Move legacy sysconf files to the correct sysconfdir
+if [ -d /etc/glusterd ]; then
+ mkdir -p /var/lib
+ mv /etc/glusterd /var/lib/
+ ln -sf /var/lib/glusterd /etc/glusterd
+fi
+
+if [ -d /var/lib/glusterd/vols ]; then
+ # Rename old volfiles in an RPM-standard way. These aren't actually
+ # considered package config files, so %config doesn't work for them.
+ for file in $(find /var/lib/glusterd/vols -name '*.vol'); do
+ newfile=${file}.rpmsave
+ echo "warning: ${file} saved as ${newfile}"
+ cp ${file} ${newfile}
+ done
+fi
+
+pidof -c -o %PPID -x glusterd &> /dev/null
+if [ $? -eq 0 ]; then
+ kill -9 `pgrep -f gsyncd.py` &> /dev/null
+
+ killall glusterd &> /dev/null
+ #add marker translator
+ glusterd --xlator-option *.upgrade=on -N
+ glusterd
+else
+ glusterd --xlator-option *.upgrade=on -N
+fi
+
+%preun server
+if [ $1 -eq 0 ]; then
+ /sbin/service glusterd stop &>/dev/null || :
+ /sbin/chkconfig --del glusterd
+fi
+if [ $1 -ge 1 ]; then
+ /sbin/service glusterd condrestart &>/dev/null || :
+fi
+
+# Legacy server
+if [ $1 -eq 0 ]; then
+ /sbin/service glusterfsd stop &>/dev/null || :
+ /sbin/chkconfig --del glusterfsd
+fi
+if [ $1 -ge 1 ]; then
+ /sbin/service glusterfsd condrestart &>/dev/null || :
+fi
+
+%files server
+%defattr(-,root,root,-)
+%doc extras/clear_xattrs.sh
+#%doc examples/ doc/glusterfs*.vol.sample
+%config(noreplace) %{_sysconfdir}/glusterfs
+%{_sysconfdir}/init.d/glusterd
+%{_sbindir}/gluster
+%{_sbindir}/glusterd
+%{_libdir}/glusterfs/%{version}/xlator/storage*
+%{_libdir}/glusterfs/%{version}/xlator/features/posix*
+%{_libdir}/glusterfs/%{version}/xlator/protocol/server*
+%{_libdir}/glusterfs/%{version}/xlator/mgmt*
+%{_libdir}/glusterfs/%{version}/xlator/nfs*
+%{_sharedstatedir}/glusterd/hook-scripts
+%ghost %attr(0644,-,-) %{_sharedstatedir}/glusterd/glusterd.info
+# This is really ugly, but I have no idea how to mark these directories in an
+# other way. They should belong to the glusterfs-server package, but don't
+# exist after installation. They are generated on the first start...
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/pre
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start/pre
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick/pre
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set/pre
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/pre
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/pre
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glustershd
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/vols
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/peers
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/glusterfs
+%exclude %{_includedir}/glusterfs/y.tab.h
+%{_libdir}/*.so
%changelog
-* Wed Jul 01 2009 Harshavardhana <harsha@gluster.com> - 2.1
-- Removed mod_glusterfs.so and added new --without epoll build
- option.
-
-* Thu Apr 16 2009 Harshavardhana <harsha@gluster.com> - 2.0
-- Galore of updates including new packages added common,
- client,server splitting the original package. rpmbuild
- fully restructured to adhere to Fedora rpm standards.
- Older changelog removed as there were warnings when
- tried with 'rpmlint'.
+* Mon Mar 4 2013 Niels de Vos <ndevos@redhat.com>
+- Package /var/run/gluster so that statedumps can be created
+
+* Tue Jul 10 2012 Niels de Vos <ndevos@redhat.com>
+- Include extras/clear_xattrs.sh in the glusterfs-server sub-package
+
+* Thu Jun 07 2012 Niels de Vos <ndevos@redhat.com>
+- Mark /var/lib/glusterd as owned by glusterfs, subdirs belong to -server
+
+* Wed May 9 2012 Kaleb S. KEITHLEY <kkeithle[at]redhat.com>
+- Add BuildRequires: libxml2-devel so that configure will DTRT on for
+- Fedora's Koji build system
+
+* Wed Nov 9 2011 Joe Julian <me@joejulian.name> - git master
+- Merge fedora specfile into gluster's spec.in.
+- Add conditionals to allow the same spec file to be used for both 3.1 and 3.2
+- http://bugs.gluster.com/show_bug.cgi?id=2970
+
+* Wed Oct 5 2011 Joe Julian <me@joejulian.name> - 3.2.4-1
+- Update to 3.2.4
+- Removed the $local_fs requirement from the init scripts as in RHEL/CentOS that's provided
+- by netfs, which needs to be started after glusterd.
+
+* Sun Sep 25 2011 Joe Julian <me@joejulian.name> - 3.2.3-2
+- Merged in upstream changes
+- Fixed version reporting 3.2git
+- Added nfs init script (disabled by default)
+
+* Fri Sep 1 2011 Joe Julian <me@joejulian.name> - 3.2.3-1
+- Update to 3.2.3
+
+* Tue Jul 19 2011 Joe Julian <me@joejulian.name> - 3.2.2-3
+- Add readline and libtermcap dependencies
+
+* Tue Jul 19 2011 Joe Julian <me@joejulian.name> - 3.2.2-2
+- Critical patch to prevent glusterd from walking outside of its own volume during rebalance
+
+* Thu Jul 14 2011 Joe Julian <me@joejulian.name> - 3.2.2-1
+- Update to 3.2.2
+
+* Wed Jul 13 2011 Joe Julian <me@joejulian.name> - 3.2.1-2
+- fix hardcoded path to gsyncd in source to match the actual file location
+
+* Mon Jun 21 2011 Joe Julian <me@joejulian.name> - 3.2.1
+- Update to 3.2.1
+
+* Mon Jun 20 2011 Joe Julian <me@joejulian.name> - 3.1.5
+- Update to 3.1.5
+
+* Mon May 31 2011 Joe Julian <me@joejulian.name> - 3.1.5-qa1.4
+- Current git
+
+* Sun May 29 2011 Joe Julian <me@joejulian.name> - 3.1.5-qa1.2
+- set _sharedstatedir to /var/lib for FHS compliance in RHEL5/CentOS5
+- mv /etc/glusterd, if it exists, to the new state dir for upgrading from gluster packaging
+
+* Sat May 28 2011 Joe Julian <me@joejulian.name> - 3.1.5-qa1.1
+- Update to 3.1.5-qa1
+- Add patch to remove optimization disabling
+- Add patch to remove forced 64 bit compile
+- Obsolete glusterfs-core to allow for upgrading from gluster packaging
+
+* Sun Mar 19 2011 Jonathan Steffan <jsteffan@fedoraproject.org> - 3.1.3-1
+- Update to 3.1.3
+- Merge in more upstream SPEC changes
+- Remove patches from GlusterFS bugzilla #2309 and #2311
+- Remove inode-gen.patch
+
+* Sun Feb 06 2011 Jonathan Steffan <jsteffan@fedoraproject.org> - 3.1.2-3
+- Add back in legacy SPEC elements to support older branches
+
+* Tue Feb 03 2011 Jonathan Steffan <jsteffan@fedoraproject.org> - 3.1.2-2
+- Add patches from CloudFS project
+
+* Tue Jan 25 2011 Jonathan Steffan <jsteffan@fedoraproject.org> - 3.1.2-1
+- Update to 3.1.2
+
+* Wed Jan 5 2011 Dan Horák <dan[at]danny.cz> - 3.1.1-3
+- no InfiniBand on s390(x)
+
+* Sat Jan 1 2011 Jonathan Steffan <jsteffan@fedoraproject.org> - 3.1.1-2
+- Update to support readline
+- Update to not parallel build
+
+* Mon Dec 27 2010 Silas Sewell <silas@sewell.ch> - 3.1.1-1
+- Update to 3.1.1
+- Change package names to mirror upstream
+
+* Mon Dec 20 2010 Jonathan Steffan <jsteffan@fedoraproject.org> - 3.0.7-1
+- Update to 3.0.7
+
+* Wed Jul 28 2010 Jonathan Steffan <jsteffan@fedoraproject.org> - 3.0.5-1
+- Update to 3.0.x
+
+* Sat Apr 10 2010 Jonathan Steffan <jsteffan@fedoraproject.org> - 2.0.9-2
+- Move python version requires into a proper BuildRequires otherwise
+ the spec always turned off python bindings as python is not part
+ of buildsys-build and the chroot will never have python unless we
+ require it
+- Temporarily set -D_FORTIFY_SOURCE=1 until upstream fixes code
+ GlusterFS Bugzilla #197 (#555728)
+- Move glusterfs-volgen to devel subpackage (#555724)
+- Update description (#554947)
+
+* Sat Jan 2 2010 Jonathan Steffan <jsteffan@fedoraproject.org> - 2.0.9-1
+- Update to 2.0.9
+
+* Sat Nov 8 2009 Jonathan Steffan <jsteffan@fedoraproject.org> - 2.0.8-1
+- Update to 2.0.8
+- Remove install of glusterfs-volgen, it's properly added to
+ automake upstream now
+
+* Sat Oct 31 2009 Jonathan Steffan <jsteffan@fedoraproject.org> - 2.0.7-1
+- Update to 2.0.7
+- Install glusterfs-volgen, until it's properly added to automake
+ by upstream
+- Add macro to be able to ship more docs
+
+* Thu Sep 17 2009 Peter Lemenkov <lemenkov@gmail.com> 2.0.6-2
+- Rebuilt with new fuse
+
+* Sat Sep 12 2009 Matthias Saou <http://freshrpms.net/> 2.0.6-1
+- Update to 2.0.6.
+- No longer default to disable the client on RHEL5 (#522192).
+- Update spec file URLs.
+
+* Mon Jul 27 2009 Matthias Saou <http://freshrpms.net/> 2.0.4-1
+- Update to 2.0.4.
+
+* Thu Jun 11 2009 Matthias Saou <http://freshrpms.net/> 2.0.1-2
+- Remove libglusterfs/src/y.tab.c to fix koji F11/devel builds.
+
+* Sat May 16 2009 Matthias Saou <http://freshrpms.net/> 2.0.1-1
+- Update to 2.0.1.
+
+* Thu May 7 2009 Matthias Saou <http://freshrpms.net/> 2.0.0-1
+- Update to 2.0.0 final.
+
+* Wed Apr 29 2009 Matthias Saou <http://freshrpms.net/> 2.0.0-0.3.rc8
+- Move glusterfsd to common, since the client has a symlink to it.
+
+* Fri Apr 24 2009 Matthias Saou <http://freshrpms.net/> 2.0.0-0.2.rc8
+- Update to 2.0.0rc8.
+
+* Sun Apr 12 2009 Matthias Saou <http://freshrpms.net/> 2.0.0-0.2.rc7
+- Update glusterfsd init script to the new style init.
+- Update files to match the new default vol file names.
+- Include logrotate for glusterfsd, use a pid file by default.
+- Include logrotate for glusterfs, using killall for lack of anything better.
+
+* Sat Apr 11 2009 Matthias Saou <http://freshrpms.net/> 2.0.0-0.1.rc7
+- Update to 2.0.0rc7.
+- Rename "libs" to "common" and move the binary, man page and log dir there.
+
+* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org>
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Mon Feb 16 2009 Matthias Saou <http://freshrpms.net/> 2.0.0-0.1.rc1
+- Update to 2.0.0rc1.
+- Include new libglusterfsclient.h.
+
+* Mon Feb 16 2009 Matthias Saou <http://freshrpms.net/> 1.3.12-1
+- Update to 1.3.12.
+- Remove no longer needed ocreat patch.
+
+* Thu Jul 17 2008 Matthias Saou <http://freshrpms.net/> 1.3.10-1
+- Update to 1.3.10.
+- Remove mount patch, it's been included upstream now.
+
+* Fri May 16 2008 Matthias Saou <http://freshrpms.net/> 1.3.9-1
+- Update to 1.3.9.
+
+* Fri May 9 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-1
+- Update to 1.3.8 final.
+
+* Tue Apr 23 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-0.10
+- Include short patch to include fixes from latest TLA 751.
+
+* Mon Apr 22 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-0.9
+- Update to 1.3.8pre6.
+- Include glusterfs binary in both the client and server packages, now that
+ glusterfsd is a symlink to it instead of a separate binary.
+* Sun Feb 3 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-0.8
+- Add python version check and disable bindings for version < 2.4.
+
+* Sun Feb 3 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-0.7
+- Add --without client rpmbuild option, make it the default for RHEL (no fuse).
+ (I hope "rhel" is the proper default macro name, couldn't find it...)
+
+* Wed Jan 30 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-0.6
+- Add --without ibverbs rpmbuild option to the package.
+
+* Mon Jan 14 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-0.5
+- Update to current TLA again, patch-636 which fixes the known segfaults.
+
+* Thu Jan 10 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-0.4
+- Downgrade to glusterfs--mainline--2.5--patch-628 which is more stable.
+
+* Tue Jan 8 2008 Matthias Saou <http://freshrpms.net/> 1.3.8-0.3
+- Update to current TLA snapshot.
+- Include umount.glusterfs wrapper script (really needed? dunno).
+- Include patch to mount wrapper to avoid multiple identical mounts.
+
+* Sun Dec 30 2007 Matthias Saou <http://freshrpms.net/> 1.3.8-0.1
+- Update to current TLA snapshot, which includes "volume-name=" fstab option.
+
+* Mon Dec 3 2007 Matthias Saou <http://freshrpms.net/> 1.3.7-6
+- Re-add the /var/log/glusterfs directory in the client sub-package (required).
+- Include custom patch to support vol= in fstab for -n glusterfs client option.
+
+* Mon Nov 26 2007 Matthias Saou <http://freshrpms.net/> 1.3.7-4
+- Re-enable libibverbs.
+- Check and update License field to GPLv3+.
+- Add glusterfs-common obsoletes, to provide upgrade path from old packages.
+- Include patch to add mode to O_CREATE opens.
+
+* Thu Nov 22 2007 Matthias Saou <http://freshrpms.net/> 1.3.7-3
+- Remove Makefile* files from examples.
+- Include RHEL/Fedora type init script, since the included ones don't do.
+
+* Wed Nov 21 2007 Matthias Saou <http://freshrpms.net/> 1.3.7-1
+- Major spec file cleanup.
+- Add misssing %%clean section.
+- Fix ldconfig calls (weren't set for the proper sub-package).
+
+* Sat Aug 4 2007 Matt Paine <matt@mattsoftware.com> - 1.3.pre7
+- Added support to build rpm without ibverbs support (use --without ibverbs
+ switch)
+
+* Sun Jul 15 2007 Matt Paine <matt@mattsoftware.com> - 1.3.pre6
+- Initial spec file
diff --git a/glusterfsd/src/Makefile.am b/glusterfsd/src/Makefile.am
index 537eda0bb..510b9dc1f 100644
--- a/glusterfsd/src/Makefile.am
+++ b/glusterfsd/src/Makefile.am
@@ -1,9 +1,6 @@
sbin_PROGRAMS = glusterfsd
glusterfsd_SOURCES = glusterfsd.c glusterfsd-mgmt.c
-if GF_DARWIN_HOST_OS
-glusterfsd_SOURCES += $(CONTRIBDIR)/apple/daemon.c
-endif
glusterfsd_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
$(top_builddir)/rpc/xdr/src/libgfxdr.la \
@@ -15,9 +12,6 @@ AM_CFLAGS = -fPIC -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)\
-I$(top_srcdir)/libglusterfs/src -DDATADIR=\"$(localstatedir)\" \
-DCONFDIR=\"$(sysconfdir)/glusterfs\" $(GF_GLUSTERFS_CFLAGS) \
-I$(top_srcdir)/rpc/rpc-lib/src -I$(top_srcdir)/rpc/xdr/src
-if GF_DARWIN_HOST_OS
-AM_CFLAGS += -I$(CONTRIBDIR)/apple
-endif
CLEANFILES =
@@ -30,6 +24,7 @@ uninstall-local:
install-data-local:
$(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/run
+ $(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/run/gluster
$(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/log/glusterfs
rm -f $(DESTDIR)$(sbindir)/glusterfs
rm -f $(DESTDIR)$(sbindir)/glusterd
diff --git a/glusterfsd/src/glusterfsd-mem-types.h b/glusterfsd/src/glusterfsd-mem-types.h
index dc5e97f68..4b1ffc854 100644
--- a/glusterfsd/src/glusterfsd-mem-types.h
+++ b/glusterfsd/src/glusterfsd-mem-types.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __GLUSTERFSD_MEM_TYPES_H__
@@ -30,6 +21,7 @@ enum gfd_mem_types_ {
gfd_mt_xlator_cmdline_option_t,
gfd_mt_char,
gfd_mt_call_pool_t,
+ gfd_mt_vol_top_priv_t,
gfd_mt_end
};
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
index 1e10056ac..f451ed1fc 100644
--- a/glusterfsd/src/glusterfsd-mgmt.c
+++ b/glusterfsd/src/glusterfsd-mgmt.c
@@ -1,26 +1,19 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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
@@ -36,22 +29,23 @@
#include "rpc-clnt.h"
#include "protocol-common.h"
#include "glusterfs3.h"
-#include "portmap.h"
-#include "glusterd1.h"
+#include "portmap-xdr.h"
+#include "xdr-generic.h"
#include "glusterfsd.h"
+#include "glusterfsd-mem-types.h"
#include "rpcsvc.h"
+#include "cli1-xdr.h"
+#include "statedump.h"
+#include "syncop.h"
+#include "xlator.h"
static char is_mgmt_rpc_reconnect;
-typedef ssize_t (*mgmt_serialize_t) (struct iovec outmsg, void *args);
-typedef ssize_t (*gf_serialize_t) (struct iovec outmsg, void *args);
-
-
-
int glusterfs_mgmt_pmap_signin (glusterfs_ctx_t *ctx);
int glusterfs_volfile_fetch (glusterfs_ctx_t *ctx);
int glusterfs_process_volfp (glusterfs_ctx_t *ctx, FILE *fp);
+int glusterfs_graph_unknown_options (glusterfs_graph_t *graph);
int
mgmt_cbk_spec (void *data)
@@ -65,19 +59,27 @@ mgmt_cbk_spec (void *data)
return 0;
}
+
+int
+mgmt_cbk_event (void *data)
+{
+ return 0;
+}
struct iobuf *
glusterfs_serialize_reply (rpcsvc_request_t *req, void *arg,
- gf_serialize_t sfunc, struct iovec *outmsg)
+ struct iovec *outmsg, xdrproc_t xdrproc)
{
struct iobuf *iob = NULL;
ssize_t retlen = -1;
+ ssize_t xdr_size = 0;
/* First, get the io buffer into which the reply in arg will
* be serialized.
*/
- iob = iobuf_get (req->svc->ctx->iobuf_pool);
+ xdr_size = xdr_sizeof (xdrproc, arg);
+ iob = iobuf_get2 (req->svc->ctx->iobuf_pool, xdr_size);
if (!iob) {
- gf_log ("", GF_LOG_ERROR, "Failed to get iobuf");
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to get iobuf");
goto ret;
}
@@ -88,16 +90,15 @@ glusterfs_serialize_reply (rpcsvc_request_t *req, void *arg,
/* retlen is used to received the error since size_t is unsigned and we
* need -1 for error notification during encoding.
*/
- retlen = sfunc (*outmsg, arg);
+ retlen = xdr_serialize_generic (*outmsg, arg, xdrproc);
if (retlen == -1) {
- gf_log ("", GF_LOG_ERROR, "Failed to encode message");
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to encode message");
goto ret;
}
outmsg->iov_len = retlen;
ret:
if (retlen == -1) {
- iobuf_unref (iob);
iob = NULL;
}
@@ -107,7 +108,7 @@ ret:
int
glusterfs_submit_reply (rpcsvc_request_t *req, void *arg,
struct iovec *payload, int payloadcount,
- struct iobref *iobref, gf_serialize_t sfunc)
+ struct iobref *iobref, xdrproc_t xdrproc)
{
struct iobuf *iob = NULL;
int ret = -1;
@@ -119,25 +120,23 @@ glusterfs_submit_reply (rpcsvc_request_t *req, void *arg,
goto out;
}
-
if (!iobref) {
iobref = iobref_new ();
if (!iobref) {
- gf_log ("", GF_LOG_ERROR, "out of memory");
+ gf_log (THIS->name, GF_LOG_ERROR, "out of memory");
goto out;
}
new_iobref = 1;
}
- iob = glusterfs_serialize_reply (req, arg, sfunc, &rsp);
+ iob = glusterfs_serialize_reply (req, arg, &rsp, xdrproc);
if (!iob) {
- gf_log ("", GF_LOG_ERROR, "Failed to serialize reply");
- goto out;
+ gf_log_callingfn (THIS->name, GF_LOG_ERROR, "Failed to serialize reply");
+ } else {
+ iobref_add (iobref, iob);
}
- iobref_add (iobref, iob);
-
ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount,
iobref);
@@ -145,18 +144,18 @@ glusterfs_submit_reply (rpcsvc_request_t *req, void *arg,
* we can safely unref the iob in the hope that RPC layer must have
* ref'ed the iob on receiving into the txlist.
*/
- iobuf_unref (iob);
if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "Reply submission failed");
+ gf_log (THIS->name, GF_LOG_ERROR, "Reply submission failed");
goto out;
}
ret = 0;
out:
+ if (iob)
+ iobuf_unref (iob);
- if (new_iobref) {
+ if (new_iobref && iobref)
iobref_unref (iobref);
- }
return ret;
}
@@ -175,12 +174,12 @@ glusterfs_terminate_response_send (rpcsvc_request_t *req, int op_ret)
if (dict)
ret = dict_allocate_and_serialize (dict, &rsp.output.output_val,
- (size_t *)&rsp.output.output_len);
+ &rsp.output.output_len);
if (ret == 0)
ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
- gd_xdr_serialize_mgmt_brick_op_rsp);
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
if (rsp.output.output_val)
GF_FREE (rsp.output.output_val);
@@ -190,65 +189,137 @@ glusterfs_terminate_response_send (rpcsvc_request_t *req, int op_ret)
}
int
-glusterfs_listener_stop (void)
+glusterfs_handle_terminate (rpcsvc_request_t *req)
{
- glusterfs_ctx_t *ctx = NULL;
- cmd_args_t *cmd_args = NULL;
- int ret = 0;
- xlator_t *this = NULL;
- ctx = glusterfs_ctx_get ();
- GF_ASSERT (ctx);
- cmd_args = &ctx->cmd_args;
- if (cmd_args->sock_file) {
- ret = unlink (cmd_args->sock_file);
- if (ret && (ENOENT == errno)) {
- ret = 0;
- }
- }
+ glusterfs_terminate_response_send (req, 0);
+ cleanup_and_exit (SIGTERM);
+ return 0;
+}
- if (ret) {
- this = THIS;
- gf_log (this->name, GF_LOG_ERROR, "Failed to unlink linstener "
- "socket %s, error: %s", cmd_args->sock_file,
- strerror (errno));
+int
+glusterfs_translator_info_response_send (rpcsvc_request_t *req, int ret,
+ char *msg, dict_t *output)
+{
+ gd1_mgmt_brick_op_rsp rsp = {0,};
+ gf_boolean_t free_ptr = _gf_false;
+ GF_ASSERT (req);
+
+ rsp.op_ret = ret;
+ rsp.op_errno = 0;
+ if (ret && msg && msg[0])
+ rsp.op_errstr = msg;
+ else
+ rsp.op_errstr = "";
+
+ ret = -1;
+ if (output) {
+ ret = dict_allocate_and_serialize (output,
+ &rsp.output.output_val,
+ &rsp.output.output_len);
}
+ if (!ret)
+ free_ptr = _gf_true;
+
+ glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = 0;
+ if (free_ptr)
+ GF_FREE (rsp.output.output_val);
return ret;
}
int
-glusterfs_handle_terminate (rpcsvc_request_t *req)
+glusterfs_handle_translator_info_get_cont (gfd_vol_top_priv_t *priv)
{
+ int ret = -1;
+ xlator_t *any = NULL;
+ xlator_t *xlator = NULL;
+ glusterfs_graph_t *active = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char msg[2048] = {0,};
+ dict_t *output = NULL;
+ dict_t *dict = NULL;
- (void) glusterfs_listener_stop ();
- glusterfs_terminate_response_send (req, 0);
- cleanup_and_exit (SIGTERM);
- return 0;
+ GF_ASSERT (priv);
+
+ dict = dict_new ();
+ ret = dict_unserialize (priv->xlator_req.input.input_val,
+ priv->xlator_req.input.input_len, &dict);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Unable to unserialize dict");
+ goto cont;
+ }
+ ret = dict_set_double (dict, "time", priv->time);
+ if (ret)
+ goto cont;
+ ret = dict_set_double (dict, "throughput", priv->throughput);
+ if (ret)
+ goto cont;
+
+cont:
+ ctx = glusterfs_ctx_get ();
+ GF_ASSERT (ctx);
+ active = ctx->active;
+ any = active->first;
+
+ xlator = xlator_search_by_name (any, priv->xlator_req.name);
+ if (!xlator) {
+ snprintf (msg, sizeof (msg), "xlator %s is not loaded",
+ priv->xlator_req.name);
+ goto out;
+ }
+
+ output = dict_new ();
+ ret = xlator->notify (xlator, GF_EVENT_TRANSLATOR_INFO, dict, output);
+
+out:
+ ret = glusterfs_translator_info_response_send (priv->req, ret,
+ msg, output);
+
+ if (priv->xlator_req.name)
+ free (priv->xlator_req.name);
+ if (priv->xlator_req.input.input_val)
+ free (priv->xlator_req.input.input_val);
+ if (dict)
+ dict_unref (dict);
+ if (output)
+ dict_unref (output);
+ GF_FREE (priv);
+
+ return ret;
}
int
-glusterfs_translator_info_response_send (rpcsvc_request_t *req, int ret,
- char *msg, dict_t *output)
+glusterfs_xlator_op_response_send (rpcsvc_request_t *req, int op_ret,
+ char *msg, dict_t *output)
{
gd1_mgmt_brick_op_rsp rsp = {0,};
- GF_ASSERT (msg);
+ int ret = -1;
+ gf_boolean_t free_ptr = _gf_false;
GF_ASSERT (req);
- GF_ASSERT (output);
- rsp.op_ret = ret;
+ rsp.op_ret = op_ret;
rsp.op_errno = 0;
- if (ret && msg[0])
+ if (op_ret && msg && msg[0])
rsp.op_errstr = msg;
else
rsp.op_errstr = "";
- ret = dict_allocate_and_serialize (output, &rsp.output.output_val,
- (size_t *)&rsp.output.output_len);
+ if (output) {
+ ret = dict_allocate_and_serialize (output,
+ &rsp.output.output_val,
+ &rsp.output.output_len);
+ }
+ if (!ret)
+ free_ptr = _gf_true;
ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
- gd_xdr_serialize_mgmt_brick_op_rsp);
- if (rsp.output.output_val)
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+
+ if (free_ptr)
GF_FREE (rsp.output.output_val);
+
return ret;
}
@@ -258,6 +329,394 @@ glusterfs_handle_translator_info_get (rpcsvc_request_t *req)
int32_t ret = -1;
gd1_mgmt_brick_op_req xlator_req = {0,};
dict_t *dict = NULL;
+ xlator_t *this = NULL;
+ gf1_cli_top_op top_op = 0;
+ uint32_t blk_size = 0;
+ uint32_t blk_count = 0;
+ gfd_vol_top_priv_t *priv = NULL;
+ pthread_t tid = -1;
+
+ GF_ASSERT (req);
+ this = THIS;
+ GF_ASSERT (this);
+
+ if (!xdr_to_generic (req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+ dict = dict_new ();
+
+ ret = dict_unserialize (xlator_req.input.input_val,
+ xlator_req.input.input_len,
+ &dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ }
+
+ priv = GF_MALLOC (sizeof (gfd_vol_top_priv_t), gfd_mt_vol_top_priv_t);
+ if (!priv) {
+ gf_log ("glusterd", GF_LOG_ERROR, "failed to allocate memory");
+ goto out;
+ }
+ priv->xlator_req = xlator_req;
+ priv->req = req;
+
+ ret = dict_get_int32 (dict, "top-op", (int32_t *)&top_op);
+ if ((!ret) && (GF_CLI_TOP_READ_PERF == top_op ||
+ GF_CLI_TOP_WRITE_PERF == top_op)) {
+ ret = dict_get_uint32 (dict, "blk-size", &blk_size);
+ if (ret)
+ goto cont;
+ ret = dict_get_uint32 (dict, "blk-cnt", &blk_count);
+ if (ret)
+ goto cont;
+ priv->blk_size = blk_size;
+ priv->blk_count = blk_count;
+ if (GF_CLI_TOP_READ_PERF == top_op) {
+ ret = pthread_create (&tid, NULL,
+ glusterfs_volume_top_read_perf,
+ priv);
+ } else if ( GF_CLI_TOP_WRITE_PERF == top_op) {
+ ret = pthread_create (&tid, NULL,
+ glusterfs_volume_top_write_perf,
+ priv);
+ }
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Thread create failed");
+ goto cont;
+ }
+ gf_log ("glusterd", GF_LOG_DEBUG, "Created new thread with "
+ "tid %u", (unsigned int)tid);
+ goto out;
+ }
+cont:
+ priv->throughput = 0;
+ priv->time = 0;
+ ret = glusterfs_handle_translator_info_get_cont (priv);
+out:
+ if (dict)
+ dict_unref (dict);
+ return ret;
+}
+
+void *
+glusterfs_volume_top_write_perf (void *args)
+{
+ int32_t fd = -1;
+ int32_t input_fd = -1;
+ char export_path[PATH_MAX];
+ char *buf = NULL;
+ uint32_t blk_size = 0;
+ uint32_t blk_count = 0;
+ int32_t iter = 0;
+ int32_t ret = -1;
+ uint64_t total_blks = 0;
+ struct timeval begin, end = {0,};
+ double throughput = 0;
+ double time = 0;
+ gfd_vol_top_priv_t *priv = NULL;
+
+ GF_ASSERT (args);
+ priv = (gfd_vol_top_priv_t *)args;
+
+ blk_size = priv->blk_size;
+ blk_count = priv->blk_count;
+
+ snprintf (export_path, sizeof (export_path), "%s/%s",
+ priv->xlator_req.name, ".gf-tmp-stats-perf");
+
+ fd = open (export_path, O_CREAT|O_RDWR, S_IRWXU);
+ if (-1 == fd) {
+ ret = -1;
+ gf_log ("glusterd", GF_LOG_ERROR, "Could not open tmp file");
+ goto out;
+ }
+
+ buf = GF_MALLOC (blk_size * sizeof(*buf), gf_common_mt_char);
+ if (!buf) {
+ ret = -1;
+ goto out;
+ }
+
+ input_fd = open ("/dev/zero", O_RDONLY);
+ if (-1 == input_fd) {
+ ret = -1;
+ gf_log ("glusterd",GF_LOG_ERROR, "Unable to open input file");
+ goto out;
+ }
+
+ gettimeofday (&begin, NULL);
+ for (iter = 0; iter < blk_count; iter++) {
+ ret = read (input_fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ ret = write (fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ total_blks += ret;
+ }
+ ret = 0;
+ if (total_blks != ((uint64_t)blk_size * blk_count)) {
+ gf_log ("glusterd", GF_LOG_WARNING, "Error in write");
+ ret = -1;
+ goto out;
+ }
+
+ gettimeofday (&end, NULL);
+ time = (end.tv_sec - begin.tv_sec) * 1e6
+ + (end.tv_usec - begin.tv_usec);
+ throughput = total_blks / time;
+ gf_log ("glusterd", GF_LOG_INFO, "Throughput %.2f Mbps time %.2f secs "
+ "bytes written %"PRId64, throughput, time, total_blks);
+
+out:
+ priv->throughput = throughput;
+ priv->time = time;
+
+ if (fd >= 0)
+ close (fd);
+ if (input_fd >= 0)
+ close (input_fd);
+ if (buf)
+ GF_FREE (buf);
+ unlink (export_path);
+
+ (void)glusterfs_handle_translator_info_get_cont (priv);
+
+ return NULL;
+}
+
+void *
+glusterfs_volume_top_read_perf (void *args)
+{
+ int32_t fd = -1;
+ int32_t input_fd = -1;
+ int32_t output_fd = -1;
+ char export_path[PATH_MAX];
+ char *buf = NULL;
+ uint32_t blk_size = 0;
+ uint32_t blk_count = 0;
+ int32_t iter = 0;
+ int32_t ret = -1;
+ uint64_t total_blks = 0;
+ struct timeval begin, end = {0,};
+ double throughput = 0;
+ double time = 0;
+ gfd_vol_top_priv_t *priv = NULL;
+
+ GF_ASSERT (args);
+ priv = (gfd_vol_top_priv_t *)args;
+
+ blk_size = priv->blk_size;
+ blk_count = priv->blk_count;
+
+ snprintf (export_path, sizeof (export_path), "%s/%s",
+ priv->xlator_req.name, ".gf-tmp-stats-perf");
+ fd = open (export_path, O_CREAT|O_RDWR, S_IRWXU);
+ if (-1 == fd) {
+ ret = -1;
+ gf_log ("glusterd", GF_LOG_ERROR, "Could not open tmp file");
+ goto out;
+ }
+
+ buf = GF_MALLOC (blk_size * sizeof(*buf), gf_common_mt_char);
+ if (!buf) {
+ ret = -1;
+ gf_log ("glusterd", GF_LOG_ERROR, "Could not allocate memory");
+ goto out;
+ }
+
+ input_fd = open ("/dev/zero", O_RDONLY);
+ if (-1 == input_fd) {
+ ret = -1;
+ gf_log ("glusterd", GF_LOG_ERROR, "Could not open input file");
+ goto out;
+ }
+
+ output_fd = open ("/dev/null", O_RDWR);
+ if (-1 == output_fd) {
+ ret = -1;
+ gf_log ("glusterd", GF_LOG_ERROR, "Could not open output file");
+ goto out;
+ }
+
+ for (iter = 0; iter < blk_count; iter++) {
+ ret = read (input_fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ ret = write (fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ }
+
+ ret = fsync (fd);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "could not flush cache");
+ goto out;
+ }
+ ret = lseek (fd, 0L, 0);
+ if (ret != 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "could not seek back to start");
+ ret = -1;
+ goto out;
+ }
+ gettimeofday (&begin, NULL);
+ for (iter = 0; iter < blk_count; iter++) {
+ ret = read (fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ ret = write (output_fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ total_blks += ret;
+ }
+ ret = 0;
+ if (total_blks != ((uint64_t)blk_size * blk_count)) {
+ ret = -1;
+ gf_log ("glusterd", GF_LOG_WARNING, "Error in read");
+ goto out;
+ }
+
+ gettimeofday (&end, NULL);
+ time = (end.tv_sec - begin.tv_sec) * 1e6
+ + (end.tv_usec - begin.tv_usec);
+ throughput = total_blks / time;
+ gf_log ("glusterd", GF_LOG_INFO, "Throughput %.2f Mbps time %.2f secs "
+ "bytes read %"PRId64, throughput, time, total_blks);
+
+out:
+ priv->throughput = throughput;
+ priv->time = time;
+
+ if (fd >= 0)
+ close (fd);
+ if (input_fd >= 0)
+ close (input_fd);
+ if (output_fd >= 0)
+ close (output_fd);
+ if (buf)
+ GF_FREE (buf);
+ unlink (export_path);
+
+ (void)glusterfs_handle_translator_info_get_cont (priv);
+
+ return NULL;
+}
+
+int
+glusterfs_handle_translator_op (void *data)
+{
+ int32_t ret = -1;
+ gd1_mgmt_brick_op_req xlator_req = {0,};
+ dict_t *input = NULL;
+ xlator_t *xlator = NULL;
+ xlator_t *any = NULL;
+ dict_t *output = NULL;
+ char key[2048] = {0};
+ char *xname = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *this = NULL;
+ int i = 0;
+ int count = 0;
+ rpcsvc_request_t *req = data;
+
+ GF_ASSERT (req);
+ this = THIS;
+ GF_ASSERT (this);
+
+ if (!xdr_to_generic (req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ ctx = glusterfs_ctx_get ();
+ active = ctx->active;
+ any = active->first;
+ input = dict_new ();
+ ret = dict_unserialize (xlator_req.input.input_val,
+ xlator_req.input.input_len,
+ &input);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ } else {
+ input->extra_stdfree = xlator_req.input.input_val;
+ }
+
+ ret = dict_get_int32 (input, "count", &count);
+
+ output = dict_new ();
+ if (!output) {
+ ret = -1;
+ goto out;
+ }
+
+ for (i = 0; i < count; i++) {
+ snprintf (key, sizeof (key), "xl-%d", i);
+ ret = dict_get_str (input, key, &xname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Couldn't get "
+ "xlator %s ", key);
+ goto out;
+ }
+ xlator = xlator_search_by_name (any, xname);
+ if (!xlator) {
+ gf_log (this->name, GF_LOG_ERROR, "xlator %s is not "
+ "loaded", xname);
+ goto out;
+ }
+ }
+ for (i = 0; i < count; i++) {
+ snprintf (key, sizeof (key), "xl-%d", i);
+ ret = dict_get_str (input, key, &xname);
+ xlator = xlator_search_by_name (any, xname);
+ XLATOR_NOTIFY (xlator, GF_EVENT_TRANSLATOR_OP, input, output);
+ if (ret)
+ break;
+ }
+out:
+ glusterfs_xlator_op_response_send (req, ret, "", output);
+ if (input)
+ dict_unref (input);
+ if (output)
+ dict_unref (output);
+ if (xlator_req.name)
+ free (xlator_req.name); //malloced by xdr
+
+ return 0;
+}
+
+
+int
+glusterfs_handle_defrag (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gd1_mgmt_brick_op_req xlator_req = {0,};
+ dict_t *dict = NULL;
xlator_t *xlator = NULL;
xlator_t *any = NULL;
dict_t *output = NULL;
@@ -274,13 +733,21 @@ glusterfs_handle_translator_info_get (rpcsvc_request_t *req)
GF_ASSERT (ctx);
active = ctx->active;
+ if (!active) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
any = active->first;
- if (!gd_xdr_to_mgmt_brick_op_req (req->msg[0], &xlator_req)) {
+ if (!xdr_to_generic (req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
dict = dict_new ();
+ if (!dict)
+ goto out;
ret = dict_unserialize (xlator_req.input.input_val,
xlator_req.input.input_len,
@@ -291,19 +758,24 @@ glusterfs_handle_translator_info_get (rpcsvc_request_t *req)
"unserialize req-buffer to dictionary");
goto out;
}
-
xlator = xlator_search_by_name (any, xlator_req.name);
if (!xlator) {
snprintf (msg, sizeof (msg), "xlator %s is not loaded",
xlator_req.name);
- ret = -1;
goto out;
}
output = dict_new ();
- ret = xlator->notify (xlator, GF_EVENT_TRANSLATOR_INFO, dict, output);
+ if (!output) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = xlator->notify (xlator, GF_EVENT_VOLUME_DEFRAG, dict, output);
+
+ ret = glusterfs_translator_info_response_send (req, ret,
+ msg, output);
out:
- ret = glusterfs_translator_info_response_send (req, ret, msg, output);
if (dict)
dict_unref (dict);
if (xlator_req.input.input_val)
@@ -312,31 +784,471 @@ out:
dict_unref (output);
if (xlator_req.name)
free (xlator_req.name); //malloced by xdr
+
+ return ret;
+
+}
+int
+glusterfs_handle_brick_status (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ gd1_mgmt_brick_op_req brick_req = {0,};
+ gd1_mgmt_brick_op_rsp rsp = {0,};
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *this = NULL;
+ xlator_t *any = NULL;
+ xlator_t *xlator = NULL;
+ dict_t *dict = NULL;
+ dict_t *output = NULL;
+ char *volname = NULL;
+ char *xname = NULL;
+ uint32_t cmd = 0;
+ char *msg = NULL;
+
+ GF_ASSERT (req);
+ this = THIS;
+ GF_ASSERT (this);
+
+ if (!xdr_to_generic (req->msg[0], &brick_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ dict = dict_new ();
+ ret = dict_unserialize (brick_req.input.input_val,
+ brick_req.input.input_len, &dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to unserialize "
+ "req-buffer to dictionary");
+ goto out;
+ }
+
+ ret = dict_get_uint32 (dict, "cmd", &cmd);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Couldn't get status op");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Couldn't get volname");
+ goto out;
+ }
+
+ ctx = glusterfs_ctx_get ();
+ GF_ASSERT (ctx);
+ active = ctx->active;
+ any = active->first;
+
+ ret = gf_asprintf (&xname, "%s-server", volname);
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Out of memory");
+ goto out;
+ }
+
+ xlator = xlator_search_by_name (any, xname);
+ if (!xlator) {
+ gf_log (this->name, GF_LOG_ERROR, "xlator %s is not loaded",
+ xname);
+ ret = -1;
+ goto out;
+ }
+
+
+ output = dict_new ();
+ switch (cmd & GF_CLI_STATUS_MASK) {
+ case GF_CLI_STATUS_MEM:
+ ret = 0;
+ gf_proc_dump_mem_info_to_dict (output);
+ gf_proc_dump_mempool_info_to_dict (ctx, output);
+ break;
+
+ case GF_CLI_STATUS_CLIENTS:
+ ret = xlator->dumpops->priv_to_dict (xlator, output);
+ break;
+
+ case GF_CLI_STATUS_INODE:
+ ret = xlator->dumpops->inode_to_dict (xlator, output);
+ break;
+
+ case GF_CLI_STATUS_FD:
+ ret = xlator->dumpops->fd_to_dict (xlator, output);
+ break;
+
+ case GF_CLI_STATUS_CALLPOOL:
+ ret = 0;
+ gf_proc_dump_pending_frames_to_dict (ctx->pool, output);
+ break;
+
+ default:
+ ret = -1;
+ msg = gf_strdup ("Unknown status op");
+ break;
+ }
+ rsp.op_ret = ret;
+ rsp.op_errno = 0;
+ if (ret && msg)
+ rsp.op_errstr = msg;
+ else
+ rsp.op_errstr = "";
+
+ ret = dict_allocate_and_serialize (output, &rsp.output.output_val,
+ &rsp.output.output_len);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to serialize output dict to rsp");
+ goto out;
+ }
+
+ glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = 0;
+
+out:
+ if (dict)
+ dict_unref (dict);
+ if (output)
+ dict_unref (output);
+ if (brick_req.input.input_val)
+ free (brick_req.input.input_val);
+ if (xname)
+ GF_FREE (xname);
+ if (msg)
+ GF_FREE (msg);
+ if (rsp.output.output_val)
+ GF_FREE (rsp.output.output_val);
+
+ return ret;
+}
+
+static int
+glusterfs_command_done (int ret, call_frame_t *sync_frame, void *data)
+{
+ STACK_DESTROY (sync_frame->root);
+ return 0;
+}
+
+int
+glusterfs_handle_node_status (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ gd1_mgmt_brick_op_req node_req = {0,};
+ gd1_mgmt_brick_op_rsp rsp = {0,};
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *any = NULL;
+ xlator_t *node = NULL;
+ xlator_t *subvol = NULL;
+ dict_t *dict = NULL;
+ dict_t *output = NULL;
+ char *volname = NULL;
+ char *node_name = NULL;
+ char *subvol_name = NULL;
+ uint32_t cmd = 0;
+ char *msg = NULL;
+
+ GF_ASSERT (req);
+
+ if (!xdr_to_generic (req->msg[0], &node_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ dict = dict_new ();
+ ret = dict_unserialize (node_req.input.input_val,
+ node_req.input.input_len, &dict);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to unserialize "
+ "req buffer to dictionary");
+ goto out;
+ }
+
+ ret = dict_get_uint32 (dict, "cmd", &cmd);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get status op");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get volname");
+ goto out;
+ }
+
+ ctx = glusterfs_ctx_get ();
+ GF_ASSERT (ctx);
+ active = ctx->active;
+ any = active->first;
+
+ if ((cmd & GF_CLI_STATUS_NFS) != 0)
+ ret = gf_asprintf (&node_name, "%s", "nfs-server");
+ else if ((cmd & GF_CLI_STATUS_SHD) != 0)
+ ret = gf_asprintf (&node_name, "%s", "glustershd");
+ else {
+ ret = -1;
+ goto out;
+ }
+ if (ret == -1) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to set node xlator name");
+ goto out;
+ }
+
+ node = xlator_search_by_name (any, node_name);
+ if (!node) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_ERROR, "%s xlator is not loaded",
+ node_name);
+ goto out;
+ }
+
+ if ((cmd & GF_CLI_STATUS_NFS) != 0)
+ ret = gf_asprintf (&subvol_name, "%s", volname);
+ else if ((cmd & GF_CLI_STATUS_SHD) != 0)
+ ret = gf_asprintf (&subvol_name, "%s-replicate-0", volname);
+ else {
+ ret = -1;
+ goto out;
+ }
+ if (ret == -1) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to set node xlator name");
+ goto out;
+ }
+
+ subvol = xlator_search_by_name (node, subvol_name);
+ if (!subvol) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_ERROR, "%s xlator is not loaded",
+ subvol_name);
+ goto out;
+ }
+
+ output = dict_new ();
+ switch (cmd & GF_CLI_STATUS_MASK) {
+ case GF_CLI_STATUS_MEM:
+ ret = 0;
+ gf_proc_dump_mem_info_to_dict (output);
+ gf_proc_dump_mempool_info_to_dict (ctx, output);
+ break;
+
+ case GF_CLI_STATUS_CLIENTS:
+ // clients not availbale for SHD
+ if ((cmd & GF_CLI_STATUS_SHD) != 0)
+ break;
+
+ ret = dict_set_str (output, "volname", volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Error setting volname to dict");
+ goto out;
+ }
+ ret = node->dumpops->priv_to_dict (node, output);
+ break;
+
+ case GF_CLI_STATUS_INODE:
+ ret = 0;
+ inode_table_dump_to_dict (subvol->itable, "conn0",
+ output);
+ ret = dict_set_int32 (output, "conncount", 1);
+ break;
+
+ case GF_CLI_STATUS_FD:
+ // cannot find fd-tables in nfs-server graph
+ // TODO: finish once found
+ break;
+
+ case GF_CLI_STATUS_CALLPOOL:
+ ret = 0;
+ gf_proc_dump_pending_frames_to_dict (ctx->pool, output);
+ break;
+
+ default:
+ ret = -1;
+ msg = gf_strdup ("Unknown status op");
+ gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
+ break;
+ }
+ rsp.op_ret = ret;
+ rsp.op_errno = 0;
+ if (ret && msg)
+ rsp.op_errstr = msg;
+ else
+ rsp.op_errstr = "";
+
+ ret = dict_allocate_and_serialize (output, &rsp.output.output_val,
+ &rsp.output.output_len);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to serialize output dict to rsp");
+ goto out;
+ }
+
+ glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = 0;
+
+out:
+ if (dict)
+ dict_unref (dict);
+ if (node_req.input.input_val)
+ free (node_req.input.input_val);
+ if (msg)
+ GF_FREE (msg);
+ if (rsp.output.output_val)
+ GF_FREE (rsp.output.output_val);
+ if (node_name)
+ GF_FREE (node_name);
+ if (subvol_name)
+ GF_FREE (subvol_name);
+
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterfs_handle_nfs_profile (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ gd1_mgmt_brick_op_req nfs_req = {0,};
+ gd1_mgmt_brick_op_rsp rsp = {0,};
+ dict_t *dict = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *any = NULL;
+ xlator_t *nfs = NULL;
+ xlator_t *subvol = NULL;
+ char *volname = NULL;
+ dict_t *output = NULL;
+
+ GF_ASSERT (req);
+
+ if (!xdr_to_generic (req->msg[0], &nfs_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ dict = dict_new ();
+ ret = dict_unserialize (nfs_req.input.input_val,
+ nfs_req.input.input_len, &dict);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to "
+ "unserialize req-buffer to dict");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get volname");
+ goto out;
+ }
+
+ ctx = glusterfs_ctx_get ();
+ GF_ASSERT (ctx);
+
+ active = ctx->active;
+ any = active->first;
+
+ // is this needed?
+ // are problems possible by searching for subvol directly from "any"?
+ nfs = xlator_search_by_name (any, "nfs-server");
+ if (!nfs) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_ERROR, "xlator nfs-server is "
+ "not loaded");
+ goto out;
+ }
+
+ subvol = xlator_search_by_name (nfs, volname);
+ if (!subvol) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_ERROR, "xlator %s is no loaded",
+ volname);
+ goto out;
+ }
+
+ output = dict_new ();
+ ret = subvol->notify (subvol, GF_EVENT_TRANSLATOR_INFO, dict, output);
+
+ rsp.op_ret = ret;
+ rsp.op_errno = 0;
+ rsp.op_errstr = "";
+
+ ret = dict_allocate_and_serialize (output, &rsp.output.output_val,
+ &rsp.output.output_len);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to serialize output dict to rsp");
+ goto out;
+ }
+
+ glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = 0;
+
+out:
+ if (nfs_req.input.input_val)
+ free (nfs_req.input.input_val);
+ if (dict)
+ dict_unref (dict);
+ if (output)
+ dict_unref (output);
+ if (rsp.output.output_val)
+ GF_FREE (rsp.output.output_val);
+
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int
glusterfs_handle_rpc_msg (rpcsvc_request_t *req)
{
- int ret = -1;
- xlator_t *this = THIS;
+ int ret = -1;
+ xlator_t *this = THIS;
+ call_frame_t *frame = NULL;
+
GF_ASSERT (this);
switch (req->procnum) {
- case GF_BRICK_TERMINATE:
+ case GLUSTERD_BRICK_TERMINATE:
ret = glusterfs_handle_terminate (req);
break;
- case GF_BRICK_XLATOR_INFO:
+ case GLUSTERD_BRICK_XLATOR_INFO:
ret = glusterfs_handle_translator_info_get (req);
break;
+ case GLUSTERD_BRICK_XLATOR_OP:
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame)
+ goto out;
+ ret = synctask_new (this->ctx->env,
+ glusterfs_handle_translator_op,
+ glusterfs_command_done, frame, req);
+ break;
+ case GLUSTERD_BRICK_STATUS:
+ ret = glusterfs_handle_brick_status (req);
+ break;
+ case GLUSTERD_BRICK_XLATOR_DEFRAG:
+ ret = glusterfs_handle_defrag (req);
+ break;
+ case GLUSTERD_NODE_PROFILE:
+ ret = glusterfs_handle_nfs_profile (req);
+ break;
+ case GLUSTERD_NODE_STATUS:
+ ret = glusterfs_handle_node_status (req);
default:
break;
}
-
+out:
return ret;
}
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},
};
@@ -370,6 +1282,7 @@ char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
[GF_HNDSK_SETVOLUME] = "SETVOLUME",
[GF_HNDSK_GETSPEC] = "GETSPEC",
[GF_HNDSK_PING] = "PING",
+ [GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
};
rpc_clnt_prog_t clnt_handshake_prog = {
@@ -380,52 +1293,59 @@ rpc_clnt_prog_t clnt_handshake_prog = {
};
rpcsvc_actor_t glusterfs_actors[] = {
- [GF_BRICK_NULL] = { "NULL", GF_BRICK_NULL, glusterfs_handle_rpc_msg, NULL, NULL},
- [GF_BRICK_TERMINATE] = { "TERMINATE", GF_BRICK_TERMINATE, glusterfs_handle_rpc_msg, NULL, NULL},
- [GF_BRICK_XLATOR_INFO] = { "TRANSLATOR INFO", GF_BRICK_XLATOR_INFO, glusterfs_handle_rpc_msg, NULL, NULL}
+ [GLUSTERD_BRICK_NULL] = { "NULL", GLUSTERD_BRICK_NULL, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_BRICK_TERMINATE] = { "TERMINATE", GLUSTERD_BRICK_TERMINATE, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_BRICK_XLATOR_INFO] = { "TRANSLATOR INFO", GLUSTERD_BRICK_XLATOR_INFO, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_BRICK_XLATOR_OP] = { "TRANSLATOR OP", GLUSTERD_BRICK_XLATOR_OP, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_BRICK_STATUS] = {"STATUS", GLUSTERD_BRICK_STATUS, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_BRICK_XLATOR_DEFRAG] = { "TRANSLATOR DEFRAG", GLUSTERD_BRICK_XLATOR_DEFRAG, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_NODE_PROFILE] = {"NFS PROFILE", GLUSTERD_NODE_PROFILE, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_NODE_STATUS] = {"NFS STATUS", GLUSTERD_NODE_STATUS, glusterfs_handle_rpc_msg, NULL, NULL, 0}
};
struct rpcsvc_program glusterfs_mop_prog = {
- .progname = "GlusterFS Mops",
- .prognum = GLUSTERFS_PROGRAM,
- .progver = GLUSTERFS_VERSION,
- .numactors = GLUSTERFS_PROCCNT,
+ .progname = "Gluster Brick operations",
+ .prognum = GD_BRICK_PROGRAM,
+ .progver = GD_BRICK_VERSION,
.actors = glusterfs_actors,
+ .numactors = GLUSTERD_BRICK_MAXVALUE,
};
int
mgmt_submit_request (void *req, call_frame_t *frame,
glusterfs_ctx_t *ctx,
rpc_clnt_prog_t *prog, int procnum,
- mgmt_serialize_t sfunc, fop_cbk_fn_t cbkfn)
+ 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;
}
- iobuf = iobuf_get (ctx->iobuf_pool);
- if (!iobuf) {
- goto out;
- };
+ if (req) {
+ xdr_size = xdr_sizeof (xdrproc, req);
- iobref_add (iobref, iobuf);
+ iobuf = iobuf_get2 (ctx->iobuf_pool, xdr_size);
+ if (!iobuf) {
+ goto out;
+ };
- iov.iov_base = iobuf->ptr;
- iov.iov_len = 128 * GF_UNIT_KB;
+ iobref_add (iobref, iobuf);
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_pagesize (iobuf);
- /* Create the xdr payload */
- if (req && sfunc) {
- ret = sfunc (iov, req);
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic (iov, req, xdrproc);
if (ret == -1) {
- gf_log ("", GF_LOG_WARNING, "failed to create XDR payload");
+ gf_log (THIS->name, GF_LOG_WARNING, "failed to create XDR payload");
goto out;
}
iov.iov_len = ret;
@@ -441,6 +1361,8 @@ out:
if (iobref)
iobref_unref (iobref);
+ if (iobuf)
+ iobuf_unref (iobuf);
return ret;
}
@@ -518,9 +1440,9 @@ out:
}
/* Function has 3types of return value 0, -ve , 1
- * return 0 =======> reconfiguration of options has succeded
+ * 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 occured during the operation
+ * return -1(or -ve) =======> Some Internal Error occurred during the operation
*/
static int
glusterfs_volfile_reconfigure (FILE *newvolfile_fp)
@@ -579,7 +1501,7 @@ glusterfs_volfile_reconfigure (FILE *newvolfile_fp)
if (!oldvolfile_graph) {
gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
- "glsuterfs_ctx->active is NULL");
+ "glusterfs_ctx->active is NULL");
goto out;
}
@@ -616,7 +1538,7 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
goto out;
}
- ret = xdr_to_getspec_rsp (*iov, &rsp);
+ 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;
@@ -634,7 +1556,8 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
size = rsp.op_ret;
if (size == oldvollen && (memcmp (oldvolfile, rsp.spec, size) == 0)) {
- gf_log ("", GF_LOG_INFO, "No change in volfile, continuing");
+ gf_log (frame->this->name, GF_LOG_INFO,
+ "No change in volfile, continuing");
goto out;
}
@@ -650,9 +1573,9 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
/* 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 succeded
+ * 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 occured during the operation
+ * return -1(or -ve) =======> Some Internal Error occurred during the operation
*/
ret = glusterfs_volfile_reconfigure (tmpfp);
@@ -715,30 +1638,149 @@ glusterfs_volfile_fetch (glusterfs_ctx_t *ctx)
req.flags = 0;
ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,
- GF_HNDSK_GETSPEC, xdr_from_getspec_req,
- mgmt_getspec_cbk);
+ GF_HNDSK_GETSPEC, mgmt_getspec_cbk,
+ (xdrproc_t)xdr_gf_getspec_req);
+ return ret;
+}
+
+int32_t
+mgmt_event_notify_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_event_notify_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = 0;
+
+ frame = myframe;
+ ctx = frame->this->ctx;
+
+ if (-1 == req->rpc_status) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_event_notify_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 rsp from server");
+ ret = -1;
+ goto out;
+ }
+out:
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val); //malloced by xdr
return ret;
+
}
+int32_t
+glusterfs_rebalance_event_notify_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf_event_notify_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = 0;
+
+ frame = myframe;
+ ctx = frame->this->ctx;
+
+ if (-1 == req->rpc_status) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "failed to get the rsp from server");
+ ret = -1;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_event_notify_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,
+ "Received error (%s) from server",
+ strerror (rsp.op_errno));
+ ret = -1;
+ goto out;
+ }
+out:
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val); //malloced by xdr
+ return ret;
+
+}
+
+int32_t
+glusterfs_rebalance_event_notify (dict_t *dict)
+{
+ glusterfs_ctx_t *ctx = NULL;
+ gf_event_notify_req req = {0,};
+ int32_t ret = -1;
+ cmd_args_t *cmd_args = NULL;
+ call_frame_t *frame = NULL;
+
+ ctx = glusterfs_ctx_get ();
+ cmd_args = &ctx->cmd_args;
+
+ frame = create_frame (THIS, ctx->pool);
+
+ req.op = GF_EN_DEFRAG_STATUS;
+
+ if (dict) {
+ ret = dict_set_str (dict, "volname", cmd_args->volfile_id);
+ if (ret)
+ gf_log ("", GF_LOG_ERROR, "failed to set volname");
+
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ }
+
+ ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,
+ GF_HNDSK_EVENT_NOTIFY,
+ glusterfs_rebalance_event_notify_cbk,
+ (xdrproc_t)xdr_gf_event_notify_req);
+
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
+
+ STACK_DESTROY (frame->root);
+ 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;
int ret = 0;
this = mydata;
ctx = this->ctx;
-
+ cmd_args = &ctx->cmd_args;
switch (event) {
case RPC_CLNT_DISCONNECT:
if (!ctx->active) {
+ cmd_args->max_connect_attempts--;
gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
"failed to connect with remote-host: %s",
strerror (errno));
- cleanup_and_exit (1);
+ gf_log ("glusterfsd-mgmt", GF_LOG_INFO,
+ "%d connect attempts left",
+ cmd_args->max_connect_attempts);
+ if (0 >= cmd_args->max_connect_attempts)
+ cleanup_and_exit (1);
}
break;
case RPC_CLNT_CONNECT:
@@ -768,16 +1810,10 @@ int
glusterfs_rpcsvc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
void *data)
{
- xlator_t *this = NULL;
- rpc_transport_t *xprt = NULL;
-
if (!xl || !data) {
goto out;
}
- this = xl;
- xprt = data;
-
switch (event) {
case RPCSVC_EVENT_ACCEPT:
{
@@ -817,7 +1853,7 @@ glusterfs_listener_init (glusterfs_ctx_t *ctx)
if (ret)
goto out;
- rpc = rpcsvc_init (ctx, options);
+ rpc = rpcsvc_init (THIS, ctx, options, 8);
if (rpc == NULL) {
goto out;
}
@@ -845,6 +1881,66 @@ out:
}
int
+glusterfs_listener_stop (glusterfs_ctx_t *ctx)
+{
+ cmd_args_t *cmd_args = NULL;
+ rpcsvc_t *rpc = NULL;
+ rpcsvc_listener_t *listener = NULL;
+ rpcsvc_listener_t *next = NULL;
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ GF_ASSERT (ctx);
+
+ rpc = ctx->listener;
+ ctx->listener = NULL;
+
+ (void) rpcsvc_program_unregister(rpc, &glusterfs_mop_prog);
+
+ list_for_each_entry_safe (listener, next, &rpc->listeners, list) {
+ rpcsvc_listener_destroy (listener);
+ }
+
+ (void) rpcsvc_unregister_notify (rpc, glusterfs_rpcsvc_notify, THIS);
+
+ GF_FREE (rpc);
+
+ cmd_args = &ctx->cmd_args;
+ if (cmd_args->sock_file) {
+ ret = unlink (cmd_args->sock_file);
+ if (ret && (ENOENT == errno)) {
+ ret = 0;
+ }
+ }
+
+ if (ret) {
+ this = THIS;
+ gf_log (this->name, GF_LOG_ERROR, "Failed to unlink linstener "
+ "socket %s, error: %s", cmd_args->sock_file,
+ strerror (errno));
+ }
+ return ret;
+}
+
+int
+glusterfs_mgmt_notify (int32_t op, void *data, ...)
+{
+ int ret = 0;
+ switch (op)
+ {
+ case GF_EN_DEFRAG_STATUS:
+ ret = glusterfs_rebalance_event_notify ((dict_t*) data);
+ break;
+
+ default:
+ gf_log ("", GF_LOG_ERROR, "Invalid op");
+ break;
+ }
+
+ return ret;
+}
+
+int
glusterfs_mgmt_init (glusterfs_ctx_t *ctx)
{
cmd_args_t *cmd_args = NULL;
@@ -870,41 +1966,82 @@ glusterfs_mgmt_init (glusterfs_ctx_t *ctx)
if (ret)
goto out;
- rpc = rpc_clnt_new (options, THIS->ctx, THIS->name);
+ rpc = rpc_clnt_new (options, THIS->ctx, THIS->name, 8);
if (!rpc) {
ret = -1;
- gf_log ("", GF_LOG_WARNING, "failed to create rpc clnt");
+ 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 ("", GF_LOG_WARNING, "failed to register notify function");
+ gf_log (THIS->name, GF_LOG_WARNING, "failed to register notify function");
goto out;
}
ret = rpcclnt_cbk_program_register (rpc, &mgmt_cbk_prog);
if (ret) {
- gf_log ("", GF_LOG_WARNING, "failed to register callback function");
+ gf_log (THIS->name, GF_LOG_WARNING, "failed to register callback function");
goto out;
}
- ret = rpc_clnt_start (rpc);
- if (ret)
- 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;
}
static int
+mgmt_pmap_signin2_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ pmap_signin_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ int ret = 0;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_signin_rsp);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR, "XDR decode error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 == rsp.op_ret) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "failed to register the port with glusterd");
+ goto out;
+ }
+out:
+ STACK_DESTROY (frame->root);
+ return 0;
+
+}
+
+static int
mgmt_pmap_signin_cbk (struct rpc_req *req, struct iovec *iov, int count,
void *myframe)
{
pmap_signin_rsp rsp = {0,};
call_frame_t *frame = NULL;
int ret = 0;
+ pmap_signin_req pmap_req = {0, };
+ cmd_args_t *cmd_args = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char brick_name[PATH_MAX] = {0,};
frame = myframe;
@@ -914,7 +2051,7 @@ mgmt_pmap_signin_cbk (struct rpc_req *req, struct iovec *iov, int count,
goto out;
}
- ret = xdr_to_pmap_signin_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_signin_rsp);
if (ret < 0) {
gf_log (frame->this->name, GF_LOG_ERROR, "XDR decode error");
rsp.op_ret = -1;
@@ -927,6 +2064,27 @@ mgmt_pmap_signin_cbk (struct rpc_req *req, struct iovec *iov, int count,
"failed to register the port with glusterd");
goto out;
}
+
+ ctx = glusterfs_ctx_get ();
+ cmd_args = &ctx->cmd_args;
+
+ if (!cmd_args->brick_port2) {
+ /* We are done with signin process */
+ goto out;
+ }
+
+ snprintf (brick_name, PATH_MAX, "%s.rdma", cmd_args->brick_name);
+ pmap_req.port = cmd_args->brick_port2;
+ pmap_req.brick = brick_name;
+
+ ret = mgmt_submit_request (&pmap_req, frame, ctx, &clnt_pmap_prog,
+ GF_PMAP_SIGNIN, mgmt_pmap_signin2_cbk,
+ (xdrproc_t)xdr_pmap_signin_req);
+ if (ret)
+ goto out;
+
+ return 0;
+
out:
STACK_DESTROY (frame->root);
@@ -954,8 +2112,8 @@ glusterfs_mgmt_pmap_signin (glusterfs_ctx_t *ctx)
req.brick = cmd_args->brick_name;
ret = mgmt_submit_request (&req, frame, ctx, &clnt_pmap_prog,
- GF_PMAP_SIGNIN, xdr_from_pmap_signin_req,
- mgmt_pmap_signin_cbk);
+ GF_PMAP_SIGNIN, mgmt_pmap_signin_cbk,
+ (xdrproc_t)xdr_pmap_signin_req);
out:
return ret;
@@ -967,12 +2125,9 @@ mgmt_pmap_signout_cbk (struct rpc_req *req, struct iovec *iov, int count,
void *myframe)
{
pmap_signout_rsp rsp = {0,};
- call_frame_t *frame = NULL;
int ret = 0;
glusterfs_ctx_t *ctx = NULL;
- frame = myframe;
-
if (-1 == req->rpc_status) {
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
@@ -980,22 +2135,20 @@ mgmt_pmap_signout_cbk (struct rpc_req *req, struct iovec *iov, int count,
}
ctx = glusterfs_ctx_get ();
- ret = xdr_to_pmap_signout_rsp (*iov, &rsp);
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_signout_rsp);
if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "XDR decoding failed");
+ gf_log (THIS->name, GF_LOG_ERROR, "XDR decoding failed");
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
goto out;
}
if (-1 == rsp.op_ret) {
- gf_log ("", GF_LOG_ERROR,
+ gf_log (THIS->name, GF_LOG_ERROR,
"failed to register the port with glusterd");
goto out;
}
out:
-// if (frame)
-// STACK_DESTROY (frame->root);
return 0;
}
@@ -1021,8 +2174,8 @@ glusterfs_mgmt_pmap_signout (glusterfs_ctx_t *ctx)
req.brick = cmd_args->brick_name;
ret = mgmt_submit_request (&req, frame, ctx, &clnt_pmap_prog,
- GF_PMAP_SIGNOUT, xdr_from_pmap_signout_req,
- mgmt_pmap_signout_cbk);
+ GF_PMAP_SIGNOUT, mgmt_pmap_signout_cbk,
+ (xdrproc_t)xdr_pmap_signout_req);
out:
return ret;
}
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
index 9406d74ac..51f0a30c9 100644
--- a/glusterfsd/src/glusterfsd.c
+++ b/glusterfsd/src/glusterfsd.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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>
@@ -25,6 +16,7 @@
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/file.h>
+#include <sys/wait.h>
#include <netdb.h>
#include <signal.h>
#include <libgen.h>
@@ -38,6 +30,7 @@
#include <time.h>
#include <semaphore.h>
#include <errno.h>
+#include <pwd.h>
#ifndef _CONFIG_H
#define _CONFIG_H
@@ -74,13 +67,14 @@
#include "call-stub.h"
#include <fnmatch.h>
#include "rpc-clnt.h"
+#include "syncop.h"
-#ifdef GF_DARWIN_HOST_OS
#include "daemon.h"
-#else
-#define os_daemon(u, v) daemon (u, v)
-#endif
+/* process mode definitions */
+#define GF_SERVER_PROCESS 0
+#define GF_CLIENT_PROCESS 1
+#define GF_GLUSTERD_PROCESS 2
/* using argp for command line parsing */
static char gf_doc[] = "";
@@ -89,11 +83,11 @@ static char argp_doc[] = "--volfile-server=SERVER [MOUNT-POINT]\n" \
const char *argp_program_version = "" \
PACKAGE_NAME" "PACKAGE_VERSION" built on "__DATE__" "__TIME__ \
"\nRepository revision: " GLUSTERFS_REPOSITORY_REVISION "\n" \
- "Copyright (c) 2006-2010 Gluster Inc. " \
+ "Copyright (c) 2006-2011 Gluster Inc. " \
"<http://www.gluster.com>\n" \
"GlusterFS comes with ABSOLUTELY NO WARRANTY.\n" \
"You may redistribute copies of GlusterFS under the terms of "\
- "the GNU Affero General Public License.";
+ "the GNU General Public License.";
const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
static error_t parse_opts (int32_t key, char *arg, struct argp_state *_state);
@@ -139,13 +133,23 @@ static struct argp_option gf_options[] = {
{"debug", ARGP_DEBUG_KEY, 0, 0,
"Run in debug mode. This option sets --no-daemon, --log-level "
"to DEBUG and --log-file to console"},
- {"volume-name", ARGP_VOLUME_NAME_KEY, "VOLUME-NAME", 0,
- "Volume name to be used for MOUNT-POINT [default: top most volume "
- "in VOLFILE]"},
- {"xlator-option", ARGP_XLATOR_OPTION_KEY,"VOLUME-NAME.OPTION=VALUE", 0,
- "Add/override a translator option for a volume with specified value"},
+ {"volume-name", ARGP_VOLUME_NAME_KEY, "XLATOR-NAME", 0,
+ "Translator name to be used for MOUNT-POINT [default: top most volume "
+ "definition in VOLFILE]"},
+ {"xlator-option", ARGP_XLATOR_OPTION_KEY,"XLATOR-NAME.OPTION=VALUE", 0,
+ "Add/override an option for a translator in volume file with specified"
+ " value"},
{"read-only", ARGP_READ_ONLY_KEY, 0, 0,
"Mount the filesystem in 'read-only' mode"},
+ {"acl", ARGP_ACL_KEY, 0, 0,
+ "Mount the filesystem with POSIX ACL support"},
+ {"selinux", ARGP_SELINUX_KEY, 0, 0,
+ "Enable SELinux label (extened attributes) support on inodes"},
+ {"enable-ino32", ARGP_INODE32_KEY, "BOOL", OPTION_ARG_OPTIONAL,
+ "Use 32-bit inodes when mounting to workaround broken applications"
+ "that don't support 64-bit inodes"},
+ {"worm", ARGP_WORM_KEY, 0, 0,
+ "Mount the filesystem in 'worm' mode"},
{"mac-compat", ARGP_MAC_COMPAT_KEY, "BOOL", OPTION_ARG_OPTIONAL,
"Provide stubs for attributes needed for seamless operation on Macs "
#ifdef GF_DARWIN_HOST_OS
@@ -171,10 +175,14 @@ static struct argp_option gf_options[] = {
"[default: 1]"},
{"client-pid", ARGP_CLIENT_PID_KEY, "PID", OPTION_HIDDEN,
"client will authenticate itself with process id PID to server"},
+ {"user-map-root", ARGP_USER_MAP_ROOT_KEY, "USER", OPTION_HIDDEN,
+ "replace USER with root in messages"},
{"dump-fuse", ARGP_DUMP_FUSE_KEY, "PATH", 0,
"Dump fuse traffic to PATH"},
{"volfile-check", ARGP_VOLFILE_CHECK_KEY, 0, 0,
"Enable strict volume file checking"},
+ {"mem-accounting", ARGP_MEM_ACCOUNTING_KEY, 0, OPTION_HIDDEN,
+ "Enable internal memory accounting"},
{0, 0, 0, 0, "Miscellaneous Options:"},
{0, }
};
@@ -186,6 +194,7 @@ int glusterfs_pidfile_cleanup (glusterfs_ctx_t *ctx);
int glusterfs_volumes_init (glusterfs_ctx_t *ctx);
int glusterfs_mgmt_init (glusterfs_ctx_t *ctx);
int glusterfs_listener_init (glusterfs_ctx_t *ctx);
+int glusterfs_listener_stop (glusterfs_ctx_t *ctx);
int
create_fuse_mount (glusterfs_ctx_t *ctx)
@@ -193,6 +202,8 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
int ret = 0;
cmd_args_t *cmd_args = NULL;
xlator_t *master = NULL;
+ char *mount_point = NULL;
+ char cwd[PATH_MAX] = {0,};
cmd_args = &ctx->cmd_args;
@@ -202,6 +213,12 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
return 0;
}
+ if (ctx->process_mode != GF_CLIENT_PROCESS) {
+ gf_log("glusterfsd", GF_LOG_ERROR,
+ "Not a client process, not performing mount operation");
+ return -1;
+ }
+
master = GF_CALLOC (1, sizeof (*master),
gfd_mt_xlator_t);
if (!master)
@@ -223,8 +240,28 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
if (!master->options)
goto err;
- ret = dict_set_static_ptr (master->options, ZR_MOUNTPOINT_OPT,
- cmd_args->mount_point);
+ /* Check if mount-point is absolute path,
+ * if not convert to absolute path by concating with CWD
+ */
+ if (cmd_args->mount_point[0] != '/') {
+ if (getcwd (cwd, PATH_MAX) != NULL) {
+ ret = gf_asprintf (&mount_point, "%s/%s", cwd,
+ cmd_args->mount_point);
+ if (ret == -1) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "Could not create absolute mountpoint "
+ "path");
+ goto err;
+ }
+ } else {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "Could not get current working directory");
+ goto err;
+ }
+ } else
+ mount_point = gf_strdup (cmd_args->mount_point);
+
+ ret = dict_set_dynstr (master->options, ZR_MOUNTPOINT_OPT, mount_point);
if (ret < 0) {
gf_log ("glusterfsd", GF_LOG_ERROR,
"failed to set mount-point to options dictionary");
@@ -265,6 +302,17 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
}
}
+ if (cmd_args->uid_map_root) {
+ ret = dict_set_int32 (master->options, "uid-map-root",
+ cmd_args->uid_map_root);
+ if (ret < 0) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "failed to set dict value for key %s",
+ "uid-map-root");
+ goto err;
+ }
+ }
+
if (cmd_args->volfile_check) {
ret = dict_set_int32 (master->options, ZR_STRICT_VOLFILE_CHECK,
cmd_args->volfile_check);
@@ -287,6 +335,42 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
}
}
+ if (cmd_args->acl) {
+ ret = dict_set_static_ptr (master->options, "acl", "on");
+ if (ret < 0) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "failed to set dict value for key acl");
+ goto err;
+ }
+ }
+
+ if (cmd_args->selinux) {
+ ret = dict_set_static_ptr (master->options, "selinux", "on");
+ if (ret < 0) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "failed to set dict value for key selinux");
+ goto err;
+ }
+ }
+
+ if (cmd_args->enable_ino32) {
+ ret = dict_set_static_ptr (master->options, "enable-ino32", "on");
+ if (ret < 0) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "failed to set 'on' for key enable-ino32");
+ goto err;
+ }
+ }
+
+ if (cmd_args->read_only) {
+ ret = dict_set_static_ptr (master->options, "read-only", "on");
+ if (ret < 0) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "failed to set dict value for key read-only");
+ goto err;
+ }
+ }
+
switch (cmd_args->fuse_direct_io_mode) {
case GF_OPTION_DISABLE: /* disable */
ret = dict_set_static_ptr (master->options, ZR_DIRECT_IO_OPT,
@@ -315,6 +399,16 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
break;
}
+ if (!cmd_args->no_daemon_mode) {
+ ret = dict_set_static_ptr (master->options, "sync-to-mount",
+ "enable");
+ if (ret < 0) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "failed to set dict value for key sync-mtab");
+ goto err;
+ }
+ }
+
ret = xlator_init (master);
if (ret) {
gf_log ("", GF_LOG_DEBUG, "failed to initialize fuse translator");
@@ -365,7 +459,6 @@ get_volfp (glusterfs_ctx_t *ctx)
return specfp;
}
-
static int
gf_remember_xlator_option (struct list_head *options, char *arg)
{
@@ -447,12 +540,16 @@ out:
static error_t
parse_opts (int key, char *arg, struct argp_state *state)
{
+ glusterfs_ctx_t *ctx = NULL;
cmd_args_t *cmd_args = NULL;
uint32_t n = 0;
double d = 0.0;
gf_boolean_t b = _gf_false;
char *pwd = NULL;
char tmp_buf[2048] = {0,};
+ char *tmp_str = NULL;
+ char *port_str = NULL;
+ struct passwd *pw = NULL;
cmd_args = state->input;
@@ -477,6 +574,22 @@ parse_opts (int key, char *arg, struct argp_state *state)
cmd_args->read_only = 1;
break;
+ case ARGP_ACL_KEY:
+ cmd_args->acl = 1;
+ break;
+
+ case ARGP_SELINUX_KEY:
+ cmd_args->selinux = 1;
+ break;
+
+ case ARGP_INODE32_KEY:
+ cmd_args->enable_ino32 = 1;
+ break;
+
+ case ARGP_WORM_KEY:
+ cmd_args->worm = 1;
+ break;
+
case ARGP_MAC_COMPAT_KEY:
if (!arg)
arg = "on";
@@ -638,6 +751,15 @@ parse_opts (int key, char *arg, struct argp_state *state)
"unknown client pid %s", arg);
break;
+ case ARGP_USER_MAP_ROOT_KEY:
+ pw = getpwnam (arg);
+ if (pw)
+ cmd_args->uid_map_root = pw->pw_uid;
+ else
+ argp_failure (state, -1, 0,
+ "user %s does not exist", arg);
+ break;
+
case ARGP_VOLFILE_CHECK_KEY:
cmd_args->volfile_check = 1;
break;
@@ -671,14 +793,30 @@ parse_opts (int key, char *arg, struct argp_state *state)
case ARGP_BRICK_PORT_KEY:
n = 0;
- if (gf_string2uint_base10 (arg, &n) == 0) {
+ port_str = strtok_r (arg, ",", &tmp_str);
+ if (gf_string2uint_base10 (port_str, &n) == 0) {
cmd_args->brick_port = n;
+ port_str = strtok_r (NULL, ",", &tmp_str);
+ if (port_str) {
+ if (gf_string2uint_base10 (port_str, &n) == 0)
+ cmd_args->brick_port2 = n;
+ break;
+
+ argp_failure (state, -1, 0,
+ "wrong brick (listen) port %s", arg);
+ }
break;
}
argp_failure (state, -1, 0,
"unknown brick (listen) port %s", arg);
break;
+
+ case ARGP_MEM_ACCOUNTING_KEY:
+ /* TODO: it should have got handled much earlier */
+ ctx = glusterfs_ctx_get ();
+ ctx->mem_accounting = 1;
+ break;
}
return 0;
@@ -705,7 +843,7 @@ cleanup_and_exit (int signum)
ctx->cleanup_started = 1;
glusterfs_mgmt_pmap_signout (ctx);
if (ctx->listener) {
- ctx->listener = NULL;
+ (void) glusterfs_listener_stop (ctx);
}
/* Call fini() of FUSE xlator first:
@@ -721,9 +859,12 @@ cleanup_and_exit (int signum)
exit (0);
#if 0
- /* TODO: Properly do cleanup_and_exit(), with synchronisations */
- if (ctx->mgmt)
+ /* TODO: Properly do cleanup_and_exit(), with synchronization */
+ if (ctx->mgmt) {
+ /* cleanup the saved-frames before last unref */
+ rpc_clnt_connection_cleanup (&ctx->mgmt->conn);
rpc_clnt_unref (ctx->mgmt);
+ }
/* call fini() of each xlator */
trav = NULL;
@@ -755,12 +896,11 @@ reincarnate (int signum)
"Fetching the volume file from server...");
ret = glusterfs_volfile_fetch (ctx);
} else {
- gf_log ("glusterfsd", GF_LOG_INFO,
- "Reloading volfile ...");
- ret = glusterfs_volumes_init (ctx);
+ gf_log ("glusterfsd", GF_LOG_DEBUG,
+ "Not reloading volume specification file on SIGHUP");
}
- /* Also, SIGHUP should do logroate */
+ /* Also, SIGHUP should do logrotate */
gf_log_logrotate (1);
if (ret < 0)
@@ -777,7 +917,6 @@ generate_uuid ()
char tmp_str[1024] = {0,};
char hostname[256] = {0,};
struct timeval tv = {0,};
- struct tm now = {0, };
char now_str[32];
if (gettimeofday (&tv, NULL) == -1) {
@@ -786,23 +925,19 @@ generate_uuid ()
strerror (errno));
}
- if (gethostname (hostname, 256) == -1) {
+ if (gethostname (hostname, sizeof hostname) == -1) {
gf_log ("glusterfsd", GF_LOG_ERROR,
"gethostname: failed %s",
strerror (errno));
}
- localtime_r (&tv.tv_sec, &now);
- strftime (now_str, 32, "%Y/%m/%d-%H:%M:%S", &now);
- snprintf (tmp_str, 1024, "%s-%d-%s:%" GF_PRI_SUSECONDS,
+ gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T);
+ snprintf (tmp_str, sizeof tmp_str, "%s-%d-%s:%" GF_PRI_SUSECONDS,
hostname, getpid(), now_str, tv.tv_usec);
return gf_strdup (tmp_str);
}
-#define GF_SERVER_PROCESS 0
-#define GF_CLIENT_PROCESS 1
-#define GF_GLUSTERD_PROCESS 2
static uint8_t
gf_get_process_mode (char *exec_name)
@@ -907,7 +1042,7 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
ctx->page_size = 128 * GF_UNIT_KB;
- ctx->iobuf_pool = iobuf_pool_new (8 * GF_UNIT_MB, ctx->page_size);
+ ctx->iobuf_pool = iobuf_pool_new ();
if (!ctx->iobuf_pool) {
gf_log ("", GF_LOG_CRITICAL,
"ERROR: glusterfs iobuf pool creation failed");
@@ -929,17 +1064,15 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
return -1;
}
- /* frame_mem_pool size 112 * 16k */
- pool->frame_mem_pool = mem_pool_new (call_frame_t, 16384);
-
+ /* frame_mem_pool size 112 * 4k */
+ pool->frame_mem_pool = mem_pool_new (call_frame_t, 4096);
if (!pool->frame_mem_pool) {
gf_log ("", GF_LOG_CRITICAL,
"ERROR: glusterfs frame pool creation failed");
return -1;
}
- /* stack_mem_pool size 256 * 8k */
- pool->stack_mem_pool = mem_pool_new (call_stack_t, 8192);
-
+ /* stack_mem_pool size 256 * 1024 */
+ pool->stack_mem_pool = mem_pool_new (call_stack_t, 1024);
if (!pool->stack_mem_pool) {
gf_log ("", GF_LOG_CRITICAL,
"ERROR: glusterfs stack pool creation failed");
@@ -953,6 +1086,19 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
return -1;
}
+ ctx->dict_pool = mem_pool_new (dict_t, GF_MEMPOOL_COUNT_OF_DICT_T);
+ if (!ctx->dict_pool)
+ return -1;
+
+ ctx->dict_pair_pool = mem_pool_new (data_pair_t,
+ GF_MEMPOOL_COUNT_OF_DATA_PAIR_T);
+ if (!ctx->dict_pair_pool)
+ return -1;
+
+ ctx->dict_data_pool = mem_pool_new (data_t, GF_MEMPOOL_COUNT_OF_DATA_T);
+ if (!ctx->dict_data_pool)
+ return -1;
+
INIT_LIST_HEAD (&pool->all_frames);
LOCK_INIT (&pool->lock);
ctx->pool = pool;
@@ -963,14 +1109,15 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
/* parsing command line arguments */
cmd_args->log_level = DEFAULT_LOG_LEVEL;
+
+ cmd_args->mac_compat = GF_OPTION_DISABLE;
+ cmd_args->enable_ino32 = GF_OPTION_DISABLE;
#ifdef GF_DARWIN_HOST_OS
- cmd_args->mac_compat = GF_OPTION_DEFERRED;
/* On Darwin machines, O_APPEND is not handled,
* which may corrupt the data
*/
cmd_args->fuse_direct_io_mode = GF_OPTION_DISABLE;
#else
- cmd_args->mac_compat = GF_OPTION_DISABLE;
cmd_args->fuse_direct_io_mode = GF_OPTION_DEFERRED;
#endif
cmd_args->fuse_attribute_timeout = -1;
@@ -985,7 +1132,6 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
return 0;
}
-
static int
logging_init (glusterfs_ctx_t *ctx)
{
@@ -1013,20 +1159,29 @@ logging_init (glusterfs_ctx_t *ctx)
return 0;
}
+void
+gf_check_and_set_mem_acct (int argc, char *argv[], glusterfs_ctx_t *ctx)
+{
+ int i = 0;
+ for (i = 0; i < argc; i++) {
+ if (strcmp (argv[i], "--mem-accounting") == 0) {
+ ctx->mem_accounting = 1;
+ break;
+ }
+ }
+}
int
parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
{
- int process_mode = 0;
- int ret = 0;
- struct stat stbuf = {0, };
- struct tm *tm = NULL;
- time_t utime;
- char timestr[256];
- char tmp_logfile[1024] = { 0 };
- char *tmp_logfile_dyn = NULL;
- char *tmp_logfilebase = NULL;
- cmd_args_t *cmd_args = NULL;
+ int process_mode = 0;
+ int ret = 0;
+ struct stat stbuf = {0, };
+ char timestr[32];
+ char tmp_logfile[1024] = { 0 };
+ char *tmp_logfile_dyn = NULL;
+ char *tmp_logfilebase = NULL;
+ cmd_args_t *cmd_args = NULL;
cmd_args = &ctx->cmd_args;
@@ -1039,6 +1194,17 @@ parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
}
process_mode = gf_get_process_mode (argv[0]);
+ ctx->process_mode = process_mode;
+
+ /* Make sure after the parsing cli, if '--volfile-server' option is
+ given, then '--volfile-id' is mandatory */
+ if (cmd_args->volfile_server && !cmd_args->volfile_id) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "ERROR: '--volfile-id' is mandatory if '-s' OR "
+ "'--volfile-server' option is given");
+ ret = -1;
+ goto out;
+ }
if ((cmd_args->volfile_server == NULL)
&& (cmd_args->volfile == NULL)) {
@@ -1048,6 +1214,19 @@ parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
cmd_args->volfile = gf_strdup (DEFAULT_GLUSTERD_VOLFILE);
else
cmd_args->volfile = gf_strdup (DEFAULT_CLIENT_VOLFILE);
+
+ /* Check if the volfile exists, if not give usage output
+ and exit */
+ ret = stat (cmd_args->volfile, &stbuf);
+ if (ret) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "ERROR: parsing the volfile failed (%s)\n",
+ strerror (errno));
+ /* argp_usage (argp.) */
+ fprintf (stderr, "USAGE: %s [options] [mountpoint]\n",
+ argv[0]);
+ goto out;
+ }
}
if (cmd_args->run_id) {
@@ -1058,9 +1237,9 @@ parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
if (((ret == 0) &&
(S_ISREG (stbuf.st_mode) || S_ISLNK (stbuf.st_mode))) ||
(ret == -1)) {
- /* Have seperate logfile per run */
- tm = localtime (&utime);
- strftime (timestr, 256, "%Y%m%d.%H%M%S", tm);
+ /* Have separate logfile per run */
+ gf_time_fmt (timestr, sizeof timestr, time (NULL),
+ gf_timefmt_FT);
sprintf (tmp_logfile, "%s.%s.%d",
cmd_args->log_file, timestr, getpid ());
@@ -1073,15 +1252,23 @@ parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
cmd_args->log_file);
if (ret == -1) {
fprintf (stderr, "ERROR: symlink of logfile failed\n");
- } else {
- GF_FREE (cmd_args->log_file);
- cmd_args->log_file = gf_strdup (tmp_logfile);
+ goto out;
}
+ GF_FREE (cmd_args->log_file);
+ cmd_args->log_file = gf_strdup (tmp_logfile);
+
GF_FREE (tmp_logfile_dyn);
}
}
+#ifdef GF_DARWIN_HOST_OS
+ if (cmd_args->mount_point)
+ cmd_args->mac_compat = GF_OPTION_DEFERRED;
+#endif
+
+ ret = 0;
+out:
return ret;
}
@@ -1135,7 +1322,7 @@ glusterfs_pidfile_setup (glusterfs_ctx_t *ctx)
int
glusterfs_pidfile_cleanup (glusterfs_ctx_t *ctx)
{
- cmd_args_t *cmd_args = NULL;
+ cmd_args_t *cmd_args = NULL;
cmd_args = &ctx->cmd_args;
@@ -1143,18 +1330,18 @@ glusterfs_pidfile_cleanup (glusterfs_ctx_t *ctx)
return 0;
gf_log ("glusterfsd", GF_LOG_TRACE,
- "pidfile %s unlocking",
+ "pidfile %s cleanup",
cmd_args->pid_file);
- lockf (fileno (ctx->pidfp), F_ULOCK, 0);
- fclose (ctx->pidfp);
- ctx->pidfp = NULL;
-
if (ctx->cmd_args.pid_file) {
unlink (ctx->cmd_args.pid_file);
ctx->cmd_args.pid_file = NULL;
}
+ lockf (fileno (ctx->pidfp), F_ULOCK, 0);
+ fclose (ctx->pidfp);
+ ctx->pidfp = NULL;
+
return 0;
}
@@ -1219,6 +1406,7 @@ glusterfs_sigwaiter (void *arg)
int sig = 0;
+ sigemptyset (&set);
sigaddset (&set, SIGINT); /* cleanup_and_exit */
sigaddset (&set, SIGTERM); /* cleanup_and_exit */
sigaddset (&set, SIGHUP); /* reincarnate */
@@ -1310,6 +1498,7 @@ daemonize (glusterfs_ctx_t *ctx)
{
int ret = -1;
cmd_args_t *cmd_args = NULL;
+ int cstatus = 0;
cmd_args = &ctx->cmd_args;
@@ -1323,11 +1512,24 @@ daemonize (glusterfs_ctx_t *ctx)
if (cmd_args->debug_mode)
goto postfork;
- ret = os_daemon (0, 0);
- if (ret == -1) {
+ ret = os_daemon_return (0, 0);
+ switch (ret) {
+ case -1:
gf_log ("daemonize", GF_LOG_ERROR,
"Daemonization failed: %s", strerror(errno));
goto out;
+ case 0:
+ break;
+ default:
+ if (ctx->mnt_pid > 0) {
+ ret = waitpid (ctx->mnt_pid, &cstatus, 0);
+ if (!(ret == ctx->mnt_pid && cstatus == 0)) {
+ gf_log ("daemonize", GF_LOG_ERROR,
+ "mount failed");
+ exit (1);
+ }
+ }
+ _exit (0);
}
postfork:
@@ -1446,7 +1648,10 @@ main (int argc, char *argv[])
"ERROR: glusterfs context not initialized");
return ENOMEM;
}
-
+#ifndef DEBUG
+ /* Enable memory accounting on the fly based on argument */
+ gf_check_and_set_mem_acct (argc, argv, ctx);
+#endif
ret = glusterfs_ctx_defaults_init (ctx);
if (ret)
goto out;
@@ -1459,6 +1664,11 @@ main (int argc, char *argv[])
if (ret)
goto out;
+ /* log the version of glusterfs running here */
+ gf_log (argv[0], GF_LOG_INFO,
+ "Started running %s version %s",
+ argv[0], PACKAGE_VERSION);
+
gf_proc_dump_init();
ret = create_fuse_mount (ctx);
@@ -1469,6 +1679,13 @@ main (int argc, char *argv[])
if (ret)
goto out;
+ ctx->env = syncenv_new (0);
+ if (!ctx->env) {
+ gf_log ("", GF_LOG_ERROR,
+ "Could not create new sync-environment");
+ goto out;
+ }
+
ret = glusterfs_volumes_init (ctx);
if (ret)
goto out;
diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h
index 6fb1ebbe3..30e3a543c 100644
--- a/glusterfsd/src/glusterfsd.h
+++ b/glusterfsd/src/glusterfsd.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __GLUSTERFSD_H__
@@ -24,7 +15,8 @@
#define _CONFIG_H
#include "config.h"
#endif
-
+#include "rpcsvc.h"
+#include "glusterd1-xdr.h"
#define DEFAULT_GLUSTERD_VOLFILE CONFDIR "/glusterd.vol"
#define DEFAULT_CLIENT_VOLFILE CONFDIR "/glusterfs.vol"
@@ -39,12 +31,17 @@
#define ARGP_LOG_LEVEL_CRITICAL_OPTION "CRITICAL"
#define ARGP_LOG_LEVEL_ERROR_OPTION "ERROR"
#define ARGP_LOG_LEVEL_WARNING_OPTION "WARNING"
-#define ARGP_LOG_LEVEL_INFO_OPTION "INFO"
+#define ARGP_LOG_LEVEL_INFO_OPTION "INFO"
#define ARGP_LOG_LEVEL_DEBUG_OPTION "DEBUG"
#define ENABLE_NO_DAEMON_MODE 1
#define ENABLE_DEBUG_MODE 1
+#define GF_MEMPOOL_COUNT_OF_DICT_T 4096
+/* Considering 4 key/value pairs in a dictionary on an average */
+#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)
+
enum argp_option_keys {
ARGP_VOLFILE_SERVER_KEY = 's',
ARGP_VOLUME_FILE_KEY = 'f',
@@ -76,11 +73,30 @@ enum argp_option_keys {
ARGP_BRICK_NAME_KEY = 151,
ARGP_BRICK_PORT_KEY = 152,
ARGP_CLIENT_PID_KEY = 153,
+ ARGP_ACL_KEY = 154,
+ ARGP_WORM_KEY = 155,
+ ARGP_USER_MAP_ROOT_KEY = 156,
+ ARGP_MEM_ACCOUNTING_KEY = 157,
+ ARGP_SELINUX_KEY = 158,
+ ARGP_INODE32_KEY = 159,
+};
+
+struct _gfd_vol_top_priv_t {
+ rpcsvc_request_t *req;
+ gd1_mgmt_brick_op_req xlator_req;
+ uint32_t blk_count;
+ uint32_t blk_size;
+ double throughput;
+ double time;
+ int32_t ret;
};
+typedef struct _gfd_vol_top_priv_t gfd_vol_top_priv_t;
int glusterfs_mgmt_pmap_signout (glusterfs_ctx_t *ctx);
int glusterfs_mgmt_pmap_signin (glusterfs_ctx_t *ctx);
int glusterfs_volfile_fetch (glusterfs_ctx_t *ctx);
void cleanup_and_exit (int signum);
+void *glusterfs_volume_top_read_perf (void *args);
+void *glusterfs_volume_top_write_perf (void *args);
#endif /* __GLUSTERFSD_H__ */
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index 4c1c87360..aadd97971 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -1,21 +1,54 @@
-libglusterfs_la_CFLAGS = -fPIC -Wall -g -shared -nostartfiles $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS)
+libglusterfs_la_CFLAGS = -fPIC -Wall -g -shared -nostartfiles $(GF_CFLAGS) \
+ $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \
+ -DDATADIR=\"$(localstatedir)\"
-libglusterfs_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D_GNU_SOURCE -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" -D$(GF_HOST_OS) -I$(CONTRIBDIR)/rbtree -DSCHEDULERDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler\" -I$(CONTRIBDIR)/md5
+libglusterfs_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 \
+ -D_GNU_SOURCE -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \
+ -D$(GF_HOST_OS) -I$(CONTRIBDIR)/rbtree \
+ -DSCHEDULERDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler\"
libglusterfs_la_LIBADD = @LEXLIB@
lib_LTLIBRARIES = libglusterfs.la
-libglusterfs_la_SOURCES = dict.c graph.lex.c y.tab.c xlator.c logging.c hashfn.c defaults.c common-utils.c timer.c inode.c call-stub.c compat.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c iobuf.c globals.c statedump.c stack.c checksum.c $(CONTRIBDIR)/md5/md5.c $(CONTRIBDIR)/rbtree/rb.c rbthash.c latency.c graph.c $(CONTRIBDIR)/uuid/clear.c $(CONTRIBDIR)/uuid/copy.c $(CONTRIBDIR)/uuid/gen_uuid.c $(CONTRIBDIR)/uuid/pack.c $(CONTRIBDIR)/uuid/parse.c $(CONTRIBDIR)/uuid/unparse.c $(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c $(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c graph-print.c trie.c
-
-noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h logging.h xlator.h stack.h timer.h list.h inode.h call-stub.h compat.h fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h gf-dirent.h locking.h syscall.h iobuf.h globals.h statedump.h checksum.h $(CONTRIBDIR)/md5/md5.h $(CONTRIBDIR)/rbtree/rb.h rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h $(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h $(CONTRIBDIR)/uuid/uuid_types.h syncop.h graph-utils.h graph-mem-types.h trie.h trie-mem-types.h
-
-EXTRA_DIST = graph.l graph.y $(CONTRIBDIR)/apple/daemon.c $(CONTRIBDIR)/apple/daemon.h
+CONTRIB_BUILDDIR = $(top_builddir)/contrib
+
+libglusterfs_la_SOURCES = dict.c xlator.c logging.c \
+ hashfn.c defaults.c common-utils.c timer.c inode.c call-stub.c \
+ compat.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c \
+ iobuf.c globals.c statedump.c stack.c checksum.c daemon.c \
+ $(CONTRIBDIR)/rbtree/rb.c rbthash.c latency.c \
+ graph.c $(CONTRIBDIR)/uuid/clear.c $(CONTRIBDIR)/uuid/copy.c \
+ $(CONTRIBDIR)/uuid/gen_uuid.c $(CONTRIBDIR)/uuid/pack.c \
+ $(CONTRIBDIR)/uuid/parse.c $(CONTRIBDIR)/uuid/unparse.c \
+ $(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c \
+ $(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c \
+ graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c \
+ event-history.c \
+ $(CONTRIBDIR)/libgen/basename_r.c $(CONTRIBDIR)/libgen/dirname_r.c \
+ $(CONTRIBDIR)/stdlib/gf_mkostemp.c
+
+nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c
+
+BUILT_SOURCES = graph.lex.c
+
+noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h \
+ logging.h xlator.h stack.h timer.h list.h inode.h call-stub.h compat.h \
+ fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h \
+ gf-dirent.h locking.h syscall.h iobuf.h globals.h statedump.h \
+ checksum.h daemon.h $(CONTRIBDIR)/rbtree/rb.h \
+ rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h \
+ $(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h \
+ $(CONTRIB_BUILDDIR)/uuid/uuid_types.h syncop.h graph-utils.h trie.h run.h \
+ options.h lkowner.h fd-lk.h circ-buff.h event-history.h
+
+EXTRA_DIST = graph.l graph.y
graph.lex.c: graph.l y.tab.h
$(LEX) -t $(srcdir)/graph.l > $@
-y.tab.c y.tab.h: graph.y
+y.tab.h: graph.y
$(YACC) -d $(srcdir)/graph.y
CLEANFILES = graph.lex.c y.tab.c y.tab.h
+CONFIG_CLEAN_FILES = $(CONTRIB_BUILDDIR)/uuid/uuid_types.h
diff --git a/libglusterfs/src/byte-order.h b/libglusterfs/src/byte-order.h
index cabfcf4c6..4101db2c7 100644
--- a/libglusterfs/src/byte-order.h
+++ b/libglusterfs/src/byte-order.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _BYTE_ORDER_H
@@ -38,6 +29,23 @@ static uint64_t (*hton64) (uint64_t);
#define ntoh32 hton32
#define ntoh64 hton64
+static uint16_t (*htole16) (uint16_t);
+static uint32_t (*htole32) (uint32_t);
+static uint64_t (*htole64) (uint64_t);
+
+#define letoh16 htole16
+#define letoh32 htole32
+#define letoh64 htole64
+
+static uint16_t (*htobe16) (uint16_t);
+static uint32_t (*htobe32) (uint32_t);
+static uint64_t (*htobe64) (uint64_t);
+
+#define betoh16 htobe16
+#define betoh32 htobe32
+#define betoh64 htobe64
+
+
#define do_swap2(x) (((x&LS1) << 8)|(((x&MS1) >> 8)))
#define do_swap4(x) ((do_swap2(x&LS2) << 16)|(do_swap2((x&MS2) >> 16)))
#define do_swap8(x) ((do_swap4(x&LS4) << 32)|(do_swap4((x&MS4) >> 32)))
@@ -86,15 +94,17 @@ __noswap64 (uint64_t x)
static inline uint16_t
-__byte_order_init16 (uint16_t i)
+__byte_order_n16 (uint16_t i)
{
uint32_t num = 1;
if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
hton16 = __swap16;
hton32 = __swap32;
hton64 = __swap64;
} else {
+ /* cpu is be */
hton16 = __noswap16;
hton32 = __noswap32;
hton64 = __noswap64;
@@ -105,15 +115,17 @@ __byte_order_init16 (uint16_t i)
static inline uint32_t
-__byte_order_init32 (uint32_t i)
+__byte_order_n32 (uint32_t i)
{
uint32_t num = 1;
if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
hton16 = __swap16;
hton32 = __swap32;
hton64 = __swap64;
} else {
+ /* cpu is be */
hton16 = __noswap16;
hton32 = __noswap32;
hton64 = __noswap64;
@@ -124,15 +136,17 @@ __byte_order_init32 (uint32_t i)
static inline uint64_t
-__byte_order_init64 (uint64_t i)
+__byte_order_n64 (uint64_t i)
{
uint32_t num = 1;
if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
hton16 = __swap16;
hton32 = __swap32;
hton64 = __swap64;
} else {
+ /* cpu is be */
hton16 = __noswap16;
hton32 = __noswap32;
hton64 = __noswap64;
@@ -142,9 +156,146 @@ __byte_order_init64 (uint64_t i)
}
-static uint16_t (*hton16) (uint16_t) = __byte_order_init16;
-static uint32_t (*hton32) (uint32_t) = __byte_order_init32;
-static uint64_t (*hton64) (uint64_t) = __byte_order_init64;
+static uint16_t (*hton16) (uint16_t) = __byte_order_n16;
+static uint32_t (*hton32) (uint32_t) = __byte_order_n32;
+static uint64_t (*hton64) (uint64_t) = __byte_order_n64;
+
+
+static inline uint16_t
+__byte_order_le16 (uint16_t i)
+{
+ uint32_t num = 1;
+
+ if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
+ htole16 = __noswap16;
+ htole32 = __noswap32;
+ htole64 = __noswap64;
+ } else {
+ /* cpu is be */
+ htole16 = __swap16;
+ htole32 = __swap32;
+ htole64 = __swap64;
+ }
+
+ return htole16 (i);
+}
+
+
+static inline uint32_t
+__byte_order_le32 (uint32_t i)
+{
+ uint32_t num = 1;
+
+ if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
+ htole16 = __noswap16;
+ htole32 = __noswap32;
+ htole64 = __noswap64;
+ } else {
+ /* cpu is be */
+ htole16 = __swap16;
+ htole32 = __swap32;
+ htole64 = __swap64;
+ }
+
+ return htole32 (i);
+}
+
+
+static inline uint64_t
+__byte_order_le64 (uint64_t i)
+{
+ uint32_t num = 1;
+
+ if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
+ htole16 = __noswap16;
+ htole32 = __noswap32;
+ htole64 = __noswap64;
+ } else {
+ /* cpu is be */
+ htole16 = __swap16;
+ htole32 = __swap32;
+ htole64 = __swap64;
+ }
+
+ return htole64 (i);
+}
+
+
+static uint16_t (*htole16) (uint16_t) = __byte_order_le16;
+static uint32_t (*htole32) (uint32_t) = __byte_order_le32;
+static uint64_t (*htole64) (uint64_t) = __byte_order_le64;
+
+
+static inline uint16_t
+__byte_order_be16 (uint16_t i)
+{
+ uint32_t num = 1;
+
+ if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
+ htobe16 = __swap16;
+ htobe32 = __swap32;
+ htobe64 = __swap64;
+ } else {
+ /* cpu is be */
+ htobe16 = __noswap16;
+ htobe32 = __noswap32;
+ htobe64 = __noswap64;
+ }
+
+ return htobe16 (i);
+}
+
+
+static inline uint32_t
+__byte_order_be32 (uint32_t i)
+{
+ uint32_t num = 1;
+
+ if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
+ htobe16 = __swap16;
+ htobe32 = __swap32;
+ htobe64 = __swap64;
+ } else {
+ /* cpu is be */
+ htobe16 = __noswap16;
+ htobe32 = __noswap32;
+ htobe64 = __noswap64;
+ }
+
+ return htobe32 (i);
+}
+
+
+static inline uint64_t
+__byte_order_be64 (uint64_t i)
+{
+ uint32_t num = 1;
+
+ if (((char *)(&num))[0] == 1) {
+ /* cpu is le */
+ htobe16 = __swap16;
+ htobe32 = __swap32;
+ htobe64 = __swap64;
+ } else {
+ /* cpu is be */
+ htobe16 = __noswap16;
+ htobe32 = __noswap32;
+ htobe64 = __noswap64;
+ }
+
+ return htobe64 (i);
+}
+
+
+static uint16_t (*htobe16) (uint16_t) = __byte_order_be16;
+static uint32_t (*htobe32) (uint32_t) = __byte_order_be32;
+static uint64_t (*htobe64) (uint64_t) = __byte_order_be64;
+
#endif /* _BYTE_ORDER_H */
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c
index 3715dfffa..85a1aaa7b 100644
--- a/libglusterfs/src/call-stub.c
+++ b/libglusterfs/src/call-stub.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -22,9 +13,9 @@
#include "config.h"
#endif
+#include <openssl/md5.h>
#include <inttypes.h>
-#include "md5.h"
#include "call-stub.h"
#include "mem-types.h"
@@ -55,7 +46,7 @@ call_stub_t *
fop_lookup_stub (call_frame_t *frame,
fop_lookup_t fn,
loc_t *loc,
- dict_t *xattr_req)
+ dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -67,10 +58,10 @@ fop_lookup_stub (call_frame_t *frame,
stub->args.lookup.fn = fn;
- if (xattr_req)
- stub->args.lookup.xattr_req = dict_ref (xattr_req);
-
loc_copy (&stub->args.lookup.loc, loc);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -83,7 +74,7 @@ fop_lookup_cbk_stub (call_frame_t *frame,
int32_t op_errno,
inode_t *inode,
struct iatt *buf,
- dict_t *dict,
+ dict_t *xdata,
struct iatt *postparent)
{
call_stub_t *stub = NULL;
@@ -100,10 +91,11 @@ fop_lookup_cbk_stub (call_frame_t *frame,
stub->args.lookup_cbk.inode = inode_ref (inode);
if (buf)
stub->args.lookup_cbk.buf = *buf;
- if (dict)
- stub->args.lookup_cbk.dict = dict_ref (dict);
if (postparent)
stub->args.lookup_cbk.postparent = *postparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -113,7 +105,7 @@ out:
call_stub_t *
fop_stat_stub (call_frame_t *frame,
fop_stat_t fn,
- loc_t *loc)
+ loc_t *loc, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -125,6 +117,9 @@ fop_stat_stub (call_frame_t *frame,
stub->args.stat.fn = fn;
loc_copy (&stub->args.stat.loc, loc);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -135,7 +130,7 @@ fop_stat_cbk_stub (call_frame_t *frame,
fop_stat_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct iatt *buf, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -149,6 +144,9 @@ fop_stat_cbk_stub (call_frame_t *frame,
stub->args.stat_cbk.op_errno = op_errno;
if (op_ret == 0)
stub->args.stat_cbk.buf = *buf;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -157,7 +155,7 @@ out:
call_stub_t *
fop_fstat_stub (call_frame_t *frame,
fop_fstat_t fn,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -170,6 +168,9 @@ fop_fstat_stub (call_frame_t *frame,
if (fd)
stub->args.fstat.fd = fd_ref (fd);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -180,7 +181,7 @@ fop_fstat_cbk_stub (call_frame_t *frame,
fop_fstat_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct iatt *buf, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -194,6 +195,9 @@ fop_fstat_cbk_stub (call_frame_t *frame,
stub->args.fstat_cbk.op_errno = op_errno;
if (buf)
stub->args.fstat_cbk.buf = *buf;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -205,7 +209,7 @@ call_stub_t *
fop_truncate_stub (call_frame_t *frame,
fop_truncate_t fn,
loc_t *loc,
- off_t off)
+ off_t off, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -218,6 +222,9 @@ fop_truncate_stub (call_frame_t *frame,
stub->args.truncate.fn = fn;
loc_copy (&stub->args.truncate.loc, loc);
stub->args.truncate.off = off;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -229,7 +236,7 @@ fop_truncate_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf)
+ struct iatt *postbuf, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -245,6 +252,9 @@ fop_truncate_cbk_stub (call_frame_t *frame,
stub->args.truncate_cbk.prebuf = *prebuf;
if (postbuf)
stub->args.truncate_cbk.postbuf = *postbuf;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -254,7 +264,7 @@ call_stub_t *
fop_ftruncate_stub (call_frame_t *frame,
fop_ftruncate_t fn,
fd_t *fd,
- off_t off)
+ off_t off, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -268,6 +278,9 @@ fop_ftruncate_stub (call_frame_t *frame,
stub->args.ftruncate.fd = fd_ref (fd);
stub->args.ftruncate.off = off;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -279,7 +292,7 @@ fop_ftruncate_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf)
+ struct iatt *postbuf, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -295,6 +308,9 @@ fop_ftruncate_cbk_stub (call_frame_t *frame,
stub->args.ftruncate_cbk.prebuf = *prebuf;
if (postbuf)
stub->args.ftruncate_cbk.postbuf = *postbuf;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -304,7 +320,7 @@ call_stub_t *
fop_access_stub (call_frame_t *frame,
fop_access_t fn,
loc_t *loc,
- int32_t mask)
+ int32_t mask, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -317,6 +333,9 @@ fop_access_stub (call_frame_t *frame,
stub->args.access.fn = fn;
loc_copy (&stub->args.access.loc, loc);
stub->args.access.mask = mask;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -326,7 +345,7 @@ call_stub_t *
fop_access_cbk_stub (call_frame_t *frame,
fop_access_cbk_t fn,
int32_t op_ret,
- int32_t op_errno)
+ int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -338,6 +357,9 @@ fop_access_cbk_stub (call_frame_t *frame,
stub->args.access_cbk.fn = fn;
stub->args.access_cbk.op_ret = op_ret;
stub->args.access_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -347,7 +369,7 @@ call_stub_t *
fop_readlink_stub (call_frame_t *frame,
fop_readlink_t fn,
loc_t *loc,
- size_t size)
+ size_t size, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -360,6 +382,9 @@ fop_readlink_stub (call_frame_t *frame,
stub->args.readlink.fn = fn;
loc_copy (&stub->args.readlink.loc, loc);
stub->args.readlink.size = size;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -371,7 +396,7 @@ fop_readlink_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *path,
- struct iatt *sbuf)
+ struct iatt *sbuf, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -387,14 +412,17 @@ fop_readlink_cbk_stub (call_frame_t *frame,
stub->args.readlink_cbk.buf = gf_strdup (path);
if (sbuf)
stub->args.readlink_cbk.sbuf = *sbuf;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
call_stub_t *
-fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn,
- loc_t *loc, mode_t mode, dev_t rdev, dict_t *params)
+fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -408,8 +436,10 @@ fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn,
loc_copy (&stub->args.mknod.loc, loc);
stub->args.mknod.mode = mode;
stub->args.mknod.rdev = rdev;
- if (params)
- stub->args.mknod.params = dict_ref (params);
+ stub->args.mknod.umask = umask;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -423,7 +453,7 @@ fop_mknod_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -443,6 +473,9 @@ fop_mknod_cbk_stub (call_frame_t *frame,
stub->args.mknod_cbk.preparent = *preparent;
if (postparent)
stub->args.mknod_cbk.postparent = *postparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -450,7 +483,7 @@ out:
call_stub_t *
fop_mkdir_stub (call_frame_t *frame, fop_mkdir_t fn,
- loc_t *loc, mode_t mode, dict_t *params)
+ loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -462,9 +495,12 @@ fop_mkdir_stub (call_frame_t *frame, fop_mkdir_t fn,
stub->args.mkdir.fn = fn;
loc_copy (&stub->args.mkdir.loc, loc);
- stub->args.mkdir.mode = mode;
- if (params)
- stub->args.mkdir.params = dict_ref (params);
+ stub->args.mkdir.mode = mode;
+ stub->args.mkdir.umask = umask;
+
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -478,7 +514,7 @@ fop_mkdir_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -498,6 +534,9 @@ fop_mkdir_cbk_stub (call_frame_t *frame,
stub->args.mkdir_cbk.preparent = *preparent;
if (postparent)
stub->args.mkdir_cbk.postparent = *postparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -506,7 +545,7 @@ out:
call_stub_t *
fop_unlink_stub (call_frame_t *frame,
fop_unlink_t fn,
- loc_t *loc)
+ loc_t *loc, int xflag, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -518,6 +557,10 @@ fop_unlink_stub (call_frame_t *frame,
stub->args.unlink.fn = fn;
loc_copy (&stub->args.unlink.loc, loc);
+ stub->args.unlink.xflag = xflag;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -529,7 +572,7 @@ fop_unlink_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -545,6 +588,9 @@ fop_unlink_cbk_stub (call_frame_t *frame,
stub->args.unlink_cbk.preparent = *preparent;
if (postparent)
stub->args.unlink_cbk.postparent = *postparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -553,7 +599,7 @@ out:
call_stub_t *
fop_rmdir_stub (call_frame_t *frame, fop_rmdir_t fn,
- loc_t *loc, int flags)
+ loc_t *loc, int flags, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -566,6 +612,9 @@ fop_rmdir_stub (call_frame_t *frame, fop_rmdir_t fn,
stub->args.rmdir.fn = fn;
loc_copy (&stub->args.rmdir.loc, loc);
stub->args.rmdir.flags = flags;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -577,7 +626,7 @@ fop_rmdir_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -593,6 +642,9 @@ fop_rmdir_cbk_stub (call_frame_t *frame,
stub->args.rmdir_cbk.preparent = *preparent;
if (postparent)
stub->args.rmdir_cbk.postparent = *postparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -600,7 +652,7 @@ out:
call_stub_t *
fop_symlink_stub (call_frame_t *frame, fop_symlink_t fn,
- const char *linkname, loc_t *loc, dict_t *params)
+ const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -613,9 +665,11 @@ fop_symlink_stub (call_frame_t *frame, fop_symlink_t fn,
stub->args.symlink.fn = fn;
stub->args.symlink.linkname = gf_strdup (linkname);
+ stub->args.symlink.umask = umask;
loc_copy (&stub->args.symlink.loc, loc);
- if (params)
- stub->args.symlink.params = dict_ref (params);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -629,7 +683,7 @@ fop_symlink_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -649,6 +703,9 @@ fop_symlink_cbk_stub (call_frame_t *frame,
stub->args.symlink_cbk.preparent = *preparent;
if (postparent)
stub->args.symlink_cbk.postparent = *postparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -658,7 +715,7 @@ call_stub_t *
fop_rename_stub (call_frame_t *frame,
fop_rename_t fn,
loc_t *oldloc,
- loc_t *newloc)
+ loc_t *newloc, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -672,6 +729,9 @@ fop_rename_stub (call_frame_t *frame,
stub->args.rename.fn = fn;
loc_copy (&stub->args.rename.old, oldloc);
loc_copy (&stub->args.rename.new, newloc);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -686,7 +746,7 @@ fop_rename_cbk_stub (call_frame_t *frame,
struct iatt *preoldparent,
struct iatt *postoldparent,
struct iatt *prenewparent,
- struct iatt *postnewparent)
+ struct iatt *postnewparent, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -708,6 +768,9 @@ fop_rename_cbk_stub (call_frame_t *frame,
stub->args.rename_cbk.prenewparent = *prenewparent;
if (postnewparent)
stub->args.rename_cbk.postnewparent = *postnewparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -717,7 +780,7 @@ call_stub_t *
fop_link_stub (call_frame_t *frame,
fop_link_t fn,
loc_t *oldloc,
- loc_t *newloc)
+ loc_t *newloc, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -732,6 +795,9 @@ fop_link_stub (call_frame_t *frame,
loc_copy (&stub->args.link.oldloc, oldloc);
loc_copy (&stub->args.link.newloc, newloc);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -745,7 +811,7 @@ fop_link_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -765,6 +831,9 @@ fop_link_cbk_stub (call_frame_t *frame,
stub->args.link_cbk.preparent = *preparent;
if (postparent)
stub->args.link_cbk.postparent = *postparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -773,7 +842,7 @@ out:
call_stub_t *
fop_create_stub (call_frame_t *frame, fop_create_t fn,
loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params)
+ mode_t umask, fd_t *fd, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -787,10 +856,12 @@ fop_create_stub (call_frame_t *frame, fop_create_t fn,
loc_copy (&stub->args.create.loc, loc);
stub->args.create.flags = flags;
stub->args.create.mode = mode;
+ stub->args.create.umask = umask;
if (fd)
stub->args.create.fd = fd_ref (fd);
- if (params)
- stub->args.create.params = dict_ref (params);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -805,7 +876,7 @@ fop_create_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -827,6 +898,9 @@ fop_create_cbk_stub (call_frame_t *frame,
stub->args.create_cbk.preparent = *preparent;
if (postparent)
stub->args.create_cbk.postparent = *postparent;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -837,7 +911,7 @@ fop_open_stub (call_frame_t *frame,
fop_open_t fn,
loc_t *loc,
int32_t flags, fd_t *fd,
- int32_t wbflags)
+ dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -850,9 +924,11 @@ fop_open_stub (call_frame_t *frame,
stub->args.open.fn = fn;
loc_copy (&stub->args.open.loc, loc);
stub->args.open.flags = flags;
- stub->args.open.wbflags = wbflags;
if (fd)
stub->args.open.fd = fd_ref (fd);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -863,8 +939,7 @@ fop_open_cbk_stub (call_frame_t *frame,
fop_open_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd)
-
+ fd_t *fd, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -878,6 +953,9 @@ fop_open_cbk_stub (call_frame_t *frame,
stub->args.open_cbk.op_errno = op_errno;
if (fd)
stub->args.open_cbk.fd = fd_ref (fd);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -888,7 +966,7 @@ fop_readv_stub (call_frame_t *frame,
fop_readv_t fn,
fd_t *fd,
size_t size,
- off_t off)
+ off_t off, uint32_t flags, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -900,8 +978,13 @@ fop_readv_stub (call_frame_t *frame,
stub->args.readv.fn = fn;
if (fd)
stub->args.readv.fd = fd_ref (fd);
- stub->args.readv.size = size;
- stub->args.readv.off = off;
+ stub->args.readv.size = size;
+ stub->args.readv.off = off;
+ stub->args.readv.flags = flags;
+
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -915,8 +998,7 @@ fop_readv_cbk_stub (call_frame_t *frame,
struct iovec *vector,
int32_t count,
struct iatt *stbuf,
- struct iobref *iobref)
-
+ struct iobref *iobref, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -934,6 +1016,9 @@ fop_readv_cbk_stub (call_frame_t *frame,
stub->args.readv_cbk.stbuf = *stbuf;
stub->args.readv_cbk.iobref = iobref_ref (iobref);
}
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -945,8 +1030,8 @@ fop_writev_stub (call_frame_t *frame,
fd_t *fd,
struct iovec *vector,
int32_t count,
- off_t off,
- struct iobref *iobref)
+ off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -960,9 +1045,13 @@ fop_writev_stub (call_frame_t *frame,
if (fd)
stub->args.writev.fd = fd_ref (fd);
stub->args.writev.vector = iov_dup (vector, count);
- stub->args.writev.count = count;
- stub->args.writev.off = off;
+ stub->args.writev.count = count;
+ stub->args.writev.off = off;
+ stub->args.writev.flags = flags;
stub->args.writev.iobref = iobref_ref (iobref);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -974,8 +1063,7 @@ fop_writev_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf)
-
+ struct iatt *postbuf, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -991,6 +1079,9 @@ fop_writev_cbk_stub (call_frame_t *frame,
stub->args.writev_cbk.postbuf = *postbuf;
if (prebuf)
stub->args.writev_cbk.prebuf = *prebuf;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1000,7 +1091,7 @@ out:
call_stub_t *
fop_flush_stub (call_frame_t *frame,
fop_flush_t fn,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1012,6 +1103,9 @@ fop_flush_stub (call_frame_t *frame,
stub->args.flush.fn = fn;
if (fd)
stub->args.flush.fd = fd_ref (fd);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1021,8 +1115,7 @@ call_stub_t *
fop_flush_cbk_stub (call_frame_t *frame,
fop_flush_cbk_t fn,
int32_t op_ret,
- int32_t op_errno)
-
+ int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1034,6 +1127,9 @@ fop_flush_cbk_stub (call_frame_t *frame,
stub->args.flush_cbk.fn = fn;
stub->args.flush_cbk.op_ret = op_ret;
stub->args.flush_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1045,7 +1141,7 @@ call_stub_t *
fop_fsync_stub (call_frame_t *frame,
fop_fsync_t fn,
fd_t *fd,
- int32_t datasync)
+ int32_t datasync, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1058,6 +1154,9 @@ fop_fsync_stub (call_frame_t *frame,
if (fd)
stub->args.fsync.fd = fd_ref (fd);
stub->args.fsync.datasync = datasync;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1069,7 +1168,7 @@ fop_fsync_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf)
+ struct iatt *postbuf, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1085,6 +1184,9 @@ fop_fsync_cbk_stub (call_frame_t *frame,
stub->args.fsync_cbk.prebuf = *prebuf;
if (postbuf)
stub->args.fsync_cbk.postbuf = *postbuf;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1093,7 +1195,7 @@ out:
call_stub_t *
fop_opendir_stub (call_frame_t *frame,
fop_opendir_t fn,
- loc_t *loc, fd_t *fd)
+ loc_t *loc, fd_t *fd, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1107,6 +1209,9 @@ fop_opendir_stub (call_frame_t *frame,
loc_copy (&stub->args.opendir.loc, loc);
if (fd)
stub->args.opendir.fd = fd_ref (fd);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1117,8 +1222,7 @@ fop_opendir_cbk_stub (call_frame_t *frame,
fop_opendir_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd)
-
+ fd_t *fd, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1133,6 +1237,9 @@ fop_opendir_cbk_stub (call_frame_t *frame,
if (fd)
stub->args.opendir_cbk.fd = fd_ref (fd);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1142,7 +1249,7 @@ call_stub_t *
fop_fsyncdir_stub (call_frame_t *frame,
fop_fsyncdir_t fn,
fd_t *fd,
- int32_t datasync)
+ int32_t datasync, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1155,6 +1262,9 @@ fop_fsyncdir_stub (call_frame_t *frame,
if (fd)
stub->args.fsyncdir.fd = fd_ref (fd);
stub->args.fsyncdir.datasync = datasync;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1164,8 +1274,7 @@ call_stub_t *
fop_fsyncdir_cbk_stub (call_frame_t *frame,
fop_fsyncdir_cbk_t fn,
int32_t op_ret,
- int32_t op_errno)
-
+ int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1177,6 +1286,9 @@ fop_fsyncdir_cbk_stub (call_frame_t *frame,
stub->args.fsyncdir_cbk.fn = fn;
stub->args.fsyncdir_cbk.op_ret = op_ret;
stub->args.fsyncdir_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1185,7 +1297,7 @@ out:
call_stub_t *
fop_statfs_stub (call_frame_t *frame,
fop_statfs_t fn,
- loc_t *loc)
+ loc_t *loc, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1197,6 +1309,9 @@ fop_statfs_stub (call_frame_t *frame,
stub->args.statfs.fn = fn;
loc_copy (&stub->args.statfs.loc, loc);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1207,8 +1322,7 @@ fop_statfs_cbk_stub (call_frame_t *frame,
fop_statfs_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- struct statvfs *buf)
-
+ struct statvfs *buf, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1222,6 +1336,9 @@ fop_statfs_cbk_stub (call_frame_t *frame,
stub->args.statfs_cbk.op_errno = op_errno;
if (op_ret == 0)
stub->args.statfs_cbk.buf = *buf;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1232,7 +1349,7 @@ fop_setxattr_stub (call_frame_t *frame,
fop_setxattr_t fn,
loc_t *loc,
dict_t *dict,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1248,6 +1365,9 @@ fop_setxattr_stub (call_frame_t *frame,
if (dict)
stub->args.setxattr.dict = dict_ref (dict);
stub->args.setxattr.flags = flags;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1257,7 +1377,7 @@ call_stub_t *
fop_setxattr_cbk_stub (call_frame_t *frame,
fop_setxattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno)
+ int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1269,6 +1389,9 @@ fop_setxattr_cbk_stub (call_frame_t *frame,
stub->args.setxattr_cbk.fn = fn;
stub->args.setxattr_cbk.op_ret = op_ret;
stub->args.setxattr_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1277,7 +1400,7 @@ call_stub_t *
fop_getxattr_stub (call_frame_t *frame,
fop_getxattr_t fn,
loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1292,6 +1415,9 @@ fop_getxattr_stub (call_frame_t *frame,
if (name)
stub->args.getxattr.name = gf_strdup (name);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1302,7 +1428,7 @@ fop_getxattr_cbk_stub (call_frame_t *frame,
fop_getxattr_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- dict_t *dict)
+ dict_t *dict, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1317,6 +1443,9 @@ fop_getxattr_cbk_stub (call_frame_t *frame,
/* TODO */
if (dict)
stub->args.getxattr_cbk.dict = dict_ref (dict);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1327,7 +1456,7 @@ fop_fsetxattr_stub (call_frame_t *frame,
fop_fsetxattr_t fn,
fd_t *fd,
dict_t *dict,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1344,6 +1473,9 @@ fop_fsetxattr_stub (call_frame_t *frame,
if (dict)
stub->args.fsetxattr.dict = dict_ref (dict);
stub->args.fsetxattr.flags = flags;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1353,7 +1485,7 @@ call_stub_t *
fop_fsetxattr_cbk_stub (call_frame_t *frame,
fop_fsetxattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno)
+ int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1365,6 +1497,9 @@ fop_fsetxattr_cbk_stub (call_frame_t *frame,
stub->args.fsetxattr_cbk.fn = fn;
stub->args.fsetxattr_cbk.op_ret = op_ret;
stub->args.fsetxattr_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1374,7 +1509,7 @@ call_stub_t *
fop_fgetxattr_stub (call_frame_t *frame,
fop_fgetxattr_t fn,
fd_t *fd,
- const char *name)
+ const char *name, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1389,6 +1524,9 @@ fop_fgetxattr_stub (call_frame_t *frame,
if (name)
stub->args.fgetxattr.name = gf_strdup (name);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1399,7 +1537,7 @@ fop_fgetxattr_cbk_stub (call_frame_t *frame,
fop_fgetxattr_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- dict_t *dict)
+ dict_t *dict, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1415,6 +1553,9 @@ fop_fgetxattr_cbk_stub (call_frame_t *frame,
/* TODO */
if (dict)
stub->args.fgetxattr_cbk.dict = dict_ref (dict);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1424,7 +1565,7 @@ call_stub_t *
fop_removexattr_stub (call_frame_t *frame,
fop_removexattr_t fn,
loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1438,6 +1579,9 @@ fop_removexattr_stub (call_frame_t *frame,
stub->args.removexattr.fn = fn;
loc_copy (&stub->args.removexattr.loc, loc);
stub->args.removexattr.name = gf_strdup (name);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1447,7 +1591,7 @@ call_stub_t *
fop_removexattr_cbk_stub (call_frame_t *frame,
fop_removexattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno)
+ int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1459,17 +1603,68 @@ fop_removexattr_cbk_stub (call_frame_t *frame,
stub->args.removexattr_cbk.fn = fn;
stub->args.removexattr_cbk.op_ret = op_ret;
stub->args.removexattr_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
+out:
+ return stub;
+}
+
+call_stub_t *
+fop_fremovexattr_stub (call_frame_t *frame,
+ fop_fremovexattr_t fn,
+ fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", name, out);
+
+ stub = stub_new (frame, 1, GF_FOP_FREMOVEXATTR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->args.fremovexattr.fn = fn;
+ stub->args.fremovexattr.fd = fd_ref (fd);
+ stub->args.fremovexattr.name = gf_strdup (name);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
call_stub_t *
+fop_fremovexattr_cbk_stub (call_frame_t *frame,
+ fop_fremovexattr_cbk_t fn,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+
+ stub = stub_new (frame, 0, GF_FOP_FREMOVEXATTR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->args.fremovexattr_cbk.fn = fn;
+ stub->args.fremovexattr_cbk.op_ret = op_ret;
+ stub->args.fremovexattr_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
+out:
+ return stub;
+}
+
+call_stub_t *
fop_lk_stub (call_frame_t *frame,
fop_lk_t fn,
fd_t *fd,
int32_t cmd,
- struct gf_flock *lock)
+ struct gf_flock *lock, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1484,6 +1679,9 @@ fop_lk_stub (call_frame_t *frame,
stub->args.lk.fd = fd_ref (fd);
stub->args.lk.cmd = cmd;
stub->args.lk.lock = *lock;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1494,8 +1692,7 @@ fop_lk_cbk_stub (call_frame_t *frame,
fop_lk_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock)
-
+ struct gf_flock *lock, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1509,13 +1706,17 @@ fop_lk_cbk_stub (call_frame_t *frame,
stub->args.lk_cbk.op_errno = op_errno;
if (op_ret == 0)
stub->args.lk_cbk.lock = *lock;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
call_stub_t *
fop_inodelk_stub (call_frame_t *frame, fop_inodelk_t fn,
- const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock)
+ const char *volume, loc_t *loc, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1533,13 +1734,16 @@ fop_inodelk_stub (call_frame_t *frame, fop_inodelk_t fn,
loc_copy (&stub->args.inodelk.loc, loc);
stub->args.inodelk.cmd = cmd;
stub->args.inodelk.lock = *lock;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
call_stub_t *
fop_inodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1552,6 +1756,9 @@ fop_inodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
stub->args.inodelk_cbk.op_ret = op_ret;
stub->args.inodelk_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1559,7 +1766,8 @@ out:
call_stub_t *
fop_finodelk_stub (call_frame_t *frame, fop_finodelk_t fn,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock)
+ const char *volume, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1580,6 +1788,9 @@ fop_finodelk_stub (call_frame_t *frame, fop_finodelk_t fn,
stub->args.finodelk.cmd = cmd;
stub->args.finodelk.lock = *lock;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1587,7 +1798,7 @@ out:
call_stub_t *
fop_finodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1600,6 +1811,9 @@ fop_finodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
stub->args.finodelk_cbk.op_ret = op_ret;
stub->args.finodelk_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1608,7 +1822,7 @@ out:
call_stub_t *
fop_entrylk_stub (call_frame_t *frame, fop_entrylk_t fn,
const char *volume, loc_t *loc, const char *name,
- entrylk_cmd cmd, entrylk_type type)
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1629,13 +1843,16 @@ fop_entrylk_stub (call_frame_t *frame, fop_entrylk_t fn,
if (name)
stub->args.entrylk.name = gf_strdup (name);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
call_stub_t *
fop_entrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1648,6 +1865,9 @@ fop_entrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
stub->args.entrylk_cbk.op_ret = op_ret;
stub->args.entrylk_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1656,7 +1876,7 @@ out:
call_stub_t *
fop_fentrylk_stub (call_frame_t *frame, fop_fentrylk_t fn,
const char *volume, fd_t *fd, const char *name,
- entrylk_cmd cmd, entrylk_type type)
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1677,13 +1897,16 @@ fop_fentrylk_stub (call_frame_t *frame, fop_fentrylk_t fn,
if (name)
stub->args.fentrylk.name = gf_strdup (name);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
call_stub_t *
fop_fentrylk_cbk_stub (call_frame_t *frame, fop_fentrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1696,6 +1919,9 @@ fop_fentrylk_cbk_stub (call_frame_t *frame, fop_fentrylk_cbk_t fn,
stub->args.fentrylk_cbk.op_ret = op_ret;
stub->args.fentrylk_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1706,7 +1932,7 @@ fop_readdirp_cbk_stub (call_frame_t *frame,
fop_readdirp_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- gf_dirent_t *entries)
+ gf_dirent_t *entries, dict_t *xdata)
{
call_stub_t *stub = NULL;
gf_dirent_t *stub_entry = NULL, *entry = NULL;
@@ -1738,6 +1964,9 @@ fop_readdirp_cbk_stub (call_frame_t *frame,
&stub->args.readdirp_cbk.entries.list);
}
}
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1748,7 +1977,7 @@ fop_readdir_cbk_stub (call_frame_t *frame,
fop_readdir_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- gf_dirent_t *entries)
+ gf_dirent_t *entries, dict_t *xdata)
{
call_stub_t *stub = NULL;
gf_dirent_t *stub_entry = NULL, *entry = NULL;
@@ -1780,6 +2009,9 @@ fop_readdir_cbk_stub (call_frame_t *frame,
&stub->args.readdir_cbk.entries.list);
}
}
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1789,7 +2021,7 @@ fop_readdir_stub (call_frame_t *frame,
fop_readdir_t fn,
fd_t *fd,
size_t size,
- off_t off)
+ off_t off, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1801,6 +2033,9 @@ fop_readdir_stub (call_frame_t *frame,
stub->args.readdir.size = size;
stub->args.readdir.off = off;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1810,7 +2045,8 @@ fop_readdirp_stub (call_frame_t *frame,
fop_readdirp_t fn,
fd_t *fd,
size_t size,
- off_t off)
+ off_t off,
+ dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1821,6 +2057,8 @@ fop_readdirp_stub (call_frame_t *frame,
stub->args.readdirp.fd = fd_ref (fd);
stub->args.readdirp.size = size;
stub->args.readdirp.off = off;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
out:
return stub;
@@ -1830,7 +2068,7 @@ call_stub_t *
fop_rchecksum_stub (call_frame_t *frame,
fop_rchecksum_t fn,
fd_t *fd, off_t offset,
- int32_t len)
+ int32_t len, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1844,6 +2082,9 @@ fop_rchecksum_stub (call_frame_t *frame,
stub->args.rchecksum.fd = fd_ref (fd);
stub->args.rchecksum.offset = offset;
stub->args.rchecksum.len = len;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1855,7 +2096,7 @@ fop_rchecksum_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
uint32_t weak_checksum,
- uint8_t *strong_checksum)
+ uint8_t *strong_checksum, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1874,8 +2115,11 @@ fop_rchecksum_cbk_stub (call_frame_t *frame,
weak_checksum;
stub->args.rchecksum_cbk.strong_checksum =
- memdup (strong_checksum, MD5_DIGEST_LEN);
+ memdup (strong_checksum, MD5_DIGEST_LENGTH);
}
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1885,7 +2129,7 @@ call_stub_t *
fop_xattrop_cbk_stub (call_frame_t *frame,
fop_xattrop_cbk_t fn,
int32_t op_ret,
- int32_t op_errno)
+ int32_t op_errno, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1898,6 +2142,9 @@ fop_xattrop_cbk_stub (call_frame_t *frame,
stub->args.xattrop_cbk.op_ret = op_ret;
stub->args.xattrop_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1908,7 +2155,7 @@ fop_fxattrop_cbk_stub (call_frame_t *frame,
fop_fxattrop_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- dict_t *xattr)
+ dict_t *xattr, dict_t *xdata)
{
call_stub_t *stub = NULL;
GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
@@ -1922,6 +2169,9 @@ fop_fxattrop_cbk_stub (call_frame_t *frame,
if (xattr)
stub->args.fxattrop_cbk.xattr = dict_ref (xattr);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1932,7 +2182,7 @@ fop_xattrop_stub (call_frame_t *frame,
fop_xattrop_t fn,
loc_t *loc,
gf_xattrop_flags_t optype,
- dict_t *xattr)
+ dict_t *xattr, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1949,6 +2199,9 @@ fop_xattrop_stub (call_frame_t *frame,
stub->args.xattrop.optype = optype;
stub->args.xattrop.xattr = dict_ref (xattr);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1958,7 +2211,7 @@ fop_fxattrop_stub (call_frame_t *frame,
fop_fxattrop_t fn,
fd_t *fd,
gf_xattrop_flags_t optype,
- dict_t *xattr)
+ dict_t *xattr, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1975,6 +2228,9 @@ fop_fxattrop_stub (call_frame_t *frame,
stub->args.fxattrop.optype = optype;
stub->args.fxattrop.xattr = dict_ref (xattr);
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -1986,7 +2242,7 @@ fop_setattr_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *statpre,
- struct iatt *statpost)
+ struct iatt *statpost, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -2005,6 +2261,9 @@ fop_setattr_cbk_stub (call_frame_t *frame,
if (statpost)
stub->args.setattr_cbk.statpost = *statpost;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -2015,7 +2274,7 @@ fop_fsetattr_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *statpre,
- struct iatt *statpost)
+ struct iatt *statpost, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -2033,6 +2292,9 @@ fop_fsetattr_cbk_stub (call_frame_t *frame,
stub->args.setattr_cbk.statpre = *statpre;
if (statpost)
stub->args.fsetattr_cbk.statpost = *statpost;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -2042,7 +2304,7 @@ fop_setattr_stub (call_frame_t *frame,
fop_setattr_t fn,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid)
+ int32_t valid, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -2061,6 +2323,9 @@ fop_setattr_stub (call_frame_t *frame,
stub->args.setattr.valid = valid;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -2070,7 +2335,7 @@ fop_fsetattr_stub (call_frame_t *frame,
fop_fsetattr_t fn,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid)
+ int32_t valid, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -2090,6 +2355,9 @@ fop_fsetattr_stub (call_frame_t *frame,
stub->args.fsetattr.valid = valid;
+ if (xdata)
+ stub->xdata = dict_ref (xdata);
+
out:
return stub;
}
@@ -2106,7 +2374,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
&stub->args.open.loc,
stub->args.open.flags, stub->args.open.fd,
- stub->args.open.wbflags);
+ stub->xdata);
break;
}
case GF_FOP_CREATE:
@@ -2116,15 +2384,16 @@ call_resume_wind (call_stub_t *stub)
&stub->args.create.loc,
stub->args.create.flags,
stub->args.create.mode,
+ stub->args.create.umask,
stub->args.create.fd,
- stub->args.create.params);
+ stub->xdata);
break;
}
case GF_FOP_STAT:
{
stub->args.stat.fn (stub->frame,
stub->frame->this,
- &stub->args.stat.loc);
+ &stub->args.stat.loc, stub->xdata);
break;
}
case GF_FOP_READLINK:
@@ -2132,7 +2401,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.readlink.fn (stub->frame,
stub->frame->this,
&stub->args.readlink.loc,
- stub->args.readlink.size);
+ stub->args.readlink.size, stub->xdata);
break;
}
@@ -2142,7 +2411,7 @@ call_resume_wind (call_stub_t *stub)
&stub->args.mknod.loc,
stub->args.mknod.mode,
stub->args.mknod.rdev,
- stub->args.mknod.params);
+ stub->args.mknod.umask, stub->xdata);
}
break;
@@ -2151,7 +2420,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.mkdir.fn (stub->frame, stub->frame->this,
&stub->args.mkdir.loc,
stub->args.mkdir.mode,
- stub->args.mkdir.params);
+ stub->args.mkdir.umask, stub->xdata);
}
break;
@@ -2159,7 +2428,8 @@ call_resume_wind (call_stub_t *stub)
{
stub->args.unlink.fn (stub->frame,
stub->frame->this,
- &stub->args.unlink.loc);
+ &stub->args.unlink.loc,
+ stub->args.unlink.xflag, stub->xdata);
}
break;
@@ -2167,7 +2437,7 @@ call_resume_wind (call_stub_t *stub)
{
stub->args.rmdir.fn (stub->frame, stub->frame->this,
&stub->args.rmdir.loc,
- stub->args.rmdir.flags);
+ stub->args.rmdir.flags, stub->xdata);
}
break;
@@ -2177,7 +2447,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.symlink.linkname,
&stub->args.symlink.loc,
- stub->args.symlink.params);
+ stub->args.symlink.umask, stub->xdata);
}
break;
@@ -2186,7 +2456,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.rename.fn (stub->frame,
stub->frame->this,
&stub->args.rename.old,
- &stub->args.rename.new);
+ &stub->args.rename.new, stub->xdata);
}
break;
@@ -2195,7 +2465,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.link.fn (stub->frame,
stub->frame->this,
&stub->args.link.oldloc,
- &stub->args.link.newloc);
+ &stub->args.link.newloc, stub->xdata);
}
break;
@@ -2204,7 +2474,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.truncate.fn (stub->frame,
stub->frame->this,
&stub->args.truncate.loc,
- stub->args.truncate.off);
+ stub->args.truncate.off, stub->xdata);
break;
}
@@ -2214,7 +2484,8 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.readv.fd,
stub->args.readv.size,
- stub->args.readv.off);
+ stub->args.readv.off,
+ stub->args.readv.flags, stub->xdata);
break;
}
@@ -2226,7 +2497,8 @@ call_resume_wind (call_stub_t *stub)
stub->args.writev.vector,
stub->args.writev.count,
stub->args.writev.off,
- stub->args.writev.iobref);
+ stub->args.writev.flags,
+ stub->args.writev.iobref, stub->xdata);
break;
}
@@ -2234,14 +2506,14 @@ call_resume_wind (call_stub_t *stub)
{
stub->args.statfs.fn (stub->frame,
stub->frame->this,
- &stub->args.statfs.loc);
+ &stub->args.statfs.loc, stub->xdata);
break;
}
case GF_FOP_FLUSH:
{
stub->args.flush.fn (stub->frame,
stub->frame->this,
- stub->args.flush.fd);
+ stub->args.flush.fd, stub->xdata);
break;
}
@@ -2250,7 +2522,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.fsync.fn (stub->frame,
stub->frame->this,
stub->args.fsync.fd,
- stub->args.fsync.datasync);
+ stub->args.fsync.datasync, stub->xdata);
break;
}
@@ -2260,7 +2532,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
&stub->args.setxattr.loc,
stub->args.setxattr.dict,
- stub->args.setxattr.flags);
+ stub->args.setxattr.flags, stub->xdata);
break;
}
@@ -2269,7 +2541,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.getxattr.fn (stub->frame,
stub->frame->this,
&stub->args.getxattr.loc,
- stub->args.getxattr.name);
+ stub->args.getxattr.name, stub->xdata);
break;
}
@@ -2279,7 +2551,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.fsetxattr.fd,
stub->args.fsetxattr.dict,
- stub->args.fsetxattr.flags);
+ stub->args.fsetxattr.flags, stub->xdata);
break;
}
@@ -2288,7 +2560,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.fgetxattr.fn (stub->frame,
stub->frame->this,
stub->args.fgetxattr.fd,
- stub->args.fgetxattr.name);
+ stub->args.fgetxattr.name, stub->xdata);
break;
}
@@ -2297,7 +2569,16 @@ call_resume_wind (call_stub_t *stub)
stub->args.removexattr.fn (stub->frame,
stub->frame->this,
&stub->args.removexattr.loc,
- stub->args.removexattr.name);
+ stub->args.removexattr.name, stub->xdata);
+ break;
+ }
+
+ case GF_FOP_FREMOVEXATTR:
+ {
+ stub->args.fremovexattr.fn (stub->frame,
+ stub->frame->this,
+ stub->args.fremovexattr.fd,
+ stub->args.fremovexattr.name, stub->xdata);
break;
}
@@ -2306,7 +2587,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.opendir.fn (stub->frame,
stub->frame->this,
&stub->args.opendir.loc,
- stub->args.opendir.fd);
+ stub->args.opendir.fd, stub->xdata);
break;
}
@@ -2315,7 +2596,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.fsyncdir.fn (stub->frame,
stub->frame->this,
stub->args.fsyncdir.fd,
- stub->args.fsyncdir.datasync);
+ stub->args.fsyncdir.datasync, stub->xdata);
break;
}
@@ -2324,7 +2605,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.access.fn (stub->frame,
stub->frame->this,
&stub->args.access.loc,
- stub->args.access.mask);
+ stub->args.access.mask, stub->xdata);
break;
}
@@ -2333,7 +2614,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.ftruncate.fn (stub->frame,
stub->frame->this,
stub->args.ftruncate.fd,
- stub->args.ftruncate.off);
+ stub->args.ftruncate.off, stub->xdata);
break;
}
@@ -2341,7 +2622,7 @@ call_resume_wind (call_stub_t *stub)
{
stub->args.fstat.fn (stub->frame,
stub->frame->this,
- stub->args.fstat.fd);
+ stub->args.fstat.fd, stub->xdata);
break;
}
@@ -2351,7 +2632,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.lk.fd,
stub->args.lk.cmd,
- &stub->args.lk.lock);
+ &stub->args.lk.lock, stub->xdata);
break;
}
@@ -2362,7 +2643,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.inodelk.volume,
&stub->args.inodelk.loc,
stub->args.inodelk.cmd,
- &stub->args.inodelk.lock);
+ &stub->args.inodelk.lock, stub->xdata);
break;
}
@@ -2373,7 +2654,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.finodelk.volume,
stub->args.finodelk.fd,
stub->args.finodelk.cmd,
- &stub->args.finodelk.lock);
+ &stub->args.finodelk.lock, stub->xdata);
break;
}
@@ -2385,7 +2666,7 @@ call_resume_wind (call_stub_t *stub)
&stub->args.entrylk.loc,
stub->args.entrylk.name,
stub->args.entrylk.cmd,
- stub->args.entrylk.type);
+ stub->args.entrylk.type, stub->xdata);
break;
}
@@ -2397,7 +2678,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.fentrylk.fd,
stub->args.fentrylk.name,
stub->args.fentrylk.cmd,
- stub->args.fentrylk.type);
+ stub->args.fentrylk.type, stub->xdata);
break;
}
@@ -2408,7 +2689,7 @@ call_resume_wind (call_stub_t *stub)
stub->args.lookup.fn (stub->frame,
stub->frame->this,
&stub->args.lookup.loc,
- stub->args.lookup.xattr_req);
+ stub->xdata);
break;
}
@@ -2418,7 +2699,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.rchecksum.fd,
stub->args.rchecksum.offset,
- stub->args.rchecksum.len);
+ stub->args.rchecksum.len, stub->xdata);
break;
}
@@ -2428,7 +2709,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.readdir.fd,
stub->args.readdir.size,
- stub->args.readdir.off);
+ stub->args.readdir.off, stub->xdata);
break;
}
@@ -2438,7 +2719,8 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.readdirp.fd,
stub->args.readdirp.size,
- stub->args.readdirp.off);
+ stub->args.readdirp.off,
+ stub->xdata);
break;
}
@@ -2448,7 +2730,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
&stub->args.xattrop.loc,
stub->args.xattrop.optype,
- stub->args.xattrop.xattr);
+ stub->args.xattrop.xattr, stub->xdata);
break;
}
@@ -2458,7 +2740,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.fxattrop.fd,
stub->args.fxattrop.optype,
- stub->args.fxattrop.xattr);
+ stub->args.fxattrop.xattr, stub->xdata);
break;
}
@@ -2468,7 +2750,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
&stub->args.setattr.loc,
&stub->args.setattr.stbuf,
- stub->args.setattr.valid);
+ stub->args.setattr.valid, stub->xdata);
break;
}
case GF_FOP_FSETATTR:
@@ -2477,7 +2759,7 @@ call_resume_wind (call_stub_t *stub)
stub->frame->this,
stub->args.fsetattr.fd,
&stub->args.fsetattr.stbuf,
- stub->args.fsetattr.valid);
+ stub->args.fsetattr.valid, stub->xdata);
break;
}
default:
@@ -2507,14 +2789,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.open_cbk.op_ret,
stub->args.open_cbk.op_errno,
- stub->args.open_cbk.fd);
+ stub->args.open_cbk.fd, stub->xdata);
else
stub->args.open_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.open_cbk.op_ret,
stub->args.open_cbk.op_errno,
- stub->args.open_cbk.fd);
+ stub->args.open_cbk.fd, stub->xdata);
break;
}
@@ -2528,7 +2810,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.create_cbk.inode,
&stub->args.create_cbk.buf,
&stub->args.create_cbk.preparent,
- &stub->args.create_cbk.postparent);
+ &stub->args.create_cbk.postparent, stub->xdata);
else
stub->args.create_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2539,7 +2821,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.create_cbk.inode,
&stub->args.create_cbk.buf,
&stub->args.create_cbk.preparent,
- &stub->args.create_cbk.postparent);
+ &stub->args.create_cbk.postparent, stub->xdata);
break;
}
@@ -2550,14 +2832,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.stat_cbk.op_ret,
stub->args.stat_cbk.op_errno,
- &stub->args.stat_cbk.buf);
+ &stub->args.stat_cbk.buf, stub->xdata);
else
stub->args.stat_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.stat_cbk.op_ret,
stub->args.stat_cbk.op_errno,
- &stub->args.stat_cbk.buf);
+ &stub->args.stat_cbk.buf, stub->xdata);
break;
}
@@ -2569,7 +2851,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.readlink_cbk.op_ret,
stub->args.readlink_cbk.op_errno,
stub->args.readlink_cbk.buf,
- &stub->args.readlink_cbk.sbuf);
+ &stub->args.readlink_cbk.sbuf, stub->xdata);
else
stub->args.readlink_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2577,7 +2859,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.readlink_cbk.op_ret,
stub->args.readlink_cbk.op_errno,
stub->args.readlink_cbk.buf,
- &stub->args.readlink_cbk.sbuf);
+ &stub->args.readlink_cbk.sbuf, stub->xdata);
break;
}
@@ -2591,7 +2873,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.mknod_cbk.inode,
&stub->args.mknod_cbk.buf,
&stub->args.mknod_cbk.preparent,
- &stub->args.mknod_cbk.postparent);
+ &stub->args.mknod_cbk.postparent, stub->xdata);
else
stub->args.mknod_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2601,7 +2883,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.mknod_cbk.inode,
&stub->args.mknod_cbk.buf,
&stub->args.mknod_cbk.preparent,
- &stub->args.mknod_cbk.postparent);
+ &stub->args.mknod_cbk.postparent, stub->xdata);
break;
}
@@ -2614,7 +2896,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.mkdir_cbk.inode,
&stub->args.mkdir_cbk.buf,
&stub->args.mkdir_cbk.preparent,
- &stub->args.mkdir_cbk.postparent);
+ &stub->args.mkdir_cbk.postparent, stub->xdata);
else
stub->args.mkdir_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2624,7 +2906,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.mkdir_cbk.inode,
&stub->args.mkdir_cbk.buf,
&stub->args.mkdir_cbk.preparent,
- &stub->args.mkdir_cbk.postparent);
+ &stub->args.mkdir_cbk.postparent, stub->xdata);
if (stub->args.mkdir_cbk.inode)
inode_unref (stub->args.mkdir_cbk.inode);
@@ -2639,7 +2921,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.unlink_cbk.op_ret,
stub->args.unlink_cbk.op_errno,
&stub->args.unlink_cbk.preparent,
- &stub->args.unlink_cbk.postparent);
+ &stub->args.unlink_cbk.postparent, stub->xdata);
else
stub->args.unlink_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2647,7 +2929,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.unlink_cbk.op_ret,
stub->args.unlink_cbk.op_errno,
&stub->args.unlink_cbk.preparent,
- &stub->args.unlink_cbk.postparent);
+ &stub->args.unlink_cbk.postparent, stub->xdata);
break;
}
@@ -2658,7 +2940,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.rmdir_cbk.op_ret,
stub->args.rmdir_cbk.op_errno,
&stub->args.rmdir_cbk.preparent,
- &stub->args.rmdir_cbk.postparent);
+ &stub->args.rmdir_cbk.postparent, stub->xdata);
else
stub->args.rmdir_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2666,7 +2948,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.rmdir_cbk.op_ret,
stub->args.rmdir_cbk.op_errno,
&stub->args.rmdir_cbk.preparent,
- &stub->args.rmdir_cbk.postparent);
+ &stub->args.rmdir_cbk.postparent, stub->xdata);
break;
}
@@ -2679,7 +2961,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.symlink_cbk.inode,
&stub->args.symlink_cbk.buf,
&stub->args.symlink_cbk.preparent,
- &stub->args.symlink_cbk.postparent);
+ &stub->args.symlink_cbk.postparent, stub->xdata);
else
stub->args.symlink_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2689,13 +2971,12 @@ call_resume_unwind (call_stub_t *stub)
stub->args.symlink_cbk.inode,
&stub->args.symlink_cbk.buf,
&stub->args.symlink_cbk.preparent,
- &stub->args.symlink_cbk.postparent);
+ &stub->args.symlink_cbk.postparent, stub->xdata);
}
break;
case GF_FOP_RENAME:
{
-#if 0
if (!stub->args.rename_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.rename_cbk.op_ret,
@@ -2704,7 +2985,7 @@ call_resume_unwind (call_stub_t *stub)
&stub->args.rename_cbk.preoldparent,
&stub->args.rename_cbk.postoldparent,
&stub->args.rename_cbk.prenewparent,
- &stub->args.rename_cbk.postnewparent);
+ &stub->args.rename_cbk.postnewparent, stub->xdata);
else
stub->args.rename_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2715,8 +2996,7 @@ call_resume_unwind (call_stub_t *stub)
&stub->args.rename_cbk.preoldparent,
&stub->args.rename_cbk.postoldparent,
&stub->args.rename_cbk.prenewparent,
- &stub->args.rename_cbk.postnewparent);
-#endif
+ &stub->args.rename_cbk.postnewparent, stub->xdata);
break;
}
@@ -2727,7 +3007,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.link_cbk.op_ret,
stub->args.link_cbk.op_errno,
stub->args.link_cbk.inode,
- &stub->args.link_cbk.buf);
+ &stub->args.link_cbk.buf, stub->xdata);
else
stub->args.link_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2737,7 +3017,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.link_cbk.inode,
&stub->args.link_cbk.buf,
&stub->args.link_cbk.preparent,
- &stub->args.link_cbk.postparent);
+ &stub->args.link_cbk.postparent, stub->xdata);
break;
}
@@ -2748,7 +3028,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.truncate_cbk.op_ret,
stub->args.truncate_cbk.op_errno,
&stub->args.truncate_cbk.prebuf,
- &stub->args.truncate_cbk.postbuf);
+ &stub->args.truncate_cbk.postbuf, stub->xdata);
else
stub->args.truncate_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2756,7 +3036,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.truncate_cbk.op_ret,
stub->args.truncate_cbk.op_errno,
&stub->args.truncate_cbk.prebuf,
- &stub->args.truncate_cbk.postbuf);
+ &stub->args.truncate_cbk.postbuf, stub->xdata);
break;
}
@@ -2769,7 +3049,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.readv_cbk.vector,
stub->args.readv_cbk.count,
&stub->args.readv_cbk.stbuf,
- stub->args.readv_cbk.iobref);
+ stub->args.readv_cbk.iobref, stub->xdata);
else
stub->args.readv_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2779,7 +3059,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.readv_cbk.vector,
stub->args.readv_cbk.count,
&stub->args.readv_cbk.stbuf,
- stub->args.readv_cbk.iobref);
+ stub->args.readv_cbk.iobref, stub->xdata);
}
break;
@@ -2790,7 +3070,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.writev_cbk.op_ret,
stub->args.writev_cbk.op_errno,
&stub->args.writev_cbk.prebuf,
- &stub->args.writev_cbk.postbuf);
+ &stub->args.writev_cbk.postbuf, stub->xdata);
else
stub->args.writev_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2798,7 +3078,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.writev_cbk.op_ret,
stub->args.writev_cbk.op_errno,
&stub->args.writev_cbk.prebuf,
- &stub->args.writev_cbk.postbuf);
+ &stub->args.writev_cbk.postbuf, stub->xdata);
break;
}
@@ -2808,14 +3088,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.statfs_cbk.op_ret,
stub->args.statfs_cbk.op_errno,
- &(stub->args.statfs_cbk.buf));
+ &(stub->args.statfs_cbk.buf), stub->xdata);
else
stub->args.statfs_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.statfs_cbk.op_ret,
stub->args.statfs_cbk.op_errno,
- &(stub->args.statfs_cbk.buf));
+ &(stub->args.statfs_cbk.buf), stub->xdata);
}
break;
@@ -2824,13 +3104,13 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.flush_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.flush_cbk.op_ret,
- stub->args.flush_cbk.op_errno);
+ stub->args.flush_cbk.op_errno, stub->xdata);
else
stub->args.flush_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.flush_cbk.op_ret,
- stub->args.flush_cbk.op_errno);
+ stub->args.flush_cbk.op_errno, stub->xdata);
break;
}
@@ -2842,7 +3122,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.fsync_cbk.op_ret,
stub->args.fsync_cbk.op_errno,
&stub->args.fsync_cbk.prebuf,
- &stub->args.fsync_cbk.postbuf);
+ &stub->args.fsync_cbk.postbuf, stub->xdata);
else
stub->args.fsync_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -2850,7 +3130,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.fsync_cbk.op_ret,
stub->args.fsync_cbk.op_errno,
&stub->args.fsync_cbk.prebuf,
- &stub->args.fsync_cbk.postbuf);
+ &stub->args.fsync_cbk.postbuf, stub->xdata);
break;
}
@@ -2859,14 +3139,14 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.setxattr_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.setxattr_cbk.op_ret,
- stub->args.setxattr_cbk.op_errno);
+ stub->args.setxattr_cbk.op_errno, stub->xdata);
else
stub->args.setxattr_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.setxattr_cbk.op_ret,
- stub->args.setxattr_cbk.op_errno);
+ stub->args.setxattr_cbk.op_errno, stub->xdata);
break;
}
@@ -2877,14 +3157,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.getxattr_cbk.op_ret,
stub->args.getxattr_cbk.op_errno,
- stub->args.getxattr_cbk.dict);
+ stub->args.getxattr_cbk.dict, stub->xdata);
else
stub->args.getxattr_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.getxattr_cbk.op_ret,
stub->args.getxattr_cbk.op_errno,
- stub->args.getxattr_cbk.dict);
+ stub->args.getxattr_cbk.dict, stub->xdata);
break;
}
@@ -2893,14 +3173,14 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.fsetxattr_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.fsetxattr_cbk.op_ret,
- stub->args.fsetxattr_cbk.op_errno);
+ stub->args.fsetxattr_cbk.op_errno, stub->xdata);
else
stub->args.fsetxattr_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.fsetxattr_cbk.op_ret,
- stub->args.fsetxattr_cbk.op_errno);
+ stub->args.fsetxattr_cbk.op_errno, stub->xdata);
break;
}
@@ -2911,14 +3191,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.fgetxattr_cbk.op_ret,
stub->args.fgetxattr_cbk.op_errno,
- stub->args.fgetxattr_cbk.dict);
+ stub->args.fgetxattr_cbk.dict, stub->xdata);
else
stub->args.fgetxattr_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.fgetxattr_cbk.op_ret,
stub->args.fgetxattr_cbk.op_errno,
- stub->args.fgetxattr_cbk.dict);
+ stub->args.fgetxattr_cbk.dict, stub->xdata);
break;
}
@@ -2927,13 +3207,29 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.removexattr_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.removexattr_cbk.op_ret,
- stub->args.removexattr_cbk.op_errno);
+ stub->args.removexattr_cbk.op_errno, stub->xdata);
else
stub->args.removexattr_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.removexattr_cbk.op_ret,
- stub->args.removexattr_cbk.op_errno);
+ stub->args.removexattr_cbk.op_errno, stub->xdata);
+
+ break;
+ }
+
+ case GF_FOP_FREMOVEXATTR:
+ {
+ if (!stub->args.fremovexattr_cbk.fn)
+ STACK_UNWIND (stub->frame,
+ stub->args.fremovexattr_cbk.op_ret,
+ stub->args.fremovexattr_cbk.op_errno, stub->xdata);
+ else
+ stub->args.fremovexattr_cbk.fn (stub->frame,
+ stub->frame->cookie,
+ stub->frame->this,
+ stub->args.fremovexattr_cbk.op_ret,
+ stub->args.fremovexattr_cbk.op_errno, stub->xdata);
break;
}
@@ -2944,14 +3240,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.opendir_cbk.op_ret,
stub->args.opendir_cbk.op_errno,
- stub->args.opendir_cbk.fd);
+ stub->args.opendir_cbk.fd, stub->xdata);
else
stub->args.opendir_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.opendir_cbk.op_ret,
stub->args.opendir_cbk.op_errno,
- stub->args.opendir_cbk.fd);
+ stub->args.opendir_cbk.fd, stub->xdata);
break;
}
@@ -2960,13 +3256,13 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.fsyncdir_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.fsyncdir_cbk.op_ret,
- stub->args.fsyncdir_cbk.op_errno);
+ stub->args.fsyncdir_cbk.op_errno, stub->xdata);
else
stub->args.fsyncdir_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.fsyncdir_cbk.op_ret,
- stub->args.fsyncdir_cbk.op_errno);
+ stub->args.fsyncdir_cbk.op_errno, stub->xdata);
break;
}
@@ -2975,13 +3271,13 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.access_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.access_cbk.op_ret,
- stub->args.access_cbk.op_errno);
+ stub->args.access_cbk.op_errno, stub->xdata);
else
stub->args.access_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.access_cbk.op_ret,
- stub->args.access_cbk.op_errno);
+ stub->args.access_cbk.op_errno, stub->xdata);
break;
}
@@ -2993,7 +3289,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.ftruncate_cbk.op_ret,
stub->args.ftruncate_cbk.op_errno,
&stub->args.ftruncate_cbk.prebuf,
- &stub->args.ftruncate_cbk.postbuf);
+ &stub->args.ftruncate_cbk.postbuf, stub->xdata);
else
stub->args.ftruncate_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -3001,7 +3297,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.ftruncate_cbk.op_ret,
stub->args.ftruncate_cbk.op_errno,
&stub->args.ftruncate_cbk.prebuf,
- &stub->args.ftruncate_cbk.postbuf);
+ &stub->args.ftruncate_cbk.postbuf, stub->xdata);
break;
}
@@ -3011,14 +3307,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.fstat_cbk.op_ret,
stub->args.fstat_cbk.op_errno,
- &stub->args.fstat_cbk.buf);
+ &stub->args.fstat_cbk.buf, stub->xdata);
else
stub->args.fstat_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.fstat_cbk.op_ret,
stub->args.fstat_cbk.op_errno,
- &stub->args.fstat_cbk.buf);
+ &stub->args.fstat_cbk.buf, stub->xdata);
break;
}
@@ -3029,14 +3325,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.lk_cbk.op_ret,
stub->args.lk_cbk.op_errno,
- &stub->args.lk_cbk.lock);
+ &stub->args.lk_cbk.lock, stub->xdata);
else
stub->args.lk_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.lk_cbk.op_ret,
stub->args.lk_cbk.op_errno,
- &stub->args.lk_cbk.lock);
+ &stub->args.lk_cbk.lock, stub->xdata);
break;
}
@@ -3045,14 +3341,14 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.inodelk_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.inodelk_cbk.op_ret,
- stub->args.inodelk_cbk.op_errno);
+ stub->args.inodelk_cbk.op_errno, stub->xdata);
else
stub->args.inodelk_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.inodelk_cbk.op_ret,
- stub->args.inodelk_cbk.op_errno);
+ stub->args.inodelk_cbk.op_errno, stub->xdata);
break;
}
@@ -3061,14 +3357,14 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.finodelk_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.finodelk_cbk.op_ret,
- stub->args.finodelk_cbk.op_errno);
+ stub->args.finodelk_cbk.op_errno, stub->xdata);
else
stub->args.finodelk_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.finodelk_cbk.op_ret,
- stub->args.finodelk_cbk.op_errno);
+ stub->args.finodelk_cbk.op_errno, stub->xdata);
break;
}
@@ -3077,14 +3373,14 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.entrylk_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.entrylk_cbk.op_ret,
- stub->args.entrylk_cbk.op_errno);
+ stub->args.entrylk_cbk.op_errno, stub->xdata);
else
stub->args.entrylk_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.entrylk_cbk.op_ret,
- stub->args.entrylk_cbk.op_errno);
+ stub->args.entrylk_cbk.op_errno, stub->xdata);
break;
}
@@ -3093,14 +3389,14 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.fentrylk_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.fentrylk_cbk.op_ret,
- stub->args.fentrylk_cbk.op_errno);
+ stub->args.fentrylk_cbk.op_errno, stub->xdata);
else
stub->args.fentrylk_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.fentrylk_cbk.op_ret,
- stub->args.fentrylk_cbk.op_errno);
+ stub->args.fentrylk_cbk.op_errno, stub->xdata);
break;
}
@@ -3112,7 +3408,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.lookup_cbk.op_errno,
stub->args.lookup_cbk.inode,
&stub->args.lookup_cbk.buf,
- stub->args.lookup_cbk.dict,
+ stub->xdata,
&stub->args.lookup_cbk.postparent);
else
stub->args.lookup_cbk.fn (stub->frame,
@@ -3122,12 +3418,10 @@ call_resume_unwind (call_stub_t *stub)
stub->args.lookup_cbk.op_errno,
stub->args.lookup_cbk.inode,
&stub->args.lookup_cbk.buf,
- stub->args.lookup_cbk.dict,
+ stub->xdata,
&stub->args.lookup_cbk.postparent);
/* FIXME NULL should not be passed */
- if (stub->args.lookup_cbk.dict)
- dict_unref (stub->args.lookup_cbk.dict);
if (stub->args.lookup_cbk.inode)
inode_unref (stub->args.lookup_cbk.inode);
@@ -3141,7 +3435,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.rchecksum_cbk.op_ret,
stub->args.rchecksum_cbk.op_errno,
stub->args.rchecksum_cbk.weak_checksum,
- stub->args.rchecksum_cbk.strong_checksum);
+ stub->args.rchecksum_cbk.strong_checksum, stub->xdata);
else
stub->args.rchecksum_cbk.fn (stub->frame,
stub->frame->cookie,
@@ -3149,11 +3443,10 @@ call_resume_unwind (call_stub_t *stub)
stub->args.rchecksum_cbk.op_ret,
stub->args.rchecksum_cbk.op_errno,
stub->args.rchecksum_cbk.weak_checksum,
- stub->args.rchecksum_cbk.strong_checksum);
+ stub->args.rchecksum_cbk.strong_checksum, stub->xdata);
+
if (stub->args.rchecksum_cbk.op_ret >= 0)
- {
GF_FREE (stub->args.rchecksum_cbk.strong_checksum);
- }
break;
}
@@ -3164,14 +3457,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.readdir_cbk.op_ret,
stub->args.readdir_cbk.op_errno,
- &stub->args.readdir_cbk.entries);
+ &stub->args.readdir_cbk.entries, stub->xdata);
else
stub->args.readdir_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.readdir_cbk.op_ret,
stub->args.readdir_cbk.op_errno,
- &stub->args.readdir_cbk.entries);
+ &stub->args.readdir_cbk.entries, stub->xdata);
if (stub->args.readdir_cbk.op_ret > 0)
gf_dirent_free (&stub->args.readdir_cbk.entries);
@@ -3185,14 +3478,14 @@ call_resume_unwind (call_stub_t *stub)
STACK_UNWIND (stub->frame,
stub->args.readdirp_cbk.op_ret,
stub->args.readdirp_cbk.op_errno,
- &stub->args.readdirp_cbk.entries);
+ &stub->args.readdirp_cbk.entries, stub->xdata);
else
stub->args.readdirp_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.readdirp_cbk.op_ret,
stub->args.readdirp_cbk.op_errno,
- &stub->args.readdirp_cbk.entries);
+ &stub->args.readdirp_cbk.entries, stub->xdata);
if (stub->args.readdirp_cbk.op_ret > 0)
gf_dirent_free (&stub->args.readdirp_cbk.entries);
@@ -3205,14 +3498,14 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.xattrop_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.xattrop_cbk.op_ret,
- stub->args.xattrop_cbk.op_errno);
+ stub->args.xattrop_cbk.op_errno, stub->xdata);
else
stub->args.xattrop_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.xattrop_cbk.op_ret,
stub->args.xattrop_cbk.op_errno,
- stub->args.xattrop_cbk.xattr);
+ stub->args.xattrop_cbk.xattr, stub->xdata);
if (stub->args.xattrop_cbk.xattr)
dict_unref (stub->args.xattrop_cbk.xattr);
@@ -3224,14 +3517,14 @@ call_resume_unwind (call_stub_t *stub)
if (!stub->args.fxattrop_cbk.fn)
STACK_UNWIND (stub->frame,
stub->args.fxattrop_cbk.op_ret,
- stub->args.fxattrop_cbk.op_errno);
+ stub->args.fxattrop_cbk.op_errno, stub->xdata);
else
stub->args.fxattrop_cbk.fn (stub->frame,
stub->frame->cookie,
stub->frame->this,
stub->args.fxattrop_cbk.op_ret,
stub->args.fxattrop_cbk.op_errno,
- stub->args.fxattrop_cbk.xattr);
+ stub->args.fxattrop_cbk.xattr, stub->xdata);
if (stub->args.fxattrop_cbk.xattr)
dict_unref (stub->args.fxattrop_cbk.xattr);
@@ -3245,7 +3538,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.setattr_cbk.op_ret,
stub->args.setattr_cbk.op_errno,
&stub->args.setattr_cbk.statpre,
- &stub->args.setattr_cbk.statpost);
+ &stub->args.setattr_cbk.statpost, stub->xdata);
else
stub->args.setattr_cbk.fn (
stub->frame,
@@ -3254,7 +3547,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.setattr_cbk.op_ret,
stub->args.setattr_cbk.op_errno,
&stub->args.setattr_cbk.statpre,
- &stub->args.setattr_cbk.statpost);
+ &stub->args.setattr_cbk.statpost, stub->xdata);
break;
}
case GF_FOP_FSETATTR:
@@ -3264,7 +3557,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.fsetattr_cbk.op_ret,
stub->args.fsetattr_cbk.op_errno,
&stub->args.fsetattr_cbk.statpre,
- &stub->args.fsetattr_cbk.statpost);
+ &stub->args.fsetattr_cbk.statpost, stub->xdata);
else
stub->args.fsetattr_cbk.fn (
stub->frame,
@@ -3273,7 +3566,7 @@ call_resume_unwind (call_stub_t *stub)
stub->args.fsetattr_cbk.op_ret,
stub->args.fsetattr_cbk.op_errno,
&stub->args.fsetattr_cbk.statpre,
- &stub->args.fsetattr_cbk.statpost);
+ &stub->args.fsetattr_cbk.statpost, stub->xdata);
break;
}
default:
@@ -3292,6 +3585,9 @@ out:
static void
call_stub_destroy_wind (call_stub_t *stub)
{
+ if (stub->xdata)
+ dict_unref (stub->xdata);
+
switch (stub->fop) {
case GF_FOP_OPEN:
{
@@ -3305,8 +3601,6 @@ call_stub_destroy_wind (call_stub_t *stub)
loc_wipe (&stub->args.create.loc);
if (stub->args.create.fd)
fd_unref (stub->args.create.fd);
- if (stub->args.create.params)
- dict_unref (stub->args.create.params);
break;
}
case GF_FOP_STAT:
@@ -3323,16 +3617,12 @@ call_stub_destroy_wind (call_stub_t *stub)
case GF_FOP_MKNOD:
{
loc_wipe (&stub->args.mknod.loc);
- if (stub->args.mknod.params)
- dict_unref (stub->args.mknod.params);
}
break;
case GF_FOP_MKDIR:
{
loc_wipe (&stub->args.mkdir.loc);
- if (stub->args.mkdir.params)
- dict_unref (stub->args.mkdir.params);
}
break;
@@ -3352,8 +3642,6 @@ call_stub_destroy_wind (call_stub_t *stub)
{
GF_FREE ((char *)stub->args.symlink.linkname);
loc_wipe (&stub->args.symlink.loc);
- if (stub->args.symlink.params)
- dict_unref (stub->args.symlink.params);
}
break;
@@ -3453,6 +3741,13 @@ call_stub_destroy_wind (call_stub_t *stub)
break;
}
+ case GF_FOP_FREMOVEXATTR:
+ {
+ fd_unref (stub->args.fremovexattr.fd);
+ GF_FREE ((char *)stub->args.fremovexattr.name);
+ break;
+ }
+
case GF_FOP_OPENDIR:
{
loc_wipe (&stub->args.opendir.loc);
@@ -3538,8 +3833,6 @@ call_stub_destroy_wind (call_stub_t *stub)
case GF_FOP_LOOKUP:
{
loc_wipe (&stub->args.lookup.loc);
- if (stub->args.lookup.xattr_req)
- dict_unref (stub->args.lookup.xattr_req);
break;
}
@@ -3561,6 +3854,7 @@ call_stub_destroy_wind (call_stub_t *stub)
{
if (stub->args.readdirp.fd)
fd_unref (stub->args.readdirp.fd);
+
break;
}
@@ -3602,6 +3896,9 @@ call_stub_destroy_wind (call_stub_t *stub)
static void
call_stub_destroy_unwind (call_stub_t *stub)
{
+ if (stub->xdata)
+ dict_unref (stub->xdata);
+
switch (stub->fop) {
case GF_FOP_OPEN:
{
@@ -3717,6 +4014,8 @@ call_stub_destroy_unwind (call_stub_t *stub)
case GF_FOP_REMOVEXATTR:
break;
+ case GF_FOP_FREMOVEXATTR:
+ break;
case GF_FOP_OPENDIR:
{
@@ -3756,9 +4055,6 @@ call_stub_destroy_unwind (call_stub_t *stub)
{
if (stub->args.lookup_cbk.inode)
inode_unref (stub->args.lookup_cbk.inode);
-
- if (stub->args.lookup_cbk.dict)
- dict_unref (stub->args.lookup_cbk.dict);
}
break;
@@ -3824,12 +4120,8 @@ call_stub_destroy_unwind (call_stub_t *stub)
void
call_stub_destroy (call_stub_t *stub)
{
- struct mem_pool *tmp_pool = NULL;
-
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- tmp_pool = stub->stub_mem_pool;
-
if (stub->wind) {
call_stub_destroy_wind (stub);
} else {
@@ -3837,10 +4129,8 @@ call_stub_destroy (call_stub_t *stub)
}
stub->stub_mem_pool = NULL;
- mem_put (tmp_pool, stub);
+ mem_put (stub);
out:
- tmp_pool = NULL;
-
return;
}
diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h
index 4e1c3cb33..633fc4cbb 100644
--- a/libglusterfs/src/call-stub.h
+++ b/libglusterfs/src/call-stub.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _CALL_STUB_H_
@@ -34,21 +25,20 @@ typedef struct {
char wind;
call_frame_t *frame;
glusterfs_fop_t fop;
- struct mem_pool *stub_mem_pool; /* pointer to stub mempool in glusterfs ctx */
+ struct mem_pool *stub_mem_pool; /* pointer to stub mempool in ctx_t */
+ dict_t *xdata; /* common accross all the fops */
union {
/* lookup */
struct {
fop_lookup_t fn;
loc_t loc;
- dict_t *xattr_req;
} lookup;
struct {
fop_lookup_cbk_t fn;
int32_t op_ret, op_errno;
inode_t *inode;
struct iatt buf;
- dict_t *dict;
struct iatt postparent;
} lookup_cbk;
@@ -130,7 +120,7 @@ typedef struct {
loc_t loc;
mode_t mode;
dev_t rdev;
- dict_t *params;
+ mode_t umask;
} mknod;
struct {
fop_mknod_cbk_t fn;
@@ -146,7 +136,7 @@ typedef struct {
fop_mkdir_t fn;
loc_t loc;
mode_t mode;
- dict_t *params;
+ mode_t umask;
} mkdir;
struct {
fop_mkdir_cbk_t fn;
@@ -161,6 +151,7 @@ typedef struct {
struct {
fop_unlink_t fn;
loc_t loc;
+ int xflag;
} unlink;
struct {
fop_unlink_cbk_t fn;
@@ -187,7 +178,7 @@ typedef struct {
fop_symlink_t fn;
const char *linkname;
loc_t loc;
- dict_t *params;
+ mode_t umask;
} symlink;
struct {
fop_symlink_cbk_t fn;
@@ -236,7 +227,7 @@ typedef struct {
int32_t flags;
mode_t mode;
fd_t *fd;
- dict_t *params;
+ mode_t umask;
} create;
struct {
fop_create_cbk_t fn;
@@ -254,7 +245,6 @@ typedef struct {
loc_t loc;
int32_t flags;
fd_t *fd;
- int32_t wbflags;
} open;
struct {
fop_open_cbk_t fn;
@@ -268,6 +258,7 @@ typedef struct {
fd_t *fd;
size_t size;
off_t off;
+ uint32_t flags;
} readv;
struct {
fop_readv_cbk_t fn;
@@ -286,6 +277,7 @@ typedef struct {
struct iovec *vector;
int32_t count;
off_t off;
+ uint32_t flags;
struct iobref *iobref;
} writev;
struct {
@@ -412,6 +404,18 @@ typedef struct {
int32_t op_ret, op_errno;
} removexattr_cbk;
+
+ /* fremovexattr */
+ struct {
+ fop_fremovexattr_t fn;
+ fd_t *fd;
+ const char *name;
+ } fremovexattr;
+ struct {
+ fop_fremovexattr_cbk_t fn;
+ int32_t op_ret, op_errno;
+ } fremovexattr_cbk;
+
/* lk */
struct {
fop_lk_t fn;
@@ -588,7 +592,7 @@ call_stub_t *
fop_lookup_stub (call_frame_t *frame,
fop_lookup_t fn,
loc_t *loc,
- dict_t *xattr_req);
+ dict_t *xdata);
call_stub_t *
fop_lookup_cbk_stub (call_frame_t *frame,
@@ -597,34 +601,34 @@ fop_lookup_cbk_stub (call_frame_t *frame,
int32_t op_errno,
inode_t *inode,
struct iatt *buf,
- dict_t *dict,
+ dict_t *xdata,
struct iatt *postparent);
call_stub_t *
fop_stat_stub (call_frame_t *frame,
fop_stat_t fn,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
call_stub_t *
fop_stat_cbk_stub (call_frame_t *frame,
fop_stat_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
call_stub_t *
fop_fstat_stub (call_frame_t *frame,
fop_fstat_t fn,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
call_stub_t *
fop_fstat_cbk_stub (call_frame_t *frame,
fop_fstat_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
call_stub_t *
fop_truncate_stub (call_frame_t *frame,
fop_truncate_t fn,
loc_t *loc,
- off_t off);
+ off_t off, dict_t *xdata);
call_stub_t *
fop_truncate_cbk_stub (call_frame_t *frame,
@@ -632,13 +636,13 @@ fop_truncate_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
call_stub_t *
fop_ftruncate_stub (call_frame_t *frame,
fop_ftruncate_t fn,
fd_t *fd,
- off_t off);
+ off_t off, dict_t *xdata);
call_stub_t *
fop_ftruncate_cbk_stub (call_frame_t *frame,
@@ -646,25 +650,25 @@ fop_ftruncate_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
call_stub_t *
fop_access_stub (call_frame_t *frame,
fop_access_t fn,
loc_t *loc,
- int32_t mask);
+ int32_t mask, dict_t *xdata);
call_stub_t *
fop_access_cbk_stub (call_frame_t *frame,
fop_access_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_readlink_stub (call_frame_t *frame,
fop_readlink_t fn,
loc_t *loc,
- size_t size);
+ size_t size, dict_t *xdata);
call_stub_t *
fop_readlink_cbk_stub (call_frame_t *frame,
@@ -672,11 +676,11 @@ fop_readlink_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *path,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
call_stub_t *
-fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn,
- loc_t *loc, mode_t mode, dev_t rdev, dict_t *params);
+fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata);
call_stub_t *
fop_mknod_cbk_stub (call_frame_t *frame,
@@ -686,11 +690,11 @@ fop_mknod_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
-fop_mkdir_stub (call_frame_t *frame, fop_mkdir_t fn,
- loc_t *loc, mode_t mode, dict_t *params);
+fop_mkdir_stub (call_frame_t *frame, fop_mkdir_t fn, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata);
call_stub_t *
fop_mkdir_cbk_stub (call_frame_t *frame,
@@ -700,12 +704,11 @@ fop_mkdir_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
-fop_unlink_stub (call_frame_t *frame,
- fop_unlink_t fn,
- loc_t *loc);
+fop_unlink_stub (call_frame_t *frame, fop_unlink_t fn,
+ loc_t *loc, int xflag, dict_t *xdata);
call_stub_t *
fop_unlink_cbk_stub (call_frame_t *frame,
@@ -713,11 +716,11 @@ fop_unlink_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_rmdir_stub (call_frame_t *frame, fop_rmdir_t fn,
- loc_t *loc, int flags);
+ loc_t *loc, int flags, dict_t *xdata);
call_stub_t *
fop_rmdir_cbk_stub (call_frame_t *frame,
@@ -725,11 +728,11 @@ fop_rmdir_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_symlink_stub (call_frame_t *frame, fop_symlink_t fn,
- const char *linkname, loc_t *loc, dict_t *params);
+ const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata);
call_stub_t *
fop_symlink_cbk_stub (call_frame_t *frame,
@@ -739,13 +742,13 @@ fop_symlink_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_rename_stub (call_frame_t *frame,
fop_rename_t fn,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
call_stub_t *
fop_rename_cbk_stub (call_frame_t *frame,
@@ -756,13 +759,13 @@ fop_rename_cbk_stub (call_frame_t *frame,
struct iatt *preoldparent,
struct iatt *postoldparent,
struct iatt *prenewparent,
- struct iatt *postnewparent);
+ struct iatt *postnewparent, dict_t *xdata);
call_stub_t *
fop_link_stub (call_frame_t *frame,
fop_link_t fn,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
call_stub_t *
fop_link_cbk_stub (call_frame_t *frame,
@@ -772,12 +775,12 @@ fop_link_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_create_stub (call_frame_t *frame, fop_create_t fn,
loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
+ mode_t umask, fd_t *fd, dict_t *xdata);
call_stub_t *
fop_create_cbk_stub (call_frame_t *frame,
@@ -788,7 +791,7 @@ fop_create_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_open_stub (call_frame_t *frame,
@@ -796,21 +799,21 @@ fop_open_stub (call_frame_t *frame,
loc_t *loc,
int32_t flags,
fd_t *fd,
- int32_t wbflags);
+ dict_t *xdata);
call_stub_t *
fop_open_cbk_stub (call_frame_t *frame,
fop_open_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
call_stub_t *
fop_readv_stub (call_frame_t *frame,
fop_readv_t fn,
fd_t *fd,
size_t size,
- off_t off);
+ off_t off, uint32_t flags, dict_t *xdata);
call_stub_t *
fop_readv_cbk_stub (call_frame_t *frame,
@@ -820,7 +823,7 @@ fop_readv_cbk_stub (call_frame_t *frame,
struct iovec *vector,
int32_t count,
struct iatt *stbuf,
- struct iobref *iobref);
+ struct iobref *iobref, dict_t *xdata);
call_stub_t *
fop_writev_stub (call_frame_t *frame,
@@ -828,8 +831,8 @@ fop_writev_stub (call_frame_t *frame,
fd_t *fd,
struct iovec *vector,
int32_t count,
- off_t off,
- struct iobref *iobref);
+ off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
call_stub_t *
fop_writev_cbk_stub (call_frame_t *frame,
@@ -837,24 +840,24 @@ fop_writev_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
call_stub_t *
fop_flush_stub (call_frame_t *frame,
fop_flush_t fn,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
call_stub_t *
fop_flush_cbk_stub (call_frame_t *frame,
fop_flush_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_fsync_stub (call_frame_t *frame,
fop_fsync_t fn,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
call_stub_t *
fop_fsync_cbk_stub (call_frame_t *frame,
@@ -862,190 +865,205 @@ fop_fsync_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
call_stub_t *
fop_opendir_stub (call_frame_t *frame,
fop_opendir_t fn,
- loc_t *loc, fd_t *fd);
+ loc_t *loc, fd_t *fd, dict_t *xdata);
call_stub_t *
fop_opendir_cbk_stub (call_frame_t *frame,
fop_opendir_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
call_stub_t *
fop_fsyncdir_stub (call_frame_t *frame,
fop_fsyncdir_t fn,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
call_stub_t *
fop_fsyncdir_cbk_stub (call_frame_t *frame,
fop_fsyncdir_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_statfs_stub (call_frame_t *frame,
fop_statfs_t fn,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
call_stub_t *
fop_statfs_cbk_stub (call_frame_t *frame,
fop_statfs_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- struct statvfs *buf);
+ struct statvfs *buf, dict_t *xdata);
call_stub_t *
fop_setxattr_stub (call_frame_t *frame,
fop_setxattr_t fn,
loc_t *loc,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
call_stub_t *
fop_setxattr_cbk_stub (call_frame_t *frame,
fop_setxattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_getxattr_stub (call_frame_t *frame,
fop_getxattr_t fn,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
call_stub_t *
fop_getxattr_cbk_stub (call_frame_t *frame,
fop_getxattr_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- dict_t *value);
+ dict_t *value, dict_t *xdata);
call_stub_t *
fop_fsetxattr_stub (call_frame_t *frame,
fop_fsetxattr_t fn,
fd_t *fd,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
call_stub_t *
fop_fsetxattr_cbk_stub (call_frame_t *frame,
fop_fsetxattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_fgetxattr_stub (call_frame_t *frame,
fop_fgetxattr_t fn,
fd_t *fd,
- const char *name);
+ const char *name, dict_t *xdata);
call_stub_t *
fop_fgetxattr_cbk_stub (call_frame_t *frame,
fop_fgetxattr_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- dict_t *value);
+ dict_t *value, dict_t *xdata);
call_stub_t *
fop_removexattr_stub (call_frame_t *frame,
fop_removexattr_t fn,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
call_stub_t *
fop_removexattr_cbk_stub (call_frame_t *frame,
fop_removexattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
+
+
+call_stub_t *
+fop_fremovexattr_stub (call_frame_t *frame,
+ fop_fremovexattr_t fn,
+ fd_t *fd,
+ const char *name, dict_t *xdata);
+
+call_stub_t *
+fop_fremovexattr_cbk_stub (call_frame_t *frame,
+ fop_fremovexattr_cbk_t fn,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
call_stub_t *
fop_lk_stub (call_frame_t *frame,
fop_lk_t fn,
fd_t *fd,
int32_t cmd,
- struct gf_flock *lock);
+ struct gf_flock *lock, dict_t *xdata);
call_stub_t *
fop_lk_cbk_stub (call_frame_t *frame,
fop_lk_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock);
+ struct gf_flock *lock, dict_t *xdata);
call_stub_t *
fop_inodelk_stub (call_frame_t *frame, fop_inodelk_t fn,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock);
+ struct gf_flock *lock, dict_t *xdata);
call_stub_t *
fop_finodelk_stub (call_frame_t *frame, fop_finodelk_t fn,
const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *lock);
+ struct gf_flock *lock, dict_t *xdata);
call_stub_t *
fop_entrylk_stub (call_frame_t *frame, fop_entrylk_t fn,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
call_stub_t *
fop_fentrylk_stub (call_frame_t *frame, fop_fentrylk_t fn,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
call_stub_t *
fop_inodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_finodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_entrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_fentrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_readdir_stub (call_frame_t *frame,
fop_readdir_t fn,
fd_t *fd,
size_t size,
- off_t off);
+ off_t off, dict_t *xdata);
call_stub_t *
fop_readdirp_stub (call_frame_t *frame,
- fop_readdir_t fn,
+ fop_readdirp_t fn,
fd_t *fd,
size_t size,
- off_t off);
+ off_t off,
+ dict_t *xdata);
call_stub_t *
fop_readdirp_cbk_stub (call_frame_t *frame,
fop_readdir_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- gf_dirent_t *entries);
+ gf_dirent_t *entries, dict_t *xdata);
call_stub_t *
fop_readdir_cbk_stub (call_frame_t *frame,
fop_readdir_cbk_t fn,
int32_t op_ret,
int32_t op_errno,
- gf_dirent_t *entries);
+ gf_dirent_t *entries, dict_t *xdata);
call_stub_t *
fop_rchecksum_stub (call_frame_t *frame,
fop_rchecksum_t fn,
fd_t *fd, off_t offset,
- int32_t len);
+ int32_t len, dict_t *xdata);
call_stub_t *
fop_rchecksum_cbk_stub (call_frame_t *frame,
@@ -1053,40 +1071,40 @@ fop_rchecksum_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
uint32_t weak_checksum,
- uint8_t *strong_checksum);
+ uint8_t *strong_checksum, dict_t *xdata);
call_stub_t *
fop_xattrop_stub (call_frame_t *frame,
fop_xattrop_t fn,
loc_t *loc,
gf_xattrop_flags_t optype,
- dict_t *xattr);
+ dict_t *xattr, dict_t *xdata);
call_stub_t *
fop_xattrop_stub_cbk_stub (call_frame_t *frame,
fop_xattrop_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_fxattrop_stub (call_frame_t *frame,
fop_fxattrop_t fn,
fd_t *fd,
gf_xattrop_flags_t optype,
- dict_t *xattr);
+ dict_t *xattr, dict_t *xdata);
call_stub_t *
fop_fxattrop_stub_cbk_stub (call_frame_t *frame,
fop_xattrop_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_setattr_stub (call_frame_t *frame,
fop_setattr_t fn,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
call_stub_t *
fop_setattr_cbk_stub (call_frame_t *frame,
@@ -1094,14 +1112,14 @@ fop_setattr_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *statpre,
- struct iatt *statpost);
+ struct iatt *statpost, dict_t *xdata);
call_stub_t *
fop_fsetattr_stub (call_frame_t *frame,
fop_fsetattr_t fn,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
call_stub_t *
fop_fsetattr_cbk_stub (call_frame_t *frame,
@@ -1109,7 +1127,7 @@ fop_fsetattr_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *statpre,
- struct iatt *statpost);
+ struct iatt *statpost, dict_t *xdata);
void call_resume (call_stub_t *stub);
void call_stub_destroy (call_stub_t *stub);
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
index 8c71f6c6a..e14a3044c 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -1,28 +1,17 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <inttypes.h>
+#include <openssl/md5.h>
+#include <stdint.h>
#include "glusterfs.h"
-#include "md5.h"
-#include "checksum.h"
-
/*
* The "weak" checksum required for the rsync algorithm,
@@ -31,22 +20,26 @@
*
* "a simple 32 bit checksum that can be upadted from either end
* (inspired by Mark Adler's Adler-32 checksum)"
+ *
+ * Note: these functions are only called to compute checksums on
+ * pathnames; they don't need to handle arbitrarily long strings of
+ * data. Thus int32_t and uint32_t are sufficient
*/
uint32_t
-gf_rsync_weak_checksum (char *buf1, int32_t len)
+gf_rsync_weak_checksum (unsigned char *buf, size_t len)
{
- int32_t i;
+ int32_t i = 0;
uint32_t s1, s2;
- signed char *buf = (signed char *) buf1;
uint32_t csum;
s1 = s2 = 0;
- for (i = 0; i < (len-4); i+=4) {
- s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3];
-
- s1 += buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3];
+ if (len >= 4) {
+ for (; i < (len-4); i+=4) {
+ s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3];
+ s1 += buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3];
+ }
}
for (; i < len; i++) {
@@ -66,13 +59,7 @@ gf_rsync_weak_checksum (char *buf1, int32_t len)
*/
void
-gf_rsync_strong_checksum (char *buf, int32_t len, uint8_t *sum)
+gf_rsync_strong_checksum (unsigned char *data, size_t len, unsigned char *md5)
{
- md_context m;
-
- md5_begin (&m);
- md5_update (&m, (unsigned char *) buf, len);
- md5_result (&m, (unsigned char *) sum);
-
- return;
+ MD5(data, len, md5);
}
diff --git a/libglusterfs/src/checksum.h b/libglusterfs/src/checksum.h
index b2e9ac57f..bf7eeede8 100644
--- a/libglusterfs/src/checksum.h
+++ b/libglusterfs/src/checksum.h
@@ -1,27 +1,20 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __CHECKSUM_H__
#define __CHECKSUM_H__
-uint32_t gf_rsync_weak_checksum (char *buf, int32_t len);
+uint32_t
+gf_rsync_weak_checksum (unsigned char *buf, size_t len);
-void gf_rsync_strong_checksum (char *buf, int32_t len, uint8_t *sum);
+void
+gf_rsync_strong_checksum (unsigned char *buf, size_t len, unsigned char *sum);
#endif /* __CHECKSUM_H__ */
diff --git a/libglusterfs/src/circ-buff.c b/libglusterfs/src/circ-buff.c
new file mode 100644
index 000000000..6c7907a09
--- /dev/null
+++ b/libglusterfs/src/circ-buff.c
@@ -0,0 +1,170 @@
+/*
+ Copyright (c) 2008-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 "circ-buff.h"
+
+/* hold lock while calling this function */
+int
+__cb_add_entry_buffer (buffer_t *buffer, void *item)
+{
+ circular_buffer_t *ptr = NULL;
+ int ret = -1;
+ //DO we really need the assert here?
+ GF_ASSERT (buffer->used_len <= buffer->size_buffer);
+
+ if (buffer->use_once == _gf_true &&
+ buffer->used_len == buffer->size_buffer) {
+ gf_log ("", GF_LOG_WARNING, "buffer %p is use once buffer",
+ buffer);
+ return -1;
+ } else {
+ if (buffer->used_len == buffer->size_buffer) {
+ if (buffer->cb[buffer->w_index]) {
+ ptr = buffer->cb[buffer->w_index];
+ if (ptr->data) {
+ GF_FREE (ptr->data);
+ ptr->data = NULL;
+ GF_FREE (ptr);
+ }
+ buffer->cb[buffer->w_index] = NULL;
+ ptr = NULL;
+ }
+ }
+
+ buffer->cb[buffer->w_index] =
+ GF_CALLOC (1, sizeof (circular_buffer_t),
+ gf_common_mt_circular_buffer_t);
+ if (!buffer->cb[buffer->w_index])
+ return -1;
+
+ buffer->cb[buffer->w_index]->data = item;
+ ret = gettimeofday (&buffer->cb[buffer->w_index]->tv, NULL);
+ if (ret == -1)
+ gf_log_callingfn ("", GF_LOG_WARNING, "getting time of"
+ "the day failed");
+ buffer->w_index++;
+ buffer->w_index %= buffer->size_buffer - 1;
+ //used_buffer size cannot be greater than the total buffer size
+
+ if (buffer->used_len < buffer->size_buffer)
+ buffer->used_len++;
+ return buffer->w_index;
+ }
+}
+
+int
+cb_add_entry_buffer (buffer_t *buffer, void *item)
+{
+ int write_index = -1;
+
+ pthread_mutex_lock (&buffer->lock);
+ {
+ write_index = __cb_add_entry_buffer (buffer, item);
+ }
+ pthread_mutex_unlock (&buffer->lock);
+
+ return write_index;
+}
+
+void
+cb_buffer_show (buffer_t *buffer)
+{
+ pthread_mutex_lock (&buffer->lock);
+ {
+ gf_log ("", GF_LOG_DEBUG, "w_index: %d, size: %"GF_PRI_SIZET
+ " used_buffer: %d", buffer->w_index,
+ buffer->size_buffer,
+ buffer->used_len);
+ }
+ pthread_mutex_unlock (&buffer->lock);
+}
+
+void
+cb_buffer_dump (buffer_t *buffer, void *data,
+ int (fn) (circular_buffer_t *buffer, void *data))
+{
+ int i = 0;
+ circular_buffer_t *entry = NULL;
+ int entries = 0;
+
+ pthread_mutex_lock (&buffer->lock);
+ {
+ if (buffer->use_once == _gf_false) {
+ for (i = (buffer->w_index - 1) ; entries <
+ buffer->used_len ; entries++) {
+ entry = buffer->cb[i];
+ if (entry)
+ fn (entry, data);
+ if (0 == i)
+ i = buffer->used_len - 1;
+ else
+ i = (i - 1) % (buffer->used_len - 1);
+ }
+ } else {
+ for (i = 0; i < buffer->used_len ; i++) {
+ entry = buffer->cb[i];
+ fn (entry, data);
+ }
+ }
+ }
+ pthread_mutex_unlock (&buffer->lock);
+}
+
+buffer_t *
+cb_buffer_new (size_t buffer_size, gf_boolean_t use_once)
+{
+ buffer_t *buffer = NULL;
+
+ buffer = GF_CALLOC (1, sizeof (*buffer), gf_common_mt_buffer_t);
+ if (!buffer) {
+ gf_log ("", GF_LOG_ERROR, "could not allocate the "
+ "buffer");
+ goto out;
+ }
+
+ buffer->cb = GF_CALLOC (buffer_size,
+ sizeof (circular_buffer_t *),
+ gf_common_mt_circular_buffer_t);
+ if (!buffer->cb) {
+ gf_log ("", GF_LOG_ERROR, "could not allocate the "
+ "memory for the circular buffer");
+ GF_FREE (buffer);
+ buffer = NULL;
+ goto out;
+ }
+
+ buffer->w_index = 0;
+ buffer->size_buffer = buffer_size;
+ buffer->use_once = use_once;
+ buffer->used_len = 0;
+ pthread_mutex_init (&buffer->lock, NULL);
+
+out:
+ return buffer;
+}
+
+void
+cb_buffer_destroy (buffer_t *buffer)
+{
+ int i = 0;
+
+ if (buffer) {
+ if (buffer->cb) {
+ for (i = 0; i < buffer->used_len ; i++) {
+ if (buffer->cb[i])
+ GF_FREE (buffer->cb[i]);
+ }
+ GF_FREE (buffer->cb);
+ }
+ pthread_mutex_destroy (&buffer->lock);
+ GF_FREE (buffer);
+ }
+}
+
diff --git a/libglusterfs/src/circ-buff.h b/libglusterfs/src/circ-buff.h
new file mode 100644
index 000000000..5b5acc387
--- /dev/null
+++ b/libglusterfs/src/circ-buff.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (c) 2008-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 _CB_H
+#define _CB_H
+
+#include "common-utils.h"
+#include "logging.h"
+#include "mem-types.h"
+
+#define BUFFER_SIZE 10
+#define TOTAL_SIZE BUFFER_SIZE + 1
+
+
+struct _circular_buffer {
+ struct timeval tv;
+ void *data;
+};
+
+typedef struct _circular_buffer circular_buffer_t;
+
+struct _buffer {
+ unsigned int w_index;
+ size_t size_buffer;
+ gf_boolean_t use_once;
+ /* This variable is assigned the proper value at the time of initing */
+ /* the buffer. It indicates, whether the buffer should be used once */
+ /* it becomes full. */
+
+ int used_len;
+ /* indicates the amount of circular buffer used. */
+
+ circular_buffer_t **cb;
+
+ pthread_mutex_t lock;
+};
+
+typedef struct _buffer buffer_t;
+
+int
+cb_add_entry_buffer (buffer_t *buffer, void *item);
+
+void
+cb_buffer_show (buffer_t *buffer);
+
+buffer_t *
+cb_buffer_new (size_t buffer_size,gf_boolean_t use_buffer_once);
+
+void
+cb_buffer_destroy (buffer_t *buffer);
+
+void
+cb_buffer_dump (buffer_t *buffer, void *data,
+ int (fn) (circular_buffer_t *buffer, void *data));
+
+#endif /* _CB_H */
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index e745ec0fa..dbcee77be 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -40,6 +31,11 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
+#include <stdlib.h>
+
+#if defined GF_BSD_HOST_OS || defined GF_DARWIN_HOST_OS
+#include <sys/sysctl.h>
+#endif
#include "logging.h"
#include "common-utils.h"
@@ -47,7 +43,11 @@
#include "glusterfs.h"
#include "stack.h"
#include "globals.h"
-#include "md5.h"
+#include "lkowner.h"
+
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG 0
+#endif /* AI_ADDRCONFIG */
typedef int32_t (*rw_op_t)(int32_t fd, char *buf, int32_t size);
typedef int32_t (*rwv_op_t)(int32_t fd, const struct iovec *buf, int32_t size);
@@ -342,10 +342,8 @@ void
gf_print_trace (int32_t signum)
{
extern FILE *gf_log_logfile;
- struct tm *tm = NULL;
char msg[1024] = {0,};
- char timestr[256] = {0,};
- time_t utime = 0;
+ char timestr[64] = {0,};
int ret = 0;
int fd = 0;
@@ -353,6 +351,9 @@ gf_print_trace (int32_t signum)
/* Pending frames, (if any), list them in order */
ret = write (fd, "pending frames:\n", 16);
+ if (ret < 0)
+ goto out;
+
{
glusterfs_ctx_t *ctx = glusterfs_ctx_get ();
struct list_head *trav = ((call_pool_t *)ctx->pool)->all_frames.next;
@@ -368,25 +369,36 @@ gf_print_trace (int32_t signum)
gf_mgmt_list[tmp->root->op]);
ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
+
trav = trav->next;
}
ret = write (fd, "\n", 1);
+ if (ret < 0)
+ goto out;
}
sprintf (msg, "patchset: %s\n", GLUSTERFS_REPOSITORY_REVISION);
ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
sprintf (msg, "signal received: %d\n", signum);
ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
{
/* Dump the timestamp of the crash too, so the previous logs
can be related */
- utime = time (NULL);
- tm = localtime (&utime);
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S\n", tm);
+ gf_time_fmt (timestr, sizeof timestr, time (NULL), gf_timefmt_FT);
ret = write (fd, "time of crash: ", 15);
+ if (ret < 0)
+ goto out;
ret = write (fd, timestr, strlen (timestr));
+ if (ret < 0)
+ goto out;
}
gf_dump_config_flags (fd);
@@ -400,9 +412,12 @@ gf_print_trace (int32_t signum)
backtrace_symbols_fd (&array[1], size-1, fd);
sprintf (msg, "---------\n");
ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
}
#endif /* HAVE_BACKTRACE */
+out:
/* Send a signal to terminate the process */
signal (signum, SIG_DFL);
raise (signum);
@@ -419,8 +434,7 @@ gf_trim (char *string)
{
register char *s, *t;
- if (string == NULL)
- {
+ if (string == NULL) {
return NULL;
}
@@ -451,19 +465,17 @@ gf_strsplit (const char *str, const char *delim,
int j = 0;
if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
return -1;
}
_running = gf_strdup (str);
if (_running == NULL)
- {
return -1;
- }
+
running = _running;
- while ((token = strsep (&running, delim)) != NULL)
- {
+ while ((token = strsep (&running, delim)) != NULL) {
if (token[0] != '\0')
count++;
}
@@ -471,20 +483,17 @@ gf_strsplit (const char *str, const char *delim,
_running = gf_strdup (str);
if (_running == NULL)
- {
return -1;
- }
+
running = _running;
if ((token_list = GF_CALLOC (count, sizeof (char *),
- gf_common_mt_char)) == NULL)
- {
+ gf_common_mt_char)) == NULL) {
GF_FREE (_running);
return -1;
}
- while ((token = strsep (&running, delim)) != NULL)
- {
+ while ((token = strsep (&running, delim)) != NULL) {
if (token[0] == '\0')
continue;
@@ -503,9 +512,8 @@ gf_strsplit (const char *str, const char *delim,
free_exit:
GF_FREE (_running);
for (j = 0; j < i; j++)
- {
GF_FREE (token_list[j]);
- }
+
GF_FREE (token_list);
return -1;
}
@@ -522,7 +530,7 @@ gf_strstr (const char *str, const char *delim, const char *match)
tmp_str = strdup (str);
if (str == NULL || delim == NULL || match == NULL || tmp_str == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
ret = -1;
goto out;
}
@@ -553,17 +561,14 @@ gf_volume_name_validate (const char *volume_name)
const char *vname = NULL;
if (volume_name == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
return -1;
}
if (!isalpha (volume_name[0]))
- {
return 1;
- }
- for (vname = &volume_name[1]; *vname != '\0'; vname++)
- {
+ for (vname = &volume_name[1]; *vname != '\0'; vname++) {
if (!(isalnum (*vname) || *vname == '_'))
return 1;
}
@@ -580,23 +585,17 @@ gf_string2time (const char *str, uint32_t *n)
int old_errno = 0;
const char *s = NULL;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
- for (s = str; *s != '\0'; s++)
- {
+ for (s = str; *s != '\0'; s++) {
if (isspace (*s))
- {
continue;
- }
if (*s == '-')
- {
return -1;
- }
break;
}
@@ -605,21 +604,16 @@ gf_string2time (const char *str, uint32_t *n)
value = strtol (str, &tail, 0);
if (errno == ERANGE || errno == EINVAL)
- {
return -1;
- }
if (errno == 0)
- {
errno = old_errno;
- }
if (!((tail[0] == '\0') ||
((tail[0] == 's') && (tail[1] == '\0')) ||
- ((tail[0] == 's') && (tail[1] == 'e') && (tail[2] == 'c') && (tail[3] == '\0'))))
- {
+ ((tail[0] == 's') && (tail[1] == 'e') &&
+ (tail[2] == 'c') && (tail[3] == '\0'))))
return -1;
- }
*n = value;
@@ -635,23 +629,17 @@ gf_string2percent (const char *str, uint32_t *n)
int old_errno = 0;
const char *s = NULL;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
- for (s = str; *s != '\0'; s++)
- {
+ for (s = str; *s != '\0'; s++) {
if (isspace (*s))
- {
continue;
- }
if (*s == '-')
- {
return -1;
- }
break;
}
@@ -660,20 +648,14 @@ gf_string2percent (const char *str, uint32_t *n)
value = strtol (str, &tail, 0);
if (errno == ERANGE || errno == EINVAL)
- {
return -1;
- }
if (errno == 0)
- {
errno = old_errno;
- }
if (!((tail[0] == '\0') ||
((tail[0] == '%') && (tail[1] == '\0'))))
- {
return -1;
- }
*n = value;
@@ -688,9 +670,8 @@ _gf_string2long (const char *str, long *n, int base)
char *tail = NULL;
int old_errno = 0;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
@@ -700,20 +681,13 @@ _gf_string2long (const char *str, long *n, int base)
value = strtol (str, &tail, base);
if (errno == ERANGE || errno == EINVAL)
- {
return -1;
- }
if (errno == 0)
- {
errno = old_errno;
- }
if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
return -1;
- }
*n = value;
@@ -728,25 +702,17 @@ _gf_string2ulong (const char *str, unsigned long *n, int base)
int old_errno = 0;
const char *s = NULL;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
- for (s = str; *s != '\0'; s++)
- {
+ for (s = str; *s != '\0'; s++) {
if (isspace (*s))
- {
continue;
- }
if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
return -1;
- }
break;
}
@@ -755,20 +721,13 @@ _gf_string2ulong (const char *str, unsigned long *n, int base)
value = strtoul (str, &tail, base);
if (errno == ERANGE || errno == EINVAL)
- {
return -1;
- }
if (errno == 0)
- {
errno = old_errno;
- }
if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
return -1;
- }
*n = value;
@@ -783,25 +742,17 @@ _gf_string2uint (const char *str, unsigned int *n, int base)
int old_errno = 0;
const char *s = NULL;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
- for (s = str; *s != '\0'; s++)
- {
+ for (s = str; *s != '\0'; s++) {
if (isspace (*s))
- {
continue;
- }
if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
return -1;
- }
break;
}
@@ -810,20 +761,13 @@ _gf_string2uint (const char *str, unsigned int *n, int base)
value = strtoul (str, &tail, base);
if (errno == ERANGE || errno == EINVAL)
- {
return -1;
- }
if (errno == 0)
- {
errno = old_errno;
- }
if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
return -1;
- }
*n = (unsigned int)value;
@@ -838,7 +782,7 @@ _gf_string2double (const char *str, double *n)
int old_errno = 0;
if (str == NULL || n == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
@@ -847,17 +791,14 @@ _gf_string2double (const char *str, double *n)
errno = 0;
value = strtod (str, &tail);
- if (errno == ERANGE || errno == EINVAL) {
+ if (errno == ERANGE || errno == EINVAL)
return -1;
- }
- if (errno == 0) {
+ if (errno == 0)
errno = old_errno;
- }
- if (tail[0] != '\0') {
+ if (tail[0] != '\0')
return -1;
- }
*n = value;
@@ -871,9 +812,8 @@ _gf_string2longlong (const char *str, long long *n, int base)
char *tail = NULL;
int old_errno = 0;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
@@ -883,20 +823,13 @@ _gf_string2longlong (const char *str, long long *n, int base)
value = strtoll (str, &tail, base);
if (errno == ERANGE || errno == EINVAL)
- {
return -1;
- }
if (errno == 0)
- {
errno = old_errno;
- }
if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
return -1;
- }
*n = value;
@@ -911,25 +844,17 @@ _gf_string2ulonglong (const char *str, unsigned long long *n, int base)
int old_errno = 0;
const char *s = NULL;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
- for (s = str; *s != '\0'; s++)
- {
+ for (s = str; *s != '\0'; s++) {
if (isspace (*s))
- {
continue;
- }
if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
return -1;
- }
break;
}
@@ -938,20 +863,13 @@ _gf_string2ulonglong (const char *str, unsigned long long *n, int base)
value = strtoull (str, &tail, base);
if (errno == ERANGE || errno == EINVAL)
- {
return -1;
- }
if (errno == 0)
- {
errno = old_errno;
- }
if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
return -1;
- }
*n = value;
@@ -1016,8 +934,7 @@ gf_string2int8 (const char *str, int8_t *n)
if (rv != 0)
return rv;
- if (l >= INT8_MIN && l <= INT8_MAX)
- {
+ if (l >= INT8_MIN && l <= INT8_MAX) {
*n = (int8_t) l;
return 0;
}
@@ -1036,8 +953,7 @@ gf_string2int16 (const char *str, int16_t *n)
if (rv != 0)
return rv;
- if (l >= INT16_MIN && l <= INT16_MAX)
- {
+ if (l >= INT16_MIN && l <= INT16_MAX) {
*n = (int16_t) l;
return 0;
}
@@ -1056,8 +972,7 @@ gf_string2int32 (const char *str, int32_t *n)
if (rv != 0)
return rv;
- if (l >= INT32_MIN && l <= INT32_MAX)
- {
+ if (l >= INT32_MIN && l <= INT32_MAX) {
*n = (int32_t) l;
return 0;
}
@@ -1076,8 +991,7 @@ gf_string2int64 (const char *str, int64_t *n)
if (rv != 0)
return rv;
- if (l >= INT64_MIN && l <= INT64_MAX)
- {
+ if (l >= INT64_MIN && l <= INT64_MAX) {
*n = (int64_t) l;
return 0;
}
@@ -1096,8 +1010,7 @@ gf_string2uint8 (const char *str, uint8_t *n)
if (rv != 0)
return rv;
- if (l >= 0 && l <= UINT8_MAX)
- {
+ if (l >= 0 && l <= UINT8_MAX) {
*n = (uint8_t) l;
return 0;
}
@@ -1116,8 +1029,7 @@ gf_string2uint16 (const char *str, uint16_t *n)
if (rv != 0)
return rv;
- if (l >= 0 && l <= UINT16_MAX)
- {
+ if (l >= 0 && l <= UINT16_MAX) {
*n = (uint16_t) l;
return 0;
}
@@ -1136,8 +1048,7 @@ gf_string2uint32 (const char *str, uint32_t *n)
if (rv != 0)
return rv;
- if (l >= 0 && l <= UINT32_MAX)
- {
+ if (l >= 0 && l <= UINT32_MAX) {
*n = (uint32_t) l;
return 0;
}
@@ -1156,8 +1067,7 @@ gf_string2uint64 (const char *str, uint64_t *n)
if (rv != 0)
return rv;
- if (l >= 0 && l <= UINT64_MAX)
- {
+ if (l >= 0 && l <= UINT64_MAX) {
*n = (uint64_t) l;
return 0;
}
@@ -1188,8 +1098,7 @@ gf_string2uint8_base10 (const char *str, uint8_t *n)
if (rv != 0)
return rv;
- if (l >= 0 && l <= UINT8_MAX)
- {
+ if (l >= 0 && l <= UINT8_MAX) {
*n = (uint8_t) l;
return 0;
}
@@ -1208,8 +1117,7 @@ gf_string2uint16_base10 (const char *str, uint16_t *n)
if (rv != 0)
return rv;
- if (l >= 0 && l <= UINT16_MAX)
- {
+ if (l >= 0 && l <= UINT16_MAX) {
*n = (uint16_t) l;
return 0;
}
@@ -1228,8 +1136,7 @@ gf_string2uint32_base10 (const char *str, uint32_t *n)
if (rv != 0)
return rv;
- if (l >= 0 && l <= UINT32_MAX)
- {
+ if (l >= 0 && l <= UINT32_MAX) {
*n = (uint32_t) l;
return 0;
}
@@ -1248,8 +1155,7 @@ gf_string2uint64_base10 (const char *str, uint64_t *n)
if (rv != 0)
return rv;
- if (l >= 0 && l <= UINT64_MAX)
- {
+ if (l >= 0 && l <= UINT64_MAX) {
*n = (uint64_t) l;
return 0;
}
@@ -1258,6 +1164,42 @@ gf_string2uint64_base10 (const char *str, uint64_t *n)
return -1;
}
+char *
+gf_uint64_2human_readable (uint64_t n)
+{
+ int ret = 0;
+ char *str = NULL;
+
+ if (n >= GF_UNIT_PB) {
+ ret = gf_asprintf (&str, "%.1lfPB", ((double) n)/GF_UNIT_PB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_TB) {
+ ret = gf_asprintf (&str, "%.1lfTB", ((double) n)/GF_UNIT_TB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_GB) {
+ ret = gf_asprintf (&str, "%.1lfGB", ((double) n)/GF_UNIT_GB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_MB) {
+ ret = gf_asprintf (&str, "%.1lfMB", ((double) n)/GF_UNIT_MB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_KB) {
+ ret = gf_asprintf (&str, "%.1lfKB", ((double) n)/GF_UNIT_KB);
+ if (ret < 0)
+ goto err;
+ } else {
+ ret = gf_asprintf (&str, "%luBytes", n);
+ if (ret < 0)
+ goto err;
+ }
+ return str;
+err:
+ return NULL;
+}
+
int
gf_string2bytesize (const char *str, uint64_t *n)
{
@@ -1266,25 +1208,17 @@ gf_string2bytesize (const char *str, uint64_t *n)
int old_errno = 0;
const char *s = NULL;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
errno = EINVAL;
return -1;
}
- for (s = str; *s != '\0'; s++)
- {
+ for (s = str; *s != '\0'; s++) {
if (isspace (*s))
- {
continue;
- }
if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
return -1;
- }
break;
}
@@ -1293,42 +1227,82 @@ gf_string2bytesize (const char *str, uint64_t *n)
value = strtoull (str, &tail, 10);
if (errno == ERANGE || errno == EINVAL)
- {
return -1;
- }
if (errno == 0)
- {
errno = old_errno;
- }
if (tail[0] != '\0')
{
if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0)
- {
value *= GF_UNIT_KB;
- }
else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0)
- {
value *= GF_UNIT_MB;
- }
else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0)
- {
value *= GF_UNIT_GB;
- }
else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0)
- {
value *= GF_UNIT_TB;
- }
else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0)
- {
value *= GF_UNIT_PB;
- }
else
- {
- /* bala: invalid integer format */
return -1;
- }
+ }
+
+ *n = value;
+
+ return 0;
+}
+
+int
+gf_string2percent_or_bytesize (const char *str,
+ uint64_t *n,
+ gf_boolean_t *is_percent)
+{
+ uint64_t value = 0ULL;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtoull (str, &tail, 10);
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
+
+ if (errno == 0)
+ errno = old_errno;
+
+ if (tail[0] != '\0') {
+ if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0)
+ value *= GF_UNIT_KB;
+ else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0)
+ value *= GF_UNIT_MB;
+ else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0)
+ value *= GF_UNIT_GB;
+ else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0)
+ value *= GF_UNIT_TB;
+ else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0)
+ value *= GF_UNIT_PB;
+ else if (strcasecmp (tail, GF_UNIT_PERCENT_STRING) == 0)
+ *is_percent = _gf_true;
+ else
+ return -1;
}
*n = value;
@@ -1379,7 +1353,7 @@ int
gf_string2boolean (const char *str, gf_boolean_t *b)
{
if (str == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
return -1;
}
@@ -1485,65 +1459,6 @@ get_checksum_for_file (int fd, uint32_t *checksum)
}
-/* One should pass the command here with command with full path,
- otherwise, execv will fail */
-int
-gf_system (const char *command)
-{
- int ret = -1;
- pid_t pid = 0;
- int status = 0;
- int idx = 0;
- char *dupcmd = NULL;
- char *arg = NULL;
- char *tmp = NULL;
- char *argv[100] = { NULL, };
-
- dupcmd = gf_strdup (command);
- if (!dupcmd)
- goto out;
-
- pid = fork ();
- if (pid < 0) {
- /* failure */
- goto out;
- }
- if (pid == 0) {
- /* Child process */
- /* Step 0: Prepare the argv */
- arg = strtok_r (dupcmd, " ", &tmp);
- while (arg) {
- argv[idx] = arg;
- arg = strtok_r (NULL, " ", &tmp);
- idx++;
- }
- /* Step 1: Close all 'fd' */
- for (idx = 3; idx < 65536; idx++) {
- close (idx);
- }
- /* Step 2: execv (); */
- ret = execvp (argv[0], argv);
-
- /* Code will not come here at all */
- gf_log ("", GF_LOG_ERROR, "execv of (%s) failed", command);
-
- kill (getpid(), SIGKILL);
- }
- if (pid > 0) {
- /* Current, ie, parent process */
- pid = waitpid (pid, &status, 0);
- if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS)
- ret = 0;
- else
- ret = -1;
- }
-out:
- if (dupcmd)
- GF_FREE (dupcmd);
-
- return ret;
-}
-
int
get_checksum_for_path (char *path, uint32_t *checksum)
{
@@ -1556,7 +1471,7 @@ get_checksum_for_path (char *path, uint32_t *checksum)
fd = open (path, O_RDWR);
if (fd == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to open %s, errno: %d",
+ gf_log (THIS->name, GF_LOG_ERROR, "Unable to open %s, errno: %d",
path, errno);
goto out;
}
@@ -1583,60 +1498,181 @@ strtail (char *str, const char *pattern)
return NULL;
}
+void
+skipwhite (char **s)
+{
+ while (isspace (**s))
+ (*s)++;
+}
+
+char *
+nwstrtail (char *str, char *pattern)
+{
+ for (;;) {
+ skipwhite (&str);
+ skipwhite (&pattern);
+
+ if (*str != *pattern || !*str)
+ break;
+
+ str++;
+ pattern++;
+ }
+
+ return *pattern ? NULL : str;
+}
+
+void
+skipword (char **s)
+{
+ if (!*s)
+ return;
+
+ skipwhite (s);
+
+ while (!isspace(**s))
+ (*s)++;
+}
+
+char *
+get_nth_word (const char *str, int n)
+{
+ char buf[4096] = {0};
+ char *start = NULL;
+ char *word = NULL;
+ int i = 0;
+ int word_len = 0;
+ const char *end = NULL;
+
+ if (!str)
+ goto out;
+
+ snprintf (buf, sizeof (buf), "%s", str);
+ start = buf;
+
+ for (i = 0; i < n-1; i++)
+ skipword (&start);
+
+ skipwhite (&start);
+ end = strpbrk ((const char *)start, " \t\n\0");
+
+ if (!end)
+ goto out;
+
+ word_len = abs (end - start);
+
+ word = GF_CALLOC (1, word_len + 1, gf_common_mt_strdup);
+ if (!word)
+ goto out;
+
+ strncpy (word, start, word_len);
+ *(word + word_len) = '\0';
+ out:
+ return word;
+}
+
/* RFC 1123 & 952 */
+/* Syntax formed combining RFC 1123 & 952 *
+ <hname> ::= <first-name>*["."<gen-name>] *
+ <first-name> ::= <let-or-digit> <[*[<let-or-digit-or-hyphen>]<let-or-digit>]
+ <gen-name> ::= <let>[*[<let-or-digit-or-hyphen>]<let-or-digit>] */
char
valid_host_name (char *address, int length)
{
- int i = 0;
- char ret = 1;
+ int i = 0;
+ int str_len = 0;
+ char ret = 1;
+ char *dup_addr = NULL;
+ char *temp_str = NULL;
+ char *save_ptr = NULL;
+
+ if ((length > _POSIX_HOST_NAME_MAX) || (length < 1)) {
+ ret = 0;
+ goto out;
+ }
- if ((length > 75) || (length == 1)) {
+ dup_addr = gf_strdup (address);
+ if (!dup_addr) {
ret = 0;
goto out;
}
+ temp_str = strtok_r (dup_addr,".", &save_ptr);
- if (!isalnum (address[length - 1])) {
+ /* first-name */
+ if (!temp_str ||
+ !isalnum(temp_str[0]) ||
+ !isalnum (temp_str[strlen(temp_str)-1])) {
ret = 0;
goto out;
}
+ for (i = 1; i < (strlen (temp_str) - 1); i++) {
+ if (!isalnum (temp_str[i]) && (temp_str[i] != '-')) {
+ ret = 0;
+ goto out;
+ }
+ }
+
+ /* gen-name */
+ while ((temp_str = strtok_r (NULL, ".", &save_ptr))) {
+ str_len = strlen (temp_str);
- for (i = 0; i < length; i++) {
- if (!isalnum (address[i]) && (address[i] != '.')
- && (address[i] != '-')) {
+ if (!isalpha (temp_str[0]) ||
+ !isalnum (temp_str[str_len-1])) {
ret = 0;
goto out;
}
+ for (i = 1; i < str_len; i++) {
+ if (!isalnum (temp_str[i]) && (temp_str[i] != '-')) {
+ ret = 0;
+ goto out;
+ }
+ }
}
out:
+ if (dup_addr)
+ GF_FREE (dup_addr);
return ret;
}
+/* Matches all ipv4 address, if wildcard_acc is true '*' wildcard pattern for*
+ subnets is considerd as valid strings as well */
char
-valid_ipv4_address (char *address, int length)
+valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc)
{
int octets = 0;
int value = 0;
char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
char ret = 1;
+ int is_wildcard = 0;
tmp = gf_strdup (address);
+
+ /* To prevent cases where last character is '.' */
+ if (!isdigit (tmp[length - 1]) && (tmp[length - 1] != '*')) {
+ ret = 0;
+ goto out;
+ }
+
prev = tmp;
prev = strtok_r (tmp, ".", &ptr);
- while (prev != NULL)
- {
+ while (prev != NULL) {
octets++;
- value = strtol (prev, &endptr, 10);
- if ((value > 255) || (value < 0) || (endptr != NULL)) {
- ret = 0;
- goto out;
+ if (wildcard_acc && !strcmp (prev, "*")) {
+ is_wildcard = 1;
+ } else {
+ value = strtol (prev, &endptr, 10);
+ if ((value > 255) || (value < 0) ||
+ (endptr != NULL && *endptr != '\0')) {
+ ret = 0;
+ goto out;
+ }
}
-
prev = strtok_r (NULL, ".", &ptr);
}
- if (octets != 4) {
+ if ((octets > 4) || (octets < 4 && !is_wildcard)) {
ret = 0;
}
@@ -1646,30 +1682,53 @@ out:
}
char
-valid_ipv6_address (char *address, int length)
+valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc)
{
int hex_numbers = 0;
int value = 0;
+ int i = 0;
char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
char ret = 1;
+ int is_wildcard = 0;
+ int is_compressed = 0;
tmp = gf_strdup (address);
+
+ /* Check for compressed form */
+ if (tmp[length - 1] == ':') {
+ ret = 0;
+ goto out;
+ }
+ for (i = 0; i < (length - 1) ; i++) {
+ if (tmp[i] == ':' && tmp[i + 1] == ':') {
+ if (is_compressed == 0)
+ is_compressed = 1;
+ else {
+ ret = 0;
+ goto out;
+ }
+ }
+ }
+
prev = strtok_r (tmp, ":", &ptr);
- while (prev != NULL)
- {
+ while (prev != NULL) {
hex_numbers++;
- value = strtol (prev, &endptr, 16);
- if ((value > 0xffff) || (value < 0)
- || (endptr != NULL && *endptr != '\0')) {
- ret = 0;
- goto out;
+ if (wildcard_acc && !strcmp (prev, "*")) {
+ is_wildcard = 1;
+ } else {
+ value = strtol (prev, &endptr, 16);
+ if ((value > 0xffff) || (value < 0)
+ || (endptr != NULL && *endptr != '\0')) {
+ ret = 0;
+ goto out;
+ }
}
-
prev = strtok_r (NULL, ":", &ptr);
}
- if (hex_numbers > 8) {
+ if ((hex_numbers > 8) || (hex_numbers < 8 && !is_wildcard
+ && !is_compressed)) {
ret = 0;
}
@@ -1679,26 +1738,24 @@ out:
}
char
-valid_internet_address (char *address)
+valid_internet_address (char *address, gf_boolean_t wildcard_acc)
{
char ret = 0;
int length = 0;
if (address == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
goto out;
}
length = strlen (address);
- if (length == 0) {
+ if (length == 0)
goto out;
- }
- if (valid_ipv4_address (address, length)
- || valid_ipv6_address (address, length)
- || valid_host_name (address, length)) {
+ if (valid_ipv4_address (address, length, wildcard_acc)
+ || valid_ipv6_address (address, length, wildcard_acc)
+ || valid_host_name (address, length))
ret = 1;
- }
out:
return ret;
@@ -1723,17 +1780,23 @@ uuid_utoa_r (uuid_t uuid, char *dst)
return dst;
}
-void _get_md5_str (char *out_str, size_t outlen,
- const uint8_t *input, int n)
+/*Thread safe conversion function*/
+char *
+lkowner_utoa (gf_lkowner_t *lkowner)
{
- uint8_t out[MD5_DIGEST_LEN] = {0};
- int j = 0;
-
- GF_ASSERT (outlen >= (2*MD5_DIGEST_LEN + 1));
- get_md5 (out, input, n);
- for (j = 0; j < MD5_DIGEST_LEN; j++)
- snprintf(out_str + j * 2, outlen-j*2, "%02x", out[j]);
+ char *lkowner_buffer = glusterfs_lkowner_buf_get();
+ lkowner_unparse (lkowner, lkowner_buffer, GF_LKOWNER_BUF_SIZE);
+ return lkowner_buffer;
+}
+/*Re-entrant conversion function*/
+char *
+lkowner_utoa_r (gf_lkowner_t *lkowner, char *dst, int len)
+{
+ if(!dst)
+ return NULL;
+ lkowner_unparse (lkowner, dst, len);
+ return dst;
}
void* gf_array_elem (void *a, int index, size_t elem_size)
@@ -1764,8 +1827,8 @@ gf_array_insertionsort (void *A, int l, int r, size_t elem_size,
for(i = l; i < N; i++) {
Temp = gf_array_elem (A, i, elem_size);
j = i - 1;
- while((cmp (Temp, gf_array_elem (A, j, elem_size)) < 0) && j>=0)
- {
+ while((cmp (Temp, gf_array_elem (A, j, elem_size))
+ < 0) && j>=0) {
gf_elem_swap (Temp, gf_array_elem (A, j, elem_size),
elem_size);
Temp = gf_array_elem (A, j, elem_size);
@@ -1781,7 +1844,7 @@ gf_is_str_int (const char *value)
char *str = NULL;
char *fptr = NULL;
- GF_VALIDATE_OR_GOTO ("", value, out);
+ GF_VALIDATE_OR_GOTO (THIS->name, value, out);
str = gf_strdup (value);
if (!str)
@@ -1803,4 +1866,194 @@ out:
return flag;
}
+/*
+ * rounds up nr to power of two. If nr is already a power of two, just returns
+ * nr
+ */
+
+inline int32_t
+gf_roundup_power_of_two (uint32_t nr)
+{
+ uint32_t result = 1;
+
+ if (nr < 0) {
+ gf_log ("common-utils", GF_LOG_WARNING,
+ "negative number passed");
+ result = -1;
+ goto out;
+ }
+
+ while (result < nr)
+ result *= 2;
+
+out:
+ return result;
+}
+
+/*
+ * rounds up nr to next power of two. If nr is already a power of two, next
+ * power of two is returned.
+ */
+
+/*
+ * rounds up nr to next power of two. If nr is already a power of two, next
+ * power of two is returned.
+ */
+
+inline int32_t
+gf_roundup_next_power_of_two (uint32_t nr)
+{
+ int32_t result = 1;
+
+ if (nr < 0) {
+ gf_log ("common-utils", GF_LOG_WARNING,
+ "negative number passed");
+ result = -1;
+ goto out;
+ }
+
+ while (result <= nr)
+ result *= 2;
+
+out:
+ return result;
+}
+
+int
+validate_brick_name (char *brick)
+{
+ char *delimiter = NULL;
+ int ret = 0;
+ delimiter = strrchr (brick, ':');
+ if (!delimiter || delimiter == brick
+ || *(delimiter+1) != '/')
+ ret = -1;
+
+ return ret;
+}
+
+char *
+get_host_name (char *word, char **host)
+{
+ char *delimiter = NULL;
+ delimiter = strrchr (word, ':');
+ if (delimiter)
+ *delimiter = '\0';
+ else
+ return NULL;
+ *host = word;
+ return *host;
+}
+
+
+char *
+get_path_name (char *word, char **path)
+{
+ char *delimiter = NULL;
+ delimiter = strchr (word, '/');
+ if (!delimiter)
+ return NULL;
+ *path = delimiter;
+ return *path;
+}
+
+void
+gf_path_strip_trailing_slashes (char *path)
+{
+ int i = 0;
+ int len = 0;
+
+ if (!path)
+ return;
+
+ len = strlen (path);
+ for (i = len - 1; i > 0; i--) {
+ if (path[i] != '/')
+ break;
+ }
+
+ if (i < (len -1))
+ path [i+1] = '\0';
+
+ return;
+}
+
+uint64_t
+get_mem_size ()
+{
+ uint64_t memsize = -1;
+
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS
+
+ uint64_t page_size = 0;
+ uint64_t num_pages = 0;
+
+ page_size = sysconf (_SC_PAGESIZE);
+ num_pages = sysconf (_SC_PHYS_PAGES);
+
+ memsize = page_size * num_pages;
+#endif
+
+#if defined GF_BSD_HOST_OS || defined GF_DARWIN_HOST_OS
+
+ size_t len = sizeof(memsize);
+ int name [] = { CTL_HW, HW_PHYSMEM };
+
+ sysctl (name, 2, &memsize, &len, NULL, 0);
+#endif
+ return memsize;
+}
+
+/* Strips all whitespace characters in a string and returns length of new string
+ * on success
+ */
+int
+gf_strip_whitespace (char *str, int len)
+{
+ int i = 0;
+ int new_len = 0;
+ char *new_str = NULL;
+
+ GF_ASSERT (str);
+
+ new_str = GF_CALLOC (1, len + 1, gf_common_mt_char);
+ if (new_str == NULL)
+ return -1;
+
+ for (i = 0; i < len; i++) {
+ if (!isspace (str[i]))
+ new_str[new_len++] = str[i];
+ }
+ new_str[new_len] = '\0';
+
+ if (new_len != len) {
+ memset (str, 0, len);
+ strncpy (str, new_str, new_len);
+ }
+
+ GF_FREE (new_str);
+ return new_len;
+}
+
+static const char *__gf_timefmts[] = {
+ "%F %T",
+ "%Y/%m/%d-%T",
+ "%b %d %T",
+ "%F %H%M%S"
+};
+
+static const char *__gf_zerotimes[] = {
+ "0000-00-00 00:00:00",
+ "0000/00/00-00:00:00",
+ "xxx 00 00:00:00",
+ "0000-00-00 000000"
+};
+
+void
+_gf_timestuff (gf_timefmts *fmt, const char ***fmts, const char ***zeros)
+{
+ *fmt = gf_timefmt_last;
+ *fmts = __gf_timefmts;
+ *zeros = __gf_zerotimes;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index a1df3de35..3df6dd91c 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _COMMON_UTILS_H
@@ -50,6 +41,7 @@ void trap (void);
#include "uuid.h"
+
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define roof(a,b) ((((a)+(b)-1)/((b)?(b):1))*(b))
@@ -68,7 +60,22 @@ void trap (void);
#define GF_UNIT_TB_STRING "TB"
#define GF_UNIT_PB_STRING "PB"
+#define GF_UNIT_PERCENT_STRING "%"
+
#define GEOREP "geo-replication"
+#define GHADOOP "glusterfs-hadoop"
+
+#define WIPE(statp) do { typeof(*statp) z = {0,}; if (statp) *statp = z; } while (0)
+
+#define IS_EXT_FS(fs_name) \
+ (!strcmp (fs_name, "ext2") || \
+ !strcmp (fs_name, "ext3") || \
+ !strcmp (fs_name, "ext4"))
+
+/* Defining this here as it is needed by glusterd for setting
+ * nfs port in volume status.
+ */
+#define GF_NFS3_PORT 38467
enum _gf_boolean
{
@@ -76,7 +83,23 @@ enum _gf_boolean
_gf_true = 1
};
+/*
+ * we could have initialized these as +ve values and treated
+ * them as negative while comparing etc.. (which would have
+ * saved us with the pain of assigning values), but since we
+ * only have a couple of clients that use this feature, it's
+ * okay.
+ */
+enum _gf_client_pid
+{
+ GF_CLIENT_PID_MAX = 0,
+ GF_CLIENT_PID_GSYNCD = -1,
+ GF_CLIENT_PID_HADOOP = -2,
+ GF_CLIENT_PID_DEFRAG = -3,
+};
+
typedef enum _gf_boolean gf_boolean_t;
+typedef enum _gf_client_pid gf_client_pid_t;
typedef int (*gf_cmp) (void *, void *);
void gf_global_variable_init(void);
@@ -101,7 +124,7 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
"invalid argument: " #arg); \
goto label; \
} \
- } while (0);
+ } while (0)
#define GF_VALIDATE_OR_GOTO(name,arg,label) do { \
if (!arg) { \
@@ -110,7 +133,7 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
"invalid argument: " #arg); \
goto label; \
} \
- } while (0);
+ } while (0)
#define GF_VALIDATE_OR_GOTO_WITH_ERROR(name, arg, label, errno, error) do { \
if (!arg) { \
@@ -119,7 +142,15 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
"invalid argument: " #arg); \
goto label; \
} \
- }while (0);
+ }while (0)
+
+#define GF_ASSERT_AND_GOTO_WITH_ERROR(name, arg, label, errno, error) do { \
+ if (!arg) { \
+ GF_ASSERT (0); \
+ errno = error; \
+ goto label; \
+ } \
+ }while (0)
#define GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO(name,arg,label) \
do { \
@@ -130,7 +161,57 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
"invalid argument: " #arg); \
goto label; \
} \
- } while (0);
+ } while (0)
+
+#define GF_REMOVE_SLASH_FROM_PATH(path, string) \
+ do { \
+ int i = 0; \
+ for (i = 1; i < strlen (path); i++) { \
+ string[i-1] = path[i]; \
+ if (string[i-1] == '/') \
+ string[i-1] = '-'; \
+ } \
+ } while (0)
+
+
+#define GF_IF_INTERNAL_XATTR_GOTO(pattern, dict, trav, op_errno, label) \
+ do { \
+ if (!dict) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "setxattr dict is null"); \
+ goto label; \
+ } \
+ trav = dict->members_list; \
+ while (trav) { \
+ if (!fnmatch (pattern, trav->key, 0)) { \
+ op_errno = EPERM; \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "attempt to set internal" \
+ " xattr: %s: %s", trav->key, \
+ strerror (op_errno)); \
+ goto label; \
+ } \
+ trav = trav->next; \
+ } \
+ } while (0)
+
+#define GF_IF_NATIVE_XATTR_GOTO(pattern, key, op_errno, label) \
+ do { \
+ if (!key) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "no key for removexattr"); \
+ goto label; \
+ } \
+ if (!fnmatch (pattern, key, 0)) { \
+ op_errno = EPERM; \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "attempt to remove internal " \
+ "xattr: %s: %s", key, \
+ strerror (op_errno)); \
+ goto label; \
+ } \
+ } while (0)
+
#define GF_FILE_CONTENT_REQUESTED(_xattr_req,_content_limit) \
(dict_get_uint64 (_xattr_req, "glusterfs.content", _content_limit) == 0)
@@ -144,9 +225,20 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
gf_log_callingfn ("", GF_LOG_ERROR, \
"Assertion failed: " #x); \
} \
- } while (0);
+ } while (0)
#endif
+#define GF_UUID_ASSERT(u) \
+ if (uuid_is_null (u))\
+ GF_ASSERT (!"uuid null");
+
+union gf_sock_union {
+ struct sockaddr_storage storage;
+ struct sockaddr_in6 sin6;
+ struct sockaddr_in sin;
+ struct sockaddr sa;
+};
+
#define GF_HIDDEN_PATH ".glusterfs"
static inline void
@@ -300,6 +392,47 @@ memdup (const void *ptr, size_t size)
return newptr;
}
+typedef enum {
+ gf_timefmt_default = 0,
+ gf_timefmt_FT = 0, /* YYYY-MM-DD hh:mm:ss */
+ gf_timefmt_Ymd_T, /* YYYY/MM-DD-hh:mm:ss */
+ gf_timefmt_bdT, /* ddd DD hh:mm:ss */
+ gf_timefmt_F_HMS, /* YYYY-MM-DD hhmmss */
+ gf_timefmt_last
+} gf_timefmts;
+
+static inline void
+gf_time_fmt (char *dst, size_t sz_dst, time_t utime, unsigned int fmt)
+{
+ extern void _gf_timestuff (gf_timefmts *, const char ***, const char ***);
+ static gf_timefmts timefmt_last = (gf_timefmts) -1;
+ static const char **fmts;
+ static const char **zeros;
+ struct tm tm;
+
+ if (timefmt_last == -1)
+ _gf_timestuff (&timefmt_last, &fmts, &zeros);
+ if (timefmt_last < fmt) fmt = gf_timefmt_default;
+ if (gmtime_r (&utime, &tm) != NULL) {
+ strftime (dst, sz_dst, fmts[fmt], &tm);
+ } else {
+ strncpy (dst, zeros[fmt], sz_dst);
+ }
+}
+
+/*
+ * rounds up nr to power of two. If nr is already a power of two, just returns
+ * nr
+ */
+
+int32_t gf_roundup_power_of_two (uint32_t nr);
+
+/*
+ * rounds up nr to next power of two. If nr is already a power of two, next
+ * power of two is returned.
+ */
+
+int32_t gf_roundup_next_power_of_two (uint32_t nr);
char *gf_trim (char *string);
int gf_strsplit (const char *str, const char *delim,
@@ -333,6 +466,8 @@ int gf_string2uint32_base10 (const char *str, uint32_t *n);
int gf_string2uint64_base10 (const char *str, uint64_t *n);
int gf_string2bytesize (const char *str, uint64_t *n);
+int gf_string2percent_or_bytesize (const char *str, uint64_t *n,
+ gf_boolean_t *is_percent);
int gf_string2boolean (const char *str, gf_boolean_t *b);
int gf_string2percent (const char *str, uint32_t *n);
@@ -344,21 +479,37 @@ int gf_unlockfd (int fd);
int get_checksum_for_file (int fd, uint32_t *checksum);
int log_base2 (unsigned long x);
-int gf_system (const char *command);
int get_checksum_for_path (char *path, uint32_t *checksum);
char *strtail (char *str, const char *pattern);
+void skipwhite (char **s);
+char *nwstrtail (char *str, char *pattern);
+void skip_word (char **str);
+/* returns a new string with nth word of given string. n>=1 */
+char *get_nth_word (const char *str, int n);
char valid_host_name (char *address, int length);
-char valid_ipv4_address (char *address, int length);
-char valid_ipv6_address (char *address, int length);
-char valid_internet_address (char *address);
+char valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc);
+char valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc);
+char valid_internet_address (char *address, gf_boolean_t wildcard_acc);
+char valid_ipv4_wildcard_check (char *address);
+char valid_ipv6_wildcard_check (char *address);
+char valid_wildcard_internet_address (char *address);
char *uuid_utoa (uuid_t uuid);
char *uuid_utoa_r (uuid_t uuid, char *dst);
-void _get_md5_str (char *out_str, size_t outlen,
- const uint8_t *input, int n);
+char *lkowner_utoa (gf_lkowner_t *lkowner);
+char *lkowner_utoa_r (gf_lkowner_t *lkowner, char *dst, int len);
+
void gf_array_insertionsort (void *a, int l, int r, size_t elem_size,
gf_cmp cmp);
int gf_is_str_int (const char *value);
+
+char *gf_uint64_2human_readable (uint64_t);
+int validate_brick_name (char *brick);
+char *get_host_name (char *word, char **host);
+char *get_path_name (char *word, char **path);
+void gf_path_strip_trailing_slashes (char *path);
+uint64_t get_mem_size ();
+int gf_strip_whitespace (char *str, int len);
#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/compat-errno.c b/libglusterfs/src/compat-errno.c
index 1a7290fe7..fd5cc49ce 100644
--- a/libglusterfs/src/compat-errno.c
+++ b/libglusterfs/src/compat-errno.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -567,7 +558,7 @@ init_compat_errno_arrays ()
gf_error_to_errno_array[GF_ERROR_CODE_BADMACHO] = EBADMACHO;
gf_errno_to_error_array[EBADMACHO] = GF_ERROR_CODE_BADMACHO;
-#if 0
+#ifdef EDOOFUS
/* EDOOFUS 88 / * Programming error */
gf_error_to_errno_array[GF_ERROR_CODE_DOOFUS] = EDOOFUS;
gf_errno_to_error_array[EDOOFUS] = GF_ERROR_CODE_DOOFUS;
@@ -858,9 +849,11 @@ init_compat_errno_arrays ()
gf_error_to_errno_array[GF_ERROR_CODE_NOATTR] = ENOATTR;
gf_errno_to_error_array[ENOATTR] = GF_ERROR_CODE_NOATTR;
+#ifdef EDOOFUS
/* EDOOFUS 88 / * Programming error */
gf_error_to_errno_array[GF_ERROR_CODE_DOOFUS] = EDOOFUS;
gf_errno_to_error_array[EDOOFUS] = GF_ERROR_CODE_DOOFUS;
+#endif
/* EBADMSG 89 / * Bad message */
gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
diff --git a/libglusterfs/src/compat-errno.h b/libglusterfs/src/compat-errno.h
index d6ca42acf..65e52081d 100644
--- a/libglusterfs/src/compat-errno.h
+++ b/libglusterfs/src/compat-errno.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 __COMPAT_ERRNO_H__
diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c
index 42c20f527..2dcd56a41 100644
--- a/libglusterfs/src/compat.c
+++ b/libglusterfs/src/compat.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -121,7 +112,7 @@ make_export_path (const char *real_path, char **path)
ret = solaris_getxattr ("/", GFID_XATTR_KEY, gfid, 16);
/* Return value of getxattr */
if (ret == 16) {
- if (!__is_root_gfid (gfid)){
+ if (__is_root_gfid (gfid)){
strcat (export_path, "/");
ret = 0;
goto done;
@@ -135,7 +126,7 @@ make_export_path (const char *real_path, char **path)
strcat (export_path, dup);
ret = solaris_getxattr (export_path, GFID_XATTR_KEY, gfid, 16);
if (ret == 16) {
- if (!__is_root_gfid (gfid)) {
+ if (__is_root_gfid (gfid)) {
ret = 0;
goto done;
}
@@ -181,7 +172,7 @@ solaris_xattr_resolve_path (const char *real_path, char **path)
if (lstat (export_path, &statbuf)) {
ret = mkdir (export_path, 0777);
if (ret && (errno != EEXIST)) {
- gf_log ("", GF_LOG_DEBUG, "mkdir failed,"
+ gf_log (THIS->name, GF_LOG_DEBUG, "mkdir failed,"
" errno: %d", errno);
goto out;
}
@@ -195,7 +186,7 @@ solaris_xattr_resolve_path (const char *real_path, char **path)
if (ret) {
ret = mknod (xattr_path, S_IFREG|O_WRONLY, 0);
if (ret && (errno != EEXIST)) {
- gf_log ("", GF_LOG_WARNING,"Failed to create "
+ gf_log (THIS->name, GF_LOG_WARNING,"Failed to create "
"mapped file %s, error %d", xattr_path,
errno);
goto out;
@@ -490,13 +481,13 @@ int solaris_unlink (const char *path)
if (!ret && mapped_path) {
if (lstat(path, &stbuf)) {
- gf_log ("",GF_LOG_WARNING, "Stat failed on mapped"
+ gf_log (THIS->name, GF_LOG_WARNING, "Stat failed on mapped"
" file %s with error %d", mapped_path, errno);
goto out;
}
if (stbuf.st_nlink == 1) {
if(remove (mapped_path))
- gf_log ("", GF_LOG_WARNING, "Failed to remove mapped "
+ gf_log (THIS->name, GF_LOG_WARNING, "Failed to remove mapped "
"file %s. Errno %d", mapped_path, errno);
}
@@ -520,7 +511,7 @@ solaris_rename (const char *old_path, const char *new_path)
if (!ret && mapped_path) {
if (!remove (mapped_path))
- gf_log ("", GF_LOG_WARNING, "Failed to remove mapped "
+ gf_log (THIS->name, GF_LOG_WARNING, "Failed to remove mapped "
"file %s. Errno %d", mapped_path, errno);
GF_FREE (mapped_path);
}
@@ -528,6 +519,25 @@ solaris_rename (const char *old_path, const char *new_path)
return rename(old_path, new_path);
}
+
+char *
+mkdtemp (char *tempstring)
+{
+ char *new_string = NULL;
+ int ret = 0;
+
+ new_string = mkstemp (tempstring);
+ if (!new_string)
+ goto out;
+
+ ret = mkdir (new_string, 0700);
+ if (ret < 0)
+ new_string = NULL;
+
+out:
+ return new_string;
+}
+
#endif /* GF_SOLARIS_HOST_OS */
#ifndef HAVE_STRNLEN
diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h
index a6f1f01bd..3d0cee1a9 100644
--- a/libglusterfs/src/compat.h
+++ b/libglusterfs/src/compat.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 __COMPAT_H__
@@ -58,7 +49,7 @@
#endif /* GF_LINUX_HOST_OS */
#ifdef GF_BSD_HOST_OS
-/* In case of FreeBSD */
+/* In case of FreeBSD and NetBSD */
#define UNIX_PATH_MAX 104
#include <sys/types.h>
@@ -66,16 +57,21 @@
#include <sys/un.h>
#include <sys/endian.h>
#include <sys/extattr.h>
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif /* HAVE_SYS_XATTR_H */
#include <limits.h>
#include <libgen.h>
+#ifndef XATTR_CREATE
enum {
ATTR_CREATE = 1,
#define XATTR_CREATE ATTR_CREATE
ATTR_REPLACE = 2
#define XATTR_REPLACE ATTR_REPLACE
};
+#endif /* XATTR_CREATE */
#ifndef sighandler_t
@@ -284,6 +280,8 @@ int solaris_rename (const char *oldpath, const char *newpath);
int solaris_unlink (const char *pathname);
+char *mkdtemp (char *temp);
+
#define GF_SOLARIS_XATTR_DIR ".glusterfs_xattr_inode"
int solaris_xattr_resolve_path (const char *real_path, char **path);
@@ -336,6 +334,18 @@ dirent_size (struct dirent *entry)
return size;
}
+#ifdef THREAD_UNSAFE_BASENAME
+char *basename_r(const char *);
+#define basename(path) basename_r(path)
+#endif /* THREAD_UNSAFE_BASENAME */
+
+#ifdef THREAD_UNSAFE_DIRNAME
+char *dirname_r(char *path);
+#define dirname(path) dirname_r(path)
+#endif /* THREAD_UNSAFE_DIRNAME */
+
+int gf_mkostemp (char *tmpl, int suffixlen, int flags);
+#define mkostemp(tmpl, flags) gf_mkostemp(tmpl, 0, flags);
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
/* Linux, Solaris, Cygwin */
@@ -378,4 +388,9 @@ dirent_size (struct dirent *entry)
#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG(buf, (long)(v))
#endif
+#if defined(__GNUC__) && !defined(RELAX_POISONING)
+/* Use run API, see run.h */
+#pragma GCC poison system popen
+#endif
+
#endif /* __COMPAT_H__ */
diff --git a/libglusterfs/src/daemon.c b/libglusterfs/src/daemon.c
new file mode 100644
index 000000000..348e3ad40
--- /dev/null
+++ b/libglusterfs/src/daemon.c
@@ -0,0 +1,66 @@
+/*
+ Copyright (c) 2008-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 <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "daemon.h"
+
+int
+os_daemon_return (int nochdir, int noclose)
+{
+ pid_t pid = -1;
+ int ret = -1;
+ FILE *ptr = NULL;
+
+ ret = fork();
+ if (ret)
+ return ret;
+
+ pid = setsid();
+
+ if (pid == -1) {
+ ret = -1;
+ goto out;
+ }
+
+ if (!nochdir)
+ ret = chdir("/");
+
+ if (!noclose) {
+ ptr = freopen (DEVNULLPATH, "r", stdin);
+ if (!ptr)
+ goto out;
+
+ ptr = freopen (DEVNULLPATH, "w", stdout);
+ if (!ptr)
+ goto out;
+
+ ptr = freopen (DEVNULLPATH, "w", stderr);
+ if (!ptr)
+ goto out;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+os_daemon (int nochdir, int noclose)
+{
+ int ret = -1;
+
+ ret = os_daemon_return (nochdir, noclose);
+ if (ret <= 0)
+ return ret;
+
+ _exit (0);
+}
diff --git a/libglusterfs/src/daemon.h b/libglusterfs/src/daemon.h
new file mode 100644
index 000000000..80836a326
--- /dev/null
+++ b/libglusterfs/src/daemon.h
@@ -0,0 +1,23 @@
+/*
+ Copyright (c) 2008-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 _DAEMON_H
+#define _DAEMON_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#define DEVNULLPATH "/dev/null"
+
+int os_daemon_return(int nochdir, int noclose);
+int os_daemon(int nochdir, int noclose);
+#endif /*_DAEMON_H */
diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
index ec41ce926..bf4d01934 100644
--- a/libglusterfs/src/defaults.c
+++ b/libglusterfs/src/defaults.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
/* libglusterfs/src/defaults.c:
@@ -41,18 +32,19 @@
int32_t
default_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *dict, struct iatt *postparent)
+ struct iatt *buf, dict_t *xdata, struct iatt *postparent)
{
STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- dict, postparent);
+ xdata, postparent);
return 0;
}
int32_t
default_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
return 0;
}
@@ -60,37 +52,41 @@ default_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
default_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
+ struct iatt *postbuf,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf);
+ postbuf, xdata);
return 0;
}
int32_t
default_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
+ struct iatt *postbuf,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf);
+ postbuf, xdata);
return 0;
}
int32_t
default_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf)
+ struct iatt *buf, dict_t *xdata)
{
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf);
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf,
+ xdata);
return 0;
}
@@ -99,10 +95,10 @@ int32_t
default_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent);
+ buf, preparent, postparent, xdata);
return 0;
}
@@ -110,30 +106,31 @@ int32_t
default_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent);
+ buf, preparent, postparent, xdata);
return 0;
}
int32_t
default_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- postparent);
+ postparent, xdata);
return 0;
}
int32_t
default_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent);
+ postparent, xdata);
return 0;
}
@@ -142,10 +139,10 @@ int32_t
default_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent);
+ preparent, postparent, xdata);
return 0;
}
@@ -154,10 +151,11 @@ int32_t
default_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent)
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent);
+ postoldparent, prenewparent, postnewparent, xdata);
return 0;
}
@@ -166,10 +164,11 @@ int32_t
default_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent);
+ preparent, postparent, xdata);
return 0;
}
@@ -178,28 +177,31 @@ int32_t
default_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent);
+ preparent, postparent, xdata);
return 0;
}
int32_t
default_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd)
+ int32_t op_ret, int32_t op_errno, fd_t *fd,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
return 0;
}
int32_t
default_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref);
+ stbuf, iobref, xdata);
return 0;
}
@@ -207,18 +209,20 @@ default_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
default_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
+ struct iatt *postbuf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
return 0;
}
int32_t
default_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
return 0;
}
@@ -227,59 +231,67 @@ default_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
default_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
+ struct iatt *postbuf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf,
+ xdata);
return 0;
}
int32_t
default_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
return 0;
}
int32_t
default_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd)
+ int32_t op_ret, int32_t op_errno, fd_t *fd,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
return 0;
}
int32_t
default_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
return 0;
}
int32_t
default_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
return 0;
}
@@ -287,84 +299,104 @@ default_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
default_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict);
+ STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
return 0;
}
int32_t
default_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
return 0;
}
int32_t
default_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict);
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
return 0;
}
int32_t
default_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict);
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
return 0;
}
int32_t
default_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int32_t
+default_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
return 0;
}
int32_t
default_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
return 0;
}
@@ -372,48 +404,53 @@ default_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
default_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
- uint8_t *strong_checksum)
+ uint8_t *strong_checksum,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum);
+ strong_checksum, xdata);
return 0;
}
int32_t
default_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries);
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata);
return 0;
}
int32_t
default_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
return 0;
}
int32_t
default_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost)
+ struct iatt *statpost,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost);
+ statpost, xdata);
return 0;
}
int32_t
default_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost)
+ struct iatt *statpost,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost);
+ statpost, xdata);
return 0;
}
@@ -429,257 +466,271 @@ default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
default_fgetxattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name);
+ FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
return 0;
}
int32_t
default_fsetxattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags)
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags);
+ FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
return 0;
}
int32_t
default_setxattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags)
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags);
+ FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
return 0;
}
int32_t
-default_statfs_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_statfs_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc);
+ FIRST_CHILD(this)->fops->statfs, loc, xdata);
return 0;
}
int32_t
default_fsyncdir_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsyncdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir, fd, flags);
+ FIRST_CHILD(this)->fops->fsyncdir, fd, flags, xdata);
return 0;
}
int32_t
default_opendir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd);
+ FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
return 0;
}
int32_t
-default_fstat_resume (call_frame_t *frame, xlator_t *this, fd_t *fd)
+default_fstat_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd);
+ FIRST_CHILD(this)->fops->fstat, fd, xdata);
return 0;
}
int32_t
default_fsync_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, flags);
+ FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
return 0;
}
int32_t
-default_flush_resume (call_frame_t *frame, xlator_t *this, fd_t *fd)
+default_flush_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd);
+ FIRST_CHILD(this)->fops->flush, fd, xdata);
return 0;
}
int32_t
default_writev_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t off,
- struct iobref *iobref)
+ uint32_t flags, struct iobref *iobref, dict_t *xdata)
{
STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
- iobref);
+ flags, iobref, xdata);
return 0;
}
int32_t
default_readv_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset)
+ size_t size, off_t offset, uint32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset);
+ FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
return 0;
}
int32_t
default_open_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, int32_t wbflags)
+ int32_t flags, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
return 0;
}
int32_t
default_create_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
+ int32_t flags, mode_t mode, mode_t umask, fd_t *fd,
+ dict_t *xdata)
{
STACK_WIND (frame, default_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, fd,
- params);
+ FIRST_CHILD(this)->fops->create, loc, flags, mode, umask,
+ fd, xdata);
return 0;
}
int32_t
default_link_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
+ loc_t *newloc, dict_t *xdata)
{
STACK_WIND (frame, default_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc);
+ FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
return 0;
}
int32_t
default_rename_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
+ loc_t *newloc, dict_t *xdata)
{
STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc);
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
return 0;
}
int
default_symlink_resume (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params)
+ const char *linkpath, loc_t *loc, mode_t umask,
+ dict_t *xdata)
{
STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, params);
+ FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask,
+ xdata);
return 0;
}
int32_t
default_rmdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int flags)
+ int flags, dict_t *xdata)
{
STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags);
+ FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata);
return 0;
}
int32_t
-default_unlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_unlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int xflag, dict_t *xdata)
{
STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc);
+ FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
return 0;
}
int
default_mkdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dict_t *params)
+ mode_t mode, mode_t umask, dict_t *xdata)
{
STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
+ FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata);
return 0;
}
int
default_mknod_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t rdev, dict_t *parms)
+ mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
{
STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, parms);
+ FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask,
+ xdata);
return 0;
}
int32_t
default_readlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size)
+ size_t size, dict_t *xdata)
{
STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc, size);
+ FIRST_CHILD(this)->fops->readlink, loc, size, xdata);
return 0;
}
int32_t
default_access_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask)
+ int32_t mask, dict_t *xdata)
{
STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->access, loc, mask);
+ FIRST_CHILD(this)->fops->access, loc, mask, xdata);
return 0;
}
int32_t
default_ftruncate_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset)
+ off_t offset, dict_t *xdata)
{
STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
return 0;
}
int32_t
default_getxattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name);
+ FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
return 0;
}
int32_t
default_xattrop_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict)
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop, loc, flags, dict);
+ FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata);
return 0;
}
int32_t
default_fxattrop_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict)
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict);
+ FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata);
return 0;
}
int32_t
default_removexattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name);
+ FIRST_CHILD(this)->fops->removexattr, loc, name, xdata);
+ return 0;
+}
+
+int32_t
+default_fremovexattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ STACK_WIND (frame, default_fremovexattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata);
return 0;
}
int32_t
default_lk_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock)
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
STACK_WIND (frame, default_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata);
return 0;
}
@@ -687,117 +738,127 @@ default_lk_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
default_inodelk_resume (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock)
+ struct gf_flock *lock,
+ dict_t *xdata)
{
STACK_WIND (frame, default_inodelk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock);
+ volume, loc, cmd, lock, xdata);
return 0;
}
int32_t
default_finodelk_resume (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *lock)
+ struct gf_flock *lock,
+ dict_t *xdata)
{
STACK_WIND (frame, default_finodelk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock);
+ volume, fd, cmd, lock, xdata);
return 0;
}
int32_t
default_entrylk_resume (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type)
+ entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
STACK_WIND (frame, default_entrylk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type);
+ volume, loc, basename, cmd, type, xdata);
return 0;
}
int32_t
default_fentrylk_resume (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type)
+ entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
STACK_WIND (frame, default_fentrylk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type);
+ volume, fd, basename, cmd, type, xdata);
return 0;
}
int32_t
default_rchecksum_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, int32_t len)
+ off_t offset, int32_t len,
+ dict_t *xdata)
{
STACK_WIND (frame, default_rchecksum_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum, fd, offset, len);
+ FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata);
return 0;
}
int32_t
default_readdir_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
+ size_t size, off_t off,
+ dict_t *xdata)
{
STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir, fd, size, off);
+ FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata);
return 0;
}
int32_t
default_readdirp_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
+ size_t size, off_t off, dict_t *xdata)
{
STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, size, off);
+ FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata);
return 0;
}
int32_t
default_setattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid)
+ struct iatt *stbuf, int32_t valid,
+ dict_t *xdata)
{
STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid, xdata);
return 0;
}
int32_t
default_truncate_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset)
+ off_t offset,
+ dict_t *xdata)
{
STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset);
+ FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
return 0;
}
int32_t
-default_stat_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_stat_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata)
{
STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc);
+ FIRST_CHILD(this)->fops->stat, loc, xdata);
return 0;
}
int32_t
default_lookup_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
+ dict_t *xdata)
{
STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
+ FIRST_CHILD(this)->fops->lookup, loc, xdata);
return 0;
}
int32_t
default_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid)
+ struct iatt *stbuf, int32_t valid,
+ dict_t *xdata)
{
STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
+ FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata);
return 0;
}
@@ -805,249 +866,263 @@ default_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
default_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name);
+ FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
return 0;
}
int32_t
default_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags);
+ FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
return 0;
}
int32_t
default_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags);
+ FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
return 0;
}
int32_t
-default_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc);
+ FIRST_CHILD(this)->fops->statfs, loc, xdata);
return 0;
}
int32_t
-default_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+default_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsyncdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir, fd, flags);
+ FIRST_CHILD(this)->fops->fsyncdir, fd, flags, xdata);
return 0;
}
int32_t
-default_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
+default_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd);
+ FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
return 0;
}
int32_t
-default_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
+default_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd);
+ FIRST_CHILD(this)->fops->fstat, fd, xdata);
return 0;
}
int32_t
-default_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+default_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, flags);
+ FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
return 0;
}
int32_t
-default_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
+default_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd);
+ FIRST_CHILD(this)->fops->flush, fd, xdata);
return 0;
}
int32_t
default_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *vector, int32_t count, off_t off,
- struct iobref *iobref)
+ struct iovec *vector, int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
{
STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
- iobref);
+ flags, iobref, xdata);
return 0;
}
int32_t
default_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset)
+ off_t offset, uint32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset);
+ FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
return 0;
}
int32_t
default_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, int32_t wbflags)
+ fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
return 0;
}
int32_t
default_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, fd_t *fd, dict_t *params)
+ mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, fd,
- params);
+ FIRST_CHILD(this)->fops->create, loc, flags, mode, umask,
+ fd, xdata);
return 0;
}
int32_t
-default_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
+default_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
{
STACK_WIND (frame, default_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc);
+ FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
return 0;
}
int32_t
default_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
+ loc_t *newloc, dict_t *xdata)
{
STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc);
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
return 0;
}
int
default_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, dict_t *params)
+ loc_t *loc, mode_t umask, dict_t *xdata)
{
STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, params);
+ FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask,
+ xdata);
return 0;
}
int32_t
-default_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
+default_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata)
{
STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags);
+ FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata);
return 0;
}
int32_t
-default_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
+ dict_t *xdata)
{
STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc);
+ FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
return 0;
}
int
default_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dict_t *params)
+ mode_t umask, dict_t *xdata)
{
STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
+ FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata);
return 0;
}
int
default_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, dict_t *parms)
+ dev_t rdev, mode_t umask, dict_t *xdata)
{
STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, parms);
+ FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask,
+ xdata);
return 0;
}
int32_t
-default_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
+default_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata)
{
STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc, size);
+ FIRST_CHILD(this)->fops->readlink, loc, size, xdata);
return 0;
}
int32_t
-default_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+default_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata)
{
STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->access, loc, mask);
+ FIRST_CHILD(this)->fops->access, loc, mask, xdata);
return 0;
}
int32_t
-default_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
+default_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata)
{
STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
return 0;
}
int32_t
default_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name);
+ FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
return 0;
}
int32_t
default_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict)
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop, loc, flags, dict);
+ FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata);
return 0;
}
int32_t
default_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict)
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict);
+ FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata);
return 0;
}
int32_t
default_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name);
+ FIRST_CHILD(this)->fops->removexattr, loc, name, xdata);
+ return 0;
+}
+
+int32_t
+default_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ STACK_WIND (frame, default_fremovexattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata);
return 0;
}
int32_t
default_lk (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock)
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
STACK_WIND (frame, default_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata);
return 0;
}
@@ -1055,115 +1130,125 @@ default_lk (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
default_inodelk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock)
+ struct gf_flock *lock,
+ dict_t *xdata)
{
STACK_WIND (frame, default_inodelk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock);
+ volume, loc, cmd, lock, xdata);
return 0;
}
int32_t
default_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock)
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock,
+ dict_t *xdata)
{
STACK_WIND (frame, default_finodelk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock);
+ volume, fd, cmd, lock, xdata);
return 0;
}
int32_t
default_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type)
+ entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
STACK_WIND (frame, default_entrylk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type);
+ volume, loc, basename, cmd, type, xdata);
return 0;
}
int32_t
default_fentrylk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type)
+ entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
STACK_WIND (frame, default_fentrylk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type);
+ volume, fd, basename, cmd, type, xdata);
return 0;
}
int32_t
default_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- int32_t len)
+ int32_t len,
+ dict_t *xdata)
{
STACK_WIND (frame, default_rchecksum_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum, fd, offset, len);
+ FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata);
return 0;
}
int32_t
default_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
+ size_t size, off_t off,
+ dict_t *xdata)
{
STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir, fd, size, off);
+ FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata);
return 0;
}
int32_t
default_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
+ size_t size, off_t off, dict_t *xdata)
{
STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, size, off);
+ FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata);
return 0;
}
int32_t
default_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid)
+ struct iatt *stbuf, int32_t valid,
+ dict_t *xdata)
{
STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid, xdata);
return 0;
}
int32_t
-default_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
+default_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
+ dict_t *xdata)
{
STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset);
+ FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
return 0;
}
int32_t
-default_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata)
{
STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc);
+ FIRST_CHILD(this)->fops->stat, loc, xdata);
return 0;
}
int32_t
default_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
+ dict_t *xdata)
{
STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
+ FIRST_CHILD(this)->fops->lookup, loc, xdata);
return 0;
}
int32_t
default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid)
+ struct iatt *stbuf, int32_t valid,
+ dict_t *xdata)
{
STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
+ FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata);
return 0;
}
@@ -1171,6 +1256,8 @@ default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
default_forget (xlator_t *this, inode_t *inode)
{
+ gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not "
+ "implement forget_cbk");
return 0;
}
@@ -1178,12 +1265,16 @@ default_forget (xlator_t *this, inode_t *inode)
int32_t
default_releasedir (xlator_t *this, fd_t *fd)
{
+ gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not "
+ "implement releasedir_cbk");
return 0;
}
int32_t
default_release (xlator_t *this, fd_t *fd)
{
+ gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not "
+ "implement release_cbk");
return 0;
}
@@ -1208,6 +1299,7 @@ default_notify (xlator_t *this, int32_t event, void *data, ...)
switch (event)
{
case GF_EVENT_PARENT_UP:
+ case GF_EVENT_PARENT_DOWN:
{
xlator_list_t *list = this->children;
@@ -1221,9 +1313,10 @@ default_notify (xlator_t *this, int32_t event, void *data, ...)
case GF_EVENT_CHILD_MODIFIED:
case GF_EVENT_CHILD_DOWN:
case GF_EVENT_CHILD_UP:
+ case GF_EVENT_AUTH_FAILED:
{
xlator_list_t *parent = this->parents;
- /* Handle case of CHILD_* event specially, send it to fuse */
+ /* Handle case of CHILD_* & AUTH_FAILED event specially, send it to fuse */
if (!parent && this->ctx && this->ctx->master)
xlator_notify (this->ctx->master, event, this->graph, NULL);
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
index b9438827f..8a9de7899 100644
--- a/libglusterfs/src/defaults.h
+++ b/libglusterfs/src/defaults.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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.
*/
/* libglusterfs/src/defaults.h:
@@ -31,6 +22,18 @@
#include "xlator.h"
+int32_t default_notify (xlator_t *this,
+ int32_t event,
+ void *data,
+ ...);
+
+int32_t default_forget (xlator_t *this, inode_t *inode);
+
+int32_t default_release (xlator_t *this, fd_t *fd);
+
+int32_t default_releasedir (xlator_t *this, fd_t *fd);
+
+
/* Management Operations */
int32_t default_getspec (call_frame_t *frame,
@@ -41,83 +44,85 @@ int32_t default_getspec (call_frame_t *frame,
int32_t default_rchecksum (call_frame_t *frame,
xlator_t *this,
fd_t *fd, off_t offset,
- int32_t len);
+ int32_t len, dict_t *xdata);
/* FileSystem operations */
int32_t default_lookup (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- dict_t *xattr_req);
+ dict_t *xdata);
int32_t default_stat (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
int32_t default_fstat (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
int32_t default_truncate (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- off_t offset);
+ off_t offset, dict_t *xdata);
int32_t default_ftruncate (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- off_t offset);
+ off_t offset, dict_t *xdata);
int32_t default_access (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- int32_t mask);
+ int32_t mask, dict_t *xdata);
int32_t default_readlink (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- size_t size);
+ size_t size, dict_t *xdata);
-int32_t default_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev, dict_t *params);
+int32_t default_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata);
int32_t default_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
+ loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata);
int32_t default_unlink (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t default_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t default_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params);
+ const char *linkpath, loc_t *loc, mode_t umask,
+ dict_t *xdata);
int32_t default_rename (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
int32_t default_link (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
int32_t default_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
+ mode_t umask, fd_t *fd, dict_t *xdata);
int32_t default_open (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
int32_t flags, fd_t *fd,
- int32_t wbflags);
+ dict_t *xdata);
int32_t default_readv (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t offset);
+ off_t offset,
+ uint32_t flags, dict_t *xdata);
int32_t default_writev (call_frame_t *frame,
xlator_t *this,
@@ -125,550 +130,538 @@ int32_t default_writev (call_frame_t *frame,
struct iovec *vector,
int32_t count,
off_t offset,
- struct iobref *iobref);
+ uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
int32_t default_flush (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
int32_t default_fsync (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
int32_t default_opendir (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, fd_t *fd);
+ loc_t *loc, fd_t *fd, dict_t *xdata);
int32_t default_fsyncdir (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
int32_t default_statfs (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
int32_t default_setxattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
int32_t default_getxattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
int32_t default_fsetxattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
int32_t default_fgetxattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- const char *name);
+ const char *name, dict_t *xdata);
int32_t default_removexattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
+
+int32_t default_fremovexattr (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ const char *name, dict_t *xdata);
int32_t default_lk (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
int32_t default_inodelk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
int32_t default_finodelk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
int32_t default_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
int32_t default_fentrylk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
int32_t default_readdir (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- size_t size, off_t off);
+ size_t size, off_t off, dict_t *xdata);
int32_t default_readdirp (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- size_t size, off_t off);
+ size_t size, off_t off, dict_t *xdata);
int32_t default_xattrop (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
gf_xattrop_flags_t flags,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
int32_t default_fxattrop (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
gf_xattrop_flags_t flags,
- dict_t *dict);
-
-int32_t default_notify (xlator_t *this,
- int32_t event,
- void *data,
- ...);
-
-int32_t default_forget (xlator_t *this,
- inode_t *inode);
-
-int32_t default_release (xlator_t *this,
- fd_t *fd);
-
-int32_t default_releasedir (xlator_t *this,
- fd_t *fd);
+ dict_t *dict, dict_t *xdata);
int32_t default_setattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
int32_t default_fsetattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
/* Resume */
-int32_t default_getspec (call_frame_t *frame,
- xlator_t *this,
- const char *key,
- int32_t flag);
+int32_t default_getspec_resume (call_frame_t *frame,
+ xlator_t *this,
+ const char *key,
+ int32_t flag);
-int32_t default_rchecksum (call_frame_t *frame,
+int32_t default_rchecksum_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd, off_t offset,
- int32_t len);
+ int32_t len, dict_t *xdata);
/* FileSystem operations */
int32_t default_lookup_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xattr_req);
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *xdata);
int32_t default_stat_resume (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
int32_t default_fstat_resume (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
int32_t default_truncate_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- off_t offset);
+ off_t offset, dict_t *xdata);
int32_t default_ftruncate_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- off_t offset);
+ off_t offset, dict_t *xdata);
int32_t default_access_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- int32_t mask);
+ int32_t mask, dict_t *xdata);
int32_t default_readlink_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- size_t size);
+ size_t size, dict_t *xdata);
-int32_t default_mknod_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev, dict_t *params);
+int32_t default_mknod_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, dev_t rdev, mode_t umask,
+ dict_t *xdata);
-int32_t default_mkdir_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
+int32_t default_mkdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, mode_t umask, dict_t *xdata);
int32_t default_unlink_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
+ xlator_t *this,
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t default_rmdir_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t default_symlink_resume (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params);
+ const char *linkpath, loc_t *loc, mode_t umask,
+ dict_t *xdata);
int32_t default_rename_resume (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
int32_t default_link_resume (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
int32_t default_create_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
+ loc_t *loc, int32_t flags, mode_t mode,
+ mode_t umask, fd_t *fd, dict_t *xdata);
int32_t default_open_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags, fd_t *fd,
- int32_t wbflags);
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flags, fd_t *fd, dict_t *xdata);
int32_t default_readv_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset);
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata);
int32_t default_writev_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t offset,
- struct iobref *iobref);
+ xlator_t *this,
+ fd_t *fd,
+ struct iovec *vector,
+ int32_t count,
+ off_t offset, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
int32_t default_flush_resume (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
int32_t default_fsync_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
int32_t default_opendir_resume (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, fd_t *fd);
+ loc_t *loc, fd_t *fd, dict_t *xdata);
int32_t default_fsyncdir_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
int32_t default_statfs_resume (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
int32_t default_setxattr_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
int32_t default_getxattr_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
int32_t default_fsetxattr_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
int32_t default_fgetxattr_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- const char *name);
+ const char *name, dict_t *xdata);
int32_t default_removexattr_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
+
+int32_t default_fremovexattr_resume (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ const char *name, dict_t *xdata);
int32_t default_lk_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
int32_t default_inodelk_resume (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
int32_t default_finodelk_resume (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
int32_t default_entrylk_resume (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
int32_t default_fentrylk_resume (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
int32_t default_readdir_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- size_t size, off_t off);
+ size_t size, off_t off, dict_t *xdata);
int32_t default_readdirp_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size, off_t off);
+ xlator_t *this,
+ fd_t *fd,
+ size_t size, off_t off, dict_t *xdata);
int32_t default_xattrop_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
gf_xattrop_flags_t flags,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
int32_t default_fxattrop_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
gf_xattrop_flags_t flags,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
int32_t default_rchecksum_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd, off_t offset,
- int32_t len);
-
-int32_t default_notify (xlator_t *this,
- int32_t event,
- void *data,
- ...);
-
-int32_t default_forget (xlator_t *this,
- inode_t *inode);
-
-int32_t default_release (xlator_t *this,
- fd_t *fd);
-
-int32_t default_releasedir (xlator_t *this,
- fd_t *fd);
+ int32_t len, dict_t *xdata);
int32_t default_setattr_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
int32_t default_fsetattr_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
/* _cbk */
int32_t
default_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *dict, struct iatt *postparent);
+ struct iatt *buf, dict_t *xdata, struct iatt *postparent);
int32_t
default_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf);
+ int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata);
int32_t
default_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
int32_t
default_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
int32_t
default_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
int32_t
default_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
int32_t
default_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
int32_t
default_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
int32_t
default_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
int32_t
default_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
int32_t
default_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent);
+ struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata);
int32_t
default_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
int32_t
default_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
int32_t
default_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd);
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata);
int32_t
default_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref);
+ int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata);
int32_t
default_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
int32_t
default_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
int32_t
default_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf);
+ int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata);
int32_t
default_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd);
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata);
int32_t
default_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf);
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata);
int32_t
default_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict);
+ int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
int32_t
default_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict);
+ int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
int32_t
default_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict);
+ int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
int32_t
default_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict);
+ int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
int32_t
default_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock);
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata);
int32_t
default_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
- uint8_t *strong_checksum);
+ uint8_t *strong_checksum, dict_t *xdata);
int32_t
default_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries);
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata);
int32_t
default_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries);
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata);
int32_t
default_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost);
+ struct iatt *statpost, dict_t *xdata);
int32_t
default_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost);
+ struct iatt *statpost, dict_t *xdata);
int32_t
default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index c8f43e316..3d30dd689 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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>
@@ -22,6 +13,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
+#include <limits.h>
#ifndef _CONFIG_H
#define _CONFIG_H
@@ -35,14 +27,15 @@
#include "logging.h"
#include "compat.h"
#include "byte-order.h"
+#include "globals.h"
data_pair_t *
get_new_data_pair ()
{
data_pair_t *data_pair_ptr = NULL;
- data_pair_ptr = (data_pair_t *) GF_CALLOC (1, sizeof (data_pair_t),
- gf_common_mt_data_pair_t);
+ data_pair_ptr = mem_get0 (THIS->ctx->dict_pair_pool);
+
return data_pair_ptr;
}
@@ -51,7 +44,7 @@ get_new_data ()
{
data_t *data = NULL;
- data = (data_t *) GF_CALLOC (1, sizeof (data_t), gf_common_mt_data_t);
+ data = mem_get0 (THIS->ctx->dict_data_pool);
if (!data) {
return NULL;
}
@@ -63,18 +56,17 @@ get_new_data ()
dict_t *
get_new_dict_full (int size_hint)
{
- dict_t *dict = GF_CALLOC (1, sizeof (dict_t), gf_common_mt_dict_t);
+ dict_t *dict = mem_get0 (THIS->ctx->dict_pool);
if (!dict) {
return NULL;
}
dict->hash_size = size_hint;
- dict->members = GF_CALLOC (size_hint, sizeof (data_pair_t *),
- gf_common_mt_data_pair_t);
+ dict->members = mem_get0 (THIS->ctx->dict_pair_pool);
if (!dict->members) {
- GF_FREE (dict);
+ mem_put (dict);
return NULL;
}
@@ -107,9 +99,12 @@ int32_t
is_data_equal (data_t *one,
data_t *two)
{
- /* LOG-TODO */
- if (!one || !two || !one->data || !two->data)
- return 1;
+ if (!one || !two || !one->data || !two->data) {
+ gf_log_callingfn ("dict", GF_LOG_ERROR,
+ "input arguments are provided "
+ "with value data_t as NULL");
+ return -1;
+ }
if (one == two)
return 1;
@@ -139,13 +134,11 @@ data_destroy (data_t *data)
else
GF_FREE (data->data);
}
- if (data->vec)
- GF_FREE (data->vec);
}
data->len = 0xbabababa;
if (!data->is_const)
- GF_FREE (data);
+ mem_put (data);
}
}
@@ -158,9 +151,7 @@ data_copy (data_t *old)
return NULL;
}
- data_t *newdata = (data_t *) GF_CALLOC (1, sizeof (*newdata),
- gf_common_mt_data_t);
-
+ data_t *newdata = mem_get0 (THIS->ctx->dict_data_pool);
if (!newdata) {
return NULL;
}
@@ -172,12 +163,6 @@ data_copy (data_t *old)
if (!newdata->data)
goto err_out;
}
- if (old->vec) {
- newdata->vec = memdup (old->vec, old->len * (sizeof (void *) +
- sizeof (size_t)));
- if (!newdata->vec)
- goto err_out;
- }
}
LOCK_INIT (&newdata->lock);
@@ -187,9 +172,7 @@ err_out:
if (newdata->data)
FREE (newdata->data);
- if (newdata->vec)
- FREE (newdata->vec);
- GF_FREE (newdata);
+ mem_put (newdata);
return NULL;
}
@@ -214,6 +197,26 @@ _dict_lookup (dict_t *this, char *key)
return NULL;
}
+int32_t
+dict_lookup (dict_t *this, char *key, data_pair_t **data)
+{
+ if (!this || !key || !data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "!this || !key || !data");
+ return -1;
+ }
+
+ LOCK (&this->lock);
+ {
+ *data = _dict_lookup (this, key);
+ }
+ UNLOCK (&this->lock);
+ if (*data)
+ return 0;
+ else
+ return -1;
+
+}
static int32_t
_dict_set (dict_t *this,
@@ -248,8 +251,7 @@ _dict_set (dict_t *this,
/* Indicates duplicate key */
return 0;
}
- pair = (data_pair_t *) GF_CALLOC (1, sizeof (*pair),
- gf_common_mt_data_pair_t);
+ pair = mem_get0 (THIS->ctx->dict_pair_pool);
if (!pair) {
return -1;
}
@@ -257,7 +259,7 @@ _dict_set (dict_t *this,
pair->key = (char *) GF_CALLOC (1, strlen (key) + 1,
gf_common_mt_char);
if (!pair->key) {
- GF_FREE (pair);
+ mem_put (pair);
if (key_free)
GF_FREE (key);
@@ -361,7 +363,7 @@ dict_del (dict_t *this, char *key)
pair->next->prev = pair->prev;
GF_FREE (pair->key);
- GF_FREE (pair);
+ mem_put (pair);
this->count--;
break;
}
@@ -392,11 +394,11 @@ dict_destroy (dict_t *this)
pair = pair->next;
data_unref (prev->value);
GF_FREE (prev->key);
- GF_FREE (prev);
+ mem_put (prev);
prev = pair;
}
- GF_FREE (this->members);
+ mem_put (this->members);
if (this->extra_free)
GF_FREE (this->extra_free);
@@ -404,7 +406,7 @@ dict_destroy (dict_t *this)
free (this->extra_stdfree);
if (!this->is_static)
- GF_FREE (this);
+ mem_put (this);
return;
}
@@ -485,236 +487,6 @@ data_ref (data_t *this)
return this;
}
-/*
- Serialization format:
- ----
- Count:8
- Key_len:8:Value_len:8
- Key
- Value
- .
- .
- .
-*/
-
-int32_t
-dict_serialized_length_old (dict_t *this)
-{
-
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- int32_t len = 9; /* count + \n */
- int32_t count = this->count;
- data_pair_t *pair = this->members_list;
-
- while (count) {
- len += 18;
- len += strlen (pair->key) + 1;
- if (pair->value->vec) {
- int i;
- for (i=0; i<pair->value->len; i++) {
- len += pair->value->vec[i].iov_len;
- }
- } else {
- len += pair->value->len;
- }
- pair = pair->next;
- count--;
- }
-
- return len;
-}
-
-int32_t
-dict_serialize_old (dict_t *this, char *buf)
-{
- if (!this || !buf) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- data_pair_t *pair = this->members_list;
- int32_t count = this->count;
- uint64_t dcount = this->count;
-
- // FIXME: magic numbers
-
- sprintf (buf, "%08"PRIx64"\n", dcount);
- buf += 9;
- while (count) {
- uint64_t keylen = strlen (pair->key) + 1;
- uint64_t vallen = pair->value->len;
-
- sprintf (buf, "%08"PRIx64":%08"PRIx64"\n", keylen, vallen);
- buf += 18;
- memcpy (buf, pair->key, keylen);
- buf += keylen;
- memcpy (buf, pair->value->data, pair->value->len);
- buf += pair->value->len;
- pair = pair->next;
- count--;
- }
- return (0);
-}
-
-
-dict_t *
-dict_unserialize_old (char *buf, int32_t size, dict_t **fill)
-{
- int32_t ret = 0;
- int32_t cnt = 0;
-
- if (!buf || !fill || !(*fill)) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "buf is NULL");
- return NULL;
- }
-
- uint64_t count;
- ret = sscanf (buf, "%"SCNx64"\n", &count);
- (*fill)->count = 0;
-
- if (!ret){
- gf_log ("dict", GF_LOG_ERROR, "sscanf on buf failed");
- goto err;
- }
- buf += 9;
-
- if (count == 0) {
- gf_log ("dict", GF_LOG_ERROR, "count == 0");
- goto err;
- }
-
- for (cnt = 0; cnt < count; cnt++) {
- data_t *value = NULL;
- char *key = NULL;
- uint64_t key_len, value_len;
-
- ret = sscanf (buf, "%"SCNx64":%"SCNx64"\n", &key_len, &value_len);
- if (ret != 2) {
- gf_log ("dict", GF_LOG_ERROR,
- "sscanf for key_len and value_len failed");
- goto err;
- }
- buf += 18;
-
- key = buf;
- buf += key_len;
-
- value = get_new_data ();
- value->len = value_len;
- value->data = buf;
- value->is_static = 1;
- buf += value_len;
-
- dict_set (*fill, key, value);
- }
-
- goto ret;
-
-err:
- GF_FREE (*fill);
- *fill = NULL;
-
-ret:
- return *fill;
-}
-
-
-int32_t
-dict_iovec_len (dict_t *this)
-{
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- int32_t len = 0;
- data_pair_t *pair = this->members_list;
-
- len++; /* initial header */
- while (pair) {
- len++; /* pair header */
- len++; /* key */
-
- if (pair->value->vec)
- len += pair->value->len;
- else
- len++;
- pair = pair->next;
- }
-
- return len;
-}
-
-int32_t
-dict_to_iovec (dict_t *this,
- struct iovec *vec,
- int32_t count)
-{
- if (!this || !vec) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- int32_t i = 0;
- data_pair_t *pair = this->members_list;
-
- vec[0].iov_len = 9;
- if (vec[0].iov_base)
- sprintf (vec[0].iov_base,
- "%08"PRIx64"\n",
- (int64_t)this->count);
- i++;
-
- while (pair) {
- int64_t keylen = strlen (pair->key) + 1;
- int64_t vallen = 0;
-
- if (pair->value->vec) {
- int i;
-
- for (i=0; i<pair->value->len; i++) {
- vallen += pair->value->vec[i].iov_len;
- }
- } else {
- vallen = pair->value->len;
- }
-
- vec[i].iov_len = 18;
- if (vec[i].iov_base)
- sprintf (vec[i].iov_base,
- "%08"PRIx64":%08"PRIx64"\n",
- keylen,
- vallen);
- i++;
-
- vec[i].iov_len = keylen;
- vec[i].iov_base = pair->key;
- i++;
-
- if (pair->value->vec) {
- int k;
-
- for (k=0; k<pair->value->len; k++) {
- vec[i].iov_len = pair->value->vec[k].iov_len;
- vec[i].iov_base = pair->value->vec[k].iov_base;
- i++;
- }
- } else {
- vec[i].iov_len = pair->value->len;
- vec[i].iov_base = pair->value->data;
- i++;
- }
-
- pair = pair->next;
- }
-
- return 0;
-}
-
data_t *
int_to_data (int64_t value)
{
@@ -1064,6 +836,8 @@ data_to_int32 (data_t *data)
int16_t
data_to_int16 (data_t *data)
{
+ int16_t value = 0;
+
if (!data) {
gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
return -1;
@@ -1076,13 +850,26 @@ data_to_int16 (data_t *data)
memcpy (str, data->data, data->len);
str[data->len] = '\0';
- return strtol (str, NULL, 0);
+ errno = 0;
+ value = strtol (str, NULL, 0);
+
+ if ((SHRT_MAX > value) || (SHRT_MIN < value)) {
+ errno = ERANGE;
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "Error in data conversion: "
+ "detected overflow");
+ return -1;
+ }
+
+ return (int16_t)value;
}
int8_t
data_to_int8 (data_t *data)
{
+ int32_t value = 0;
+
if (!data) {
gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
return -1;
@@ -1095,7 +882,18 @@ data_to_int8 (data_t *data)
memcpy (str, data->data, data->len);
str[data->len] = '\0';
- return (int8_t)strtol (str, NULL, 0);
+ errno = 0;
+ value = strtol (str, NULL, 0);
+
+ if ((SCHAR_MAX > value) || (SCHAR_MIN < value)) {
+ errno = ERANGE;
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "Error in data conversion: "
+ "detected overflow");
+ return -1;
+ }
+
+ return (int8_t)value;
}
@@ -1133,6 +931,8 @@ data_to_uint32 (data_t *data)
uint16_t
data_to_uint16 (data_t *data)
{
+ uint16_t value = 0;
+
if (!data)
return -1;
@@ -1143,7 +943,49 @@ data_to_uint16 (data_t *data)
memcpy (str, data->data, data->len);
str[data->len] = '\0';
- return strtol (str, NULL, 0);
+ errno = 0;
+ value = strtol (str, NULL, 0);
+
+ if ((USHRT_MAX - value) < 0) {
+ errno = ERANGE;
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "Error in data conversion: "
+ "overflow detected");
+ return -1;
+ }
+
+ return (uint16_t)value;
+}
+
+uint8_t
+data_to_uint8 (data_t *data)
+{
+ uint32_t value = 0;
+
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return -1;
+ }
+
+ char *str = alloca (data->len + 1);
+ if (!str)
+ return -1;
+
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
+
+ errno = 0;
+ value = strtol (str, NULL, 0);
+
+ if ((UCHAR_MAX - value) < 0) {
+ errno = ERANGE;
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "data conversion overflow detected (%s)",
+ strerror(errno));
+ return -1;
+ }
+
+ return (uint8_t) value;
}
char *
@@ -1210,6 +1052,15 @@ _copy (dict_t *unused,
dict_set ((dict_t *)newdict, key, (value));
}
+static void
+_remove (dict_t *dict,
+ char *key,
+ data_t *value,
+ void *unused)
+{
+ dict_del ((dict_t *)dict, key);
+}
+
dict_t *
dict_copy (dict_t *dict,
@@ -1228,6 +1079,20 @@ dict_copy (dict_t *dict,
return new;
}
+int
+dict_reset (dict_t *dict)
+{
+ int32_t ret = -1;
+ if (!dict) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ goto out;
+ }
+ dict_foreach (dict, _remove, NULL);
+ ret = 0;
+out:
+ return ret;
+}
+
dict_t *
dict_copy_with_ref (dict_t *dict,
dict_t *new)
@@ -1936,6 +1801,36 @@ err:
}
int
+dict_get_ptr_and_len (dict_t *this, char *key, void **ptr, int *len)
+{
+ data_t * data = NULL;
+ int ret = 0;
+
+ if (!this || !key || !ptr) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_get_with_ref (this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ *len = data->len;
+
+ ret = _data_to_ptr (data, ptr);
+ if (ret != 0) {
+ goto err;
+ }
+
+err:
+ if (data)
+ data_unref (data);
+
+ return ret;
+}
+
+int
dict_set_ptr (dict_t *this, char *key, void *ptr)
{
data_t * data = NULL;
@@ -2210,7 +2105,6 @@ _dict_serialized_length (dict_t *this)
int ret = -EINVAL;
int count = 0;
int len = 0;
- int i = 0;
data_pair_t * pair = NULL;
len = DICT_HDR_LEN;
@@ -2245,28 +2139,15 @@ _dict_serialized_length (dict_t *this)
goto out;
}
- if (pair->value->vec) {
- for (i = 0; i < pair->value->len; i++) {
- if (pair->value->vec[i].iov_len < 0) {
- gf_log ("dict", GF_LOG_ERROR,
- "iov_len (%"GF_PRI_SIZET") < 0!",
- pair->value->vec[i].iov_len);
- goto out;
- }
-
- len += pair->value->vec[i].iov_len;
- }
- } else {
- if (pair->value->len < 0) {
- gf_log ("dict", GF_LOG_ERROR,
- "value->len (%d) < 0",
- pair->value->len);
- goto out;
- }
-
- len += pair->value->len;
+ if (pair->value->len < 0) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "value->len (%d) < 0",
+ pair->value->len);
+ goto out;
}
+ len += pair->value->len;
+
pair = pair->next;
count--;
}
@@ -2541,6 +2422,7 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill)
"available (%lu) < required (%lu)",
(long)(orig_buf + size),
(long)(buf + vallen));
+ goto out;
}
value = get_new_data ();
value->len = vallen;
@@ -2569,7 +2451,7 @@ out:
*/
int32_t
-dict_allocate_and_serialize (dict_t *this, char **buf, size_t *length)
+dict_allocate_and_serialize (dict_t *this, char **buf, u_int *length)
{
int ret = -EINVAL;
ssize_t len = 0;
@@ -2610,3 +2492,136 @@ unlock:
out:
return ret;
}
+
+/**
+ * _dict_serialize_value_with_delim: serialize the values in the dictionary
+ * into a buffer separated by delimiter (except the last)
+ *
+ * @this : dictionary to serialize
+ * @buf : the buffer to store the serialized data
+ * @serz_len : the length of the serialized data (excluding the last delimiter)
+ * @delimiter : the delimiter to separate the values
+ *
+ * @return : 0 -> success
+ * : -errno -> faliure
+ */
+int
+_dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter)
+{
+ int ret = -1;
+ int32_t count = 0;
+ int32_t vallen = 0;
+ int32_t total_len = 0;
+ data_pair_t *pair = NULL;
+
+ if (!buf) {
+ gf_log ("dict", GF_LOG_ERROR, "buf is null");
+ goto out;
+ }
+
+ count = this->count;
+ if (count < 0) {
+ gf_log ("dict", GF_LOG_ERROR, "count (%d) < 0", count);
+ goto out;
+ }
+
+ pair = this->members_list;
+
+ while (count) {
+ if (!pair) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "less than count data pairs found");
+ goto out;
+ }
+
+ if (!pair->key || !pair->value) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "key or value is null");
+ goto out;
+ }
+
+ if (!pair->value->data) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "null value found in dict");
+ goto out;
+ }
+
+ vallen = pair->value->len - 1; // length includes \0
+ memcpy (buf, pair->value->data, vallen);
+ buf += vallen;
+ *buf++ = delimiter;
+
+ total_len += (vallen + 1);
+
+ pair = pair->next;
+ count--;
+ }
+
+ *--buf = '\0'; // remove the last delimiter
+ total_len--; // adjust the length
+ ret = 0;
+
+ if (serz_len)
+ *serz_len = total_len;
+
+ out:
+ return ret;
+}
+
+int
+dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter)
+{
+ int ret = -1;
+
+ if (!this || !buf) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is null!");
+ goto out;
+ }
+
+ LOCK (&this->lock);
+ {
+ ret = _dict_serialize_value_with_delim (this, buf, serz_len, delimiter);
+ }
+ UNLOCK (&this->lock);
+out:
+ return ret;
+}
+
+void
+dict_dump (dict_t *this)
+{
+ int ret = 0;
+ int dumplen = 0;
+ data_pair_t *trav = NULL;
+ char dump[64*1024]; /* This is debug only, hence
+ performance should not matter */
+
+ if (!this) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict NULL");
+ goto out;
+ }
+
+ dump[0] = '\0'; /* the array is not initialized to '\0' */
+
+ /* There is a possibility of issues if data is binary, ignore it
+ for now as debugging is more important */
+ for (trav = this->members_list; trav; trav = trav->next) {
+ ret = snprintf (&dump[dumplen], ((64*1024) - dumplen - 1),
+ "(%s:%s)", trav->key, trav->value->data);
+ if ((ret == -1) || !ret)
+ break;
+
+ dumplen += ret;
+ /* snprintf doesn't append a trailing '\0', add it here */
+ dump[dumplen] = '\0';
+ }
+
+ if (dumplen)
+ gf_log_callingfn ("dict", GF_LOG_INFO,
+ "dict=%p (%s)", this, dump);
+
+out:
+ return;
+}
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
index 4ddea9422..3f0fc436c 100644
--- a/libglusterfs/src/dict.h
+++ b/libglusterfs/src/dict.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _DICT_H
@@ -35,12 +26,53 @@ typedef struct _data data_t;
typedef struct _dict dict_t;
typedef struct _data_pair data_pair_t;
+
+#define GF_PROTOCOL_DICT_SERIALIZE(this,from_dict,to,len,ope,labl) do { \
+ int ret = 0; \
+ \
+ if (!from_dict) \
+ break; \
+ \
+ ret = dict_allocate_and_serialize (from_dict, to, &len);\
+ if (ret < 0) { \
+ gf_log (this->name, GF_LOG_WARNING, \
+ "failed to get serialized dict (%s)", \
+ (#from_dict)); \
+ ope = EINVAL; \
+ goto labl; \
+ } \
+ } while (0)
+
+
+#define GF_PROTOCOL_DICT_UNSERIALIZE(xl,to,buff,len,ret,ope,labl) do { \
+ char *buf = NULL; \
+ if (!len) \
+ break; \
+ to = dict_new(); \
+ GF_VALIDATE_OR_GOTO (xl->name, to, labl); \
+ \
+ buf = memdup (buff, len); \
+ GF_VALIDATE_OR_GOTO (xl->name, buf, labl); \
+ \
+ ret = dict_unserialize (buf, len, &to); \
+ if (ret < 0) { \
+ gf_log (xl->name, GF_LOG_WARNING, \
+ "failed to unserialize dictionary (%s)", \
+ (#to)); \
+ \
+ ope = EINVAL; \
+ GF_FREE (buf); \
+ goto labl; \
+ } \
+ \
+ to->extra_free = buf; \
+ } while (0)
+
struct _data {
unsigned char is_static:1;
unsigned char is_const:1;
unsigned char is_stdalloc:1;
int32_t len;
- struct iovec *vec;
char *data;
int32_t refcount;
gf_lock_t lock;
@@ -73,15 +105,13 @@ void data_destroy (data_t *data);
int32_t dict_set (dict_t *this, char *key, data_t *value);
data_t *dict_get (dict_t *this, char *key);
void dict_del (dict_t *this, char *key);
+int dict_reset (dict_t *dict);
int32_t dict_serialized_length (dict_t *dict);
int32_t dict_serialize (dict_t *dict, char *buf);
int32_t dict_unserialize (char *buf, int32_t size, dict_t **fill);
-int32_t dict_allocate_and_serialize (dict_t *this, char **buf, size_t *length);
-
-int32_t dict_iovec_len (dict_t *dict);
-int32_t dict_to_iovec (dict_t *dict, struct iovec *vec, int32_t count);
+int32_t dict_allocate_and_serialize (dict_t *this, char **buf, u_int *length);
void dict_destroy (dict_t *dict);
void dict_unref (dict_t *dict);
@@ -89,6 +119,7 @@ dict_t *dict_ref (dict_t *dict);
data_t *data_ref (data_t *data);
void data_unref (data_t *data);
+int32_t dict_lookup (dict_t *this, char *key, data_pair_t **data);
/*
TODO: provide converts for differnt byte sizes, signedness, and void *
*/
@@ -108,6 +139,7 @@ int8_t data_to_int8 (data_t *data);
uint64_t data_to_uint64 (data_t *data);
uint32_t data_to_uint32 (data_t *data);
uint16_t data_to_uint16 (data_t *data);
+uint8_t data_to_uint8 (data_t *data);
data_t *data_from_ptr (void *value);
data_t *data_from_static_ptr (void *value);
@@ -145,6 +177,8 @@ dict_t *dict_copy (dict_t *this, dict_t *new);
GF_MUST_CHECK dict_t *dict_new (void);
dict_t *dict_copy_with_ref (dict_t *this, dict_t *new);
+GF_MUST_CHECK int dict_reset (dict_t *dict);
+
GF_MUST_CHECK int dict_get_int8 (dict_t *this, char *key, int8_t *val);
GF_MUST_CHECK int dict_set_int8 (dict_t *this, char *key, int8_t val);
@@ -171,6 +205,7 @@ GF_MUST_CHECK int dict_set_double (dict_t *this, char *key, double val);
GF_MUST_CHECK int dict_set_static_ptr (dict_t *this, char *key, void *ptr);
GF_MUST_CHECK int dict_get_ptr (dict_t *this, char *key, void **ptr);
+GF_MUST_CHECK int dict_get_ptr_and_len (dict_t *this, char *key, void **ptr, int *len);
GF_MUST_CHECK int dict_set_ptr (dict_t *this, char *key, void *ptr);
GF_MUST_CHECK int dict_set_dynptr (dict_t *this, char *key, void *ptr, size_t size);
@@ -184,4 +219,9 @@ GF_MUST_CHECK int dict_set_dynstr (dict_t *this, char *key, char *str);
GF_MUST_CHECK int dict_get_str (dict_t *this, char *key, char **str);
GF_MUST_CHECK int dict_get_str_boolean (dict_t *this, char *key, int default_val);
+GF_MUST_CHECK int dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter);
+
+void dict_dump (dict_t *dict);
+
#endif
diff --git a/libglusterfs/src/event-history.c b/libglusterfs/src/event-history.c
new file mode 100644
index 000000000..fe511caeb
--- /dev/null
+++ b/libglusterfs/src/event-history.c
@@ -0,0 +1,81 @@
+/*
+ Copyright (c) 2008-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 "event-history.h"
+
+eh_t *
+eh_new (size_t buffer_size, gf_boolean_t use_buffer_once)
+{
+ eh_t *history = NULL;
+ buffer_t *buffer = NULL;
+
+ history = GF_CALLOC (1, sizeof (eh_t), gf_common_mt_eh_t);
+ if (!history) {
+ gf_log ("", GF_LOG_ERROR, "allocating history failed.");
+ goto out;
+ }
+
+ buffer = cb_buffer_new (buffer_size, use_buffer_once);
+ if (!buffer) {
+ gf_log ("", GF_LOG_ERROR, "allocating circular buffer failed");
+ GF_FREE (history);
+ history = NULL;
+ }
+
+ history->buffer = buffer;
+
+ pthread_mutex_init (&history->lock, NULL);
+out:
+ return history;
+}
+
+void
+eh_dump (eh_t *history, void *data,
+ int (dump_fn) (circular_buffer_t *buffer, void *data))
+{
+ if (!history) {
+ gf_log ("", GF_LOG_DEBUG, "history is NULL");
+ goto out;
+ }
+
+ cb_buffer_dump (history->buffer, data, dump_fn);
+
+out:
+ return;
+}
+
+int
+eh_save_history (eh_t *history, void *data)
+{
+ int ret = -1;
+
+ ret = cb_add_entry_buffer (history->buffer, data);
+
+ return ret;
+}
+
+int
+eh_destroy (eh_t *history)
+{
+ if (!history) {
+ gf_log ("", GF_LOG_INFO, "history for the xlator is "
+ "NULL");
+ return -1;
+ }
+
+ cb_buffer_destroy (history->buffer);
+ history->buffer = NULL;
+
+ pthread_mutex_destroy (&history->lock);
+
+ GF_FREE (history);
+
+ return 0;
+}
diff --git a/libglusterfs/src/event-history.h b/libglusterfs/src/event-history.h
new file mode 100644
index 000000000..b1750bbae
--- /dev/null
+++ b/libglusterfs/src/event-history.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (c) 2008-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 _EH_H
+#define _EH_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "mem-types.h"
+#include "circ-buff.h"
+
+struct event_hist
+{
+ buffer_t *buffer;
+ pthread_mutex_t lock;
+};
+
+typedef struct event_hist eh_t;
+
+void
+eh_dump (eh_t *event , void *data,
+ int (fn) (circular_buffer_t *buffer, void *data));
+
+eh_t *
+eh_new (size_t buffer_size, gf_boolean_t use_buffer_once);
+
+int
+eh_save_history (eh_t *history, void *string);
+
+int
+eh_destroy (eh_t *history);
+
+#endif /* _EH_H */
diff --git a/libglusterfs/src/event.c b/libglusterfs/src/event.c
index 1692832f8..8f172fb24 100644
--- a/libglusterfs/src/event.c
+++ b/libglusterfs/src/event.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <sys/poll.h>
diff --git a/libglusterfs/src/event.h b/libglusterfs/src/event.h
index eb4266365..f2f8029ae 100644
--- a/libglusterfs/src/event.h
+++ b/libglusterfs/src/event.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _EVENT_H_
diff --git a/libglusterfs/src/fd-lk.c b/libglusterfs/src/fd-lk.c
new file mode 100644
index 000000000..4185e1bc7
--- /dev/null
+++ b/libglusterfs/src/fd-lk.c
@@ -0,0 +1,472 @@
+/*
+ Copyright (c) 2008-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 "fd-lk.h"
+#include "common-utils.h"
+
+
+int32_t
+_fd_lk_delete_lock (fd_lk_ctx_node_t *lock)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("fd-lk", lock, out);
+
+ list_del_init (&lock->next);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+_fd_lk_destroy_lock (fd_lk_ctx_node_t *lock)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("fd-lk", lock, out);
+
+ GF_FREE (lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+_fd_lk_destroy_lock_list (fd_lk_ctx_t *lk_ctx)
+{
+ int ret = -1;
+ fd_lk_ctx_node_t *lk = NULL;
+ fd_lk_ctx_node_t *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO ("fd-lk", lk_ctx, out);
+
+ list_for_each_entry_safe (lk, tmp, &lk_ctx->lk_list, next) {
+ _fd_lk_delete_lock (lk);
+ _fd_lk_destroy_lock (lk);
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+fd_lk_ctx_unref (fd_lk_ctx_t *lk_ctx)
+{
+ int ref = -1;
+
+ GF_VALIDATE_OR_GOTO ("fd-lk", lk_ctx, err);
+
+ LOCK (&lk_ctx->lock);
+ {
+ ref = --lk_ctx->ref;
+ if (ref < 0)
+ GF_ASSERT (!ref);
+ if (ref == 0)
+ _fd_lk_destroy_lock_list (lk_ctx);
+ }
+ UNLOCK (&lk_ctx->lock);
+
+ if (ref == 0) {
+ LOCK_DESTROY (&lk_ctx->lock);
+ GF_FREE (lk_ctx);
+ }
+
+ return 0;
+err:
+ return -1;
+}
+
+fd_lk_ctx_t *
+_fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx)
+{
+ if (!lk_ctx) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING,
+ "invalid argument");
+ return NULL;
+ }
+
+ ++lk_ctx->ref;
+
+ return lk_ctx;
+}
+
+fd_lk_ctx_t *
+fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx)
+{
+ fd_lk_ctx_t *new_lk_ctx = NULL;
+
+ if (!lk_ctx) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING,
+ "invalid argument");
+ return NULL;
+ }
+
+ LOCK (&lk_ctx->lock);
+ {
+ new_lk_ctx = _fd_lk_ctx_ref (lk_ctx);
+ }
+ UNLOCK (&lk_ctx->lock);
+
+ return new_lk_ctx;
+}
+
+fd_lk_ctx_t *
+fd_lk_ctx_try_ref (fd_lk_ctx_t *lk_ctx)
+{
+ int ret = -1;
+ fd_lk_ctx_t *new_lk_ctx = NULL;
+
+ if (!lk_ctx) {
+ goto out;
+ }
+
+ ret = TRY_LOCK (&lk_ctx->lock);
+ if (ret)
+ goto out;
+
+ new_lk_ctx = _fd_lk_ctx_ref (lk_ctx);
+ UNLOCK (&lk_ctx->lock);
+
+out:
+ return new_lk_ctx;
+}
+
+fd_lk_ctx_t *
+fd_lk_ctx_create ()
+{
+ fd_lk_ctx_t *fd_lk_ctx = NULL;
+
+ fd_lk_ctx = GF_CALLOC (1, sizeof (fd_lk_ctx_t),
+ gf_common_mt_fd_lk_ctx_t);
+ if (!fd_lk_ctx)
+ goto out;
+
+ INIT_LIST_HEAD (&fd_lk_ctx->lk_list);
+
+ LOCK_INIT (&fd_lk_ctx->lock);
+
+ fd_lk_ctx = fd_lk_ctx_ref (fd_lk_ctx);
+out:
+ return fd_lk_ctx;
+}
+
+int
+_fd_lk_insert_lock (fd_lk_ctx_t *lk_ctx,
+ fd_lk_ctx_node_t *lock)
+{
+ list_add_tail (&lock->next, &lk_ctx->lk_list);
+ return 0;
+}
+
+static off_t
+_fd_lk_get_lock_len (off_t start, off_t end)
+{
+ if (end == LLONG_MAX)
+ return 0;
+ else
+ return (end - start + 1);
+}
+
+fd_lk_ctx_node_t *
+fd_lk_ctx_node_new (int32_t cmd, struct gf_flock *flock)
+{
+ fd_lk_ctx_node_t *new_lock = NULL;
+
+ /* TODO: get from mem-pool */
+ new_lock = GF_CALLOC (1, sizeof (fd_lk_ctx_node_t),
+ gf_common_mt_fd_lk_ctx_node_t);
+ if (!new_lock)
+ goto out;
+
+ new_lock->cmd = cmd;
+
+ if (flock) {
+ new_lock->fl_type = flock->l_type;
+ new_lock->fl_start = flock->l_start;
+
+ if (flock->l_len == 0)
+ new_lock->fl_end = LLONG_MAX;
+ else
+ new_lock->fl_end = flock->l_start + flock->l_len - 1;
+
+ memcpy (&new_lock->user_flock, flock,
+ sizeof (struct gf_flock));
+ }
+
+ INIT_LIST_HEAD (&new_lock->next);
+out:
+ return new_lock;
+}
+
+int32_t
+_fd_lk_delete_unlck_locks (fd_lk_ctx_t *lk_ctx)
+{
+ int32_t ret = -1;
+ fd_lk_ctx_node_t *tmp = NULL;
+ fd_lk_ctx_node_t *lk = NULL;
+
+ GF_VALIDATE_OR_GOTO ("fd-lk", lk_ctx, out);
+
+ list_for_each_entry_safe (lk, tmp, &lk_ctx->lk_list, next) {
+ if (lk->fl_type == F_UNLCK) {
+ _fd_lk_delete_lock (lk);
+ _fd_lk_destroy_lock (lk);
+ }
+ }
+out:
+ return ret;
+}
+
+int
+fd_lk_overlap (fd_lk_ctx_node_t *l1,
+ fd_lk_ctx_node_t *l2)
+{
+ if (l1->fl_end >= l2->fl_start &&
+ l2->fl_end >= l1->fl_start)
+ return 1;
+
+ return 0;
+}
+
+fd_lk_ctx_node_t *
+_fd_lk_add_locks (fd_lk_ctx_node_t *l1,
+ fd_lk_ctx_node_t *l2)
+{
+ fd_lk_ctx_node_t *sum = NULL;
+
+ sum = fd_lk_ctx_node_new (0, NULL);
+ if (!sum)
+ goto out;
+
+ sum->fl_start = min (l1->fl_start, l2->fl_start);
+ sum->fl_end = max (l1->fl_end, l2->fl_end);
+
+ sum->user_flock.l_start = sum->fl_start;
+ sum->user_flock.l_len = _fd_lk_get_lock_len (sum->fl_start,
+ sum->fl_end);
+out:
+ return sum;
+}
+
+/* Subtract two locks */
+struct _values {
+ fd_lk_ctx_node_t *locks[3];
+};
+
+int32_t
+_fd_lk_sub_locks (struct _values *v,
+ fd_lk_ctx_node_t *big,
+ fd_lk_ctx_node_t *small)
+{
+ int32_t ret = -1;
+
+ if ((big->fl_start == small->fl_start) &&
+ (big->fl_end == small->fl_end)) {
+ /* both edges coincide with big */
+ v->locks[0] = fd_lk_ctx_node_new (small->cmd, NULL);
+ if (!v->locks[0])
+ goto out;
+
+ memcpy (v->locks[0], big, sizeof (fd_lk_ctx_node_t));
+
+ v->locks[0]->fl_type = small->fl_type;
+ v->locks[0]->user_flock.l_type = small->fl_type;
+ } else if ((small->fl_start > big->fl_start) &&
+ (small->fl_end < big->fl_end)) {
+ /* small lock is completely inside big lock,
+ break it down into 3 different locks. */
+ v->locks[0] = fd_lk_ctx_node_new (big->cmd, NULL);
+ if (!v->locks[0])
+ goto out;
+
+ v->locks[1] = fd_lk_ctx_node_new (small->cmd, NULL);
+ if (!v->locks[1])
+ goto out;
+
+ v->locks[2] = fd_lk_ctx_node_new (big->cmd, NULL);
+ if (!v->locks[2])
+ goto out;
+
+ memcpy (v->locks[0], big, sizeof (fd_lk_ctx_node_t));
+ v->locks[0]->fl_end = small->fl_start - 1;
+ v->locks[0]->user_flock.l_len =
+ _fd_lk_get_lock_len (v->locks[0]->fl_start,
+ v->locks[0]->fl_end);
+
+ memcpy (v->locks[1], small, sizeof (fd_lk_ctx_node_t));
+
+ memcpy (v->locks[2], big, sizeof (fd_lk_ctx_node_t));
+ v->locks[2]->fl_start = small->fl_end + 1;
+ v->locks[2]->user_flock.l_len =
+ _fd_lk_get_lock_len (v->locks[2]->fl_start,
+ v->locks[2]->fl_end);
+ } else if (small->fl_start == big->fl_start) {
+ /* One of the ends co-incide, break the
+ locks into two seperate parts */
+ v->locks[0] = fd_lk_ctx_node_new (small->cmd, NULL);
+ if (!v->locks[0])
+ goto out;
+
+ v->locks[1] = fd_lk_ctx_node_new (big->cmd, NULL);
+ if (!v->locks[1])
+ goto out;
+
+ memcpy (v->locks[0], small, sizeof (fd_lk_ctx_node_t));
+
+ memcpy (v->locks[1], big, sizeof (fd_lk_ctx_node_t));
+ v->locks[1]->fl_start = small->fl_end + 1;
+ v->locks[1]->user_flock.l_start = small->fl_end + 1;
+ } else if (small->fl_end == big->fl_end) {
+ /* One of the ends co-incide, break the
+ locks into two seperate parts */
+ v->locks[0] = fd_lk_ctx_node_new (small->cmd, NULL);
+ if (!v->locks[0])
+ goto out;
+
+ v->locks[1] = fd_lk_ctx_node_new (big->cmd, NULL);
+ if (!v->locks[1])
+ goto out;
+
+ memcpy (v->locks[0], big, sizeof (fd_lk_ctx_node_t));
+ v->locks[0]->fl_end = small->fl_start - 1;
+ v->locks[0]->user_flock.l_len =
+ _fd_lk_get_lock_len (v->locks[0]->fl_start,
+ v->locks[0]->fl_end);
+
+ memcpy (v->locks[1], small, sizeof (fd_lk_ctx_node_t));
+ } else {
+ /* We should never come to this case */
+ GF_ASSERT (!"Invalid case");
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+static void
+_fd_lk_insert_and_merge (fd_lk_ctx_t *lk_ctx,
+ fd_lk_ctx_node_t *lock)
+{
+ int32_t ret = -1;
+ int32_t i = 0;
+ fd_lk_ctx_node_t *entry = NULL;
+ fd_lk_ctx_node_t *t = NULL;
+ fd_lk_ctx_node_t *sum = NULL;
+ struct _values v = {.locks = {0, 0, 0 }};
+
+ list_for_each_entry_safe (entry, t, &lk_ctx->lk_list, next) {
+ if (!fd_lk_overlap (entry, lock))
+ continue;
+
+ if (entry->fl_type == lock->fl_type) {
+ sum = _fd_lk_add_locks (entry, lock);
+ if (!sum)
+ return;
+ sum->fl_type = entry->fl_type;
+ sum->user_flock.l_type = entry->fl_type;
+ _fd_lk_delete_lock (entry);
+ _fd_lk_destroy_lock (entry);
+ _fd_lk_destroy_lock (lock);
+ _fd_lk_insert_and_merge (lk_ctx, sum);
+ return;
+ } else {
+ sum = _fd_lk_add_locks (entry, lock);
+ sum->fl_type = lock->fl_type;
+ sum->user_flock.l_type = lock->fl_type;
+ ret = _fd_lk_sub_locks (&v, sum, lock);
+ if (ret)
+ return;
+ _fd_lk_delete_lock (entry);
+ _fd_lk_destroy_lock (entry);
+
+ _fd_lk_delete_lock (lock);
+ _fd_lk_destroy_lock (lock);
+
+ _fd_lk_destroy_lock (sum);
+
+ for (i = 0; i < 3; i++) {
+ if (!v.locks[i])
+ continue;
+
+ INIT_LIST_HEAD (&v.locks[i]->next);
+ _fd_lk_insert_and_merge (lk_ctx, v.locks[i]);
+ }
+ _fd_lk_delete_unlck_locks (lk_ctx);
+ return;
+ }
+ }
+
+ /* no conflicts, so just insert */
+ if (lock->fl_type != F_UNLCK) {
+ _fd_lk_insert_lock (lk_ctx, lock);
+ } else {
+ _fd_lk_destroy_lock (lock);
+ }
+}
+
+static void
+print_lock_list (fd_lk_ctx_t *lk_ctx)
+{
+ fd_lk_ctx_node_t *lk = NULL;
+
+ gf_log ("fd-lk", GF_LOG_DEBUG, "lock list:");
+
+ list_for_each_entry (lk, &lk_ctx->lk_list, next)
+ gf_log ("fd-lk", GF_LOG_DEBUG, "owner = %s, "
+ "cmd = %s fl_type = %s, fs_start = %"PRId64", "
+ "fs_end = %"PRId64", user_flock: l_type = %s, "
+ "l_start = %"PRId64", l_len = %"PRId64", ",
+ lkowner_utoa (&lk->user_flock.l_owner),
+ get_lk_cmd (lk->cmd), get_lk_type (lk->fl_type),
+ lk->fl_start, lk->fl_end,
+ get_lk_type (lk->user_flock.l_type),
+ lk->user_flock.l_start,
+ lk->user_flock.l_len);
+}
+
+int
+fd_lk_insert_and_merge (fd_t *fd, int32_t cmd,
+ struct gf_flock *flock)
+{
+ int32_t ret = -1;
+ fd_lk_ctx_t *lk_ctx = NULL;
+ fd_lk_ctx_node_t *lk = NULL;
+
+ GF_VALIDATE_OR_GOTO ("fd-lk", fd, out);
+ GF_VALIDATE_OR_GOTO ("fd-lk", flock, out);
+
+ lk_ctx = fd_lk_ctx_ref (fd->lk_ctx);
+ lk = fd_lk_ctx_node_new (cmd, flock);
+
+ gf_log ("fd-lk", GF_LOG_DEBUG,
+ "new lock requrest: owner = %s, fl_type = %s, "
+ "fs_start = %"PRId64", fs_end = %"PRId64", "
+ "user_flock: l_type = %s, l_start = %"PRId64", "
+ "l_len = %"PRId64, lkowner_utoa (&flock->l_owner),
+ get_lk_type (lk->fl_type), lk->fl_start,
+ lk->fl_end, get_lk_type (lk->user_flock.l_type),
+ lk->user_flock.l_start,
+ lk->user_flock.l_len);
+
+ LOCK (&lk_ctx->lock);
+ {
+ _fd_lk_insert_and_merge (lk_ctx, lk);
+ print_lock_list (lk_ctx);
+ }
+ UNLOCK (&lk_ctx->lock);
+
+ fd_lk_ctx_unref (lk_ctx);
+
+ ret = 0;
+out:
+ return ret;
+}
diff --git a/libglusterfs/src/fd-lk.h b/libglusterfs/src/fd-lk.h
new file mode 100644
index 000000000..bdea8c2a0
--- /dev/null
+++ b/libglusterfs/src/fd-lk.h
@@ -0,0 +1,66 @@
+/*
+ Copyright (c) 2008-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 _FD_LK_H
+#define _FD_LK_H
+
+#include "fd.h"
+#include "locking.h"
+#include "list.h"
+#include "logging.h"
+#include "mem-pool.h"
+#include "mem-types.h"
+#include "glusterfs.h"
+
+#define get_lk_type(type) \
+ type == F_UNLCK ? "F_UNLCK" : (type == F_RDLCK ? "F_RDLCK" : "F_WRLCK")
+
+#define get_lk_cmd(cmd) \
+ cmd == F_SETLKW ? "F_SETLKW" : (cmd == F_SETLK ? "F_SETLK" : "F_GETLK")
+
+struct _fd;
+
+struct fd_lk_ctx {
+ struct list_head lk_list;
+ int ref;
+ gf_lock_t lock;
+};
+typedef struct fd_lk_ctx fd_lk_ctx_t;
+
+struct fd_lk_ctx_node {
+ int32_t cmd;
+ struct gf_flock user_flock;
+ off_t fl_start;
+ off_t fl_end;
+ short fl_type;
+ struct list_head next;
+};
+typedef struct fd_lk_ctx_node fd_lk_ctx_node_t;
+
+fd_lk_ctx_t *
+_fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx);
+
+fd_lk_ctx_t *
+fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx);
+
+fd_lk_ctx_t *
+fd_lk_ctx_try_ref (fd_lk_ctx_t *lk_ctx);
+
+fd_lk_ctx_t *
+fd_lk_ctx_create ();
+
+int
+fd_lk_insert_and_merge (struct _fd *lk_ctx, int32_t cmd,
+ struct gf_flock *flock);
+
+int
+fd_lk_ctx_unref (fd_lk_ctx_t *lk_ctx);
+
+#endif /* _FD_LK_H */
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c
index 1e65f2d82..5ef4c0479 100644
--- a/libglusterfs/src/fd.c
+++ b/libglusterfs/src/fd.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "fd.h"
@@ -35,28 +26,7 @@ gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr);
fd_t *
-_fd_ref (fd_t *fd);
-
-/*
- Allocate in memory chunks of power of 2 starting from 1024B
- Assumes fdtable->lock is held
-*/
-static inline int
-gf_roundup_power_of_two (uint32_t nr)
-{
- uint32_t result = 1;
-
- if (nr < 0) {
- gf_log ("fd", GF_LOG_ERROR, "negative number passed");
- return -1;
- }
-
- while (result <= nr)
- result *= 2;
-
- return result;
-}
-
+__fd_ref (fd_t *fd);
static int
gf_fd_chain_fd_entries (fdentry_t *entries, uint32_t startidx,
@@ -96,7 +66,7 @@ gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr)
}
nr /= (1024 / sizeof (fdentry_t));
- nr = gf_roundup_power_of_two (nr + 1);
+ nr = gf_roundup_next_power_of_two (nr + 1);
nr *= (1024 / sizeof (fdentry_t));
oldfds = fdtable->fdentries;
@@ -151,7 +121,7 @@ gf_fd_fdtable_alloc (void)
}
-fdentry_t *
+static fdentry_t *
__gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
{
fdentry_t *fdentries = NULL;
@@ -189,6 +159,53 @@ gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
}
+static fdentry_t *
+__gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
+{
+ fdentry_t *fdentries = NULL;
+ int i = 0;
+
+ if (count == NULL) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!count");
+ goto out;
+ }
+
+ fdentries = GF_CALLOC (fdtable->max_fds, sizeof (fdentry_t),
+ gf_common_mt_fdentry_t);
+ if (fdentries == NULL) {
+ goto out;
+ }
+
+ *count = fdtable->max_fds;
+
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (fdtable->fdentries[i].fd != NULL) {
+ fdentries[i].fd = fd_ref (fdtable->fdentries[i].fd);
+ }
+ }
+
+out:
+ return fdentries;
+}
+
+
+fdentry_t *
+gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
+{
+ fdentry_t *entries = NULL;
+
+ if (fdtable) {
+ pthread_mutex_lock (&fdtable->lock);
+ {
+ entries = __gf_fd_fdtable_copy_all_fds (fdtable, count);
+ }
+ pthread_mutex_unlock (&fdtable->lock);
+ }
+
+ return entries;
+}
+
+
void
gf_fd_fdtable_destroy (fdtable_t *fdtable)
{
@@ -290,6 +307,10 @@ gf_fd_put (fdtable_t *fdtable, int32_t fd)
fd_t *fdptr = NULL;
fdentry_t *fde = NULL;
+ if (fd == -2)
+ /* anonymous fd */
+ return;
+
if (fdtable == NULL || fd < 0) {
gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
return;
@@ -307,7 +328,7 @@ gf_fd_put (fdtable_t *fdtable, int32_t fd)
* without doing anything.
* This has the potential of masking out any bugs in a user of
* fd that ends up calling gf_fd_put twice for the same fd or
- * for an unallocated fd, but thats a price we have to pay for
+ * for an unallocated fd, but it is a price we have to pay for
* ensuring sanity of our fd-table.
*/
if (fde->next_free != GF_FDENTRY_ALLOCATED)
@@ -326,6 +347,54 @@ unlock_out:
}
+inline void
+gf_fdptr_put (fdtable_t *fdtable, fd_t *fd)
+{
+ fdentry_t *fde = NULL;
+ int32_t i = 0;
+
+ if ((fdtable == NULL) || (fd == NULL)) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
+ return;
+ }
+
+ pthread_mutex_lock (&fdtable->lock);
+ {
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (fdtable->fdentries[i].fd == fd) {
+ fde = &fdtable->fdentries[i];
+ break;
+ }
+ }
+
+ if (fde == NULL) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING,
+ "fd (%p) is not present in fdtable", fd);
+ goto unlock_out;
+ }
+
+ /* If the entry is not allocated, put operation must return
+ * without doing anything.
+ * This has the potential of masking out any bugs in a user of
+ * fd that ends up calling gf_fd_put twice for the same fd or
+ * for an unallocated fd, but it is a price we have to pay for
+ * ensuring sanity of our fd-table.
+ */
+ if (fde->next_free != GF_FDENTRY_ALLOCATED)
+ goto unlock_out;
+ fde->fd = NULL;
+ fde->next_free = fdtable->first_free;
+ fdtable->first_free = i;
+ }
+unlock_out:
+ pthread_mutex_unlock (&fdtable->lock);
+
+ if ((fd != NULL) && (fde != NULL)) {
+ fd_unref (fd);
+ }
+}
+
+
fd_t *
gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd)
{
@@ -357,7 +426,7 @@ gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd)
fd_t *
-_fd_ref (fd_t *fd)
+__fd_ref (fd_t *fd)
{
++fd->refcount;
@@ -376,7 +445,7 @@ fd_ref (fd_t *fd)
}
LOCK (&fd->inode->lock);
- refed_fd = _fd_ref (fd);
+ refed_fd = __fd_ref (fd);
UNLOCK (&fd->inode->lock);
return refed_fd;
@@ -384,7 +453,7 @@ fd_ref (fd_t *fd)
fd_t *
-_fd_unref (fd_t *fd)
+__fd_unref (fd_t *fd)
{
GF_ASSERT (fd->refcount);
@@ -404,10 +473,9 @@ fd_destroy (fd_t *fd)
xlator_t *xl = NULL;
int i = 0;
xlator_t *old_THIS = NULL;
- struct mem_pool *tmp_pool = NULL;
if (fd == NULL){
- gf_log_callingfn ("xlator", GF_LOG_ERROR, "invalid arugument");
+ gf_log_callingfn ("xlator", GF_LOG_ERROR, "invalid argument");
goto out;
}
@@ -418,10 +486,8 @@ fd_destroy (fd_t *fd)
if (!fd->_ctx)
goto out;
- tmp_pool = fd->inode->table->fd_mem_pool;
-
if (IA_ISDIR (fd->inode->ia_type)) {
- for (i = 0; i < fd->xl_count; i++) {
+ for (i = 0; i < fd->xl_count; i++) {
if (fd->_ctx[i].key) {
xl = fd->_ctx[i].xl_key;
old_THIS = THIS;
@@ -449,8 +515,8 @@ fd_destroy (fd_t *fd)
GF_FREE (fd->_ctx);
inode_unref (fd->inode);
fd->inode = (inode_t *)0xaaaaaaaa;
- mem_put (tmp_pool,fd);
- tmp_pool = NULL;
+ fd_lk_ctx_unref (fd->lk_ctx);
+ mem_put (fd);
out:
return;
}
@@ -468,7 +534,7 @@ fd_unref (fd_t *fd)
LOCK (&fd->inode->lock);
{
- _fd_unref (fd);
+ __fd_unref (fd);
refcount = fd->refcount;
}
UNLOCK (&fd->inode->lock);
@@ -482,28 +548,35 @@ fd_unref (fd_t *fd)
fd_t *
-fd_bind (fd_t *fd)
+__fd_bind (fd_t *fd)
{
- inode_t *inode = NULL;
+ list_del_init (&fd->inode_list);
+ list_add (&fd->inode_list, &fd->inode->fd_list);
+ return fd;
+}
+
+
+fd_t *
+fd_bind (fd_t *fd)
+{
if (!fd || !fd->inode) {
gf_log_callingfn ("fd", GF_LOG_ERROR, "!fd || !fd->inode");
return NULL;
}
- inode = fd->inode;
- LOCK (&inode->lock);
+ LOCK (&fd->inode->lock);
{
- list_add (&fd->inode_list, &inode->fd_list);
+ fd = __fd_bind (fd);
}
- UNLOCK (&inode->lock);
+ UNLOCK (&fd->inode->lock);
return fd;
}
-fd_t *
-fd_create (inode_t *inode, pid_t pid)
+static fd_t *
+__fd_create (inode_t *inode, uint64_t pid)
{
fd_t *fd = NULL;
@@ -520,33 +593,105 @@ fd_create (inode_t *inode, pid_t pid)
fd->_ctx = GF_CALLOC (1, (sizeof (struct _fd_ctx) * fd->xl_count),
gf_common_mt_fd_ctx);
- if (!fd->_ctx) {
- GF_FREE (fd);
- fd = NULL;
- goto out;
- }
+ if (!fd->_ctx)
+ goto free_fd;
+
+ fd->lk_ctx = fd_lk_ctx_create ();
+ if (!fd->lk_ctx)
+ goto free_fd_ctx;
fd->inode = inode_ref (inode);
fd->pid = pid;
INIT_LIST_HEAD (&fd->inode_list);
LOCK_INIT (&fd->lock);
+out:
+ return fd;
+
+free_fd_ctx:
+ GF_FREE (fd->_ctx);
+free_fd:
+ mem_put (fd);
+
+ return NULL;
+}
+
+
+fd_t *
+fd_create (inode_t *inode, pid_t pid)
+{
+ fd_t *fd = NULL;
+
+ fd = __fd_create (inode, (uint64_t)pid);
+ if (!fd)
+ goto out;
+
+ fd = fd_ref (fd);
+
+out:
+ return fd;
+}
+
+fd_t *
+fd_create_uint64 (inode_t *inode, uint64_t pid)
+{
+ fd_t *fd = NULL;
+
+ fd = __fd_create (inode, pid);
+ if (!fd)
+ goto out;
+
+ fd = fd_ref (fd);
+
+out:
+ return fd;
+}
+
+
+static fd_t *
+__fd_lookup (inode_t *inode, uint64_t pid)
+{
+ fd_t *iter_fd = NULL;
+ fd_t *fd = NULL;
+
+ if (list_empty (&inode->fd_list))
+ return NULL;
+
+
+ list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
+ if (!pid || iter_fd->pid == pid) {
+ fd = __fd_ref (iter_fd);
+ break;
+ }
+ }
+
+ return fd;
+}
+
+
+fd_t *
+fd_lookup (inode_t *inode, pid_t pid)
+{
+ fd_t *fd = NULL;
+
+ if (!inode) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode");
+ return NULL;
+ }
LOCK (&inode->lock);
{
- fd = _fd_ref (fd);
+ fd = __fd_lookup (inode, (uint64_t)pid);
}
UNLOCK (&inode->lock);
-out:
+
return fd;
}
-
fd_t *
-fd_lookup (inode_t *inode, pid_t pid)
+fd_lookup_uint64 (inode_t *inode, uint64_t pid)
{
fd_t *fd = NULL;
- fd_t *iter_fd = NULL;
if (!inode) {
gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode");
@@ -555,28 +700,82 @@ fd_lookup (inode_t *inode, pid_t pid)
LOCK (&inode->lock);
{
- if (list_empty (&inode->fd_list)) {
- fd = NULL;
- } else {
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- if (pid) {
- if (iter_fd->pid == pid) {
- fd = _fd_ref (iter_fd);
- break;
- }
- } else {
- fd = _fd_ref (iter_fd);
- break;
- }
- }
+ fd = __fd_lookup (inode, pid);
+ }
+ UNLOCK (&inode->lock);
+
+ return fd;
+}
+
+static fd_t *
+__fd_lookup_anonymous (inode_t *inode)
+{
+ fd_t *iter_fd = NULL;
+ fd_t *fd = NULL;
+
+ if (list_empty (&inode->fd_list))
+ return NULL;
+
+ list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
+ if (iter_fd->anonymous) {
+ fd = __fd_ref (iter_fd);
+ break;
}
}
+
+ return fd;
+}
+
+static fd_t *
+__fd_anonymous (inode_t *inode)
+{
+ fd_t *fd = NULL;
+
+ fd = __fd_lookup_anonymous (inode);
+
+ /* if (fd); then we already have increased the refcount in
+ __fd_lookup_anonymous(), so no need of one more fd_ref().
+ if (!fd); then both create and bind wont bump up the ref
+ count, so we have to call fd_ref() after bind. */
+ if (!fd) {
+ fd = __fd_create (inode, 0);
+
+ if (!fd)
+ return NULL;
+
+ fd->anonymous = _gf_true;
+
+ __fd_bind (fd);
+
+ __fd_ref (fd);
+ }
+
+ return fd;
+}
+
+
+fd_t *
+fd_anonymous (inode_t *inode)
+{
+ fd_t *fd = NULL;
+
+ LOCK (&inode->lock);
+ {
+ fd = __fd_anonymous (inode);
+ }
UNLOCK (&inode->lock);
return fd;
}
+gf_boolean_t
+fd_is_anonymous (fd_t *fd)
+{
+ return (fd && fd->anonymous);
+}
+
+
uint8_t
fd_list_empty (inode_t *inode)
{
@@ -595,9 +794,12 @@ fd_list_empty (inode_t *inode)
int
__fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
{
- int index = 0;
- int ret = 0;
- int set_idx = -1;
+ int index = 0, new_xl_count = 0;
+ int ret = 0;
+ int set_idx = -1;
+ void *begin = NULL;
+ size_t diff = 0;
+ struct _fd_ctx *tmp = NULL;
if (!fd || !xlator)
return -1;
@@ -616,9 +818,33 @@ __fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
}
if (set_idx == -1) {
- gf_log_callingfn ("", GF_LOG_WARNING, "%p %s", fd, xlator->name);
- ret = -1;
- goto out;
+ set_idx = fd->xl_count;
+
+ new_xl_count = fd->xl_count + xlator->graph->xl_count;
+
+ tmp = GF_REALLOC (fd->_ctx,
+ (sizeof (struct _fd_ctx)
+ * new_xl_count));
+ if (tmp == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "realloc of fd->_ctx for fd "
+ "(ptr: %p) failed, cannot set the key"
+ , fd);
+ ret = -1;
+ goto out;
+ }
+
+ fd->_ctx = tmp;
+
+ begin = fd->_ctx;
+ begin += (fd->xl_count * sizeof (struct _fd_ctx));
+
+ diff = (new_xl_count - fd->xl_count )
+ * sizeof (struct _fd_ctx);
+
+ memset (begin, 0, diff);
+
+ fd->xl_count = new_xl_count;
}
fd->_ctx[set_idx].xl_key = xlator;
@@ -694,7 +920,7 @@ fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
}
-int
+static int
__fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
{
int index = 0;
@@ -751,16 +977,9 @@ fd_dump (fd_t *fd, char *prefix)
return;
memset(key, 0, sizeof(key));
- gf_proc_dump_build_key(key, prefix, "pid");
- gf_proc_dump_write(key, "%d", fd->pid);
- gf_proc_dump_build_key(key, prefix, "refcount");
- gf_proc_dump_write(key, "%d", fd->refcount);
- gf_proc_dump_build_key(key, prefix, "flags");
- gf_proc_dump_write(key, "%d", fd->flags);
- if (fd->inode) {
- gf_proc_dump_build_key(key, prefix, "inode");
- gf_proc_dump_write(key, "%ld", fd->inode->ino);
- }
+ gf_proc_dump_write("pid", "%llu", fd->pid);
+ gf_proc_dump_write("refcount", "%d", fd->refcount);
+ gf_proc_dump_write("flags", "%d", fd->flags);
}
@@ -790,10 +1009,8 @@ fdtable_dump (fdtable_t *fdtable, char *prefix)
ret = pthread_mutex_trylock (&fdtable->lock);
- if (ret) {
- gf_log ("fd", GF_LOG_WARNING, "Unable to acquire lock");
- return;
- }
+ if (ret)
+ goto out;
memset(key, 0, sizeof(key));
gf_proc_dump_build_key(key, prefix, "refcount");
@@ -813,6 +1030,12 @@ fdtable_dump (fdtable_t *fdtable, char *prefix)
}
pthread_mutex_unlock(&fdtable->lock);
+
+out:
+ if (ret != 0)
+ gf_proc_dump_write ("Unable to dump the fdtable",
+ "(Lock acquistion failed) %p", fdtable);
+ return;
}
@@ -831,15 +1054,13 @@ fd_ctx_dump (fd_t *fd, char *prefix)
LOCK (&fd->lock);
{
if (fd->_ctx != NULL) {
- fd_ctx = GF_CALLOC (fd->inode->table->xl->graph->xl_count,
- sizeof (*fd_ctx),
+ fd_ctx = GF_CALLOC (fd->xl_count, sizeof (*fd_ctx),
gf_common_mt_fd_ctx);
if (fd_ctx == NULL) {
goto unlock;
}
- for (i = 0; i < fd->inode->table->xl->graph->xl_count;
- i++) {
+ for (i = 0; i < fd->xl_count; i++) {
fd_ctx[i] = fd->_ctx[i];
}
}
@@ -851,7 +1072,7 @@ unlock:
goto out;
}
- for (i = 0; i < fd->inode->table->xl->graph->xl_count; i++) {
+ for (i = 0; i < fd->xl_count; i++) {
if (fd_ctx[i].xl_key) {
xl = (xlator_t *)(long)fd_ctx[i].xl_key;
if (xl->dumpops && xl->dumpops->fdctx)
@@ -866,3 +1087,95 @@ out:
return;
}
+
+void
+fdentry_dump_to_dict (fdentry_t *fdentry, char *prefix, dict_t *dict,
+ int *openfds)
+{
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int ret = -1;
+
+ if (!fdentry)
+ return;
+ if (!dict)
+ return;
+
+ if (GF_FDENTRY_ALLOCATED != fdentry->next_free)
+ return;
+
+ if (fdentry->fd) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pid", prefix);
+ ret = dict_set_int32 (dict, key, fdentry->fd->pid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.refcount", prefix);
+ ret = dict_set_int32 (dict, key, fdentry->fd->refcount);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.flags", prefix);
+ ret = dict_set_int32 (dict, key, fdentry->fd->flags);
+
+ (*openfds)++;
+ }
+ return;
+}
+
+void
+fdtable_dump_to_dict (fdtable_t *fdtable, char *prefix, dict_t *dict)
+{
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int i = 0;
+ int openfds = 0;
+ int ret = -1;
+
+ if (!fdtable)
+ return;
+ if (!dict)
+ return;
+
+ ret = pthread_mutex_trylock (&fdtable->lock);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.refcount", prefix);
+ ret = dict_set_int32 (dict, key, fdtable->refcount);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.maxfds", prefix);
+ ret = dict_set_uint32 (dict, key, fdtable->max_fds);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.firstfree", prefix);
+ ret = dict_set_int32 (dict, key, fdtable->first_free);
+ if (ret)
+ goto out;
+
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (GF_FDENTRY_ALLOCATED ==
+ fdtable->fdentries[i].next_free) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.fdentry%d",
+ prefix, i);
+ fdentry_dump_to_dict (&fdtable->fdentries[i], key,
+ dict, &openfds);
+ }
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.openfds", prefix);
+ ret = dict_set_int32 (dict, key, openfds);
+
+out:
+ pthread_mutex_unlock (&fdtable->lock);
+ return;
+}
diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h
index d19b0724f..a70707bc1 100644
--- a/libglusterfs/src/fd.h
+++ b/libglusterfs/src/fd.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _FD_H
@@ -30,9 +21,12 @@
#include <unistd.h>
#include "glusterfs.h"
#include "locking.h"
+#include "fd-lk.h"
+#include "common-utils.h"
struct _inode;
struct _dict;
+struct fd_lk_ctx;
struct _fd_ctx {
union {
@@ -45,12 +39,8 @@ struct _fd_ctx {
};
};
-/* If this structure changes, please have mercy on the booster maintainer
- * and update the fd_t struct in booster/src/booster-fd.h.
- * See the comment there to know why.
- */
struct _fd {
- pid_t pid;
+ uint64_t pid;
int32_t flags;
int32_t refcount;
struct list_head inode_list;
@@ -59,6 +49,8 @@ struct _fd {
'struct _fd_ctx' array (_ctx).*/
struct _fd_ctx *_ctx;
int xl_count; /* Number of xl referred in this fd */
+ struct fd_lk_ctx *lk_ctx;
+ gf_boolean_t anonymous; /* geo-rep anonymous fd */
};
typedef struct _fd fd_t;
@@ -117,6 +109,10 @@ gf_fd_fdtable_destroy (fdtable_t *fdtable);
fd_t *
+__fd_ref (fd_t *fd);
+
+
+fd_t *
fd_ref (fd_t *fd);
@@ -127,10 +123,22 @@ fd_unref (fd_t *fd);
fd_t *
fd_create (struct _inode *inode, pid_t pid);
+fd_t *
+fd_create_uint64 (struct _inode *inode, uint64_t pid);
fd_t *
fd_lookup (struct _inode *inode, pid_t pid);
+fd_t *
+fd_lookup_uint64 (struct _inode *inode, uint64_t pid);
+
+fd_t *
+fd_anonymous (inode_t *inode);
+
+
+gf_boolean_t
+fd_is_anonymous (fd_t *fd);
+
uint8_t
fd_list_empty (struct _inode *inode);
@@ -151,7 +159,6 @@ fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value);
int
fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value);
-
int
__fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value);
@@ -160,13 +167,14 @@ int
__fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value);
-int
-__fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value);
+void
+fd_ctx_dump (fd_t *fd, char *prefix);
+
+fdentry_t *
+gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count);
-fd_t *
-_fd_ref (fd_t *fd);
void
-fd_ctx_dump (fd_t *fd, char *prefix);
+gf_fdptr_put (fdtable_t *fdtable, fd_t *fd);
#endif /* _FD_H */
diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c
index 933647589..bb028c967 100644
--- a/libglusterfs/src/gf-dirent.c
+++ b/libglusterfs/src/gf-dirent.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -31,26 +22,6 @@
#include "xlator.h"
gf_dirent_t *
-gf_dirent_for_namelen (int len)
-{
- gf_dirent_t *gf_dirent = NULL;
-
- /* TODO: use mem-pool */
- gf_dirent = CALLOC (len, sizeof(char));
- if (!gf_dirent)
- return NULL;
-
- INIT_LIST_HEAD (&gf_dirent->list);
-
- gf_dirent->d_off = 0;
- gf_dirent->d_ino = -1;
- gf_dirent->d_type = 0;
-
- return gf_dirent;
-}
-
-
-gf_dirent_t *
gf_dirent_for_name (const char *name)
{
gf_dirent_t *gf_dirent = NULL;
@@ -86,7 +57,36 @@ gf_dirent_free (gf_dirent_t *entries)
return;
list_for_each_entry_safe (entry, tmp, &entries->list, list) {
+ if (entry->dict)
+ dict_unref (entry->dict);
+ if (entry->inode)
+ inode_unref (entry->inode);
+
list_del (&entry->list);
GF_FREE (entry);
}
}
+
+/* TODO: Currently, with this function, we will be breaking the
+ policy of 1-1 mapping of kernel nlookup refs with our inode_t's
+ nlookup count.
+ Need more thoughts before finalizing this function
+*/
+int
+gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent,
+ gf_dirent_t *entries)
+{
+ gf_dirent_t *entry = NULL;
+ inode_t *link_inode = NULL;
+
+ list_for_each_entry (entry, &entries->list, list) {
+ if (entry->inode) {
+ link_inode = inode_link (entry->inode, parent,
+ entry->d_name, &entry->d_stat);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ }
+ }
+
+ return 0;
+}
diff --git a/libglusterfs/src/gf-dirent.h b/libglusterfs/src/gf-dirent.h
index 8a6533fc3..26cb5a668 100644
--- a/libglusterfs/src/gf-dirent.h
+++ b/libglusterfs/src/gf-dirent.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -27,6 +18,7 @@
#endif
#include "iatt.h"
+#include "inode.h"
#define gf_dirent_size(name) (sizeof (gf_dirent_t) + strlen (name) + 1)
@@ -51,12 +43,16 @@ struct _gf_dirent_t {
uint32_t d_len;
uint32_t d_type;
struct iatt d_stat;
+ dict_t *dict;
+ inode_t *inode;
char d_name[0];
};
+#define DT_ISDIR(mode) (mode == DT_DIR)
gf_dirent_t *gf_dirent_for_name (const char *name);
void gf_dirent_free (gf_dirent_t *entries);
-gf_dirent_t * gf_dirent_for_namelen (int len);
+int gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent,
+ gf_dirent_t *entries);
#endif /* _GF_DIRENT_H */
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
index fe0b92dda..11f62a550 100644
--- a/libglusterfs/src/globals.c
+++ b/libglusterfs/src/globals.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -111,6 +102,7 @@ glusterfs_ctx_init ()
}
INIT_LIST_HEAD (&glusterfs_ctx->graphs);
+ INIT_LIST_HEAD (&glusterfs_ctx->mempool_list);
ret = pthread_mutex_init (&glusterfs_ctx->lock, NULL);
out:
@@ -154,6 +146,8 @@ glusterfs_this_init ()
global_xlator.type = "global";
global_xlator.ctx = glusterfs_ctx;
+ INIT_LIST_HEAD (&global_xlator.volume_options);
+
return ret;
}
@@ -290,6 +284,43 @@ glusterfs_uuid_buf_get ()
return buf;
}
+/* LKOWNER_BUFFER */
+
+static pthread_key_t lkowner_buf_key;
+static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE];
+void
+glusterfs_lkowner_buf_destroy (void *ptr)
+{
+ if (ptr)
+ FREE (ptr);
+}
+
+int
+glusterfs_lkowner_buf_init ()
+{
+ int ret = 0;
+
+ ret = pthread_key_create (&lkowner_buf_key,
+ glusterfs_lkowner_buf_destroy);
+ return ret;
+}
+
+char *
+glusterfs_lkowner_buf_get ()
+{
+ char *buf;
+ int ret = 0;
+
+ buf = pthread_getspecific (lkowner_buf_key);
+ if(!buf) {
+ buf = MALLOC (GF_LKOWNER_BUF_SIZE);
+ ret = pthread_setspecific (lkowner_buf_key, (void *) buf);
+ if(ret)
+ buf = global_lkowner_buf;
+ }
+ return buf;
+}
+
int
glusterfs_globals_init ()
{
@@ -320,6 +351,13 @@ glusterfs_globals_init ()
goto out;
}
+ ret = glusterfs_lkowner_buf_init ();
+ if(ret) {
+ gf_log ("", GF_LOG_CRITICAL,
+ "ERROR: glusterfs lkowner buffer init failed");
+ goto out;
+ }
+
gf_mem_acct_enable_set ();
ret = synctask_init ();
@@ -333,7 +371,7 @@ out:
}
-char eventstring[GF_EVENT_MAXVAL][64] = {
+char eventstring[GF_EVENT_MAXVAL+1][64] = {
"Invalid event",
"Parent Up",
"Poll In",
@@ -342,9 +380,15 @@ char eventstring[GF_EVENT_MAXVAL][64] = {
"Child Up",
"Child Down",
"Child Connecting",
+ "Child Modified",
"Transport Cleanup",
"Transport Connected",
"Volfile Modified",
+ "New Volfile",
+ "Translator Info",
+ "Xlator Op",
+ "Authentication Failed",
+ "Invalid event",
};
/* Copy the string ptr contents if needed for yourself */
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index 78ceddab3..e797db184 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _GLOBALS_H
@@ -22,12 +13,6 @@
#define GF_DEFAULT_BASE_PORT 24007
-/* This corresponds to the max 16 number of group IDs that are sent through an
- * RPC request. Since NFS is the only one going to set this, we can be safe
- * in keeping this size hardcoded.
- */
-#define GF_REQUEST_MAXGROUPS 16
-
#include "glusterfs.h"
/* CTX */
@@ -52,6 +37,7 @@ int synctask_set (void *);
/* uuid_buf */
char *glusterfs_uuid_buf_get();
+char *glusterfs_lkowner_buf_get();
/* init */
int glusterfs_globals_init (void);
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index 56b5e2b9c..4dfb4cfb0 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _GLUSTERFS_H
@@ -42,16 +33,21 @@
#include <sys/poll.h>
#include <pthread.h>
+
#include "list.h"
#include "logging.h"
-
#define GF_YES 1
#define GF_NO 0
#ifndef O_LARGEFILE
/* savannah bug #20053, patch for compiling on darwin */
-#define O_LARGEFILE 0
+#define O_LARGEFILE 0100000 /* from bits/fcntl.h */
+#endif
+
+#ifndef O_FMODE_EXEC
+/* redhat bug 843080, added from linux/fs.h */
+#define O_FMODE_EXEC 040 //0x20
#endif
#ifndef O_DIRECT
@@ -80,10 +76,23 @@
#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
#define ZR_DUMP_FUSE "dump-fuse"
+#define GF_XATTR_CLRLK_CMD "glusterfs.clrlk"
#define GF_XATTR_PATHINFO_KEY "trusted.glusterfs.pathinfo"
+#define GF_XATTR_NODE_UUID_KEY "trusted.glusterfs.node-uuid"
+#define GF_XATTR_VOL_ID_KEY "trusted.glusterfs.volume-id"
+
+#define GF_READDIR_SKIP_DIRS "readdir-filter-directories"
+
+#define XATTR_IS_PATHINFO(x) (strncmp (x, GF_XATTR_PATHINFO_KEY, \
+ strlen (GF_XATTR_PATHINFO_KEY)) == 0)
+#define XATTR_IS_NODE_UUID(x) (strncmp (x, GF_XATTR_NODE_UUID_KEY, \
+ strlen (GF_XATTR_NODE_UUID_KEY)) == 0)
+
#define GF_XATTR_LINKINFO_KEY "trusted.distribute.linkinfo"
#define GFID_XATTR_KEY "trusted.gfid"
+#define GLUSTERFS_INTERNAL_FOP_KEY "glusterfs-internal-fop"
+
#define ZR_FILE_CONTENT_STR "glusterfs.file."
#define ZR_FILE_CONTENT_STRLEN 15
@@ -91,7 +100,23 @@
#define GLUSTERFS_INODELK_COUNT "glusterfs.inodelk-count"
#define GLUSTERFS_ENTRYLK_COUNT "glusterfs.entrylk-count"
#define GLUSTERFS_POSIXLK_COUNT "glusterfs.posixlk-count"
+#define GLUSTERFS_PARENT_ENTRYLK "glusterfs.parent-entrylk"
#define QUOTA_SIZE_KEY "trusted.glusterfs.quota.size"
+#define GFID_TO_PATH_KEY "glusterfs.gfid2path"
+
+/* Index xlator related */
+#define GF_XATTROP_INDEX_GFID "glusterfs.xattrop_index_gfid"
+
+#define GF_GFIDLESS_LOOKUP "gfidless-lookup"
+/* replace-brick and pump related internal xattrs */
+#define RB_PUMP_CMD_START "glusterfs.pump.start"
+#define RB_PUMP_CMD_PAUSE "glusterfs.pump.pause"
+#define RB_PUMP_CMD_COMMIT "glusterfs.pump.commit"
+#define RB_PUMP_CMD_ABORT "glusterfs.pump.abort"
+#define RB_PUMP_CMD_STATUS "glusterfs.pump.status"
+
+#define POSIX_ACL_DEFAULT_XATTR "system.posix_acl_default"
+#define POSIX_ACL_ACCESS_XATTR "system.posix_acl_access"
#define GLUSTERFS_RDMA_INLINE_THRESHOLD (2048)
#define GLUSTERFS_RDMA_MAX_HEADER_SIZE (228) /* (sizeof (rdma_header_t) \
@@ -104,8 +129,13 @@
#define ZR_FILE_CONTENT_REQUEST(key) (!strncmp(key, ZR_FILE_CONTENT_STR, \
ZR_FILE_CONTENT_STRLEN))
-/* TODO: Should we use PATH-MAX? On some systems it may save space */
-#define ZR_PATH_MAX 4096
+#define DEFAULT_VAR_RUN_DIRECTORY DATADIR "/run/gluster"
+
+/* GlusterFS's maximum supported Auxilary GIDs */
+/* TODO: Keeping it to 200, so that we can fit in 2KB buffer for auth data
+ * in RPC server code, if there is ever need for having more aux-gids, then
+ * we have to add aux-gid in payload of actors */
+#define GF_MAX_AUX_GROUPS 200
/* NOTE: add members ONLY at the end (just before _MAXVALUE) */
typedef enum {
@@ -154,6 +184,7 @@ typedef enum {
GF_FOP_RELEASE,
GF_FOP_RELEASEDIR,
GF_FOP_GETSPEC,
+ GF_FOP_FREMOVEXATTR,
GF_FOP_MAXVALUE,
} glusterfs_fop_t;
@@ -170,15 +201,6 @@ typedef enum {
GF_OP_TYPE_MAX,
} gf_op_type_t;
-struct gf_flock {
- short l_type;
- short l_whence;
- off_t l_start;
- off_t l_len;
- pid_t l_pid;
- uint64_t l_owner;
-};
-
/* NOTE: all the miscellaneous flags used by GlusterFS should be listed here */
typedef enum {
GF_LK_GETLK = 0,
@@ -275,6 +297,10 @@ struct _cmd_args {
char *run_id;
int debug_mode;
int read_only;
+ int acl;
+ int selinux;
+ int enable_ino32;
+ int worm;
int mac_compat;
struct list_head xlator_options; /* list of xlator_option_t */
@@ -289,6 +315,8 @@ struct _cmd_args {
char *dump_fuse;
pid_t client_pid;
int client_pid_set;
+ unsigned uid_map_root;
+
/* key args */
char *mount_point;
@@ -297,6 +325,7 @@ struct _cmd_args {
/* required for portmap */
int brick_port;
char *brick_name;
+ int brick_port2;
};
typedef struct _cmd_args cmd_args_t;
@@ -316,6 +345,8 @@ struct _glusterfs_graph {
typedef struct _glusterfs_graph glusterfs_graph_t;
+typedef int32_t (*glusterfsd_mgmt_event_notify_fn_t) (int32_t event, void *data,
+ ...);
struct _glusterfs_ctx {
cmd_args_t cmd_args;
char *process_uuid;
@@ -340,6 +371,23 @@ struct _glusterfs_ctx {
int graph_id; /* Incremented per graph, value should
indicate how many times the graph has
got changed */
+ pid_t mnt_pid; /* pid of the mount agent */
+ int process_mode; /*mode in which process is runninng*/
+ struct syncenv *env; /* The env pointer to the synctasks */
+
+ struct list_head mempool_list; /* used to keep a global list of
+ mempools, used to log details of
+ mempool in statedump */
+ char *statedump_path;
+
+ struct mem_pool *dict_pool;
+ struct mem_pool *dict_pair_pool;
+ struct mem_pool *dict_data_pool;
+
+ int mem_accounting; /* if value is other than 0, it
+ will be set */
+ glusterfsd_mgmt_event_notify_fn_t notify; /* Used for xlators to make
+ call to fsd-mgmt */
};
typedef struct _glusterfs_ctx glusterfs_ctx_t;
@@ -361,12 +409,35 @@ typedef enum {
GF_EVENT_VOLFILE_MODIFIED,
GF_EVENT_GRAPH_NEW,
GF_EVENT_TRANSLATOR_INFO,
+ GF_EVENT_TRANSLATOR_OP,
+ GF_EVENT_AUTH_FAILED,
+ GF_EVENT_VOLUME_DEFRAG,
+ GF_EVENT_PARENT_DOWN,
GF_EVENT_MAXVAL,
} glusterfs_event_t;
+/* gf_lkowner_t is defined in lkowner.h */
+#include "lkowner.h"
+
+struct gf_flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+ gf_lkowner_t l_owner;
+};
+
extern char *glusterfs_strevent (glusterfs_event_t ev);
#define GF_MUST_CHECK __attribute__((warn_unused_result))
+/*
+ * Some macros (e.g. ALLOC_OR_GOTO) set variables in function scope, but the
+ * calling function might not only declare the variable to keep the macro happy
+ * and not use it otherwise. In such cases, the following can be used to
+ * suppress the "set but not used" warning that would otherwise occur.
+ */
+#define GF_UNUSED __attribute__((unused))
int glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx);
int glusterfs_graph_destroy (glusterfs_graph_t *graph);
diff --git a/libglusterfs/src/graph-mem-types.h b/libglusterfs/src/graph-mem-types.h
deleted file mode 100644
index 86e0749cd..000000000
--- a/libglusterfs/src/graph-mem-types.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __GRAPH_MEM_TYPES_H__
-#define __GRAPH_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-#define GF_MEM_TYPE_START (gf_common_mt_end + 1)
-
-enum gf_graph_mem_types {
- gf_graph_mt_buf = GF_MEM_TYPE_START,
- gf_graph_mt_end
-};
-#endif
diff --git a/libglusterfs/src/graph-print.c b/libglusterfs/src/graph-print.c
index f9a2f6cb6..667129864 100644
--- a/libglusterfs/src/graph-print.c
+++ b/libglusterfs/src/graph-print.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -26,7 +17,6 @@
#include "common-utils.h"
#include "xlator.h"
-#include "graph-mem-types.h"
#include "graph-utils.h"
@@ -180,7 +170,7 @@ glusterfs_graph_print_buf (glusterfs_graph_t *graph)
if (len == -1)
return NULL;
- buf = GF_CALLOC (1, len + 1, gf_graph_mt_buf);
+ buf = GF_CALLOC (1, len + 1, gf_common_mt_graph_buf);
if (!buf) {
return NULL;
}
diff --git a/libglusterfs/src/graph-utils.h b/libglusterfs/src/graph-utils.h
index 66bdd9844..207664fdb 100644
--- a/libglusterfs/src/graph-utils.h
+++ b/libglusterfs/src/graph-utils.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _GRAPH_H_
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c
index 990e96e2f..a42ae7cd7 100644
--- a/libglusterfs/src/graph.c
+++ b/libglusterfs/src/graph.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -37,20 +28,17 @@ _gf_dump_details (int argc, char **argv)
{
extern FILE *gf_log_logfile;
int i = 0;
- char timestr[256];
+ char timestr[64];
time_t utime = 0;
- struct tm *tm = NULL;
pid_t mypid = 0;
struct utsname uname_buf = {{0, }, };
int uname_ret = -1;
- utime = time (NULL);
- tm = localtime (&utime);
mypid = getpid ();
uname_ret = uname (&uname_buf);
- /* Which git? What time? */
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
+ utime = time (NULL);
+ gf_time_fmt (timestr, sizeof timestr, utime, gf_timefmt_FT);
fprintf (gf_log_logfile,
"========================================"
"========================================\n");
@@ -84,44 +72,6 @@ _gf_dump_details (int argc, char **argv)
#endif
-static int
-_log_if_option_is_invalid (xlator_t *xl, data_pair_t *pair)
-{
- volume_opt_list_t *vol_opt = NULL;
- volume_option_t *opt = NULL;
- int i = 0;
- int index = 0;
- int found = 0;
-
- /* Get the first volume_option */
- list_for_each_entry (vol_opt, &xl->volume_options, list) {
- /* Warn for extra option */
- if (!vol_opt->given_opt)
- break;
-
- opt = vol_opt->given_opt;
- for (index = 0;
- ((index < ZR_OPTION_MAX_ARRAY_SIZE) &&
- (opt[index].key && opt[index].key[0])); index++)
- for (i = 0; (i < ZR_VOLUME_MAX_NUM_KEY) &&
- opt[index].key[i]; i++) {
- if (fnmatch (opt[index].key[i],
- pair->key,
- FNM_NOESCAPE) == 0) {
- found = 1;
- break;
- }
- }
- }
-
- if (!found) {
- gf_log (xl->name, GF_LOG_WARNING,
- "option '%s' is not recognized",
- pair->key);
- }
- return 0;
-}
-
int
glusterfs_xlator_link (xlator_t *pxl, xlator_t *cxl)
@@ -213,23 +163,37 @@ err:
return -1;
}
-
int
-glusterfs_graph_readonly (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+glusterfs_graph_acl (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
{
int ret = 0;
cmd_args_t *cmd_args = NULL;
cmd_args = &ctx->cmd_args;
- if (!cmd_args->read_only)
+ if (!cmd_args->acl)
return 0;
- ret = glusterfs_graph_insert (graph, ctx, "features/read-only",
- "readonly-autoload");
+ ret = glusterfs_graph_insert (graph, ctx, "system/posix-acl",
+ "posix-acl-autoload");
return ret;
}
+int
+glusterfs_graph_worm (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+{
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
+
+ cmd_args = &ctx->cmd_args;
+
+ if (!cmd_args->worm)
+ return 0;
+
+ ret = glusterfs_graph_insert (graph, ctx, "features/worm",
+ "worm-autoload");
+ return ret;
+}
int
glusterfs_graph_mac_compat (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
@@ -267,7 +231,7 @@ gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args)
cmd_option->key,
cmd_option->value);
if (ret == 0) {
- gf_log (trav->name, GF_LOG_WARNING,
+ gf_log (trav->name, GF_LOG_INFO,
"adding option '%s' for "
"volume '%s' with value '%s'",
cmd_option->key, trav->name,
@@ -289,9 +253,9 @@ gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args)
int
glusterfs_graph_validate_options (glusterfs_graph_t *graph)
{
- volume_opt_list_t *vol_opt = NULL;
xlator_t *trav = NULL;
int ret = -1;
+ char *errstr = NULL;
trav = graph->first;
@@ -299,14 +263,10 @@ glusterfs_graph_validate_options (glusterfs_graph_t *graph)
if (list_empty (&trav->volume_options))
continue;
- vol_opt = list_entry (trav->volume_options.next,
- volume_opt_list_t, list);
-
- ret = validate_xlator_volume_options (trav,
- vol_opt->given_opt);
+ ret = xlator_options_validate (trav, trav->options, &errstr);
if (ret) {
gf_log (trav->name, GF_LOG_ERROR,
- "validating translator failed");
+ "validation failed: %s", errstr);
return ret;
}
trav = trav->next;
@@ -338,24 +298,36 @@ glusterfs_graph_init (glusterfs_graph_t *graph)
}
-int
-glusterfs_graph_unknown_options (glusterfs_graph_t *graph)
+static void
+_log_if_unknown_option (dict_t *dict, char *key, data_t *value, void *data)
{
- data_pair_t *pair = NULL;
- xlator_t *trav = NULL;
+ volume_option_t *found = NULL;
+ xlator_t *xl = NULL;
- trav = graph->first;
+ xl = data;
- /* Validate again phase */
- while (trav) {
- pair = trav->options->members_list;
- while (pair) {
- _log_if_option_is_invalid (trav, pair);
- pair = pair->next;
- }
- trav = trav->next;
+ found = xlator_volume_option_get (xl, key);
+
+ if (!found) {
+ gf_log (xl->name, GF_LOG_WARNING,
+ "option '%s' is not recognized", key);
}
+ return;
+}
+
+
+static void
+_xlator_check_unknown_options (xlator_t *xl, void *data)
+{
+ dict_foreach (xl->options, _log_if_unknown_option, xl);
+}
+
+
+int
+glusterfs_graph_unknown_options (glusterfs_graph_t *graph)
+{
+ xlator_foreach (graph->first, _xlator_check_unknown_options, NULL);
return 0;
}
@@ -365,8 +337,7 @@ fill_uuid (char *uuid, int size)
{
char hostname[256] = {0,};
struct timeval tv = {0,};
- struct tm now = {0, };
- char now_str[32];
+ char now_str[64];
if (gettimeofday (&tv, NULL) == -1) {
gf_log ("graph", GF_LOG_ERROR,
@@ -380,8 +351,7 @@ fill_uuid (char *uuid, int size)
strerror (errno));
}
- localtime_r (&tv.tv_sec, &now);
- strftime (now_str, 32, "%Y/%m/%d-%H:%M:%S", &now);
+ gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T);
snprintf (uuid, size, "%s-%d-%s:%"GF_PRI_SUSECONDS,
hostname, getpid(), now_str, tv.tv_usec);
@@ -451,10 +421,15 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
return -1;
}
- /* XXX: RO VOLUME */
- ret = glusterfs_graph_readonly (graph, ctx);
+ /* XXX: WORM VOLUME */
+ ret = glusterfs_graph_worm (graph, ctx);
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "glusterfs graph worm failed");
+ return -1;
+ }
+ ret = glusterfs_graph_acl (graph, ctx);
if (ret) {
- gf_log ("graph", GF_LOG_ERROR, "glusterfs graph readonly failed");
+ gf_log ("graph", GF_LOG_ERROR, "glusterfs graph ACL failed");
return -1;
}
diff --git a/libglusterfs/src/graph.l b/libglusterfs/src/graph.l
index 08f7d5367..04fff2582 100644
--- a/libglusterfs/src/graph.l
+++ b/libglusterfs/src/graph.l
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/libglusterfs/src/graph.y b/libglusterfs/src/graph.y
index 52e15940a..16ee2d43a 100644
--- a/libglusterfs/src/graph.y
+++ b/libglusterfs/src/graph.y
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -29,6 +29,8 @@
#include <sys/types.h>
#include <sys/wait.h>
+#define RELAX_POISONING
+
#include "xlator.h"
#include "graph-utils.h"
#include "logging.h"
@@ -443,8 +445,6 @@ preprocess (FILE *srcfp, FILE *dstfp)
char in_backtick = 0;
int line = 1;
int column = 0;
- int backtick_line = 0;
- int backtick_column = 0;
int character = 0;
@@ -482,9 +482,6 @@ preprocess (FILE *srcfp, FILE *dstfp)
} else {
i = 0;
cmd[i] = '\0';
-
- backtick_column = column;
- backtick_line = line;
}
in_backtick = !in_backtick;
@@ -577,7 +574,7 @@ glusterfs_graph_construct (FILE *fp)
if (tmp_file == NULL) {
gf_log ("parser", GF_LOG_ERROR,
- "cannot create temparory file");
+ "cannot create temporary file");
glusterfs_graph_destroy (graph);
return NULL;
diff --git a/libglusterfs/src/hashfn.c b/libglusterfs/src/hashfn.c
index b3870712c..f79165b22 100644
--- a/libglusterfs/src/hashfn.c
+++ b/libglusterfs/src/hashfn.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <stdint.h>
diff --git a/libglusterfs/src/hashfn.h b/libglusterfs/src/hashfn.h
index 65b1b447f..06ae37e79 100644
--- a/libglusterfs/src/hashfn.h
+++ b/libglusterfs/src/hashfn.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __HASHFN_H__
diff --git a/libglusterfs/src/iatt.h b/libglusterfs/src/iatt.h
index ce4cc495d..60ae59047 100644
--- a/libglusterfs/src/iatt.h
+++ b/libglusterfs/src/iatt.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -103,6 +94,8 @@ struct iatt {
#define IA_PROT_SGID(prot) ((prot).sgid == 1)
#define IA_PROT_STCKY(prot) ((prot).sticky == 1)
+#define IA_FILE_OR_DIR(t) (IA_ISREG(t) || IA_ISDIR(t))
+
static inline uint32_t
ia_major (uint64_t ia_dev)
{
@@ -272,6 +265,24 @@ iatt_from_stat (struct iatt *iatt, struct stat *stat)
iatt->ia_blksize = stat->st_blksize;
iatt->ia_blocks = stat->st_blocks;
+ /* There is a possibility that the backend FS (like XFS) can
+ allocate blocks beyond EOF for better performance reasons, which
+ results in 'st_blocks' with higher values than what is consumed by
+ the file descriptor. This would break few logic inside GlusterFS,
+ like quota behavior etc, thus we need the exact number of blocks
+ which are consumed by the file to the higher layers inside GlusterFS.
+ Currently, this logic won't work for sparse files (ie, file with
+ holes)
+ */
+ {
+ uint64_t maxblocks;
+
+ maxblocks = (iatt->ia_size + 511) / 512;
+
+ if (iatt->ia_blocks > maxblocks)
+ iatt->ia_blocks = maxblocks;
+ }
+
iatt->ia_atime = stat->st_atime;
iatt->ia_atime_nsec = ST_ATIM_NSEC (stat);
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index d81fa6183..e32eddb5d 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -94,7 +85,7 @@ __dentry_hash (dentry_t *dentry)
int hash = 0;
if (!dentry) {
- gf_log_callingfn ("", GF_LOG_WARNING, "dentry not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return;
}
@@ -111,7 +102,7 @@ static int
__is_dentry_hashed (dentry_t *dentry)
{
if (!dentry) {
- gf_log_callingfn ("", GF_LOG_WARNING, "dentry not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return 0;
}
@@ -123,7 +114,7 @@ static void
__dentry_unhash (dentry_t *dentry)
{
if (!dentry) {
- gf_log_callingfn ("", GF_LOG_WARNING, "dentry not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return;
}
@@ -134,14 +125,11 @@ __dentry_unhash (dentry_t *dentry)
static void
__dentry_unset (dentry_t *dentry)
{
- struct mem_pool *tmp_pool = NULL;
-
if (!dentry) {
- gf_log_callingfn ("", GF_LOG_WARNING, "dentry not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return;
}
- tmp_pool = dentry->inode->table->dentry_pool;
__dentry_unhash (dentry);
list_del_init (&dentry->inode_list);
@@ -154,9 +142,7 @@ __dentry_unset (dentry_t *dentry)
dentry->parent = NULL;
}
- mem_put (tmp_pool, dentry);
- tmp_pool = NULL;
-
+ mem_put (dentry);
}
@@ -171,19 +157,19 @@ __foreach_ancestor_dentry (dentry_t *dentry,
int ret = 0;
if (!dentry) {
- gf_log_callingfn ("", GF_LOG_WARNING, "dentry not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return 0;
}
ret = per_dentry_fn (dentry, data);
if (ret) {
- gf_log ("", GF_LOG_WARNING, "per dentry fn returned %d", ret);
+ gf_log (THIS->name, GF_LOG_WARNING, "per dentry fn returned %d", ret);
goto out;
}
parent = dentry->parent;
if (!parent) {
- gf_log ("", GF_LOG_WARNING, "parent not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "parent not found");
goto out;
}
@@ -228,8 +214,8 @@ __is_dentry_cyclic (dentry_t *dentry)
gf_log (dentry->inode->table->name, GF_LOG_CRITICAL,
"detected cyclic loop formation during inode linkage."
- " inode (%"PRId64"/%s) linking under itself as %s",
- inode->ino, uuid_utoa (inode->gfid), name);
+ " inode (%s) linking under itself as %s",
+ uuid_utoa (inode->gfid), name);
}
return ret;
@@ -240,7 +226,7 @@ static void
__inode_unhash (inode_t *inode)
{
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
}
@@ -252,7 +238,7 @@ static int
__is_inode_hashed (inode_t *inode)
{
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return 0;
}
@@ -267,7 +253,7 @@ __inode_hash (inode_t *inode)
int hash = 0;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
}
@@ -280,18 +266,25 @@ __inode_hash (inode_t *inode)
static dentry_t *
-__dentry_search_for_inode (inode_t *inode, ino_t par, const char *name)
+__dentry_search_for_inode (inode_t *inode, uuid_t pargfid, const char *name)
{
dentry_t *dentry = NULL;
dentry_t *tmp = NULL;
if (!inode || !name) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode || name not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode || name not found");
return NULL;
}
+ /* earlier, just the ino was sent, which could have been 0, now
+ we deal with gfid, and if sent gfid is null or 0, no need to
+ continue with the check */
+ if (!pargfid || uuid_is_null (pargfid))
+ return NULL;
+
list_for_each_entry (tmp, &inode->dentry_list, inode_list) {
- if (tmp->parent->ino == par && !strcmp (tmp->name, name)) {
+ if ((uuid_compare (tmp->parent->gfid, pargfid) == 0) &&
+ !strcmp (tmp->name, name)) {
dentry = tmp;
break;
}
@@ -307,20 +300,17 @@ __inode_destroy (inode_t *inode)
int index = 0;
xlator_t *xl = NULL;
xlator_t *old_THIS = NULL;
- struct mem_pool *tmp_pool = NULL;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
}
if (!inode->_ctx) {
- gf_log ("", GF_LOG_WARNING, "_ctx not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "_ctx not found");
goto noctx;
}
- tmp_pool = inode->table->inode_pool;
-
for (index = 0; index < inode->table->xl->graph->xl_count; index++) {
if (inode->_ctx[index].xl_key) {
xl = (xlator_t *)(long)inode->_ctx[index].xl_key;
@@ -336,9 +326,7 @@ __inode_destroy (inode_t *inode)
noctx:
LOCK_DESTROY (&inode->lock);
// memset (inode, 0xb, sizeof (*inode));
- mem_put (tmp_pool, inode);
- tmp_pool = NULL;
-
+ mem_put (inode);
}
@@ -360,7 +348,7 @@ __inode_passivate (inode_t *inode)
dentry_t *t = NULL;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
}
@@ -381,7 +369,7 @@ __inode_retire (inode_t *inode)
dentry_t *t = NULL;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
}
@@ -402,7 +390,7 @@ __inode_unref (inode_t *inode)
if (!inode)
return NULL;
- if (inode->ino == 1)
+ if (__is_root_gfid(inode->gfid))
return inode;
GF_ASSERT (inode->ref);
@@ -486,7 +474,7 @@ __dentry_create (inode_t *inode, inode_t *parent, const char *name)
dentry_t *newd = NULL;
if (!inode || !parent || !name) {
- gf_log_callingfn ("", GF_LOG_WARNING,
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
"inode || parent || name not found");
return NULL;
}
@@ -501,7 +489,7 @@ __dentry_create (inode_t *inode, inode_t *parent, const char *name)
newd->name = gf_strdup (name);
if (newd->name == NULL) {
- mem_put (parent->table->dentry_pool, newd);
+ mem_put (newd);
newd = NULL;
goto out;
}
@@ -523,7 +511,7 @@ __inode_create (inode_table_t *table)
inode_t *newi = NULL;
if (!table) {
- gf_log_callingfn ("", GF_LOG_WARNING, "table not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "table not found");
return NULL;
}
@@ -547,7 +535,7 @@ __inode_create (inode_table_t *table)
if (newi->_ctx == NULL) {
LOCK_DESTROY (&newi->lock);
- mem_put (table->inode_pool, newi);
+ mem_put (newi);
newi = NULL;
goto out;
}
@@ -567,7 +555,7 @@ inode_new (inode_table_t *table)
inode_t *inode = NULL;
if (!table) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return NULL;
}
@@ -643,7 +631,7 @@ inode_grep (inode_table_t *table, inode_t *parent, const char *name)
dentry_t *dentry = NULL;
if (!table || !parent || !name) {
- gf_log_callingfn ("", GF_LOG_WARNING,
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
"table || parent || name not found");
return NULL;
}
@@ -665,24 +653,94 @@ inode_grep (inode_table_t *table, inode_t *parent, const char *name)
inode_t *
-inode_get (inode_table_t *table, ino_t ino, uint64_t gen)
+inode_resolve (inode_table_t *table, char *path)
{
- return NULL;
+ char *tmp = NULL, *bname = NULL, *str = NULL, *saveptr = NULL;
+ inode_t *inode = NULL, *parent = NULL;
+
+ if ((path == NULL) || (table == NULL)) {
+ goto out;
+ }
+
+ parent = inode_ref (table->root);
+ str = tmp = gf_strdup (path);
+
+ while (1) {
+ bname = strtok_r (str, "/", &saveptr);
+ if (bname == NULL) {
+ break;
+ }
+
+ if (inode != NULL) {
+ inode_unref (inode);
+ }
+
+ inode = inode_grep (table, parent, bname);
+ if (inode == NULL) {
+ break;
+ }
+
+ if (parent != NULL) {
+ inode_unref (parent);
+ }
+
+ parent = inode_ref (inode);
+ str = NULL;
+ }
+
+ inode_unref (parent);
+ GF_FREE (tmp);
+out:
+ return inode;
}
int
+inode_grep_for_gfid (inode_table_t *table, inode_t *parent, const char *name,
+ uuid_t gfid, ia_type_t *type)
+{
+ inode_t *inode = NULL;
+ dentry_t *dentry = NULL;
+ int ret = -1;
+
+ if (!table || !parent || !name) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "table || parent || name not found");
+ return ret;
+ }
+
+ pthread_mutex_lock (&table->lock);
+ {
+ dentry = __dentry_grep (table, parent, name);
+
+ if (dentry)
+ inode = dentry->inode;
+
+ if (inode) {
+ uuid_copy (gfid, inode->gfid);
+ *type = inode->ia_type;
+ ret = 0;
+ }
+ }
+ pthread_mutex_unlock (&table->lock);
+
+ return ret;
+}
+
+
+/* return 1 if gfid is of root, 0 if not */
+gf_boolean_t
__is_root_gfid (uuid_t gfid)
{
uuid_t root;
- int ret;
memset (root, 0, 16);
root[15] = 1;
- ret = uuid_compare (gfid, root);
+ if (uuid_compare (gfid, root) == 0)
+ return _gf_true;
- return ret;
+ return _gf_false;
}
@@ -694,11 +752,11 @@ __inode_find (inode_table_t *table, uuid_t gfid)
int hash = 0;
if (!table) {
- gf_log_callingfn ("", GF_LOG_WARNING, "table not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "table not found");
goto out;
}
- if (__is_root_gfid (gfid) == 0)
+ if (__is_root_gfid (gfid))
return table->root;
hash = hash_gfid (gfid, 65536);
@@ -721,7 +779,7 @@ inode_find (inode_table_t *table, uuid_t gfid)
inode_t *inode = NULL;
if (!table) {
- gf_log_callingfn ("", GF_LOG_WARNING, "table not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "table not found");
return NULL;
}
@@ -754,6 +812,15 @@ __inode_link (inode_t *inode, inode_t *parent, const char *name,
if (!table)
return NULL;
+ if (parent) {
+ /* We should prevent inode linking between different
+ inode tables. This can cause errors which is very
+ hard to catch/debug. */
+ if (inode->table != parent->table) {
+ GF_ASSERT (!"link attempted b/w inodes of diff table");
+ }
+ }
+
link_inode = inode;
if (!__is_inode_hashed (inode)) {
@@ -764,7 +831,6 @@ __inode_link (inode_t *inode, inode_t *parent, const char *name,
return NULL;
uuid_copy (inode->gfid, iatt->ia_gfid);
- inode->ino = iatt->ia_ino;
inode->ia_type = iatt->ia_type;
old_inode = __inode_find (table, inode->gfid);
@@ -776,12 +842,25 @@ __inode_link (inode_t *inode, inode_t *parent, const char *name,
}
}
+ if (name) {
+ if (!strcmp(name, ".") || !strcmp(name, ".."))
+ return link_inode;
+ }
+
/* use only link_inode beyond this point */
if (parent) {
old_dentry = __dentry_grep (table, parent, name);
if (!old_dentry || old_dentry->inode != link_inode) {
dentry = __dentry_create (link_inode, parent, name);
+ if (!dentry) {
+ gf_log_callingfn (THIS->name, GF_LOG_ERROR,
+ "dentry create failed on "
+ "inode %s with parent %s",
+ uuid_utoa (link_inode->gfid),
+ uuid_utoa (parent->gfid));
+ return NULL;
+ }
if (old_inode && __is_dentry_cyclic (dentry)) {
__dentry_unset (dentry);
return NULL;
@@ -805,7 +884,7 @@ inode_link (inode_t *inode, inode_t *parent, const char *name,
inode_t *linked_inode = NULL;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return NULL;
}
@@ -832,7 +911,7 @@ inode_lookup (inode_t *inode)
inode_table_t *table = NULL;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return -1;
}
@@ -854,7 +933,7 @@ inode_forget (inode_t *inode, uint64_t nlookup)
inode_table_t *table = NULL;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return -1;
}
@@ -880,7 +959,7 @@ __inode_unlink (inode_t *inode, inode_t *parent, const char *name)
if (!inode || !parent || !name)
return;
- dentry = __dentry_search_for_inode (inode, parent->ino, name);
+ dentry = __dentry_search_for_inode (inode, parent->gfid, name);
/* dentry NULL for corrupted backend */
if (dentry)
@@ -894,7 +973,7 @@ inode_unlink (inode_t *inode, inode_t *parent, const char *name)
inode_table_t *table = NULL;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
}
@@ -916,7 +995,7 @@ inode_rename (inode_table_t *table, inode_t *srcdir, const char *srcname,
struct iatt *iatt)
{
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return -1;
}
@@ -963,14 +1042,14 @@ __dentry_search_arbit (inode_t *inode)
inode_t *
-inode_parent (inode_t *inode, ino_t par, const char *name)
+inode_parent (inode_t *inode, uuid_t pargfid, const char *name)
{
inode_t *parent = NULL;
inode_table_t *table = NULL;
dentry_t *dentry = NULL;
if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return NULL;
}
@@ -978,8 +1057,8 @@ inode_parent (inode_t *inode, ino_t par, const char *name)
pthread_mutex_lock (&table->lock);
{
- if (par && name) {
- dentry = __dentry_search_for_inode (inode, par, name);
+ if (pargfid && !uuid_is_null (pargfid) && name) {
+ dentry = __dentry_search_for_inode (inode, pargfid, name);
} else {
dentry = __dentry_search_arbit (inode);
}
@@ -997,81 +1076,86 @@ inode_parent (inode_t *inode, ino_t par, const char *name)
int
-inode_path (inode_t *inode, const char *name, char **bufp)
+__inode_path (inode_t *inode, const char *name, char **bufp)
{
inode_table_t *table = NULL;
- dentry_t *trav = NULL;
- size_t i = 0, size = 0;
- int64_t ret = 0;
- int len = 0;
- char *buf = NULL;
-
- if (!inode) {
- gf_log_callingfn ("", GF_LOG_WARNING, "inode not found");
+ inode_t *itrav = NULL;
+ dentry_t *trav = NULL;
+ size_t i = 0, size = 0;
+ int64_t ret = 0;
+ int len = 0;
+ char *buf = NULL;
+
+ if (!inode || uuid_is_null (inode->gfid)) {
+ GF_ASSERT (0);
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "invalid inode");
return -1;
}
table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- for (trav = __dentry_search_arbit (inode); trav;
- trav = __dentry_search_arbit (trav->parent)) {
- i ++; /* "/" */
- i += strlen (trav->name);
- if (i > PATH_MAX) {
- gf_log (table->name, GF_LOG_CRITICAL,
- "possible infinite loop detected, "
- "forcing break. name=(%s)", name);
- ret = -ENOENT;
- goto unlock;
- }
- }
-
- if ((inode->ino != 1) &&
- (i == 0)) {
- gf_log (table->name, GF_LOG_WARNING,
- "no dentry for non-root inode %"PRId64": %s",
- inode->ino, uuid_utoa (inode->gfid));
+ itrav = inode;
+ for (trav = __dentry_search_arbit (itrav); trav;
+ trav = __dentry_search_arbit (itrav)) {
+ itrav = trav->parent;
+ i ++; /* "/" */
+ i += strlen (trav->name);
+ if (i > PATH_MAX) {
+ gf_log (table->name, GF_LOG_CRITICAL,
+ "possible infinite loop detected, "
+ "forcing break. name=(%s)", name);
ret = -ENOENT;
- goto unlock;
+ goto out;
}
+ }
- if (name) {
- i++;
- i += strlen (name);
- }
+ if (!__is_root_gfid (itrav->gfid)) {
+ /* "<gfid:00000000-0000-0000-0000-000000000000>"/path */
+ i += GFID_STR_PFX_LEN;
+ }
- ret = i;
- size = i + 1;
- buf = GF_CALLOC (size, sizeof (char), gf_common_mt_char);
- if (buf) {
+ if (name) {
+ i++;
+ i += strlen (name);
+ }
- buf[size - 1] = 0;
+ ret = i;
+ size = i + 1;
+ buf = GF_CALLOC (size, sizeof (char), gf_common_mt_char);
+ if (buf) {
- if (name) {
- len = strlen (name);
- strncpy (buf + (i - len), name, len);
- buf[i-len-1] = '/';
- i -= (len + 1);
- }
+ buf[size - 1] = 0;
- for (trav = __dentry_search_arbit (inode); trav;
- trav = __dentry_search_arbit (trav->parent)) {
- len = strlen (trav->name);
- strncpy (buf + (i - len), trav->name, len);
- buf[i-len-1] = '/';
- i -= (len + 1);
- }
- *bufp = buf;
- } else {
- ret = -ENOMEM;
+ if (name) {
+ len = strlen (name);
+ strncpy (buf + (i - len), name, len);
+ buf[i-len-1] = '/';
+ i -= (len + 1);
}
+
+ itrav = inode;
+ for (trav = __dentry_search_arbit (itrav); trav;
+ trav = __dentry_search_arbit (itrav)) {
+ itrav = trav->parent;
+ len = strlen (trav->name);
+ strncpy (buf + (i - len), trav->name, len);
+ buf[i-len-1] = '/';
+ i -= (len + 1);
+ }
+
+ if (!__is_root_gfid (itrav->gfid)) {
+ snprintf (&buf[i-GFID_STR_PFX_LEN], GFID_STR_PFX_LEN,
+ INODE_PATH_FMT, uuid_utoa (itrav->gfid));
+ buf[i-1] = '>';
+ }
+
+ *bufp = buf;
+ } else {
+ ret = -ENOMEM;
}
-unlock:
- pthread_mutex_unlock (&table->lock);
- if (inode->ino == 1 && !name) {
+out:
+ if (__is_root_gfid (inode->gfid) && !name) {
ret = 1;
if (buf) {
GF_FREE (buf);
@@ -1085,9 +1169,33 @@ unlock:
}
}
+ if (ret < 0)
+ *bufp = NULL;
return ret;
}
+
+int
+inode_path (inode_t *inode, const char *name, char **bufp)
+{
+ inode_table_t *table = NULL;
+ int ret = -1;
+
+ if (!inode)
+ return -1;
+
+ table = inode->table;
+
+ pthread_mutex_lock (&table->lock);
+ {
+ ret = __inode_path (inode, name, bufp);
+ }
+ pthread_mutex_unlock (&table->lock);
+
+ return ret;
+}
+
+
static int
inode_table_prune (inode_table_t *table)
{
@@ -1156,7 +1264,7 @@ inode_table_t *
inode_table_new (size_t lru_limit, xlator_t *xl)
{
inode_table_t *new = NULL;
- int ret = 0;
+ int ret = -1;
int i = 0;
new = (void *)GF_CALLOC(1, sizeof (*new), gf_common_mt_inode_table_t);
@@ -1175,41 +1283,32 @@ inode_table_new (size_t lru_limit, xlator_t *xl)
new->inode_pool = mem_pool_new (inode_t, lru_limit);
- if (!new->inode_pool) {
- GF_FREE (new);
- return NULL;
- }
+ if (!new->inode_pool)
+ goto out;
new->dentry_pool = mem_pool_new (dentry_t, lru_limit);
- if (!new->dentry_pool) {
- GF_FREE (new);
- return NULL;
- }
+ if (!new->dentry_pool)
+ goto out;
new->inode_hash = (void *)GF_CALLOC (65536,
sizeof (struct list_head),
gf_common_mt_list_head);
- if (!new->inode_hash) {
- GF_FREE (new);
- return NULL;
- }
+ if (!new->inode_hash)
+ goto out;
new->name_hash = (void *)GF_CALLOC (new->hashsize,
sizeof (struct list_head),
gf_common_mt_list_head);
- if (!new->name_hash) {
- GF_FREE (new->inode_hash);
- GF_FREE (new);
- return NULL;
- }
+ if (!new->name_hash)
+ goto out;
- new->fd_mem_pool = mem_pool_new (fd_t, 16384);
+ /* if number of fd open in one process is more than this,
+ we may hit perf issues */
+ new->fd_mem_pool = mem_pool_new (fd_t, 1024);
- if (!new->fd_mem_pool) {
- GF_FREE (new->inode_hash);
- GF_FREE (new);
- }
+ if (!new->fd_mem_pool)
+ goto out;
for (i = 0; i < 65536; i++) {
INIT_LIST_HEAD (&new->inode_hash[i]);
@@ -1234,6 +1333,23 @@ inode_table_new (size_t lru_limit, xlator_t *xl)
pthread_mutex_init (&new->lock, NULL);
+ ret = 0;
+out:
+ if (ret) {
+ if (new) {
+ if (new->inode_hash)
+ GF_FREE (new->inode_hash);
+ if (new->name_hash)
+ GF_FREE (new->name_hash);
+ if (new->dentry_pool)
+ mem_pool_destroy (new->dentry_pool);
+ if (new->inode_pool)
+ mem_pool_destroy (new->inode_pool);
+ GF_FREE (new);
+ new = NULL;
+ }
+ }
+
return new;
}
@@ -1299,45 +1415,47 @@ out:
int
-__inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2)
+__inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
{
int ret = 0;
int index = 0;
- int put_idx = -1;
+ int set_idx = -1;
if (!inode || !xlator)
return -1;
for (index = 0; index < xlator->graph->xl_count; index++) {
if (!inode->_ctx[index].xl_key) {
- if (put_idx == -1)
- put_idx = index;
+ if (set_idx == -1)
+ set_idx = index;
/* dont break, to check if key already exists
further on */
}
if (inode->_ctx[index].xl_key == xlator) {
- put_idx = index;
+ set_idx = index;
break;
}
}
- if (put_idx == -1) {
+ if (set_idx == -1) {
ret = -1;
goto out;;
}
- inode->_ctx[put_idx].xl_key = xlator;
- inode->_ctx[put_idx].value1 = value1;
- inode->_ctx[put_idx].value2 = value2;
+ inode->_ctx[set_idx].xl_key = xlator;
+ if (value1_p)
+ inode->_ctx[set_idx].value1 = *value1_p;
+ if (value2_p)
+ inode->_ctx[set_idx].value2 = *value2_p;
out:
return ret;
}
int
-inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2)
+inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
{
int ret = 0;
@@ -1346,7 +1464,7 @@ inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
LOCK (&inode->lock);
{
- ret = __inode_ctx_put2 (inode, xlator, value1, value2);
+ ret = __inode_ctx_set2 (inode, xlator, value1_p, value2_p);
}
UNLOCK (&inode->lock);
@@ -1442,54 +1560,14 @@ unlock:
}
-int
-__inode_ctx_put (inode_t *inode, xlator_t *key, uint64_t value)
-{
- return __inode_ctx_put2 (inode, key, value, 0);
-}
-
-
-int
-inode_ctx_put (inode_t *inode, xlator_t *key, uint64_t value)
-{
- return inode_ctx_put2 (inode, key, value, 0);
-}
-
-
-int
-__inode_ctx_get (inode_t *inode, xlator_t *key, uint64_t *value)
-{
- return __inode_ctx_get2 (inode, key, value, 0);
-}
-
-
-int
-inode_ctx_get (inode_t *inode, xlator_t *key, uint64_t *value)
-{
- return inode_ctx_get2 (inode, key, value, 0);
-}
-
-
-int
-inode_ctx_del (inode_t *inode, xlator_t *key, uint64_t *value)
-{
- return inode_ctx_del2 (inode, key, value, 0);
-}
-
-
void
inode_dump (inode_t *inode, char *prefix)
{
- char key[GF_DUMP_MAX_BUF_LEN];
int ret = -1;
xlator_t *xl = NULL;
int i = 0;
fd_t *fd = NULL;
struct _inode_ctx *inode_ctx = NULL;
- struct fd_wrapper {
- fd_t *fd;
- struct list_head next;
- } *fd_wrapper, *tmp;
struct list_head fd_list;
if (!inode)
@@ -1498,24 +1576,15 @@ inode_dump (inode_t *inode, char *prefix)
INIT_LIST_HEAD (&fd_list);
ret = TRY_LOCK(&inode->lock);
-
if (ret != 0) {
- gf_log ("", GF_LOG_WARNING, "Unable to dump inode"
- " errno: %s", strerror (errno));
return;
}
{
- gf_proc_dump_build_key(key, prefix, "gfid");
- gf_proc_dump_write(key, "%s", uuid_utoa (inode->gfid));
- gf_proc_dump_build_key(key, prefix, "nlookup");
- gf_proc_dump_write(key, "%ld", inode->nlookup);
- gf_proc_dump_build_key(key, prefix, "ref");
- gf_proc_dump_write(key, "%u", inode->ref);
- gf_proc_dump_build_key(key, prefix, "ino");
- gf_proc_dump_write(key, "%ld", inode->ino);
- gf_proc_dump_build_key(key, prefix, "ia_type");
- gf_proc_dump_write(key, "%d", inode->ia_type);
+ gf_proc_dump_write("gfid", "%s", uuid_utoa (inode->gfid));
+ gf_proc_dump_write("nlookup", "%ld", inode->nlookup);
+ gf_proc_dump_write("ref", "%u", inode->ref);
+ gf_proc_dump_write("ia_type", "%d", inode->ia_type);
if (inode->_ctx) {
inode_ctx = GF_CALLOC (inode->table->xl->graph->xl_count,
sizeof (*inode_ctx),
@@ -1529,21 +1598,12 @@ inode_dump (inode_t *inode, char *prefix)
}
}
- if (list_empty (&inode->fd_list)) {
- goto unlock;
- }
-
- list_for_each_entry (fd, &inode->fd_list, inode_list) {
- fd_wrapper = GF_CALLOC (1, sizeof (*fd_wrapper),
- gf_common_mt_char);
- if (fd_wrapper == NULL) {
- goto unlock;
- }
+ if (dump_options.xl_options.dump_fdctx != _gf_true)
+ goto unlock;
- INIT_LIST_HEAD (&fd_wrapper->next);
- list_add_tail (&fd_wrapper->next, &fd_list);
- fd_wrapper->fd = _fd_ref (fd);
+ list_for_each_entry (fd, &inode->fd_list, inode_list) {
+ fd_ctx_dump (fd, prefix);
}
}
unlock:
@@ -1559,18 +1619,6 @@ unlock:
}
}
- if (!list_empty (&fd_list)
- && (dump_options.xl_options.dump_fdctx == _gf_true)) {
- list_for_each_entry_safe (fd_wrapper, tmp, &fd_list,
- next) {
- list_del (&fd_wrapper->next);
- fd_ctx_dump (fd_wrapper->fd, prefix);
-
- fd_unref (fd_wrapper->fd);
- GF_FREE (fd_wrapper);
- }
- }
-
if (inode_ctx != NULL) {
GF_FREE (inode_ctx);
}
@@ -1592,8 +1640,6 @@ inode_table_dump (inode_table_t *itable, char *prefix)
ret = pthread_mutex_trylock(&itable->lock);
if (ret != 0) {
- gf_log("", GF_LOG_WARNING, "Unable to dump inode table"
- " errno: %s", strerror (errno));
return;
}
@@ -1617,3 +1663,99 @@ inode_table_dump (inode_table_t *itable, char *prefix)
pthread_mutex_unlock(&itable->lock);
}
+
+void
+inode_dump_to_dict (inode_t *inode, char *prefix, dict_t *dict)
+{
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+
+ ret = TRY_LOCK (&inode->lock);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.gfid", prefix);
+ ret = dict_set_dynstr (dict, key, gf_strdup (uuid_utoa (inode->gfid)));
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.nlookup", prefix);
+ ret = dict_set_uint64 (dict, key, inode->nlookup);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.ref", prefix);
+ ret = dict_set_uint32 (dict, key, inode->ref);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.ia_type", prefix);
+ ret = dict_set_int32 (dict, key, inode->ia_type);
+
+out:
+ UNLOCK (&inode->lock);
+ return;
+}
+
+void
+inode_table_dump_to_dict (inode_table_t *itable, char *prefix, dict_t *dict)
+{
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int ret = 0;
+ inode_t *inode = NULL;
+ int count = 0;
+
+ ret = pthread_mutex_trylock (&itable->lock);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.active_size", prefix);
+ ret = dict_set_uint32 (dict, key, itable->active_size);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.lru_size", prefix);
+ ret = dict_set_uint32 (dict, key, itable->lru_size);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.purge_size", prefix);
+ ret = dict_set_uint32 (dict, key, itable->purge_size);
+ if (ret)
+ goto out;
+
+ list_for_each_entry (inode, &itable->active, list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.active%d", prefix,
+ count++);
+ inode_dump_to_dict (inode, key, dict);
+ }
+ count = 0;
+
+ list_for_each_entry (inode, &itable->lru, list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.lru%d", prefix,
+ count++);
+ inode_dump_to_dict (inode, key, dict);
+ }
+ count = 0;
+
+ list_for_each_entry (inode, &itable->purge, list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.purge%d", prefix,
+ count++);
+ inode_dump_to_dict (inode, key, dict);
+ }
+
+out:
+ pthread_mutex_unlock (&itable->lock);
+
+ return;
+}
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
index 375ff3ee4..41003df71 100644
--- a/libglusterfs/src/inode.h
+++ b/libglusterfs/src/inode.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _INODE_H
@@ -28,7 +19,8 @@
#include <stdint.h>
#include <sys/types.h>
-#define DEFAULT_INODE_MEMPOOL_ENTRIES 16384
+#define DEFAULT_INODE_MEMPOOL_ENTRIES 32 * 1024
+#define INODE_PATH_FMT "<gfid:%s>"
struct _inode_table;
typedef struct _inode_table inode_table_t;
@@ -96,7 +88,6 @@ struct _inode {
gf_lock_t lock;
uint64_t nlookup;
uint32_t ref; /* reference count on this inode */
- ino_t ino; /* inode number in the storage (persistent) */
ia_type_t ia_type; /* what kind of file */
struct list_head fd_list; /* list of open files on this inode */
struct list_head dentry_list; /* list of directory entries for this inode */
@@ -107,6 +98,10 @@ struct _inode {
};
+#define UUID0_STR "00000000-0000-0000-0000-000000000000"
+#define GFID_STR_PFX "<gfid:" UUID0_STR ">"
+#define GFID_STR_PFX_LEN (sizeof (GFID_STR_PFX) - 1)
+
inode_table_t *
inode_table_new (size_t lru_limit, xlator_t *xl);
@@ -121,7 +116,7 @@ void
inode_unlink (inode_t *inode, inode_t *parent, const char *name);
inode_t *
-inode_parent (inode_t *inode, ino_t par, const char *name);
+inode_parent (inode_t *inode, uuid_t pargfid, const char *name);
inode_t *
inode_ref (inode_t *inode);
@@ -143,8 +138,9 @@ inode_rename (inode_table_t *table, inode_t *olddir, const char *oldname,
inode_t *
inode_grep (inode_table_t *table, inode_t *parent, const char *name);
-inode_t *
-inode_get (inode_table_t *table, ino_t ino, uint64_t gen);
+int
+inode_grep_for_gfid (inode_table_t *table, inode_t *parent, const char *name,
+ uuid_t gfid, ia_type_t *type);
inode_t *
inode_find (inode_table_t *table, uuid_t gfid);
@@ -152,36 +148,55 @@ inode_find (inode_table_t *table, uuid_t gfid);
int
inode_path (inode_t *inode, const char *name, char **bufp);
-inode_t *
-inode_from_path (inode_table_t *table, const char *path);
-
int
-__inode_ctx_put (inode_t *inode, xlator_t *xlator, uint64_t value);
+__inode_path (inode_t *inode, const char *name, char **bufp);
-int
-inode_ctx_put (inode_t *inode, xlator_t *xlator, uint64_t value);
-
-int
-__inode_ctx_get (inode_t *inode, xlator_t *xlator, uint64_t *value);
-
-int
-inode_ctx_get (inode_t *inode, xlator_t *xlator, uint64_t *value);
+inode_t *
+inode_from_path (inode_table_t *table, const char *path);
int
-inode_ctx_del (inode_t *inode, xlator_t *xlator, uint64_t *value);
-
+inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
-inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2);
+__inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2);
+int
+__inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2);
-int
+inode_t *
+inode_resolve (inode_table_t *table, char *path);
+
+#define __inode_ctx_set(i,x,v_p) __inode_ctx_set2(i,x,v_p,0)
+#define inode_ctx_set(i,x,v_p) inode_ctx_set2(i,x,v_p,0)
+
+static inline int
+__inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
+{
+ return __inode_ctx_set2 (inode, this, &v, 0);
+}
+
+static inline int
+inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
+{
+ return inode_ctx_set2(inode, this, &v, 0);
+}
+
+#define __inode_ctx_get(i,x,v) __inode_ctx_get2(i,x,v,0)
+#define inode_ctx_get(i,x,v) inode_ctx_get2(i,x,v,0)
+
+#define inode_ctx_del(i,x,v) inode_ctx_del2(i,x,v,0)
+
+
+gf_boolean_t
__is_root_gfid (uuid_t gfid);
+
#endif /* _INODE_H */
diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c
index c5cb9ec66..f68c6c748 100644
--- a/libglusterfs/src/iobuf.c
+++ b/libglusterfs/src/iobuf.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -27,11 +18,59 @@
TODO: implement destroy margins and prefetching of arenas
*/
+#define IOBUF_ARENA_MAX_INDEX (sizeof (gf_iobuf_init_config) / \
+ (sizeof (struct iobuf_init_config)))
+
+/* Make sure this array is sorted based on pagesize */
+struct iobuf_init_config gf_iobuf_init_config[] = {
+ /* { pagesize, num_pages }, */
+ {128, 1024},
+ {512, 512},
+ {2 * 1024, 512},
+ {8 * 1024, 128},
+ {32 * 1024, 64},
+ {128 * 1024, 32},
+ {256 * 1024, 8},
+ {1 * 1024 * 1024, 2},
+};
+
+int
+gf_iobuf_get_arena_index (size_t page_size)
+{
+ int i = -1;
+
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ if (page_size <= gf_iobuf_init_config[i].pagesize)
+ break;
+ }
+
+ if (i >= IOBUF_ARENA_MAX_INDEX)
+ i = -1;
+
+ return i;
+}
+
+size_t
+gf_iobuf_get_pagesize (size_t page_size)
+{
+ int i = 0;
+ size_t size = 0;
+
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ size = gf_iobuf_init_config[i].pagesize;
+ if (page_size <= size)
+ break;
+ }
+
+ if (i >= IOBUF_ARENA_MAX_INDEX)
+ size = -1;
+
+ return size;
+}
+
void
__iobuf_arena_init_iobufs (struct iobuf_arena *iobuf_arena)
{
- size_t arena_size = 0;
- size_t page_size = 0;
int iobuf_cnt = 0;
struct iobuf *iobuf = NULL;
int offset = 0;
@@ -39,9 +78,7 @@ __iobuf_arena_init_iobufs (struct iobuf_arena *iobuf_arena)
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
- arena_size = iobuf_arena->iobuf_pool->arena_size;
- page_size = iobuf_arena->iobuf_pool->page_size;
- iobuf_cnt = arena_size / page_size;
+ iobuf_cnt = iobuf_arena->page_count;
iobuf_arena->iobufs = GF_CALLOC (sizeof (*iobuf), iobuf_cnt,
gf_common_mt_iobuf);
@@ -60,7 +97,7 @@ __iobuf_arena_init_iobufs (struct iobuf_arena *iobuf_arena)
list_add (&iobuf->list, &iobuf_arena->passive.list);
iobuf_arena->passive_cnt++;
- offset += page_size;
+ offset += iobuf_arena->page_size;
iobuf++;
}
@@ -72,20 +109,16 @@ out:
void
__iobuf_arena_destroy_iobufs (struct iobuf_arena *iobuf_arena)
{
- size_t arena_size = 0;
- size_t page_size = 0;
int iobuf_cnt = 0;
struct iobuf *iobuf = NULL;
int i = 0;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
- arena_size = iobuf_arena->iobuf_pool->arena_size;
- page_size = iobuf_arena->iobuf_pool->page_size;
- iobuf_cnt = arena_size / page_size;
+ iobuf_cnt = iobuf_arena->page_count;
if (!iobuf_arena->iobufs) {
- gf_log_callingfn ("", GF_LOG_DEBUG, "iobufs not found");
+ gf_log_callingfn (THIS->name, GF_LOG_ERROR, "iobufs not found");
return;
}
@@ -107,30 +140,26 @@ out:
void
__iobuf_arena_destroy (struct iobuf_arena *iobuf_arena)
{
- struct iobuf_pool *iobuf_pool = NULL;
-
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
- iobuf_pool = iobuf_arena->iobuf_pool;
-
__iobuf_arena_destroy_iobufs (iobuf_arena);
if (iobuf_arena->mem_base
&& iobuf_arena->mem_base != MAP_FAILED)
- munmap (iobuf_arena->mem_base, iobuf_pool->arena_size);
+ munmap (iobuf_arena->mem_base, iobuf_arena->arena_size);
GF_FREE (iobuf_arena);
-
out:
return;
}
struct iobuf_arena *
-__iobuf_arena_alloc (struct iobuf_pool *iobuf_pool)
+__iobuf_arena_alloc (struct iobuf_pool *iobuf_pool, size_t page_size,
+ int32_t num_iobufs)
{
struct iobuf_arena *iobuf_arena = NULL;
- size_t arena_size = 0;
+ size_t rounded_size = 0;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
@@ -144,17 +173,24 @@ __iobuf_arena_alloc (struct iobuf_pool *iobuf_pool)
INIT_LIST_HEAD (&iobuf_arena->passive.list);
iobuf_arena->iobuf_pool = iobuf_pool;
- arena_size = iobuf_pool->arena_size;
- iobuf_arena->mem_base = mmap (NULL, arena_size, PROT_READ|PROT_WRITE,
+ rounded_size = gf_iobuf_get_pagesize (page_size);
+
+ iobuf_arena->page_size = rounded_size;
+ iobuf_arena->page_count = num_iobufs;
+
+ iobuf_arena->arena_size = rounded_size * num_iobufs;
+
+ iobuf_arena->mem_base = mmap (NULL, iobuf_arena->arena_size,
+ PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (iobuf_arena->mem_base == MAP_FAILED) {
- gf_log ("", GF_LOG_WARNING, "maping failed");
+ gf_log (THIS->name, GF_LOG_WARNING, "maping failed");
goto err;
}
__iobuf_arena_init_iobufs (iobuf_arena);
if (!iobuf_arena->iobufs) {
- gf_log ("", GF_LOG_DEBUG, "init failed");
+ gf_log (THIS->name, GF_LOG_ERROR, "init failed");
goto err;
}
@@ -171,50 +207,67 @@ out:
struct iobuf_arena *
-__iobuf_arena_unprune (struct iobuf_pool *iobuf_pool)
+__iobuf_arena_unprune (struct iobuf_pool *iobuf_pool, size_t page_size)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *tmp = NULL;
+ int index = 0;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
- list_for_each_entry (tmp, &iobuf_pool->purge.list, list) {
+ index = gf_iobuf_get_arena_index (page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
+ "iobufs in arena being added is greater than max "
+ "available", page_size);
+ return NULL;
+ }
+
+ list_for_each_entry (tmp, &iobuf_pool->purge[index], list) {
list_del_init (&tmp->list);
iobuf_arena = tmp;
break;
}
-
out:
return iobuf_arena;
}
struct iobuf_arena *
-__iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool)
+__iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool, size_t page_size,
+ int32_t num_pages)
{
- struct iobuf_arena *iobuf_arena = NULL;
-
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+ struct iobuf_arena *iobuf_arena = NULL;
+ int index = 0;
+
+ index = gf_iobuf_get_arena_index (page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
+ "iobufs in arena being added is greater than max "
+ "available", page_size);
+ return NULL;
+ }
- iobuf_arena = __iobuf_arena_unprune (iobuf_pool);
+ iobuf_arena = __iobuf_arena_unprune (iobuf_pool, page_size);
if (!iobuf_arena)
- iobuf_arena = __iobuf_arena_alloc (iobuf_pool);
+ iobuf_arena = __iobuf_arena_alloc (iobuf_pool, page_size,
+ num_pages);
if (!iobuf_arena) {
- gf_log ("", GF_LOG_WARNING, "arena not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "arena not found");
return NULL;
}
- list_add_tail (&iobuf_arena->list, &iobuf_pool->arenas.list);
+ list_add_tail (&iobuf_arena->list, &iobuf_pool->arenas[index]);
-out:
return iobuf_arena;
}
struct iobuf_arena *
-iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool)
+iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool, size_t page_size,
+ int32_t num_pages)
{
struct iobuf_arena *iobuf_arena = NULL;
@@ -222,7 +275,8 @@ iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool)
pthread_mutex_lock (&iobuf_pool->mutex);
{
- iobuf_arena = __iobuf_pool_add_arena (iobuf_pool);
+ iobuf_arena = __iobuf_pool_add_arena (iobuf_pool, page_size,
+ num_pages);
}
pthread_mutex_unlock (&iobuf_pool->mutex);
@@ -235,78 +289,113 @@ void
iobuf_pool_destroy (struct iobuf_pool *iobuf_pool)
{
struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
+ struct iobuf_arena *tmp = NULL;
+ int i = 0;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
- list_for_each_entry_safe (iobuf_arena, tmp, &iobuf_pool->arenas.list,
- list) {
-
- list_del_init (&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ list_for_each_entry_safe (iobuf_arena, tmp,
+ &iobuf_pool->arenas[i], list) {
+ list_del_init (&iobuf_arena->list);
+ iobuf_pool->arena_cnt--;
+ __iobuf_arena_destroy (iobuf_arena);
+ }
- __iobuf_arena_destroy (iobuf_arena);
}
out:
return;
}
+static void
+iobuf_create_stdalloc_arena (struct iobuf_pool *iobuf_pool)
+{
+ struct iobuf_arena *iobuf_arena = NULL;
+
+ /* No locking required here as its called only once during init */
+ iobuf_arena = GF_CALLOC (sizeof (*iobuf_arena), 1,
+ gf_common_mt_iobuf_arena);
+ if (!iobuf_arena)
+ goto err;
+
+ INIT_LIST_HEAD (&iobuf_arena->list);
+ INIT_LIST_HEAD (&iobuf_arena->active.list);
+ INIT_LIST_HEAD (&iobuf_arena->passive.list);
+
+ iobuf_arena->iobuf_pool = iobuf_pool;
+
+ iobuf_arena->page_size = 0x7fffffff;
+
+ list_add_tail (&iobuf_arena->list,
+ &iobuf_pool->arenas[IOBUF_ARENA_MAX_INDEX]);
+
+err:
+ return;
+}
struct iobuf_pool *
-iobuf_pool_new (size_t arena_size, size_t page_size)
+iobuf_pool_new (void)
{
struct iobuf_pool *iobuf_pool = NULL;
-
- if (arena_size < page_size) {
- gf_log ("", GF_LOG_WARNING,
- "arena size (%zu) is less than page size(%zu)",
- arena_size, page_size);
- return NULL;
- }
+ int i = 0;
+ size_t page_size = 0;
+ size_t arena_size = 0;
+ int32_t num_pages = 0;
iobuf_pool = GF_CALLOC (sizeof (*iobuf_pool), 1,
gf_common_mt_iobuf_pool);
if (!iobuf_pool)
- return NULL;
+ goto out;
pthread_mutex_init (&iobuf_pool->mutex, NULL);
- INIT_LIST_HEAD (&iobuf_pool->arenas.list);
- INIT_LIST_HEAD (&iobuf_pool->filled.list);
- INIT_LIST_HEAD (&iobuf_pool->purge.list);
+ for (i = 0; i <= IOBUF_ARENA_MAX_INDEX; i++) {
+ INIT_LIST_HEAD (&iobuf_pool->arenas[i]);
+ INIT_LIST_HEAD (&iobuf_pool->filled[i]);
+ INIT_LIST_HEAD (&iobuf_pool->purge[i]);
+ }
- iobuf_pool->arena_size = arena_size;
- iobuf_pool->page_size = page_size;
+ iobuf_pool->default_page_size = 128 * GF_UNIT_KB;
+
+ arena_size = 0;
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ page_size = gf_iobuf_init_config[i].pagesize;
+ num_pages = gf_iobuf_init_config[i].num_pages;
+
+ iobuf_pool_add_arena (iobuf_pool, page_size, num_pages);
+
+ arena_size += page_size * num_pages;
+ }
- iobuf_pool_add_arena (iobuf_pool);
+ /* Need an arena to handle all the bigger iobuf requests */
+ iobuf_create_stdalloc_arena (iobuf_pool);
+
+ iobuf_pool->arena_size = arena_size;
+out:
return iobuf_pool;
}
void
-__iobuf_pool_prune (struct iobuf_pool *iobuf_pool)
+__iobuf_arena_prune (struct iobuf_pool *iobuf_pool,
+ struct iobuf_arena *iobuf_arena, int index)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
-
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
- if (list_empty (&iobuf_pool->arenas.list))
- /* buffering - preserve this one arena (if at all)
- for __iobuf_arena_unprune */
- return;
-
- list_for_each_entry_safe (iobuf_arena, tmp, &iobuf_pool->purge.list,
- list) {
- if (iobuf_arena->active_cnt)
- continue;
+ /* code flow comes here only if the arena is in purge list and we can
+ * free the arena only if we have atleast one arena in 'arenas' list
+ * (ie, at least few iobufs free in arena), that way, there won't
+ * be spurious mmap/unmap of buffers
+ */
+ if (list_empty (&iobuf_pool->arenas[index]))
+ goto out;
- list_del_init (&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
+ /* All cases matched, destroy */
+ list_del_init (&iobuf_arena->list);
+ iobuf_pool->arena_cnt--;
- __iobuf_arena_destroy (iobuf_arena);
- }
+ __iobuf_arena_destroy (iobuf_arena);
out:
return;
@@ -316,11 +405,24 @@ out:
void
iobuf_pool_prune (struct iobuf_pool *iobuf_pool)
{
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *tmp = NULL;
+ int i = 0;
+
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
pthread_mutex_lock (&iobuf_pool->mutex);
{
- __iobuf_pool_prune (iobuf_pool);
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ if (list_empty (&iobuf_pool->arenas[i])) {
+ continue;
+ }
+
+ list_for_each_entry_safe (iobuf_arena, tmp,
+ &iobuf_pool->purge[i], list) {
+ __iobuf_arena_prune (iobuf_pool, iobuf_arena, i);
+ }
+ }
}
pthread_mutex_unlock (&iobuf_pool->mutex);
@@ -330,15 +432,24 @@ out:
struct iobuf_arena *
-__iobuf_select_arena (struct iobuf_pool *iobuf_pool)
+__iobuf_select_arena (struct iobuf_pool *iobuf_pool, size_t page_size)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *trav = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *trav = NULL;
+ int index = 0;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+ index = gf_iobuf_get_arena_index (page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
+ "iobufs in arena being added is greater than max "
+ "available", page_size);
+ return NULL;
+ }
+
/* look for unused iobuf from the head-most arena */
- list_for_each_entry (trav, &iobuf_pool->arenas.list, list) {
+ list_for_each_entry (trav, &iobuf_pool->arenas[index], list) {
if (trav->passive_cnt) {
iobuf_arena = trav;
break;
@@ -346,8 +457,9 @@ __iobuf_select_arena (struct iobuf_pool *iobuf_pool)
}
if (!iobuf_arena) {
- /* all arenas were full */
- iobuf_arena = __iobuf_pool_add_arena (iobuf_pool);
+ /* all arenas were full, find the right count to add */
+ iobuf_arena = __iobuf_pool_add_arena (iobuf_pool, page_size,
+ gf_iobuf_init_config[index].num_pages);
}
out:
@@ -372,12 +484,12 @@ __iobuf_unref (struct iobuf *iobuf)
return iobuf;
}
-
struct iobuf *
-__iobuf_get (struct iobuf_arena *iobuf_arena)
+__iobuf_get (struct iobuf_arena *iobuf_arena, size_t page_size)
{
- struct iobuf *iobuf = NULL;
- struct iobuf_pool *iobuf_pool = NULL;
+ struct iobuf *iobuf = NULL;
+ struct iobuf_pool *iobuf_pool = NULL;
+ int index = 0;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
@@ -392,36 +504,141 @@ __iobuf_get (struct iobuf_arena *iobuf_arena)
list_add (&iobuf->list, &iobuf_arena->active.list);
iobuf_arena->active_cnt++;
+ /* no resetting requied for this element */
+ iobuf_arena->alloc_cnt++;
+
+ if (iobuf_arena->max_active < iobuf_arena->active_cnt)
+ iobuf_arena->max_active = iobuf_arena->active_cnt;
+
if (iobuf_arena->passive_cnt == 0) {
+ index = gf_iobuf_get_arena_index (page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
+ "iobufs in arena being added is greater "
+ "than max available", page_size);
+ goto out;
+ }
+
list_del (&iobuf_arena->list);
- list_add (&iobuf_arena->list, &iobuf_pool->filled.list);
+ list_add (&iobuf_arena->list, &iobuf_pool->filled[index]);
}
out:
return iobuf;
}
+struct iobuf *
+iobuf_get_from_stdalloc (struct iobuf_pool *iobuf_pool, size_t page_size)
+{
+ struct iobuf *iobuf = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *trav = NULL;
+ int ret = -1;
+
+ /* The first arena in the 'MAX-INDEX' will always be used for misc */
+ list_for_each_entry (trav, &iobuf_pool->arenas[IOBUF_ARENA_MAX_INDEX],
+ list) {
+ iobuf_arena = trav;
+ break;
+ }
+
+ iobuf = GF_CALLOC (1, sizeof (*iobuf), gf_common_mt_iobuf);
+ if (!iobuf)
+ goto out;
+
+ /* 4096 is the alignment */
+ iobuf->free_ptr = GF_CALLOC (1, ((page_size + GF_IOBUF_ALIGN_SIZE) - 1),
+ gf_common_mt_char);
+ if (!iobuf->free_ptr)
+ goto out;
+
+ iobuf->ptr = GF_ALIGN_BUF (iobuf->free_ptr, GF_IOBUF_ALIGN_SIZE);
+ iobuf->iobuf_arena = iobuf_arena;
+ LOCK_INIT (&iobuf->lock);
+
+ /* Hold a ref because you are allocating and using it */
+ iobuf->ref = 1;
+
+ ret = 0;
+out:
+ if (ret && iobuf) {
+ if (iobuf->free_ptr)
+ GF_FREE (iobuf->free_ptr);
+ GF_FREE (iobuf);
+ iobuf = NULL;
+ }
+
+ return iobuf;
+}
+
+
+struct iobuf *
+iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size)
+{
+ struct iobuf *iobuf = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ size_t rounded_size = 0;
+
+ if (page_size == 0) {
+ page_size = iobuf_pool->default_page_size;
+ }
+
+ rounded_size = gf_iobuf_get_pagesize (page_size);
+ if (rounded_size == -1) {
+ /* make sure to provide the requested buffer with standard
+ memory allocations */
+ iobuf = iobuf_get_from_stdalloc (iobuf_pool, page_size);
+
+ gf_log ("iobuf", GF_LOG_DEBUG, "request for iobuf of size %zu "
+ "is serviced using standard calloc() (%p) as it "
+ "exceeds the maximum available buffer size",
+ page_size, iobuf);
+
+ iobuf_pool->request_misses++;
+ return iobuf;
+ }
+
+ pthread_mutex_lock (&iobuf_pool->mutex);
+ {
+ /* most eligible arena for picking an iobuf */
+ iobuf_arena = __iobuf_select_arena (iobuf_pool, rounded_size);
+ if (!iobuf_arena)
+ goto unlock;
+
+ iobuf = __iobuf_get (iobuf_arena, rounded_size);
+ if (!iobuf)
+ goto unlock;
+
+ __iobuf_ref (iobuf);
+ }
+unlock:
+ pthread_mutex_unlock (&iobuf_pool->mutex);
+
+ return iobuf;
+}
struct iobuf *
iobuf_get (struct iobuf_pool *iobuf_pool)
{
- struct iobuf *iobuf = NULL;
- struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf *iobuf = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
pthread_mutex_lock (&iobuf_pool->mutex);
{
/* most eligible arena for picking an iobuf */
- iobuf_arena = __iobuf_select_arena (iobuf_pool);
+ iobuf_arena = __iobuf_select_arena (iobuf_pool,
+ iobuf_pool->default_page_size);
if (!iobuf_arena) {
- gf_log ("", GF_LOG_WARNING, "arena not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "arena not found");
goto unlock;
}
- iobuf = __iobuf_get (iobuf_arena);
+ iobuf = __iobuf_get (iobuf_arena,
+ iobuf_pool->default_page_size);
if (!iobuf) {
- gf_log ("", GF_LOG_WARNING, "iobuf not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "iobuf not found");
goto unlock;
}
@@ -434,20 +651,32 @@ out:
return iobuf;
}
-
void
__iobuf_put (struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
{
struct iobuf_pool *iobuf_pool = NULL;
+ int index = 0;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
iobuf_pool = iobuf_arena->iobuf_pool;
+ index = gf_iobuf_get_arena_index (iobuf_arena->page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_DEBUG, "freeing the iobuf (%p) "
+ "allocated with standard calloc()", iobuf);
+
+ /* free up properly without bothering about lists and all */
+ LOCK_DESTROY (&iobuf->lock);
+ GF_FREE (iobuf->free_ptr);
+ GF_FREE (iobuf);
+ return;
+ }
+
if (iobuf_arena->passive_cnt == 0) {
list_del (&iobuf_arena->list);
- list_add_tail (&iobuf_arena->list, &iobuf_pool->arenas.list);
+ list_add_tail (&iobuf_arena->list, &iobuf_pool->arenas[index]);
}
list_del_init (&iobuf->list);
@@ -458,7 +687,8 @@ __iobuf_put (struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
if (iobuf_arena->active_cnt == 0) {
list_del (&iobuf_arena->list);
- list_add_tail (&iobuf_arena->list, &iobuf_pool->purge.list);
+ list_add_tail (&iobuf_arena->list, &iobuf_pool->purge[index]);
+ __iobuf_arena_prune (iobuf_pool, iobuf_arena, index);
}
out:
return;
@@ -475,13 +705,13 @@ iobuf_put (struct iobuf *iobuf)
iobuf_arena = iobuf->iobuf_arena;
if (!iobuf_arena) {
- gf_log ("", GF_LOG_WARNING, "arena not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "arena not found");
return;
}
iobuf_pool = iobuf_arena->iobuf_pool;
if (!iobuf_pool) {
- gf_log ("", GF_LOG_WARNING, "iobuf pool not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "iobuf pool not found");
return;
}
@@ -491,8 +721,6 @@ iobuf_put (struct iobuf *iobuf)
}
pthread_mutex_unlock (&iobuf_pool->mutex);
- iobuf_pool_prune (iobuf_pool);
-
out:
return;
}
@@ -578,7 +806,7 @@ iobref_destroy (struct iobref *iobref)
GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) {
iobuf = iobref->iobrefs[i];
iobref->iobrefs[i] = NULL;
@@ -623,7 +851,7 @@ __iobref_add (struct iobref *iobref, struct iobuf *iobuf)
GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) {
if (iobref->iobrefs[i] == NULL) {
iobref->iobrefs[i] = iobuf_ref (iobuf);
ret = 0;
@@ -667,7 +895,7 @@ iobref_merge (struct iobref *to, struct iobref *from)
LOCK (&from->lock);
{
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) {
iobuf = from->iobrefs[i];
if (!iobuf)
@@ -694,16 +922,16 @@ iobuf_size (struct iobuf *iobuf)
GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
if (!iobuf->iobuf_arena) {
- gf_log ("", GF_LOG_WARNING, "arena not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "arena not found");
goto out;
}
if (!iobuf->iobuf_arena->iobuf_pool) {
- gf_log ("", GF_LOG_WARNING, "pool not found");
+ gf_log (THIS->name, GF_LOG_WARNING, "pool not found");
goto out;
}
- size = iobuf->iobuf_arena->iobuf_pool->page_size;
+ size = iobuf->iobuf_arena->page_size;
out:
return size;
}
@@ -719,7 +947,7 @@ iobref_size (struct iobref *iobref)
LOCK (&iobref->lock);
{
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) {
if (iobref->iobrefs[i])
size += iobuf_size (iobref->iobrefs[i]);
}
@@ -743,8 +971,6 @@ iobuf_info_dump (struct iobuf *iobuf, const char *key_prefix)
ret = TRY_LOCK(&iobuf->lock);
if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump iobuf"
- " errno: %s", strerror (errno));
return;
}
memcpy(&my_iobuf, iobuf, sizeof(my_iobuf));
@@ -774,6 +1000,12 @@ iobuf_arena_info_dump (struct iobuf_arena *iobuf_arena, const char *key_prefix)
gf_proc_dump_write(key, "%d", iobuf_arena->active_cnt);
gf_proc_dump_build_key(key, key_prefix, "passive_cnt");
gf_proc_dump_write(key, "%d", iobuf_arena->passive_cnt);
+ gf_proc_dump_build_key(key, key_prefix, "alloc_cnt");
+ gf_proc_dump_write(key, "%"PRIu64, iobuf_arena->alloc_cnt);
+ gf_proc_dump_build_key(key, key_prefix, "max_active");
+ gf_proc_dump_write(key, "%"PRIu64, iobuf_arena->max_active);
+ gf_proc_dump_build_key(key, key_prefix, "page_size");
+ gf_proc_dump_write(key, "%"PRIu64, iobuf_arena->page_size);
list_for_each_entry (trav, &iobuf_arena->active.list, list) {
gf_proc_dump_build_key(key, key_prefix,"active_iobuf.%d", i++);
gf_proc_dump_add_section(key);
@@ -787,10 +1019,10 @@ out:
void
iobuf_stats_dump (struct iobuf_pool *iobuf_pool)
{
-
char msg[1024];
struct iobuf_arena *trav = NULL;
int i = 1;
+ int j = 0;
int ret = -1;
GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
@@ -800,25 +1032,42 @@ iobuf_stats_dump (struct iobuf_pool *iobuf_pool)
ret = pthread_mutex_trylock(&iobuf_pool->mutex);
if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump iobuf pool"
- " errno: %s", strerror (errno));
return;
}
gf_proc_dump_add_section("iobuf.global");
- gf_proc_dump_write("iobuf.global.iobuf_pool","%p", iobuf_pool);
- gf_proc_dump_write("iobuf.global.iobuf_pool.page_size", "%d",
- iobuf_pool->page_size);
- gf_proc_dump_write("iobuf.global.iobuf_pool.arena_size", "%d",
+ gf_proc_dump_write("iobuf_pool","%p", iobuf_pool);
+ gf_proc_dump_write("iobuf_pool.default_page_size", "%d",
+ iobuf_pool->default_page_size);
+ gf_proc_dump_write("iobuf_pool.arena_size", "%d",
iobuf_pool->arena_size);
- gf_proc_dump_write("iobuf.global.iobuf_pool.arena_cnt", "%d",
+ gf_proc_dump_write("iobuf_pool.arena_cnt", "%d",
iobuf_pool->arena_cnt);
+ gf_proc_dump_write("iobuf_pool.request_misses", "%"PRId64,
+ iobuf_pool->request_misses);
+
+ for (j = 0; j < IOBUF_ARENA_MAX_INDEX; j++) {
+ list_for_each_entry (trav, &iobuf_pool->arenas[j], list) {
+ snprintf(msg, sizeof(msg),
+ "arena.%d", i);
+ gf_proc_dump_add_section(msg);
+ iobuf_arena_info_dump(trav,msg);
+ i++;
+ }
+ list_for_each_entry (trav, &iobuf_pool->purge[j], list) {
+ snprintf(msg, sizeof(msg),
+ "purge.%d", i);
+ gf_proc_dump_add_section(msg);
+ iobuf_arena_info_dump(trav,msg);
+ i++;
+ }
+ list_for_each_entry (trav, &iobuf_pool->filled[j], list) {
+ snprintf(msg, sizeof(msg),
+ "filled.%d", i);
+ gf_proc_dump_add_section(msg);
+ iobuf_arena_info_dump(trav,msg);
+ i++;
+ }
- list_for_each_entry (trav, &iobuf_pool->arenas.list, list) {
- snprintf(msg, sizeof(msg), "iobuf.global.iobuf_pool.arena.%d",
- i);
- gf_proc_dump_add_section(msg);
- iobuf_arena_info_dump(trav,msg);
- i++;
}
pthread_mutex_unlock(&iobuf_pool->mutex);
diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h
index fc8ff623a..b9c2a3807 100644
--- a/libglusterfs/src/iobuf.h
+++ b/libglusterfs/src/iobuf.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _IOBUF_H_
@@ -26,6 +17,9 @@
#include <sys/mman.h>
#include <sys/uio.h>
+#define GF_VARIABLE_IOBUF_COUNT 32
+#define GF_IOBREF_IOBUF_COUNT 16
+
/* Lets try to define the new anonymous mapping
* flag, in case the system is still using the
* now deprecated MAP_ANON flag.
@@ -37,6 +31,11 @@
#define MAP_ANONYMOUS MAP_ANON
#endif
+#define GF_ALIGN_BUF(ptr,bound) ((void *)((unsigned long)(ptr + bound - 1) & \
+ (unsigned long)(~(bound - 1))))
+
+#define GF_IOBUF_ALIGN_SIZE 512
+
/* one allocatable unit for the consumers of the IOBUF API */
/* each unit hosts @page_size bytes of memory */
struct iobuf;
@@ -49,6 +48,10 @@ struct iobuf_arena;
/* expandable and contractable pool of memory, internally broken into arenas */
struct iobuf_pool;
+struct iobuf_init_config {
+ size_t pagesize;
+ int32_t num_pages;
+};
struct iobuf {
union {
@@ -64,6 +67,9 @@ struct iobuf {
int ref; /* 0 == passive, >0 == active */
void *ptr; /* usable memory region by the consumer */
+
+ void *free_ptr; /* in case of stdalloc, this is the
+ one to be freed */
};
@@ -75,6 +81,13 @@ struct iobuf_arena {
struct iobuf_arena *prev;
};
};
+
+ size_t page_size; /* size of all iobufs in this arena */
+ size_t arena_size; /* this is equal to
+ (iobuf_pool->arena_size / page_size)
+ * page_size */
+ size_t page_count;
+
struct iobuf_pool *iobuf_pool;
void *mem_base;
@@ -86,25 +99,34 @@ struct iobuf_arena {
int passive_cnt;
struct iobuf passive; /* head node iobuf
(unused by itself) */
+ uint64_t alloc_cnt; /* total allocs in this pool */
+ int max_active; /* max active buffers at a given time */
};
struct iobuf_pool {
pthread_mutex_t mutex;
- size_t page_size; /* size of all iobufs in this pool */
- size_t arena_size; /* size of memory region in arena */
+ size_t arena_size; /* size of memory region in
+ arena */
+ size_t default_page_size; /* default size of iobuf */
int arena_cnt;
- struct iobuf_arena arenas; /* head node arena
- (unused by itself) */
- struct iobuf_arena filled; /* arenas without free iobufs */
- struct iobuf_arena purge; /* arenas which can be purged */
-};
+ struct list_head arenas[GF_VARIABLE_IOBUF_COUNT];
+ /* array of arenas. Each element of the array is a list of arenas
+ holding iobufs of particular page_size */
+
+ struct list_head filled[GF_VARIABLE_IOBUF_COUNT];
+ /* array of arenas without free iobufs */
+ struct list_head purge[GF_VARIABLE_IOBUF_COUNT];
+ /* array of of arenas which can be purged */
+ uint64_t request_misses; /* mostly the requests for higher
+ value of iobufs */
+};
-struct iobuf_pool *iobuf_pool_new (size_t arena_size, size_t page_size);
+struct iobuf_pool *iobuf_pool_new (void);
void iobuf_pool_destroy (struct iobuf_pool *iobuf_pool);
struct iobuf *iobuf_get (struct iobuf_pool *iobuf_pool);
void iobuf_unref (struct iobuf *iobuf);
@@ -113,14 +135,14 @@ void iobuf_pool_destroy (struct iobuf_pool *iobuf_pool);
void iobuf_to_iovec(struct iobuf *iob, struct iovec *iov);
#define iobuf_ptr(iob) ((iob)->ptr)
-#define iobpool_pagesize(iobpool) ((iobpool)->page_size)
-#define iobuf_pagesize(iob) (iobpool_pagesize((iob)->iobuf_arena->iobuf_pool))
+#define iobpool_default_pagesize(iobpool) ((iobpool)->default_page_size)
+#define iobuf_pagesize(iob) (iob->iobuf_arena->page_size)
struct iobref {
gf_lock_t lock;
int ref;
- struct iobuf *iobrefs[8];
+ struct iobuf *iobrefs[GF_IOBREF_IOBUF_COUNT];
};
struct iobref *iobref_new ();
@@ -134,4 +156,6 @@ size_t iobuf_size (struct iobuf *iobuf);
size_t iobref_size (struct iobref *iobref);
void iobuf_stats_dump (struct iobuf_pool *iobuf_pool);
+struct iobuf *
+iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size);
#endif /* !_IOBUF_H_ */
diff --git a/libglusterfs/src/latency.c b/libglusterfs/src/latency.c
index aaa196a19..58e8b9158 100644
--- a/libglusterfs/src/latency.c
+++ b/libglusterfs/src/latency.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
diff --git a/libglusterfs/src/latency.h b/libglusterfs/src/latency.h
index 610f12550..16c5994b0 100644
--- a/libglusterfs/src/latency.h
+++ b/libglusterfs/src/latency.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __LATENCY_H__
diff --git a/libglusterfs/src/list.h b/libglusterfs/src/list.h
index 52d98fc51..35fccdf25 100644
--- a/libglusterfs/src/list.h
+++ b/libglusterfs/src/list.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _LLIST_H
diff --git a/libglusterfs/src/lkowner.h b/libglusterfs/src/lkowner.h
new file mode 100644
index 000000000..969d13e50
--- /dev/null
+++ b/libglusterfs/src/lkowner.h
@@ -0,0 +1,83 @@
+/*
+ Copyright (c) 2008-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 _LK_OWNER_H
+#define _LK_OWNER_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#define GF_MAX_LOCK_OWNER_LEN 1024 /* 1kB as per NLM */
+
+/* 16strings-16strings-... */
+#define GF_LKOWNER_BUF_SIZE ((GF_MAX_LOCK_OWNER_LEN * 2) + \
+ (GF_MAX_LOCK_OWNER_LEN / 8))
+
+typedef struct gf_lkowner_ {
+ int len;
+ char data[GF_MAX_LOCK_OWNER_LEN];
+} gf_lkowner_t;
+
+
+/* LKOWNER to string functions */
+static inline void
+lkowner_unparse (gf_lkowner_t *lkowner, char *buf, int buf_len)
+{
+ int i = 0;
+ int j = 0;
+
+ for (i = 0; i < lkowner->len; i++) {
+ if (i && !(i % 8)) {
+ buf[j] = '-';
+ j++;
+ }
+ sprintf (&buf[j], "%02hhx", lkowner->data[i]);
+ j += 2;
+ if (j == buf_len)
+ break;
+ }
+ if (j < buf_len)
+ buf[j] = '\0';
+}
+
+static inline void
+set_lk_owner_from_ptr (gf_lkowner_t *lkowner, void *data)
+{
+ int i = 0;
+ int j = 0;
+
+ lkowner->len = sizeof (unsigned long);
+ for (i = 0, j = 0; i < lkowner->len; i++, j += 8) {
+ lkowner->data[i] = (char)((((unsigned long)data) >> j) & 0xff);
+ }
+}
+
+static inline void
+set_lk_owner_from_uint64 (gf_lkowner_t *lkowner, uint64_t data)
+{
+ int i = 0;
+ int j = 0;
+
+ lkowner->len = 8;
+ for (i = 0, j = 0; i < lkowner->len; i++, j += 8) {
+ lkowner->data[i] = (char)((data >> j) & 0xff);
+ }
+}
+
+/* Return true if the locks have the same owner */
+static inline int
+is_same_lkowner (gf_lkowner_t *l1, gf_lkowner_t *l2)
+{
+ return ((l1->len == l2->len) && !memcmp(l1->data, l2->data, l1->len));
+}
+
+#endif /* _LK_OWNER_H */
diff --git a/libglusterfs/src/locking.h b/libglusterfs/src/locking.h
index 207685e14..79c6992af 100644
--- a/libglusterfs/src/locking.h
+++ b/libglusterfs/src/locking.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _LOCKING_H
diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c
index eaa735d5f..0cfeed586 100644
--- a/libglusterfs/src/logging.c
+++ b/libglusterfs/src/logging.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -50,9 +41,10 @@ static uint8_t logrotate = 0;
static FILE *logfile = NULL;
static gf_loglevel_t loglevel = GF_LOG_INFO;
static int gf_log_syslog = 1;
+static gf_loglevel_t sys_log_level = GF_LOG_CRITICAL;
char gf_log_xl_log_set;
-gf_loglevel_t gf_log_loglevel; /* extern'd */
+gf_loglevel_t gf_log_loglevel = GF_LOG_INFO; /* extern'd */
FILE *gf_log_logfile;
static char *cmd_log_filename = NULL;
@@ -130,11 +122,19 @@ gf_log_globals_init (void)
int
gf_log_init (const char *file)
{
+ int fd = -1;
+
if (!file){
fprintf (stderr, "ERROR: no filename specified\n");
return -1;
}
+ if (strcmp (file, "-") == 0) {
+ gf_log_logfile = stderr;
+
+ return 0;
+ }
+
filename = gf_strdup (file);
if (!filename) {
fprintf (stderr, "ERROR: updating log-filename failed: %s\n",
@@ -142,6 +142,14 @@ gf_log_init (const char *file)
return -1;
}
+ fd = open (file, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ fprintf (stderr, "ERROR: failed to create logfile \"%s\" (%s)\n",
+ file, strerror (errno));
+ return -1;
+ }
+ close (fd);
+
logfile = fopen (file, "a");
if (!logfile){
fprintf (stderr, "ERROR: failed to open logfile \"%s\" (%s)\n",
@@ -186,29 +194,33 @@ gf_log_cleanup (void)
pthread_mutex_destroy (&logfile_mutex);
}
+void
+set_sys_log_level (gf_loglevel_t level)
+{
+ sys_log_level = level;
+}
+
int
_gf_log_nomem (const char *domain, const char *file,
const char *function, int line, gf_loglevel_t level,
size_t size)
{
const char *basename = NULL;
- struct tm *tm = NULL;
xlator_t *this = NULL;
struct timeval tv = {0,};
int ret = 0;
- gf_loglevel_t xlator_loglevel = 0;
- char msg[8092];
- char timestr[256];
- char callstr[4096];
+ char msg[8092] = {0,};
+ char timestr[256] = {0,};
+ char callstr[4096] = {0,};
this = THIS;
- xlator_loglevel = this->loglevel;
- if (xlator_loglevel == 0)
- xlator_loglevel = loglevel;
-
- if (level > xlator_loglevel)
- goto out;
+ if (gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ else if (level > gf_log_loglevel)
+ goto out;
+ }
static char *level_strings[] = {"", /* NONE */
"M", /* EMERGENCY */
@@ -259,12 +271,11 @@ _gf_log_nomem (const char *domain, const char *file,
if (-1 == ret)
goto out;
- tm = localtime (&tv.tv_sec);
-
pthread_mutex_lock (&logfile_mutex);
{
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
".%"GF_PRI_SUSECONDS, tv.tv_usec);
basename = strrchr (file, '/');
@@ -292,7 +303,7 @@ _gf_log_nomem (const char *domain, const char *file,
#ifdef GF_LINUX_HOST_OS
/* We want only serious log in 'syslog', not our debug
and trace logs */
- if (gf_log_syslog && level && (level <= GF_LOG_ERROR))
+ if (gf_log_syslog && level && (level <= sys_log_level))
syslog ((level-1), "%s\n", msg);
#endif
}
@@ -308,7 +319,6 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
int line, gf_loglevel_t level, const char *fmt, ...)
{
const char *basename = NULL;
- struct tm *tm = NULL;
xlator_t *this = NULL;
char *str1 = NULL;
char *str2 = NULL;
@@ -318,17 +328,16 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
struct timeval tv = {0,};
size_t len = 0;
int ret = 0;
- gf_loglevel_t xlator_loglevel = 0;
va_list ap;
this = THIS;
- xlator_loglevel = this->loglevel;
- if (xlator_loglevel == 0)
- xlator_loglevel = loglevel;
-
- if (level > xlator_loglevel)
- goto out;
+ if (gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ else if (level > gf_log_loglevel)
+ goto out;
+ }
static char *level_strings[] = {"", /* NONE */
"M", /* EMERGENCY */
@@ -379,14 +388,13 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
if (-1 == ret)
goto out;
- tm = localtime (&tv.tv_sec);
-
pthread_mutex_lock (&logfile_mutex);
{
va_start (ap, fmt);
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
".%"GF_PRI_SUSECONDS, tv.tv_usec);
basename = strrchr (file, '/');
@@ -426,7 +434,7 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
#ifdef GF_LINUX_HOST_OS
/* We want only serious log in 'syslog', not our debug
and trace logs */
- if (gf_log_syslog && level && (level <= GF_LOG_CRITICAL))
+ if (gf_log_syslog && level && (level <= sys_log_level))
syslog ((level-1), "%s\n", msg);
#endif
}
@@ -452,29 +460,27 @@ int
_gf_log (const char *domain, const char *file, const char *function, int line,
gf_loglevel_t level, const char *fmt, ...)
{
- const char *basename = NULL;
- FILE *new_logfile = NULL;
- va_list ap;
- struct tm *tm = NULL;
- char timestr[256];
+ const char *basename = NULL;
+ FILE *new_logfile = NULL;
+ va_list ap;
+ char timestr[256] = {0,};
struct timeval tv = {0,};
-
- char *str1 = NULL;
- char *str2 = NULL;
- char *msg = NULL;
- size_t len = 0;
- int ret = 0;
- xlator_t *this = NULL;
- gf_loglevel_t xlator_loglevel = 0;
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *msg = NULL;
+ size_t len = 0;
+ int ret = 0;
+ int fd = -1;
+ xlator_t *this = NULL;
this = THIS;
- xlator_loglevel = this->loglevel;
- if (xlator_loglevel == 0)
- xlator_loglevel = loglevel;
-
- if (level > xlator_loglevel)
- goto out;
+ if (gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ else if (level > gf_log_loglevel)
+ goto out;
+ }
static char *level_strings[] = {"", /* NONE */
"M", /* EMERGENCY */
@@ -499,6 +505,14 @@ _gf_log (const char *domain, const char *file, const char *function, int line,
if (logrotate) {
logrotate = 0;
+ fd = open (filename, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ gf_log ("logrotate", GF_LOG_ERROR,
+ "%s", strerror (errno));
+ return -1;
+ }
+ close (fd);
+
new_logfile = fopen (filename, "a");
if (!new_logfile) {
gf_log ("logrotate", GF_LOG_CRITICAL,
@@ -518,14 +532,13 @@ log:
if (-1 == ret)
goto out;
- tm = localtime (&tv.tv_sec);
-
pthread_mutex_lock (&logfile_mutex);
{
va_start (ap, fmt);
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
".%"GF_PRI_SUSECONDS, tv.tv_usec);
basename = strrchr (file, '/');
@@ -565,7 +578,7 @@ log:
#ifdef GF_LINUX_HOST_OS
/* We want only serious log in 'syslog', not our debug
and trace logs */
- if (gf_log_syslog && level && (level <= GF_LOG_CRITICAL))
+ if (gf_log_syslog && level && (level <= sys_log_level))
syslog ((level-1), "%s\n", msg);
#endif
}
@@ -587,26 +600,53 @@ out:
return (0);
}
+int
+gf_log_eh (void *data)
+{
+ int ret = -1;
+
+ ret = eh_save_history (THIS->history, data);
+
+ return ret;
+}
int
gf_cmd_log_init (const char *filename)
{
+ int fd = -1;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
if (!filename){
- gf_log ("glusterd", GF_LOG_CRITICAL, "gf_cmd_log_init: no "
+ gf_log (this->name, GF_LOG_CRITICAL, "gf_cmd_log_init: no "
"filename specified\n");
return -1;
}
cmd_log_filename = gf_strdup (filename);
if (!cmd_log_filename) {
- gf_log ("glusterd", GF_LOG_CRITICAL, "gf_cmd_log_init: strdup"
- " error\n");
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "gf_cmd_log_init: strdup error\n");
return -1;
}
+ /* close and reopen cmdlogfile for log rotate*/
+ if (cmdlogfile) {
+ fclose (cmdlogfile);
+ cmdlogfile = NULL;
+ }
+
+ fd = open (cmd_log_filename, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "%s", strerror (errno));
+ return -1;
+ }
+ close (fd);
cmdlogfile = fopen (cmd_log_filename, "a");
if (!cmdlogfile){
- gf_log ("glusterd", GF_LOG_CRITICAL,
+ gf_log (this->name, GF_LOG_CRITICAL,
"gf_cmd_log_init: failed to open logfile \"%s\" "
"(%s)\n", cmd_log_filename, strerror (errno));
return -1;
@@ -617,15 +657,14 @@ gf_cmd_log_init (const char *filename)
int
gf_cmd_log (const char *domain, const char *fmt, ...)
{
- va_list ap;
- struct tm *tm = NULL;
- char timestr[256];
+ va_list ap;
+ char timestr[64];
struct timeval tv = {0,};
- char *str1 = NULL;
- char *str2 = NULL;
- char *msg = NULL;
- size_t len = 0;
- int ret = 0;
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *msg = NULL;
+ size_t len = 0;
+ int ret = 0;
if (!cmdlogfile)
return -1;
@@ -640,11 +679,8 @@ gf_cmd_log (const char *domain, const char *fmt, ...)
ret = gettimeofday (&tv, NULL);
if (ret == -1)
goto out;
-
- tm = localtime (&tv.tv_sec);
-
va_start (ap, fmt);
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
".%"GF_PRI_SUSECONDS, tv.tv_usec);
diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h
index 0a76f1612..bbf0d9a38 100644
--- a/libglusterfs/src/logging.h
+++ b/libglusterfs/src/logging.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 __LOGGING_H__
@@ -33,12 +24,12 @@
#define GF_PRI_FSBLK "u"
#define GF_PRI_DEV PRId32
#define GF_PRI_NLINK PRIu16
-#define GF_PRI_SUSECONDS PRId32
+#define GF_PRI_SUSECONDS "06d"
#else
#define GF_PRI_FSBLK PRIu64
#define GF_PRI_DEV PRIu64
#define GF_PRI_NLINK PRIu32
-#define GF_PRI_SUSECONDS "ld"
+#define GF_PRI_SUSECONDS "06ld"
#endif
#define GF_PRI_BLKSIZE PRId32
#define GF_PRI_SIZET "zu"
@@ -108,15 +99,20 @@ extern char gf_log_xl_log_set;
void gf_log_logrotate (int signum);
-
+int
+gf_log_eh (void *data);
void gf_log_globals_init (void);
int gf_log_init (const char *filename);
void gf_log_cleanup (void);
-int _gf_log (const char *domain, const char *file, const char *function,
- int32_t line, gf_loglevel_t level, const char *fmt, ...);
-int _gf_log_callingfn (const char *domain, const char *file, const char *function,
- int32_t line, gf_loglevel_t level, const char *fmt, ...);
+int _gf_log (const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 6, 7)));
+int _gf_log_callingfn (const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 6, 7)));
int _gf_log_nomem (const char *domain, const char *file,
const char *function, int line, gf_loglevel_t level,
@@ -143,7 +139,10 @@ void gf_log_set_xl_loglevel (void *xl, gf_loglevel_t level);
#define GF_ERROR(xl, format, args...) \
gf_log ((xl)->name, GF_LOG_ERROR, format, ##args)
-int gf_cmd_log (const char *domain, const char *fmt, ...);
+int gf_cmd_log (const char *domain, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)));
int gf_cmd_log_init (const char *filename);
+
+void set_sys_log_level (gf_loglevel_t level);
#endif /* __LOGGING_H__ */
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index 0d555020b..3e8100c64 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 "mem-pool.h"
@@ -24,10 +15,12 @@
#include <stdarg.h>
#define GF_MEM_POOL_LIST_BOUNDARY (sizeof(struct list_head))
-#define GF_MEM_POOL_PAD_BOUNDARY (GF_MEM_POOL_LIST_BOUNDARY + sizeof(int))
+#define GF_MEM_POOL_PTR (sizeof(struct mem_pool*))
+#define GF_MEM_POOL_PAD_BOUNDARY (GF_MEM_POOL_LIST_BOUNDARY + GF_MEM_POOL_PTR + sizeof(int))
#define mem_pool_chunkhead2ptr(head) ((head) + GF_MEM_POOL_PAD_BOUNDARY)
#define mem_pool_ptr2chunkhead(ptr) ((ptr) - GF_MEM_POOL_PAD_BOUNDARY)
#define is_mem_chunk_in_use(ptr) (*ptr == 1)
+#define mem_pool_from_ptr(ptr) ((ptr) + GF_MEM_POOL_LIST_BOUNDARY)
#define GF_MEM_HEADER_SIZE (4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8)
#define GF_MEM_TRAILER_SIZE 8
@@ -48,26 +41,31 @@ gf_mem_acct_is_enabled ()
void
gf_mem_acct_enable_set ()
{
- char *opt = NULL;
- long val = -1;
-
#ifdef DEBUG
gf_mem_acct_enable = 1;
return;
#endif
+ glusterfs_ctx_t *ctx = NULL;
+ char *opt = NULL;
+ long val = -1;
- opt = getenv (GLUSTERFS_ENV_MEM_ACCT_STR);
-
- if (!opt)
- return;
+ gf_mem_acct_enable = 0;
- val = strtol (opt, NULL, 0);
+ ctx = glusterfs_ctx_get ();
- if (val)
- gf_mem_acct_enable = 0;
- else
+ if (ctx->mem_accounting) {
gf_mem_acct_enable = 1;
+ return;
+ }
+
+ opt = getenv (GLUSTERFS_ENV_MEM_ACCT_STR);
+ if (opt) {
+ val = strtol (opt, NULL, 0);
+ if (val)
+ gf_mem_acct_enable = 1;
+ }
+ return;
}
void
@@ -98,6 +96,7 @@ gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr,
{
xl->mem_acct.rec[type].size += size;
xl->mem_acct.rec[type].num_allocs++;
+ xl->mem_acct.rec[type].total_allocs++;
xl->mem_acct.rec[type].max_size =
max (xl->mem_acct.rec[type].max_size,
xl->mem_acct.rec[type].size);
@@ -312,16 +311,18 @@ free:
struct mem_pool *
mem_pool_new_fn (unsigned long sizeof_type,
- unsigned long count)
+ unsigned long count, char *name)
{
struct mem_pool *mem_pool = NULL;
unsigned long padded_sizeof_type = 0;
void *pool = NULL;
int i = 0;
+ int ret = 0;
struct list_head *list = NULL;
+ glusterfs_ctx_t *ctx = NULL;
if (!sizeof_type || !count) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
return NULL;
}
padded_sizeof_type = sizeof_type + GF_MEM_POOL_PAD_BOUNDARY;
@@ -330,8 +331,18 @@ mem_pool_new_fn (unsigned long sizeof_type,
if (!mem_pool)
return NULL;
+ ret = gf_asprintf (&mem_pool->name, "%s:%s", THIS->name, name);
+ if (ret < 0)
+ return NULL;
+
+ if (!mem_pool->name) {
+ GF_FREE (mem_pool);
+ return NULL;
+ }
+
LOCK_INIT (&mem_pool->lock);
INIT_LIST_HEAD (&mem_pool->list);
+ INIT_LIST_HEAD (&mem_pool->global_list);
mem_pool->padded_sizeof_type = padded_sizeof_type;
mem_pool->cold_count = count;
@@ -339,6 +350,7 @@ mem_pool_new_fn (unsigned long sizeof_type,
pool = GF_CALLOC (count, padded_sizeof_type, gf_common_mt_long);
if (!pool) {
+ GF_FREE (mem_pool->name);
GF_FREE (mem_pool);
return NULL;
}
@@ -352,6 +364,14 @@ mem_pool_new_fn (unsigned long sizeof_type,
mem_pool->pool = pool;
mem_pool->pool_end = pool + (count * (padded_sizeof_type));
+ /* add this pool to the global list */
+ ctx = glusterfs_ctx_get ();
+ if (!ctx)
+ goto out;
+
+ list_add (&mem_pool->global_list, &ctx->mempool_list);
+
+out:
return mem_pool;
}
@@ -361,7 +381,7 @@ mem_get0 (struct mem_pool *mem_pool)
void *ptr = NULL;
if (!mem_pool) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
return NULL;
}
@@ -379,14 +399,16 @@ mem_get (struct mem_pool *mem_pool)
struct list_head *list = NULL;
void *ptr = NULL;
int *in_use = NULL;
+ struct mem_pool **pool_ptr = NULL;
if (!mem_pool) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
return NULL;
}
LOCK (&mem_pool->lock);
{
+ mem_pool->alloc_count++;
if (mem_pool->cold_count) {
list = mem_pool->list.next;
list_del (list);
@@ -394,8 +416,12 @@ mem_get (struct mem_pool *mem_pool)
mem_pool->hot_count++;
mem_pool->cold_count--;
+ if (mem_pool->max_alloc < mem_pool->hot_count)
+ mem_pool->max_alloc = mem_pool->hot_count;
+
ptr = list;
- in_use = (ptr + GF_MEM_POOL_LIST_BOUNDARY);
+ in_use = (ptr + GF_MEM_POOL_LIST_BOUNDARY +
+ GF_MEM_POOL_PTR);
*in_use = 1;
goto fwd_addr_out;
@@ -404,7 +430,7 @@ mem_get (struct mem_pool *mem_pool)
/* This is a problem area. If we've run out of
* chunks in our slab above, we need to allocate
* enough memory to service this request.
- * The problem is, these indvidual chunks will fail
+ * The problem is, these individual chunks will fail
* the first address range check in __is_member. Now, since
* we're not allocating a full second slab, we wont have
* enough info perform the range check in __is_member.
@@ -421,17 +447,24 @@ mem_get (struct mem_pool *mem_pool)
* because it is too much work knowing that a better slab
* allocator is coming RSN.
*/
- ptr = MALLOC (mem_pool->real_sizeof_type);
+ mem_pool->pool_misses++;
+ mem_pool->curr_stdalloc++;
+ if (mem_pool->max_stdalloc < mem_pool->curr_stdalloc)
+ mem_pool->max_stdalloc = mem_pool->curr_stdalloc;
+ ptr = GF_CALLOC (1, mem_pool->padded_sizeof_type,
+ gf_common_mt_mem_pool);
+ gf_log_callingfn ("mem-pool", GF_LOG_DEBUG, "Mem pool is full. "
+ "Callocing mem");
/* Memory coming from the heap need not be transformed from a
* chunkhead to a usable pointer since it is not coming from
* the pool.
*/
- goto unlocked_out;
}
fwd_addr_out:
+ pool_ptr = mem_pool_from_ptr (ptr);
+ *pool_ptr = (struct mem_pool *)mem_pool;
ptr = mem_pool_chunkhead2ptr (ptr);
-unlocked_out:
UNLOCK (&mem_pool->lock);
return ptr;
@@ -442,7 +475,7 @@ static int
__is_member (struct mem_pool *pool, void *ptr)
{
if (!pool || !ptr) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
return -1;
}
@@ -458,25 +491,41 @@ __is_member (struct mem_pool *pool, void *ptr)
void
-mem_put (struct mem_pool *pool, void *ptr)
+mem_put (void *ptr)
{
struct list_head *list = NULL;
int *in_use = NULL;
void *head = NULL;
+ struct mem_pool **tmp = NULL;
+ struct mem_pool *pool = NULL;
- if (!pool || !ptr) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ if (!ptr) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
return;
}
+ list = head = mem_pool_ptr2chunkhead (ptr);
+ tmp = mem_pool_from_ptr (head);
+ if (!tmp) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR,
+ "ptr header is corrupted");
+ return;
+ }
+
+ pool = *tmp;
+ if (!pool) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR,
+ "mem-pool ptr is NULL");
+ return;
+ }
LOCK (&pool->lock);
{
switch (__is_member (pool, ptr))
{
case 1:
- list = head = mem_pool_ptr2chunkhead (ptr);
- in_use = (head + GF_MEM_POOL_LIST_BOUNDARY);
+ in_use = (head + GF_MEM_POOL_LIST_BOUNDARY +
+ GF_MEM_POOL_PTR);
if (!is_mem_chunk_in_use(in_use)) {
gf_log_callingfn ("mem-pool", GF_LOG_CRITICAL,
"mem_put called on freed ptr %p of mem "
@@ -506,7 +555,8 @@ mem_put (struct mem_pool *pool, void *ptr)
* not have enough info to distinguish between the two
* situations.
*/
- FREE (ptr);
+ pool->curr_stdalloc--;
+ GF_FREE (list);
break;
default:
/* log error */
@@ -516,14 +566,19 @@ mem_put (struct mem_pool *pool, void *ptr)
UNLOCK (&pool->lock);
}
-
void
mem_pool_destroy (struct mem_pool *pool)
{
if (!pool)
return;
+ gf_log (THIS->name, GF_LOG_INFO, "size=%lu max=%d total=%"PRIu64,
+ pool->padded_sizeof_type, pool->max_alloc, pool->alloc_count);
+
+ list_del (&pool->global_list);
+
LOCK_DESTROY (&pool->lock);
+ GF_FREE (pool->name);
GF_FREE (pool->pool);
GF_FREE (pool);
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
index 85ceeb87e..b3a25b25e 100644
--- a/libglusterfs/src/mem-pool.h
+++ b/libglusterfs/src/mem-pool.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 _MEM_POOL_H_
@@ -39,6 +30,7 @@ struct mem_acct_rec {
size_t size;
size_t max_size;
uint32_t num_allocs;
+ uint32_t total_allocs;
uint32_t max_num_allocs;
gf_lock_t lock;
};
@@ -115,7 +107,7 @@ void* __gf_default_realloc (void *oldptr, size_t size)
#define GF_REALLOC(ptr, size) __gf_realloc (ptr, size)
-#define GF_FREE(free_ptr) __gf_free (free_ptr);
+#define GF_FREE(free_ptr) __gf_free (free_ptr)
static inline
char * gf_strdup (const char *src)
@@ -145,14 +137,21 @@ struct mem_pool {
void *pool;
void *pool_end;
int real_sizeof_type;
+ uint64_t alloc_count;
+ uint64_t pool_misses;
+ int max_alloc;
+ int curr_stdalloc;
+ int max_stdalloc;
+ char *name;
+ struct list_head global_list;
};
struct mem_pool *
-mem_pool_new_fn (unsigned long sizeof_type, unsigned long count);
+mem_pool_new_fn (unsigned long sizeof_type, unsigned long count, char *name);
-#define mem_pool_new(type,count) mem_pool_new_fn (sizeof(type), count)
+#define mem_pool_new(type,count) mem_pool_new_fn (sizeof(type), count, #type)
-void mem_put (struct mem_pool *pool, void *ptr);
+void mem_put (void *ptr);
void *mem_get (struct mem_pool *pool);
void *mem_get0 (struct mem_pool *pool);
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
index 9840dac43..12379bf31 100644
--- a/libglusterfs/src/mem-types.h
+++ b/libglusterfs/src/mem-types.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __MEM_TYPES_H__
@@ -98,6 +89,19 @@ enum gf_common_mem_types_ {
gf_common_mt_sge = 73,
gf_common_mt_rpcclnt_cb_program_t = 74,
gf_common_mt_libxl_marker_local = 75,
- gf_common_mt_end = 76
+ gf_common_mt_graph_buf = 76,
+ gf_common_mt_trie_trie = 77,
+ gf_common_mt_trie_data = 78,
+ gf_common_mt_trie_node = 79,
+ gf_common_mt_trie_buf = 80,
+ gf_common_mt_trie_end = 81,
+ gf_common_mt_run_argv = 82,
+ gf_common_mt_run_logbuf = 83,
+ gf_common_mt_fd_lk_ctx_t = 84,
+ gf_common_mt_fd_lk_ctx_node_t = 85,
+ gf_common_mt_buffer_t = 86,
+ gf_common_mt_circular_buffer_t = 87,
+ gf_common_mt_eh_t = 88,
+ gf_common_mt_end = 89
};
#endif
diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c
new file mode 100644
index 000000000..0cec59fdb
--- /dev/null
+++ b/libglusterfs/src/options.c
@@ -0,0 +1,1058 @@
+/*
+ Copyright (c) 2008-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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <fnmatch.h>
+
+#include "xlator.h"
+#include "defaults.h"
+
+#define GF_OPTION_LIST_EMPTY(_opt) (_opt->value[0] == NULL)
+
+
+static int
+xlator_option_validate_path (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+
+ if (strstr (value, "../")) {
+ snprintf (errstr, 256,
+ "invalid path given '%s'",
+ value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ /* Make sure the given path is valid */
+ if (value[0] != '/') {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not an "
+ "absolute path name",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_int (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ long long inputll = 0;
+ int ret = -1;
+ char errstr[256];
+
+ /* Check the range */
+ if (gf_string2longlong (value, &inputll) != 0) {
+ snprintf (errstr, 256,
+ "invalid number format \"%s\" in option \"%s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for 'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ if ((inputll < opt->min) || (inputll > opt->max)) {
+ snprintf (errstr, 256,
+ "'%lld' in 'option %s %s' is out of range "
+ "[%"PRId64" - %"PRId64"]",
+ inputll, key, value, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_sizet (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ uint64_t size = 0;
+ int ret = -1;
+ char errstr[256];
+
+ /* Check the range */
+ if (gf_string2bytesize (value, &size) != 0) {
+ snprintf (errstr, 256,
+ "invalid number format \"%s\" in option \"%s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for 'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ if ((size < opt->min) || (size > opt->max)) {
+ if (strncmp (key, "cache-size", 10) == 0) {
+ snprintf (errstr, 256, "Cache size %"PRId64" is out of "
+ "range [%"PRId64" - %"PRId64"]",
+ size, opt->min, opt->max);
+ //*op_errstr = gf_strdup (errstr);
+ gf_log (xl->name, GF_LOG_WARNING, "%s", errstr);
+ ret = 0;
+ goto out;
+ } else {
+ snprintf (errstr, 256,
+ "'%"PRId64"' in 'option %s %s' "
+ "is out of range [%"PRId64" - %"PRId64"]",
+ size, key, value, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_bool (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ gf_boolean_t bool;
+
+
+ /* Check if the value is one of
+ '0|1|on|off|no|yes|true|false|enable|disable' */
+
+ if (gf_string2boolean (value, &bool) != 0) {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not a valid boolean value",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_xlator (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ xlator_t *xlopt = NULL;
+
+
+ /* Check if the value is one of the xlators */
+ xlopt = xl;
+ while (xlopt->prev)
+ xlopt = xlopt->prev;
+
+ while (xlopt) {
+ if (strcmp (value, xlopt->name) == 0) {
+ ret = 0;
+ break;
+ }
+ xlopt = xlopt->next;
+ }
+
+ if (!xlopt) {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not a valid volume name",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ int i = 0;
+ char errstr[256];
+ char given_array[4096] = {0,};
+
+ /* Check if the '*str' is valid */
+ if (GF_OPTION_LIST_EMPTY(opt)) {
+ ret = 0;
+ goto out;
+ }
+
+ for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i]; i++) {
+ #ifdef GF_DARWIN_HOST_OS
+ if (fnmatch (opt->value[i], value, 0) == 0) {
+ ret = 0;
+ break;
+ }
+ #else
+ if (fnmatch (opt->value[i], value, FNM_EXTMATCH) == 0) {
+ ret = 0;
+ break;
+ }
+ #endif
+ }
+
+ if (((i < ZR_OPTION_MAX_ARRAY_SIZE) && (!opt->value[i])) ||
+ (i == ZR_OPTION_MAX_ARRAY_SIZE)) {
+ /* enter here only if
+ * 1. reached end of opt->value array and haven't
+ * validated input
+ * OR
+ * 2. valid input list is less than
+ * ZR_OPTION_MAX_ARRAY_SIZE and input has not
+ * matched all possible input values.
+ */
+
+ for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i];) {
+ strcat (given_array, opt->value[i]);
+ if (((++i) < ZR_OPTION_MAX_ARRAY_SIZE) &&
+ (opt->value[i]))
+ strcat (given_array, ", ");
+ else
+ strcat (given_array, ".");
+ }
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not valid "
+ "(possible options are %s)",
+ key, value, value, given_array);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_percent (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ uint32_t percent = 0;
+
+
+ /* Check if the value is valid percentage */
+ if (gf_string2percent (value, &percent) != 0) {
+ snprintf (errstr, 256,
+ "invalid percent format \"%s\" in \"option %s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((percent < 0) || (percent > 100)) {
+ snprintf (errstr, 256,
+ "'%d' in 'option %s %s' is out of range [0 - 100]",
+ percent, key, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+static int
+xlator_option_validate_percent_or_sizet (xlator_t *xl, const char *key,
+ const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ uint64_t size = 0;
+ gf_boolean_t is_percent = _gf_false;
+
+ if (gf_string2percent_or_bytesize (value, &size, &is_percent) == 0) {
+ if (is_percent) {
+ ret = 0;
+ goto out;
+ }
+ /* Check the range */
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for "
+ "'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+ if ((size < opt->min) || (size > opt->max)) {
+ snprintf (errstr, 256,
+ "'%"PRId64"' in 'option %s %s'"
+ " is out of range [%"PRId64" -"
+ " %"PRId64"]",
+ size, key, value, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ ret = 0;
+ goto out;
+ }
+
+ /* If control reaches here, invalid argument */
+
+ snprintf (errstr, 256,
+ "invalid number format \"%s\" in \"option %s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+
+
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_time (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ uint32_t input_time = 0;
+
+ /* Check if the value is valid time */
+ if (gf_string2time (value, &input_time) != 0) {
+ snprintf (errstr, 256,
+ "invalid time format \"%s\" in "
+ "\"option %s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for "
+ "'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ if ((input_time < opt->min) || (input_time > opt->max)) {
+ snprintf (errstr, 256,
+ "'%"PRIu32"' in 'option %s %s' is "
+ "out of range [%"PRId64" - %"PRId64"]",
+ input_time, key, value,
+ opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_double (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ double val = 0.0;
+
+ /* Check if the value is valid double */
+ if (gf_string2double (value, &val) != 0) {
+ snprintf (errstr, 256,
+ "invalid double \"%s\" in \"option %s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if (val < 0.0) {
+ snprintf (errstr, 256,
+ "invalid double \"%s\" in \"option %s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for 'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+
+ if (!valid_internet_address ((char *)value, _gf_false)) {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not a valid internet-address,"
+ " it does not conform to standards.",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ if (op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ }
+
+ ret = 0;
+
+ return ret;
+}
+
+static int
+xlator_option_validate_addr_list (xlator_t *xl, const char *key,
+ const char *value, volume_option_t *opt,
+ char **op_errstr)
+{
+ int ret = -1;
+ char *dup_val = NULL;
+ char *addr_tok = NULL;
+ char *save_ptr = NULL;
+ char errstr[256];
+
+ dup_val = gf_strdup (value);
+ if (!dup_val) {
+ ret = -1;
+ snprintf (errstr, 256, "internal error, out of memory.");
+ goto out;
+ }
+
+ addr_tok = strtok_r (dup_val, ",", &save_ptr);
+ while (addr_tok) {
+ if (!valid_internet_address (addr_tok, _gf_true)) {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not a valid "
+ "internet-address-list",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ ret = -1;
+ goto out;
+ }
+ addr_tok = strtok_r (NULL, ",", &save_ptr);
+ }
+ ret = 0;
+ out:
+ if (op_errstr && ret)
+ *op_errstr = gf_strdup (errstr);
+ if (dup_val)
+ GF_FREE (dup_val);
+
+ return ret;
+}
+
+/*XXX: the rules to validate are as per block-size required for stripe xlator */
+static int
+gf_validate_size (const char *sizestr, volume_option_t *opt)
+{
+ uint64_t value = 0;
+ int ret = 0;
+
+ GF_ASSERT (opt);
+
+ if (gf_string2bytesize (sizestr, &value) != 0 ||
+ value < opt->min ||
+ value % 512) {
+ ret = -1;
+ goto out;
+ }
+
+ out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+gf_validate_number (const char *numstr, volume_option_t *opt)
+{
+ int32_t value;
+ return gf_string2int32 (numstr, &value);
+}
+
+/* Parses the string to be of the form <key1>:<value1>,<key2>:<value2>... *
+ * takes two optional validaters key_validator and value_validator */
+static int
+validate_list_elements (const char *string, volume_option_t *opt,
+ int (key_validator)( const char *),
+ int (value_validator)( const char *, volume_option_t *))
+{
+
+ char *dup_string = NULL;
+ char *str_sav = NULL;
+ char *substr_sav = NULL;
+ char *str_ptr = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ int ret = 0;
+
+ GF_ASSERT (string);
+
+ dup_string = gf_strdup (string);
+ if (NULL == dup_string)
+ goto out;
+
+ str_ptr = strtok_r (dup_string, ",", &str_sav);
+ while (str_ptr) {
+
+ key = strtok_r (str_ptr, ":", &substr_sav);
+ if (!key ||
+ (key_validator && key_validator(key))) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "invalid list '%s', key '%s' not valid.",
+ string, key);
+ goto out;
+ }
+
+ value = strtok_r (NULL, ":", &substr_sav);
+ if (!value ||
+ (value_validator && value_validator(value, opt))) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "invalid list '%s', value '%s' not valid.",
+ string, key);
+ goto out;
+ }
+
+ str_ptr = strtok_r (NULL, ",", &str_sav);
+ substr_sav = NULL;
+ }
+ out:
+ if (dup_string)
+ GF_FREE (dup_string);
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+xlator_option_validate_priority_list (xlator_t *xl, const char *key,
+ const char *value, volume_option_t *opt,
+ char **op_errstr)
+{
+ int ret =0;
+ char errstr[1024] = {0, };
+
+ GF_ASSERT (value);
+
+ ret = validate_list_elements (value, opt, NULL, &gf_validate_number);
+ if (ret) {
+ snprintf (errstr, 1024,
+ "option %s %s: '%s' is not a valid "
+ "priority-list", key, value, value);
+ *op_errstr = gf_strdup (errstr);
+ }
+
+ return ret;
+}
+
+static int
+xlator_option_validate_size_list (xlator_t *xl, const char *key,
+ const char *value, volume_option_t *opt,
+ char **op_errstr)
+{
+
+ int ret = 0;
+ char errstr[1024] = {0, };
+
+ GF_ASSERT (value);
+
+ ret = gf_validate_size (value, opt);
+ if (ret)
+ ret = validate_list_elements (value, opt, NULL, &gf_validate_size);
+
+ if (ret) {
+ snprintf (errstr, 1024,
+ "option %s %s: '%s' is not a valid "
+ "size-list", key, value, value);
+ *op_errstr = gf_strdup (errstr);
+ }
+
+ return ret;
+
+}
+
+static int
+xlator_option_validate_any (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ return 0;
+}
+
+typedef int (xlator_option_validator_t) (xlator_t *xl, const char *key,
+ const char *value,
+ volume_option_t *opt, char **operrstr);
+
+int
+xlator_option_validate (xlator_t *xl, char *key, char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ xlator_option_validator_t *validate;
+ xlator_option_validator_t *validators[] = {
+ [GF_OPTION_TYPE_PATH] = xlator_option_validate_path,
+ [GF_OPTION_TYPE_INT] = xlator_option_validate_int,
+ [GF_OPTION_TYPE_SIZET] = xlator_option_validate_sizet,
+ [GF_OPTION_TYPE_BOOL] = xlator_option_validate_bool,
+ [GF_OPTION_TYPE_XLATOR] = xlator_option_validate_xlator,
+ [GF_OPTION_TYPE_STR] = xlator_option_validate_str,
+ [GF_OPTION_TYPE_PERCENT] = xlator_option_validate_percent,
+ [GF_OPTION_TYPE_PERCENT_OR_SIZET] =
+ xlator_option_validate_percent_or_sizet,
+ [GF_OPTION_TYPE_TIME] = xlator_option_validate_time,
+ [GF_OPTION_TYPE_DOUBLE] = xlator_option_validate_double,
+ [GF_OPTION_TYPE_INTERNET_ADDRESS] = xlator_option_validate_addr,
+ [GF_OPTION_TYPE_INTERNET_ADDRESS_LIST] =
+ xlator_option_validate_addr_list,
+ [GF_OPTION_TYPE_PRIORITY_LIST] =
+ xlator_option_validate_priority_list,
+ [GF_OPTION_TYPE_SIZE_LIST] = xlator_option_validate_size_list,
+ [GF_OPTION_TYPE_ANY] = xlator_option_validate_any,
+ [GF_OPTION_TYPE_MAX] = NULL,
+ };
+
+ if (opt->type < 0 || opt->type >= GF_OPTION_TYPE_MAX) {
+ gf_log (xl->name, GF_LOG_ERROR,
+ "unknown option type '%d'", opt->type);
+ goto out;
+ }
+
+ validate = validators[opt->type];
+
+ ret = validate (xl, key, value, opt, op_errstr);
+out:
+ return ret;
+}
+
+
+static volume_option_t *
+xlator_volume_option_get_list (volume_opt_list_t *vol_list, const char *key)
+{
+ volume_option_t *opt = NULL;
+ volume_opt_list_t *opt_list = NULL;
+ volume_option_t *found = NULL;
+ int index = 0;
+ int i = 0;
+ char *cmp_key = NULL;
+
+ if (!vol_list->given_opt) {
+ opt_list = list_entry (vol_list->list.next, volume_opt_list_t,
+ list);
+ opt = opt_list->given_opt;
+ } else
+ opt = vol_list->given_opt;
+
+ for (index = 0; opt[index].key[0]; index++) {
+ for (i = 0; i < ZR_VOLUME_MAX_NUM_KEY; i++) {
+ cmp_key = opt[index].key[i];
+ if (!cmp_key)
+ break;
+ if (fnmatch (cmp_key, key, FNM_NOESCAPE) == 0) {
+ found = &opt[index];
+ goto out;
+ }
+ }
+ }
+out:
+ return found;
+}
+
+
+volume_option_t *
+xlator_volume_option_get (xlator_t *xl, const char *key)
+{
+ volume_opt_list_t *vol_list = NULL;
+ volume_option_t *found = NULL;
+
+ list_for_each_entry (vol_list, &xl->volume_options, list) {
+ found = xlator_volume_option_get_list (vol_list, key);
+ if (found)
+ break;
+ }
+
+ return found;
+}
+
+
+static void
+xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
+{
+ xlator_t *xl = NULL;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_option_t *opt = NULL;
+ int ret = 0;
+ char *errstr = NULL;
+
+ struct {
+ xlator_t *this;
+ volume_opt_list_t *vol_opt;
+ char *errstr;
+ } *stub;
+
+ stub = data;
+ xl = stub->this;
+ vol_opt = stub->vol_opt;
+
+ opt = xlator_volume_option_get_list (vol_opt, key);
+ if (!opt)
+ return;
+
+ ret = xlator_option_validate (xl, key, value->data, opt, &errstr);
+ if (ret)
+ gf_log (xl->name, GF_LOG_WARNING, "validate of %s returned %d",
+ key, ret);
+
+ if (errstr)
+ /* possible small leak of previously set stub->errstr */
+ stub->errstr = errstr;
+
+ if (fnmatch (opt->key[0], key, FNM_NOESCAPE) != 0) {
+ gf_log (xl->name, GF_LOG_WARNING, "option '%s' is deprecated, "
+ "preferred is '%s', continuing with correction",
+ key, opt->key[0]);
+ dict_set (dict, opt->key[0], value);
+ dict_del (dict, key);
+ }
+ return;
+}
+
+
+int
+xlator_options_validate_list (xlator_t *xl, dict_t *options,
+ volume_opt_list_t *vol_opt, char **op_errstr)
+{
+ int ret = 0;
+ struct {
+ xlator_t *this;
+ volume_opt_list_t *vol_opt;
+ char *errstr;
+ } stub;
+
+ stub.this = xl;
+ stub.vol_opt = vol_opt;
+ stub.errstr = NULL;
+
+ dict_foreach (options, xl_opt_validate, &stub);
+ if (stub.errstr) {
+ ret = -1;
+ if (op_errstr)
+ *op_errstr = stub.errstr;
+ }
+
+ return ret;
+}
+
+
+int
+xlator_options_validate (xlator_t *xl, dict_t *options, char **op_errstr)
+{
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+
+
+ if (!xl) {
+ gf_log (THIS->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret = -1;
+ goto out;
+ }
+
+ if (list_empty (&xl->volume_options))
+ goto out;
+
+ list_for_each_entry (vol_opt, &xl->volume_options, list) {
+ ret = xlator_options_validate_list (xl, options, vol_opt,
+ op_errstr);
+ }
+out:
+ return ret;
+}
+
+
+int
+xlator_validate_rec (xlator_t *xlator, char **op_errstr)
+{
+ int ret = -1;
+ xlator_list_t *trav = NULL;
+ xlator_t *old_THIS = NULL;
+
+ GF_VALIDATE_OR_GOTO ("xlator", xlator, out);
+
+ trav = xlator->children;
+
+ while (trav) {
+ if (xlator_validate_rec (trav->xlator, op_errstr)) {
+ gf_log ("xlator", GF_LOG_WARNING, "validate_rec failed");
+ goto out;
+ }
+
+ trav = trav->next;
+ }
+
+ if (xlator_dynload (xlator))
+ gf_log (xlator->name, GF_LOG_DEBUG, "Did not load the symbols");
+
+ old_THIS = THIS;
+ THIS = xlator;
+
+ /* Need this here, as this graph has not yet called init() */
+ if (!xlator->mem_acct.num_types) {
+ if (!xlator->mem_acct_init)
+ xlator->mem_acct_init = default_mem_acct_init;
+ xlator->mem_acct_init (xlator);
+ }
+
+ ret = xlator_options_validate (xlator, xlator->options, op_errstr);
+ THIS = old_THIS;
+
+ if (ret) {
+ gf_log (xlator->name, GF_LOG_INFO, "%s", *op_errstr);
+ goto out;
+ }
+
+ gf_log (xlator->name, GF_LOG_DEBUG, "Validated options");
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int
+graph_reconf_validateopt (glusterfs_graph_t *graph, char **op_errstr)
+{
+ xlator_t *xlator = NULL;
+ int ret = -1;
+
+ GF_ASSERT (graph);
+
+ xlator = graph->first;
+
+ ret = xlator_validate_rec (xlator, op_errstr);
+
+ return ret;
+}
+
+
+static int
+xlator_reconfigure_rec (xlator_t *old_xl, xlator_t *new_xl)
+{
+ xlator_list_t *trav1 = NULL;
+ xlator_list_t *trav2 = NULL;
+ int32_t ret = -1;
+ xlator_t *old_THIS = NULL;
+
+ GF_VALIDATE_OR_GOTO ("xlator", old_xl, out);
+ GF_VALIDATE_OR_GOTO ("xlator", new_xl, out);
+
+ trav1 = old_xl->children;
+ trav2 = new_xl->children;
+
+ while (trav1 && trav2) {
+ ret = xlator_reconfigure_rec (trav1->xlator, trav2->xlator);
+ if (ret)
+ goto out;
+
+ gf_log (trav1->xlator->name, GF_LOG_DEBUG, "reconfigured");
+
+ trav1 = trav1->next;
+ trav2 = trav2->next;
+ }
+
+ if (old_xl->reconfigure) {
+ old_THIS = THIS;
+ THIS = old_xl;
+
+ ret = old_xl->reconfigure (old_xl, new_xl->options);
+
+ THIS = old_THIS;
+
+ if (ret)
+ goto out;
+ } else {
+ gf_log (old_xl->name, GF_LOG_DEBUG, "No reconfigure() found");
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int
+xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl)
+{
+ xlator_t *new_top = NULL;
+ xlator_t *old_top = NULL;
+
+ GF_ASSERT (old_xl);
+ GF_ASSERT (new_xl);
+
+ old_top = old_xl;
+ new_top = new_xl;
+
+ return xlator_reconfigure_rec (old_top, new_top);
+}
+
+
+int
+xlator_option_info_list (volume_opt_list_t *list, char *key,
+ char **def_val, char **descr)
+{
+ int ret = -1;
+ volume_option_t *opt = NULL;
+
+
+ opt = xlator_volume_option_get_list (list, key);
+ if (!opt)
+ goto out;
+
+ if (def_val)
+ *def_val = opt->default_value;
+ if (descr)
+ *descr = opt->description;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+static int
+not_null (char *in, char **out)
+{
+ if (!in || !out)
+ return -1;
+
+ *out = in;
+ return 0;
+}
+
+
+static int
+xl_by_name (char *in, xlator_t **out)
+{
+ xlator_t *xl = NULL;
+
+ xl = xlator_search_by_name (THIS, in);
+
+ if (!xl)
+ return -1;
+ *out = xl;
+ return 0;
+}
+
+
+static int
+pc_or_size (char *in, uint64_t *out)
+{
+ uint32_t pc = 0;
+ int ret = 0;
+
+ if (gf_string2percent (in, &pc) == 0) {
+ if (pc > 100) {
+ ret = gf_string2bytesize (in, out);
+ } else {
+ *out = pc;
+ }
+ } else {
+ ret = gf_string2bytesize (in, out);
+ }
+ return ret;
+}
+
+
+DEFINE_INIT_OPT(char *, str, not_null);
+DEFINE_INIT_OPT(uint64_t, uint64, gf_string2uint64);
+DEFINE_INIT_OPT(int64_t, int64, gf_string2int64);
+DEFINE_INIT_OPT(uint32_t, uint32, gf_string2uint32);
+DEFINE_INIT_OPT(int32_t, int32, gf_string2int32);
+DEFINE_INIT_OPT(uint64_t, size, gf_string2bytesize);
+DEFINE_INIT_OPT(uint32_t, percent, gf_string2percent);
+DEFINE_INIT_OPT(uint64_t, percent_or_size, pc_or_size);
+DEFINE_INIT_OPT(gf_boolean_t, bool, gf_string2boolean);
+DEFINE_INIT_OPT(xlator_t *, xlator, xl_by_name);
+DEFINE_INIT_OPT(char *, path, not_null);
+
+
+
+DEFINE_RECONF_OPT(char *, str, not_null);
+DEFINE_RECONF_OPT(uint64_t, uint64, gf_string2uint64);
+DEFINE_RECONF_OPT(int64_t, int64, gf_string2int64);
+DEFINE_RECONF_OPT(uint32_t, uint32, gf_string2uint32);
+DEFINE_RECONF_OPT(int32_t, int32, gf_string2int32);
+DEFINE_RECONF_OPT(uint64_t, size, gf_string2bytesize);
+DEFINE_RECONF_OPT(uint32_t, percent, gf_string2percent);
+DEFINE_RECONF_OPT(uint64_t, percent_or_size, pc_or_size);
+DEFINE_RECONF_OPT(gf_boolean_t, bool, gf_string2boolean);
+DEFINE_RECONF_OPT(xlator_t *, xlator, xl_by_name);
+DEFINE_RECONF_OPT(char *, path, not_null);
diff --git a/libglusterfs/src/options.h b/libglusterfs/src/options.h
new file mode 100644
index 000000000..01d2a9d5f
--- /dev/null
+++ b/libglusterfs/src/options.h
@@ -0,0 +1,242 @@
+/*
+ Copyright (c) 2008-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 _OPTIONS_H
+#define _OPTIONS_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "xlator.h"
+/* Add possible new type of option you may need */
+typedef enum {
+ GF_OPTION_TYPE_ANY = 0,
+ GF_OPTION_TYPE_STR,
+ GF_OPTION_TYPE_INT,
+ GF_OPTION_TYPE_SIZET,
+ GF_OPTION_TYPE_PERCENT,
+ GF_OPTION_TYPE_PERCENT_OR_SIZET,
+ GF_OPTION_TYPE_BOOL,
+ GF_OPTION_TYPE_XLATOR,
+ GF_OPTION_TYPE_PATH,
+ GF_OPTION_TYPE_TIME,
+ GF_OPTION_TYPE_DOUBLE,
+ GF_OPTION_TYPE_INTERNET_ADDRESS,
+ GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ GF_OPTION_TYPE_PRIORITY_LIST,
+ GF_OPTION_TYPE_SIZE_LIST,
+ GF_OPTION_TYPE_MAX,
+} volume_option_type_t;
+
+
+#define ZR_VOLUME_MAX_NUM_KEY 4
+#define ZR_OPTION_MAX_ARRAY_SIZE 64
+
+/* Each translator should define this structure */
+typedef struct volume_options {
+ char *key[ZR_VOLUME_MAX_NUM_KEY];
+ /* different key, same meaning */
+ volume_option_type_t type;
+ int64_t min; /* 0 means no range */
+ int64_t max; /* 0 means no range */
+ char *value[ZR_OPTION_MAX_ARRAY_SIZE];
+ /* If specified, will check for one of
+ the value from this array */
+ char *default_value;
+ char *description; /* about the key */
+} volume_option_t;
+
+
+typedef struct vol_opt_list {
+ struct list_head list;
+ volume_option_t *given_opt;
+} volume_opt_list_t;
+
+
+int xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl);
+int xlator_validate_rec (xlator_t *xlator, char **op_errstr);
+int graph_reconf_validateopt (glusterfs_graph_t *graph, char **op_errstr);
+int xlator_option_info_list (volume_opt_list_t *list, char *key,
+ char **def_val, char **descr);
+/*
+int validate_xlator_volume_options (xlator_t *xl, dict_t *options,
+ volume_option_t *opt, char **op_errstr);
+*/
+int xlator_options_validate_list (xlator_t *xl, dict_t *options,
+ volume_opt_list_t *list, char **op_errstr);
+int xlator_option_validate (xlator_t *xl, char *key, char *value,
+ volume_option_t *opt, char **op_errstr);
+int xlator_options_validate (xlator_t *xl, dict_t *options, char **errstr);
+volume_option_t *
+xlator_volume_option_get (xlator_t *xl, const char *key);
+
+
+#define DECLARE_INIT_OPT(type_t, type) \
+int \
+xlator_option_init_##type (xlator_t *this, dict_t *options, char *key, \
+ type_t *val_p);
+
+DECLARE_INIT_OPT(char *, str);
+DECLARE_INIT_OPT(uint64_t, uint64);
+DECLARE_INIT_OPT(int64_t, int64);
+DECLARE_INIT_OPT(uint32_t, uint32);
+DECLARE_INIT_OPT(int32_t, int32);
+DECLARE_INIT_OPT(uint64_t, size);
+DECLARE_INIT_OPT(uint32_t, percent);
+DECLARE_INIT_OPT(uint64_t, percent_or_size);
+DECLARE_INIT_OPT(gf_boolean_t, bool);
+DECLARE_INIT_OPT(xlator_t *, xlator);
+DECLARE_INIT_OPT(char *, path);
+
+
+#define DEFINE_INIT_OPT(type_t, type, conv) \
+int \
+xlator_option_init_##type (xlator_t *this, dict_t *options, char *key, \
+ type_t *val_p) \
+{ \
+ int ret = 0; \
+ volume_option_t *opt = NULL; \
+ char *def_value = NULL; \
+ char *set_value = NULL; \
+ char *value = NULL; \
+ xlator_t *old_THIS = NULL; \
+ \
+ opt = xlator_volume_option_get (this, key); \
+ if (!opt) { \
+ gf_log (this->name, GF_LOG_WARNING, \
+ "unknown option: %s", key); \
+ ret = -1; \
+ return ret; \
+ } \
+ def_value = opt->default_value; \
+ ret = dict_get_str (options, key, &set_value); \
+ \
+ if (def_value) \
+ value = def_value; \
+ if (set_value) \
+ value = set_value; \
+ if (!value) { \
+ gf_log (this->name, GF_LOG_TRACE, "option %s not set", \
+ key); \
+ return 0; \
+ } \
+ if (value == def_value) { \
+ gf_log (this->name, GF_LOG_TRACE, \
+ "option %s using default value %s", \
+ key, value); \
+ } else { \
+ gf_log (this->name, GF_LOG_DEBUG, \
+ "option %s using set value %s", \
+ key, value); \
+ } \
+ old_THIS = THIS; \
+ THIS = this; \
+ ret = conv (value, val_p); \
+ THIS = old_THIS; \
+ if (ret) \
+ return ret; \
+ ret = xlator_option_validate (this, key, value, opt, NULL); \
+ return ret; \
+}
+
+#define GF_OPTION_INIT(key, val, type, err_label) do { \
+ int val_ret = 0; \
+ val_ret = xlator_option_init_##type (THIS, THIS->options, \
+ key, &(val)); \
+ if (val_ret) \
+ goto err_label; \
+ } while (0)
+
+
+
+#define DECLARE_RECONF_OPT(type_t, type) \
+int \
+xlator_option_reconf_##type (xlator_t *this, dict_t *options, char *key,\
+ type_t *val_p);
+
+DECLARE_RECONF_OPT(char *, str);
+DECLARE_RECONF_OPT(uint64_t, uint64);
+DECLARE_RECONF_OPT(int64_t, int64);
+DECLARE_RECONF_OPT(uint32_t, uint32);
+DECLARE_RECONF_OPT(int32_t, int32);
+DECLARE_RECONF_OPT(uint64_t, size);
+DECLARE_RECONF_OPT(uint32_t, percent);
+DECLARE_RECONF_OPT(uint64_t, percent_or_size);
+DECLARE_RECONF_OPT(gf_boolean_t, bool);
+DECLARE_RECONF_OPT(xlator_t *, xlator);
+DECLARE_RECONF_OPT(char *, path);
+
+
+#define DEFINE_RECONF_OPT(type_t, type, conv) \
+int \
+xlator_option_reconf_##type (xlator_t *this, dict_t *options, char *key, \
+ type_t *val_p) \
+{ \
+ int ret = 0; \
+ volume_option_t *opt = NULL; \
+ char *def_value = NULL; \
+ char *set_value = NULL; \
+ char *value = NULL; \
+ xlator_t *old_THIS = NULL; \
+ \
+ opt = xlator_volume_option_get (this, key); \
+ if (!opt) { \
+ gf_log (this->name, GF_LOG_WARNING, \
+ "unknown option: %s", key); \
+ ret = -1; \
+ return ret; \
+ } \
+ def_value = opt->default_value; \
+ ret = dict_get_str (options, key, &set_value); \
+ \
+ if (def_value) \
+ value = def_value; \
+ if (set_value) \
+ value = set_value; \
+ if (!value) { \
+ gf_log (this->name, GF_LOG_TRACE, "option %s not set", \
+ key); \
+ return 0; \
+ } \
+ if (value == def_value) { \
+ gf_log (this->name, GF_LOG_TRACE, \
+ "option %s using default value %s", \
+ key, value); \
+ } else { \
+ gf_log (this->name, GF_LOG_DEBUG, \
+ "option %s using set value %s", \
+ key, value); \
+ } \
+ old_THIS = THIS; \
+ THIS = this; \
+ ret = conv (value, val_p); \
+ THIS = old_THIS; \
+ if (ret) \
+ return ret; \
+ ret = xlator_option_validate (this, key, value, opt, NULL); \
+ return ret; \
+}
+
+#define GF_OPTION_RECONF(key, val, opt, type, err_label) do { \
+ int val_ret = 0; \
+ val_ret = xlator_option_reconf_##type (THIS, opt, key, \
+ &(val)); \
+ if (val_ret) \
+ goto err_label; \
+ } while (0)
+
+
+#endif /* !_OPTIONS_H */
diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c
index 2f41d9825..4f04fed93 100644
--- a/libglusterfs/src/rbthash.c
+++ b/libglusterfs/src/rbthash.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -141,6 +132,7 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc,
}
LOCK_INIT (&newtab->tablelock);
+ INIT_LIST_HEAD (&newtab->list);
newtab->numbuckets = buckets;
ret = __rbthash_init_buckets (newtab, buckets);
@@ -191,6 +183,7 @@ rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen)
goto free_entry;
}
+ INIT_LIST_HEAD (&entry->list);
memcpy (entry->key, key, keylen);
entry->keylen = keylen;
entry->keyhash = tbl->hashfunc (entry->key, entry->keylen);
@@ -199,7 +192,7 @@ rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen)
ret = 0;
free_entry:
if (ret == -1) {
- mem_put (tbl->entrypool, entry);
+ mem_put (entry);
entry = NULL;
}
@@ -221,7 +214,14 @@ rbthash_deinit_entry (rbthash_table_t *tbl, rbthash_entry_t *entry)
if (tbl) {
if ((entry->data) && (tbl->dfunc))
tbl->dfunc (entry->data);
- mem_put (tbl->entrypool, entry);
+
+ LOCK (&tbl->tablelock);
+ {
+ list_del_init (&entry->list);
+ }
+ UNLOCK (&tbl->tablelock);
+
+ mem_put (entry);
}
return;
@@ -292,6 +292,12 @@ rbthash_insert (rbthash_table_t *tbl, void *data, void *key, int keylen)
rbthash_deinit_entry (tbl, entry);
}
+ LOCK (&tbl->tablelock);
+ {
+ list_add_tail (&entry->list, &tbl->list);
+ }
+ UNLOCK (&tbl->tablelock);
+
err:
return ret;
}
@@ -376,7 +382,14 @@ rbthash_remove (rbthash_table_t *tbl, void *key, int keylen)
GF_FREE (entry->key);
dataref = entry->data;
- mem_put (tbl->entrypool, entry);
+
+ LOCK (&tbl->tablelock);
+ {
+ list_del_init (&entry->list);
+ }
+ UNLOCK (&tbl->tablelock);
+
+ mem_put (entry);
return dataref;
}
@@ -421,3 +434,26 @@ rbthash_table_destroy (rbthash_table_t *tbl)
GF_FREE (tbl->buckets);
GF_FREE (tbl);
}
+
+
+void
+rbthash_table_traverse (rbthash_table_t *tbl, rbt_traverse_t traverse,
+ void *mydata)
+{
+ rbthash_entry_t *entry = NULL;
+
+ if ((tbl == NULL) || (traverse == NULL)) {
+ goto out;
+ }
+
+ LOCK (&tbl->tablelock);
+ {
+ list_for_each_entry (entry, &tbl->list, list) {
+ traverse (entry->data, mydata);
+ }
+ }
+ UNLOCK (&tbl->tablelock);
+
+out:
+ return;
+}
diff --git a/libglusterfs/src/rbthash.h b/libglusterfs/src/rbthash.h
index 73b5b8e30..b093ce998 100644
--- a/libglusterfs/src/rbthash.h
+++ b/libglusterfs/src/rbthash.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __RBTHASH_TABLE_H_
@@ -24,6 +15,7 @@
#include "mem-pool.h"
#include "logging.h"
#include "common-utils.h"
+#include "list.h"
#include <pthread.h>
@@ -38,12 +30,14 @@ struct rbthash_bucket {
typedef struct rbthash_entry {
void *data;
void *key;
- int keylen;
- uint32_t keyhash;
+ int keylen;
+ uint32_t keyhash;
+ struct list_head list;
} rbthash_entry_t;
typedef uint32_t (*rbt_hasher_t) (void *data, int len);
typedef void (*rbt_data_destroyer_t) (void *data);
+typedef void (*rbt_traverse_t) (void *data, void *mydata);
typedef struct rbthash_table {
int size;
@@ -54,6 +48,7 @@ typedef struct rbthash_table {
rbt_hasher_t hashfunc;
rbt_data_destroyer_t dfunc;
gf_boolean_t pool_alloced;
+ struct list_head list;
} rbthash_table_t;
extern rbthash_table_t *
@@ -75,4 +70,8 @@ rbthash_replace (rbthash_table_t *tbl, void *key, int keylen, void *newdata);
extern void
rbthash_table_destroy (rbthash_table_t *tbl);
+
+extern void
+rbthash_table_traverse (rbthash_table_t *tbl, rbt_traverse_t traverse,
+ void *mydata);
#endif
diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c
new file mode 100644
index 000000000..adc61513a
--- /dev/null
+++ b/libglusterfs/src/run.c
@@ -0,0 +1,490 @@
+/*
+ Copyright (c) 2008-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 _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <assert.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+
+#ifdef RUN_STANDALONE
+#define GF_CALLOC(n, s, t) calloc(n, s)
+#define GF_ASSERT(cond) assert(cond)
+#define GF_REALLOC(p, s) realloc(p, s)
+#define GF_FREE(p) free(p)
+#define gf_strdup(s) strdup(s)
+#define gf_vasprintf(p, f, va) vasprintf(p, f, va)
+#define gf_loglevel_t int
+#define gf_log(dom, levl, fmt, args...) printf("LOG: " fmt "\n", ##args)
+#define LOG_DEBUG 0
+#ifdef __linux__
+#define GF_LINUX_HOST_OS
+#endif
+#else /* ! RUN_STANDALONE */
+#include "glusterfs.h"
+#include "common-utils.h"
+#endif
+
+#include "run.h"
+
+void
+runinit (runner_t *runner)
+{
+ int i = 0;
+
+ runner->argvlen = 64;
+ runner->argv = GF_CALLOC (runner->argvlen,
+ sizeof (*runner->argv),
+ gf_common_mt_run_argv);
+ runner->runerr = runner->argv ? 0 : errno;
+ runner->chpid = -1;
+ for (i = 0; i < 3; i++) {
+ runner->chfd[i] = -1;
+ runner->chio[i] = NULL;
+ }
+}
+
+FILE *
+runner_chio (runner_t *runner, int fd)
+{
+ GF_ASSERT (fd > 0 && fd < 3);
+
+ return runner->chio[fd];
+}
+
+static void
+runner_insert_arg (runner_t *runner, char *arg)
+{
+ int i = 0;
+
+ GF_ASSERT (arg);
+
+ if (runner->runerr)
+ return;
+
+ for (i = 0; i < runner->argvlen; i++) {
+ if (runner->argv[i] == NULL)
+ break;
+ }
+ GF_ASSERT (i < runner->argvlen);
+
+ if (i == runner->argvlen - 1) {
+ runner->argv = GF_REALLOC (runner->argv,
+ runner->argvlen * 2 * sizeof (*runner->argv));
+ if (!runner->argv) {
+ runner->runerr = errno;
+ return;
+ }
+ memset (/* "+" is aware of the type of its left side,
+ * no need to multiply with type-size */
+ runner->argv + runner->argvlen,
+ 0, runner->argvlen * sizeof (*runner->argv));
+ runner->argvlen *= 2;
+ }
+
+ runner->argv[i] = arg;
+}
+
+void
+runner_add_arg (runner_t *runner, const char *arg)
+{
+ arg = gf_strdup (arg);
+ if (!arg) {
+ runner->runerr = errno;
+ return;
+ }
+
+ runner_insert_arg (runner, (char *)arg);
+}
+
+static void
+runner_va_add_args (runner_t *runner, va_list argp)
+{
+ const char *arg;
+
+ while ((arg = va_arg (argp, const char *)))
+ runner_add_arg (runner, arg);
+}
+
+void
+runner_add_args (runner_t *runner, ...)
+{
+ va_list argp;
+
+ va_start (argp, runner);
+ runner_va_add_args (runner, argp);
+ va_end (argp);
+}
+
+void
+runner_argprintf (runner_t *runner, const char *format, ...)
+{
+ va_list argva;
+ char *arg = NULL;
+ int ret = 0;
+
+ va_start (argva, format);
+ ret = gf_vasprintf (&arg, format, argva);
+ va_end (argva);
+
+ if (ret < 0) {
+ runner->runerr = errno;
+ return;
+ }
+
+ runner_insert_arg (runner, arg);
+}
+
+void
+runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
+ const char *msg)
+{
+ char *buf = NULL;
+ size_t len = 0;
+ int i = 0;
+
+ if (runner->runerr)
+ return;
+
+ for (i = 0;; i++) {
+ if (runner->argv[i] == NULL)
+ break;
+ len += (strlen (runner->argv[i]) + 1);
+ }
+
+ buf = GF_CALLOC (1, len + 1, gf_common_mt_run_logbuf);
+ if (!buf) {
+ runner->runerr = errno;
+ return;
+ }
+ for (i = 0;; i++) {
+ if (runner->argv[i] == NULL)
+ break;
+ strcat (buf, runner->argv[i]);
+ strcat (buf, " ");
+ }
+ if (len > 0)
+ buf[len - 1] = '\0';
+
+ gf_log (dom, lvl, "%s: %s", msg, buf);
+
+ GF_FREE (buf);
+}
+
+void
+runner_redir (runner_t *runner, int fd, int tgt_fd)
+{
+ GF_ASSERT (fd > 0 && fd < 3);
+
+ runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
+}
+
+int
+runner_start (runner_t *runner)
+{
+ int pi[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}};
+ int xpi[2];
+ int ret = 0;
+ int errno_priv = 0;
+ int i = 0;
+ sigset_t set;
+
+ if (runner->runerr) {
+ errno = runner->runerr;
+ return -1;
+ }
+
+ GF_ASSERT (runner->argv[0]);
+
+ /* set up a channel to child to communicate back
+ * possible execve(2) failures
+ */
+ ret = pipe(xpi);
+ if (ret != -1)
+ ret = fcntl (xpi[1], F_SETFD, FD_CLOEXEC);
+
+ for (i = 0; i < 3; i++) {
+ if (runner->chfd[i] != -2)
+ continue;
+ ret = pipe (pi[i]);
+ if (ret != -1) {
+ runner->chio[i] = fdopen (pi[i][i ? 0 : 1], i ? "r" : "w");
+ if (!runner->chio[i])
+ ret = -1;
+ }
+ }
+
+ if (ret != -1)
+ runner->chpid = fork ();
+ switch (runner->chpid) {
+ case -1:
+ errno_priv = errno;
+ close (xpi[0]);
+ close (xpi[1]);
+ for (i = 0; i < 3; i++) {
+ close (pi[i][0]);
+ close (pi[i][1]);
+ }
+ errno = errno_priv;
+ return -1;
+ case 0:
+ for (i = 0; i < 3; i++)
+ close (pi[i][i ? 0 : 1]);
+ close (xpi[0]);
+ ret = 0;
+
+ for (i = 0; i < 3; i++) {
+ if (ret == -1)
+ break;
+ switch (runner->chfd[i]) {
+ case -1:
+ /* no redir */
+ break;
+ case -2:
+ /* redir to pipe */
+ ret = dup2 (pi[i][i ? 1 : 0], i);
+ break;
+ default:
+ /* redir to file */
+ ret = dup2 (runner->chfd[i], i);
+ }
+ }
+
+ if (ret != -1 ) {
+#ifdef GF_LINUX_HOST_OS
+ DIR *d = NULL;
+ struct dirent *de = NULL;
+ char *e = NULL;
+
+ d = opendir ("/proc/self/fd");
+ if (d) {
+ while ((de = readdir (d))) {
+ i = strtoul (de->d_name, &e, 10);
+ if (*e == '\0' && i > 2 &&
+ i != dirfd (d) && i != xpi[1])
+ close (i);
+ }
+ closedir (d);
+ } else
+ ret = -1;
+#else
+ struct rlimit rl;
+ ret = getrlimit (RLIMIT_NOFILE, &rl);
+ GF_ASSERT (ret == 0);
+
+ for (i = 3; i < rl.rlim_cur; i++) {
+ if (i != xpi[1])
+ close (i);
+ }
+#endif
+ }
+
+ if (ret != -1) {
+ /* save child from inheriting our singal handling */
+ sigemptyset (&set);
+ sigprocmask (SIG_SETMASK, &set, NULL);
+
+ execvp (runner->argv[0], runner->argv);
+ }
+ ret = write (xpi[1], &errno, sizeof (errno));
+ _exit (1);
+ }
+
+ errno_priv = errno;
+ for (i = 0; i < 3; i++)
+ close (pi[i][i ? 1 : 0]);
+ close (xpi[1]);
+ if (ret == -1) {
+ for (i = 0; i < 3; i++) {
+ if (runner->chio[i]) {
+ fclose (runner->chio[i]);
+ runner->chio[i] = NULL;
+ }
+ }
+ } else {
+ ret = read (xpi[0], (char *)&errno_priv, sizeof (errno_priv));
+ close (xpi[0]);
+ if (ret <= 0)
+ return 0;
+ GF_ASSERT (ret == sizeof (errno_priv));
+ }
+ errno = errno_priv;
+ return -1;
+}
+
+int
+runner_end_reuse (runner_t *runner)
+{
+ int i = 0;
+ int ret = -1;
+ int chstat = 0;
+
+ if (runner->chpid > 0) {
+ if (waitpid (runner->chpid, &chstat, 0) == runner->chpid)
+ ret = chstat;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (runner->chio[i]) {
+ fclose (runner->chio[i]);
+ runner->chio[i] = NULL;
+ }
+ }
+
+ return ret;
+}
+
+int
+runner_end (runner_t *runner)
+{
+ int i = 0;
+ int ret = -1;
+ char **p = NULL;
+
+ ret = runner_end_reuse (runner);
+
+ if (runner->argv) {
+ for (p = runner->argv; *p; p++)
+ GF_FREE (*p);
+ GF_FREE (runner->argv);
+ }
+ for (i = 0; i < 3; i++)
+ close (runner->chfd[i]);
+
+ return ret;
+}
+
+static int
+runner_run_generic (runner_t *runner, int (*rfin)(runner_t *runner))
+{
+ int ret = 0;
+
+ ret = runner_start (runner);
+
+ return -(rfin (runner) || ret);
+}
+
+int
+runner_run (runner_t *runner)
+{
+ return runner_run_generic (runner, runner_end);
+}
+
+int
+runner_run_reuse (runner_t *runner)
+{
+ return runner_run_generic (runner, runner_end_reuse);
+}
+
+int
+runcmd (const char *arg, ...)
+{
+ runner_t runner;
+ va_list argp;
+
+ runinit (&runner);
+ /* ISO C requires a named argument before '...' */
+ runner_add_arg (&runner, arg);
+
+ va_start (argp, arg);
+ runner_va_add_args (&runner, argp);
+ va_end (argp);
+
+ return runner_run (&runner);
+}
+
+#ifdef RUN_DO_TESTS
+static void
+TBANNER (const char *txt)
+{
+ printf("######\n### testing %s\n", txt);
+}
+
+int
+main (int argc, char **argv)
+{
+ runner_t runner;
+ char buf[80];
+ char *wdbuf;;
+ int ret;
+ int fd;
+ long pathmax = pathconf ("/", _PC_PATH_MAX);
+ struct timeval tv = {0,};
+ struct timeval *tvp = NULL;
+
+ wdbuf = malloc (pathmax);
+ assert (wdbuf);
+ getcwd (wdbuf, pathmax);
+
+ TBANNER ("basic functionality");
+ runcmd ("echo", "a", "b", NULL);
+
+ TBANNER ("argv extension");
+ runcmd ("echo", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
+ "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
+ "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
+ "31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
+ "41", "42", "43", "44", "45", "46", "47", "48", "49", "50",
+ "51", "52", "53", "54", "55", "56", "57", "58", "59", "60",
+ "61", "62", "63", "64", "65", "66", "67", "68", "69", "70",
+ "71", "72", "73", "74", "75", "76", "77", "78", "79", "80",
+ "81", "82", "83", "84", "85", "86", "87", "88", "89", "90",
+ "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", NULL);
+
+ TBANNER ("add_args, argprintf, log, and popen-style functionality");
+ runinit (&runner);
+ runner_add_args (&runner, "echo", "pid:", NULL);
+ runner_argprintf (&runner, "%d\n", getpid());
+ runner_add_arg (&runner, "wd:");
+ runner_add_arg (&runner, wdbuf);
+ runner_redir (&runner, 1, RUN_PIPE);
+ runner_start (&runner);
+ runner_log (&runner, "(x)", LOG_DEBUG, "starting program");
+ while (fgets (buf, sizeof(buf), runner_chio (&runner, 1)))
+ printf ("got: %s", buf);
+ runner_end (&runner);
+
+ TBANNER ("execve error reporting");
+ ret = runcmd ("bafflavvitty", NULL);
+ printf ("%d %d [%s]\n", ret, errno, strerror (errno));
+
+ TBANNER ("output redirection");
+ fd = mkstemp ("/tmp/foof");
+ assert (fd != -1);
+ runinit (&runner);
+ runner_add_args (&runner, "echo", "foo", NULL);
+ runner_redir (&runner, 1, fd);
+ ret = runner_run (&runner);
+ printf ("%d", ret);
+ if (ret != 0)
+ printf (" %d [%s]", errno, strerror (errno));
+ putchar ('\n');
+
+ if (argc > 1) {
+ tv.tv_sec = strtoul (argv[1], NULL, 10);
+ if (tv.tv_sec > 0)
+ tvp = &tv;
+ select (0, 0, 0, 0, tvp);
+ }
+
+ return 0;
+}
+#endif
diff --git a/libglusterfs/src/run.h b/libglusterfs/src/run.h
new file mode 100644
index 000000000..508c59c13
--- /dev/null
+++ b/libglusterfs/src/run.h
@@ -0,0 +1,188 @@
+/*
+ Copyright (c) 2008-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 __RUN_H__
+#define __RUN_H__
+
+#define RUN_PIPE -1
+
+struct runner {
+ char **argv;
+ unsigned argvlen;
+ int runerr;
+ pid_t chpid;
+ int chfd[3];
+ FILE *chio[3];
+};
+
+typedef struct runner runner_t;
+
+/**
+ * initialize runner_t instance.
+ *
+ * @param runner pointer to runner_t instance
+ */
+void runinit (runner_t *runner);
+
+/**
+ * get FILE pointer to which child's stdio is redirected.
+ *
+ * @param runner pointer to runner_t instance
+ * @param fd specifies which standard file descriptor is
+ * is asked for
+ *
+ * @see runner_redir()
+ */
+FILE *runner_chio (runner_t *runner, int fd);
+
+/**
+ * add an argument.
+ *
+ * 'arg' is duplicated.
+ *
+ * Errors are deferred, no error handling is necessary.
+ *
+ * @param runner pointer to runner_t instance
+ * @param arg command line argument
+ */
+void runner_add_arg (runner_t *runner, const char *arg);
+
+/**
+ * add a sequence of arguments.
+ *
+ * Variadic function, calls runner_add_arg() on each vararg.
+ * Argument sequence MUST be NULL terminated.
+ *
+ * Errors are deferred, no error handling is necessary.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @see runner_add_arg()
+ */
+void runner_add_args (runner_t *runner, ...);
+
+/**
+ * add an argument with printf style formatting.
+ *
+ * Errors are deferred, no error handling is necessary.
+ *
+ * @param runner pointer to runner_t instance
+ * @param format printf style format specifier
+ */
+void runner_argprintf (runner_t *runner, const char *format, ...);
+
+/**
+ * log a message about the command to be run.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @param dom log domain
+ * @param lvl log level
+ * @param msg message with which the command is prefixed in log
+ *
+ * @see gf_log()
+ */
+void runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
+ const char *msg);
+
+/**
+ * set up redirection for child.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @param fd fd of child to redirect (0, 1, or 2)
+ * @param tgt_fd fd on parent side to redirect to.
+ * Note that runner_end() will close tgt_fd,
+ * if user needs it in another context it should
+ * be dup'd beforehand.
+ * RUN_PIPE can be used for requiring a
+ * pipe from child to parent. The FILE
+ * created for this purpose will be
+ * accessible via runner_chio() (after
+ * runner_start() has been invoked).
+ *
+ * @see runner_start(), dup(2), runner_chio(), runner_start()
+ */
+void
+runner_redir (runner_t *runner, int fd, int tgt_fd);
+
+/**
+ * spawn child with accumulated arg list.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @return 0 on succesful spawn
+ * -1 on failure (either due to earlier errors or execve(2) failing)
+ *
+ * @see runner_cout()
+ */
+int runner_start (runner_t *runner);
+
+/**
+ * complete operation and free resources.
+ *
+ * If child exists, waits for it. Redirections will be closed.
+ * Dynamically allocated memory shall be freed.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @return 0 if child terminated successfully
+ * -1 if there is no running child
+ * n > 0 if child failed; value to be interpreted as status
+ * in waitpid(2)
+ *
+ * @see waitpid(2)
+ */
+int runner_end (runner_t *runner);
+
+/**
+ * variant of runner_end() which does not free internal data
+ * so that the runner instance can be run again.
+ *
+ * @see runner_end()
+ */
+int runner_end_reuse (runner_t *runner);
+
+/**
+ * spawn and child, take it to completion and free resources.
+ *
+ * Essentially it's a concatenation of runner_start() and runner_end()
+ * with simplified return semantics.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @return 0 on success
+ * -1 on failuire
+ *
+ * @see runner_start(), runner_end()
+ */
+int runner_run (runner_t *runner);
+
+/**
+ * variant of runner_run() which does not free internal data
+ * so that the runner instance can be run again.
+ *
+ * @see runner_run()
+ */
+int runner_run_reuse (runner_t *runner);
+
+/**
+ * run a command with args.
+ *
+ * Variadic function, child process is spawned with
+ * the given sequence of args and waited for.
+ * Argument sequence MUST be NULL terminated.
+ *
+ * @return 0 on success
+ * -1 on failure
+ */
+int runcmd (const char *arg, ...);
+
+#endif
diff --git a/libglusterfs/src/scheduler.c b/libglusterfs/src/scheduler.c
index e06b01857..9817f3e26 100644
--- a/libglusterfs/src/scheduler.c
+++ b/libglusterfs/src/scheduler.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
diff --git a/libglusterfs/src/scheduler.h b/libglusterfs/src/scheduler.h
index 556cdae15..2f1e12205 100644
--- a/libglusterfs/src/scheduler.h
+++ b/libglusterfs/src/scheduler.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _SCHEDULER_H
diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c
index ebaf814ad..f922be83c 100644
--- a/libglusterfs/src/stack.c
+++ b/libglusterfs/src/stack.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "statedump.h"
@@ -41,7 +32,6 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
char prefix[GF_DUMP_MAX_BUF_LEN];
va_list ap;
- char key[GF_DUMP_MAX_BUF_LEN];
call_frame_t my_frame;
int ret = -1;
@@ -66,16 +56,23 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
memcpy(&my_frame, call_frame, sizeof(my_frame));
UNLOCK(&call_frame->lock);
- gf_proc_dump_build_key(key, prefix,"ref_count");
- gf_proc_dump_write(key, "%d", my_frame.ref_count);
- gf_proc_dump_build_key(key, prefix,"translator");
- gf_proc_dump_write(key, "%s", my_frame.this->name);
- gf_proc_dump_build_key(key, prefix,"complete");
- gf_proc_dump_write(key, "%d", my_frame.complete);
- if (my_frame.parent) {
- gf_proc_dump_build_key(key, prefix,"parent");
- gf_proc_dump_write(key, "%s", my_frame.parent->this->name);
- }
+ gf_proc_dump_write("ref_count", "%d", my_frame.ref_count);
+ gf_proc_dump_write("translator", "%s", my_frame.this->name);
+ gf_proc_dump_write("complete", "%d", my_frame.complete);
+ if (my_frame.parent)
+ gf_proc_dump_write("parent", "%s", my_frame.parent->this->name);
+
+ if (my_frame.wind_from)
+ gf_proc_dump_write("wind_from", "%s", my_frame.wind_from);
+
+ if (my_frame.wind_to)
+ gf_proc_dump_write("wind_to", "%s", my_frame.wind_to);
+
+ if (my_frame.unwind_from)
+ gf_proc_dump_write("unwind_from", "%s", my_frame.unwind_from);
+
+ if (my_frame.unwind_to)
+ gf_proc_dump_write("unwind_to", "%s", my_frame.unwind_to);
}
@@ -86,7 +83,6 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
va_list ap;
call_frame_t *trav;
int32_t cnt, i;
- char key[GF_DUMP_MAX_BUF_LEN];
if (!call_stack)
return;
@@ -100,25 +96,19 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
- gf_proc_dump_build_key(key, prefix,"uid");
- gf_proc_dump_write(key, "%d", call_stack->uid);
- gf_proc_dump_build_key(key, prefix,"gid");
- gf_proc_dump_write(key, "%d", call_stack->gid);
- gf_proc_dump_build_key(key, prefix,"pid");
- gf_proc_dump_write(key, "%d", call_stack->pid);
- gf_proc_dump_build_key(key, prefix,"unique");
- gf_proc_dump_write(key, "%Ld", call_stack->unique);
+ gf_proc_dump_write("uid", "%d", call_stack->uid);
+ gf_proc_dump_write("gid", "%d", call_stack->gid);
+ gf_proc_dump_write("pid", "%d", call_stack->pid);
+ gf_proc_dump_write("unique", "%Ld", call_stack->unique);
+ gf_proc_dump_write("lk-owner", "%s", lkowner_utoa (&call_stack->lk_owner));
- gf_proc_dump_build_key(key, prefix,"op");
if (call_stack->type == GF_OP_TYPE_FOP)
- gf_proc_dump_write(key, "%s", gf_fop_list[call_stack->op]);
+ gf_proc_dump_write("op", "%s", gf_fop_list[call_stack->op]);
else if (call_stack->type == GF_OP_TYPE_MGMT)
- gf_proc_dump_write(key, "%s", gf_mgmt_list[call_stack->op]);
+ gf_proc_dump_write("op", "%s", gf_mgmt_list[call_stack->op]);
- gf_proc_dump_build_key(key, prefix,"type");
- gf_proc_dump_write(key, "%d", call_stack->type);
- gf_proc_dump_build_key(key, prefix,"cnt");
- gf_proc_dump_write(key, "%d", cnt);
+ gf_proc_dump_write("type", "%d", call_stack->type);
+ gf_proc_dump_write("cnt", "%d", cnt);
trav = &call_stack->frames;
@@ -151,8 +141,8 @@ gf_proc_dump_pending_frames (call_pool_t *call_pool)
gf_proc_dump_add_section("global.callpool");
- gf_proc_dump_write("global.callpool","%p", call_pool);
- gf_proc_dump_write("global.callpool.cnt","%d", call_pool->cnt);
+ gf_proc_dump_write("callpool_address","%p", call_pool);
+ gf_proc_dump_write("callpool.cnt","%d", call_pool->cnt);
list_for_each_entry (trav, &call_pool->all_frames, all_frames) {
@@ -163,6 +153,198 @@ gf_proc_dump_pending_frames (call_pool_t *call_pool)
UNLOCK (&(call_pool->lock));
}
+void
+gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
+ char *prefix, dict_t *dict)
+{
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ call_frame_t tmp_frame = {0,};
+
+ if (!call_frame || !dict)
+ return;
+
+ ret = TRY_LOCK (&call_frame->lock);
+ if (ret)
+ return;
+ memcpy (&tmp_frame, call_frame, sizeof (tmp_frame));
+ UNLOCK (&call_frame->lock);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.refcount", prefix);
+ ret = dict_set_int32 (dict, key, tmp_frame.ref_count);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.translator", prefix);
+ ret = dict_set_dynstr (dict, key, gf_strdup (tmp_frame.this->name));
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.complete", prefix);
+ ret = dict_set_int32 (dict, key, tmp_frame.complete);
+ if (ret)
+ return;
+
+ if (tmp_frame.parent) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.parent", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.parent->this->name));
+ if (ret)
+ return;
+ }
+
+ if (tmp_frame.wind_from) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.windfrom", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.wind_from));
+ if (ret)
+ return;
+ }
+
+ if (tmp_frame.wind_to) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.windto", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.wind_to));
+ if (ret)
+ return;
+ }
+
+ if (tmp_frame.unwind_from) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unwindfrom", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.unwind_from));
+ if (ret)
+ return;
+ }
+
+ if (tmp_frame.unwind_to) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unwind_to", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.unwind_to));
+ }
+
+ return;
+}
+
+void
+gf_proc_dump_call_stack_to_dict (call_stack_t *call_stack,
+ char *prefix, dict_t *dict)
+{
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ call_frame_t *trav = NULL;
+ int count = 0;
+ int i = 0;
+
+ if (!call_stack || !dict)
+ return;
+
+ count = call_frames_count (&call_stack->frames);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.uid", prefix);
+ ret = dict_set_int32 (dict, key, call_stack->uid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.gid", prefix);
+ ret = dict_set_int32 (dict, key, call_stack->gid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pid", prefix);
+ ret = dict_set_int32 (dict, key, call_stack->pid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unique", prefix);
+ ret = dict_set_uint64 (dict, key, call_stack->unique);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.op", prefix);
+ if (call_stack->type == GF_OP_TYPE_FOP)
+ ret = dict_set_str (dict, key,
+ gf_fop_list[call_stack->op]);
+ else if (call_stack->type == GF_OP_TYPE_MGMT)
+ ret = dict_set_str (dict, key,
+ gf_mgmt_list[call_stack->op]);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.type", prefix);
+ ret = dict_set_int32 (dict, key, call_stack->type);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.count", prefix);
+ ret = dict_set_int32 (dict, key, count);
+ if (ret)
+ return;
+
+ trav = &call_stack->frames;
+ for (i = 0; i < count; i++) {
+ if (trav) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.frame%d",
+ prefix, i);
+ gf_proc_dump_call_frame_to_dict (trav, key, dict);
+ trav = trav->next;
+ }
+ }
+
+ return;
+}
+
+void
+gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool, dict_t *dict)
+{
+ int ret = -1;
+ call_stack_t *trav = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int i = 0;
+
+ if (!call_pool || !dict)
+ return;
+
+ ret = TRY_LOCK (&call_pool->lock);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_WARNING, "Unable to dump call pool"
+ " to dict. errno: %d", errno);
+ return;
+ }
+
+ ret = dict_set_int32 (dict, "callpool.count", call_pool->cnt);
+ if (ret)
+ goto out;
+
+ list_for_each_entry (trav, &call_pool->all_frames, all_frames) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "callpool.stack%d", i);
+ gf_proc_dump_call_stack_to_dict (trav, key, dict);
+ i++;
+ }
+
+out:
+ UNLOCK (&call_pool->lock);
+
+ return;
+}
+
gf_boolean_t
__is_fuse_call (call_frame_t *frame)
{
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index 63b14ca46..63307192a 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
/*
@@ -44,8 +35,10 @@ typedef struct _call_pool_t call_pool_t;
#include "list.h"
#include "common-utils.h"
#include "globals.h"
+#include "lkowner.h"
#define NFS_PID 1
+#define LOW_PRIO_PROC_PID -1
typedef int32_t (*ret_fn_t) (call_frame_t *frame,
call_frame_t *prev_frame,
xlator_t *this,
@@ -83,6 +76,10 @@ struct _call_frame_t {
glusterfs_fop_t op;
struct timeval begin; /* when this frame was created */
struct timeval end; /* when this frame completed */
+ const char *wind_from;
+ const char *wind_to;
+ const char *unwind_from;
+ const char *unwind_to;
};
struct _call_stack_t {
@@ -94,15 +91,16 @@ struct _call_stack_t {
};
};
call_pool_t *pool;
+ gf_lock_t stack_lock;
void *trans;
uint64_t unique;
void *state; /* pointer to request state */
uid_t uid;
gid_t gid;
pid_t pid;
- uint32_t ngrps;
- uint32_t groups[GF_REQUEST_MAXGROUPS];
- uint64_t lk_owner;
+ uint16_t ngrps;
+ uint32_t groups[GF_MAX_AUX_GROUPS];
+ gf_lkowner_t lk_owner;
call_frame_t frames;
@@ -145,10 +143,10 @@ FRAME_DESTROY (call_frame_t *frame)
}
LOCK_DESTROY (&frame->lock);
- mem_put (frame->root->pool->frame_mem_pool, frame);
+ mem_put (frame);
if (local)
- GF_FREE (local);
+ mem_put (local);
}
@@ -170,16 +168,34 @@ STACK_DESTROY (call_stack_t *stack)
}
LOCK_DESTROY (&stack->frames.lock);
+ LOCK_DESTROY (&stack->stack_lock);
while (stack->frames.next) {
FRAME_DESTROY (stack->frames.next);
}
- mem_put (stack->pool->stack_mem_pool, stack);
+ mem_put (stack);
if (local)
- GF_FREE (local);
+ mem_put (local);
}
+static inline void
+STACK_RESET (call_stack_t *stack)
+{
+ void *local = NULL;
+
+ if (stack->frames.local) {
+ local = stack->frames.local;
+ stack->frames.local = NULL;
+ }
+
+ while (stack->frames.next) {
+ FRAME_DESTROY (stack->frames.next);
+ }
+
+ if (local)
+ mem_put (local);
+}
#define cbk(x) cbk_##x
@@ -213,17 +229,24 @@ STACK_DESTROY (call_stack_t *stack)
} \
typeof(fn##_cbk) tmp_cbk = rfn; \
_new->root = frame->root; \
- _new->next = frame->root->frames.next; \
- _new->prev = &frame->root->frames; \
- if (frame->root->frames.next) \
- frame->root->frames.next->prev = _new; \
- frame->root->frames.next = _new; \
_new->this = obj; \
_new->ret = (ret_fn_t) tmp_cbk; \
_new->parent = frame; \
_new->cookie = _new; \
+ _new->wind_from = __FUNCTION__; \
+ _new->wind_to = #fn; \
+ _new->unwind_to = #rfn; \
LOCK_INIT (&_new->lock); \
- frame->ref_count++; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _new->next = frame->root->frames.next; \
+ _new->prev = &frame->root->frames; \
+ if (frame->root->frames.next) \
+ frame->root->frames.next->prev = _new; \
+ frame->root->frames.next = _new; \
+ frame->ref_count++; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = obj; \
fn (_new, obj, params); \
@@ -244,17 +267,24 @@ STACK_DESTROY (call_stack_t *stack)
} \
typeof(fn##_cbk) tmp_cbk = rfn; \
_new->root = frame->root; \
- _new->next = frame->root->frames.next; \
- _new->prev = &frame->root->frames; \
- if (frame->root->frames.next) \
- frame->root->frames.next->prev = _new; \
- frame->root->frames.next = _new; \
_new->this = obj; \
_new->ret = (ret_fn_t) tmp_cbk; \
_new->parent = frame; \
_new->cookie = cky; \
+ _new->wind_from = __FUNCTION__; \
+ _new->wind_to = #fn; \
+ _new->unwind_to = #rfn; \
LOCK_INIT (&_new->lock); \
- frame->ref_count++; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ frame->ref_count++; \
+ _new->next = frame->root->frames.next; \
+ _new->prev = &frame->root->frames; \
+ if (frame->root->frames.next) \
+ frame->root->frames.next->prev = _new; \
+ frame->root->frames.next = _new; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
fn##_cbk = rfn; \
old_THIS = THIS; \
THIS = obj; \
@@ -275,10 +305,15 @@ STACK_DESTROY (call_stack_t *stack)
} \
fn = frame->ret; \
_parent = frame->parent; \
- _parent->ref_count--; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _parent->ref_count--; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = _parent->this; \
frame->complete = _gf_true; \
+ frame->unwind_from = __FUNCTION__; \
fn (_parent, frame->cookie, _parent->this, params); \
THIS = old_THIS; \
} while (0)
@@ -297,10 +332,15 @@ STACK_DESTROY (call_stack_t *stack)
} \
fn = (fop_##op##_cbk_t )frame->ret; \
_parent = frame->parent; \
- _parent->ref_count--; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _parent->ref_count--; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = _parent->this; \
frame->complete = _gf_true; \
+ frame->unwind_from = __FUNCTION__; \
fn (_parent, frame->cookie, _parent->this, params); \
THIS = old_THIS; \
} while (0)
@@ -327,8 +367,10 @@ copy_frame (call_frame_t *frame)
newstack->gid = oldstack->gid;
newstack->pid = oldstack->pid;
newstack->ngrps = oldstack->ngrps;
+ newstack->op = oldstack->op;
+ newstack->type = oldstack->type;
memcpy (newstack->groups, oldstack->groups,
- sizeof (uint32_t) * GF_REQUEST_MAXGROUPS);
+ sizeof (gid_t) * GF_MAX_AUX_GROUPS);
newstack->unique = oldstack->unique;
newstack->frames.this = frame->this;
@@ -337,6 +379,7 @@ copy_frame (call_frame_t *frame)
newstack->lk_owner = oldstack->lk_owner;
LOCK_INIT (&newstack->frames.lock);
+ LOCK_INIT (&newstack->stack_lock);
LOCK (&oldstack->pool->lock);
{
@@ -374,11 +417,13 @@ create_frame (xlator_t *xl, call_pool_t *pool)
UNLOCK (&pool->lock);
LOCK_INIT (&stack->frames.lock);
+ LOCK_INIT (&stack->stack_lock);
return &stack->frames;
}
void gf_proc_dump_pending_frames(call_pool_t *call_pool);
-
+void gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool,
+ dict_t *dict);
gf_boolean_t __is_fuse_call (call_frame_t *frame);
#endif /* _STACK_H */
diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c
index 0665f9e1b..90d345dad 100644
--- a/libglusterfs/src/statedump.c
+++ b/libglusterfs/src/statedump.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <stdarg.h>
@@ -23,13 +14,15 @@
#include "iobuf.h"
#include "statedump.h"
#include "stack.h"
+#include "common-utils.h"
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif /* MALLOC_H */
/* We don't want gf_log in this function because it may cause
- 'deadlock' with statedump */
+ 'deadlock' with statedump. This is because statedump happens
+ inside a signal handler and cannot afford to block on a lock.*/
#ifdef gf_log
# undef gf_log
#endif
@@ -62,15 +55,11 @@ gf_proc_dump_unlock (void)
static int
-gf_proc_dump_open (void)
+gf_proc_dump_open (char path[])
{
- char path[256];
int dump_fd = -1;
- memset (path, 0, sizeof (path));
- snprintf (path, sizeof (path), "%s.%d", GF_DUMP_LOGFILE_ROOT, getpid ());
-
- dump_fd = open (path, O_CREAT|O_RDWR|O_TRUNC|O_APPEND, 0600);
+ dump_fd = mkostemp (path, O_CREAT|O_RDWR|O_TRUNC|O_APPEND);
if (dump_fd < 0)
return -1;
@@ -87,13 +76,12 @@ gf_proc_dump_close (void)
}
-void
+int
gf_proc_dump_add_section (char *key, ...)
{
char buf[GF_DUMP_MAX_BUF_LEN];
va_list ap;
- int ret;
GF_ASSERT(key);
@@ -105,18 +93,17 @@ gf_proc_dump_add_section (char *key, ...)
va_end (ap);
snprintf (buf + strlen(buf),
GF_DUMP_MAX_BUF_LEN - strlen (buf), "]\n");
- ret = write (gf_dump_fd, buf, strlen (buf));
+ return write (gf_dump_fd, buf, strlen (buf));
}
-void
+int
gf_proc_dump_write (char *key, char *value,...)
{
char buf[GF_DUMP_MAX_BUF_LEN];
int offset = 0;
va_list ap;
- int ret;
GF_ASSERT (key);
@@ -132,14 +119,12 @@ gf_proc_dump_write (char *key, char *value,...)
offset = strlen (buf);
snprintf (buf + offset, GF_DUMP_MAX_BUF_LEN - offset, "\n");
- ret = write (gf_dump_fd, buf, strlen (buf));
+ return write (gf_dump_fd, buf, strlen (buf));
}
static void
gf_proc_dump_xlator_mem_info (xlator_t *xl)
{
- char key[GF_DUMP_MAX_BUF_LEN];
- char prefix[GF_DUMP_MAX_BUF_LEN];
int i = 0;
struct mem_acct rec = {0,};
@@ -149,7 +134,7 @@ gf_proc_dump_xlator_mem_info (xlator_t *xl)
if (!xl->mem_acct.rec)
return;
- gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type,xl->name);
+ gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type, xl->name);
gf_proc_dump_write ("num_types", "%d", xl->mem_acct.num_types);
for (i = 0; i < xl->mem_acct.num_types; i++) {
@@ -157,18 +142,53 @@ gf_proc_dump_xlator_mem_info (xlator_t *xl)
sizeof (struct mem_acct))))
continue;
+ gf_proc_dump_add_section ("%s.%s - usage-type %d memusage",
+ xl->type, xl->name, i);
+ gf_proc_dump_write ("size", "%u", xl->mem_acct.rec[i].size);
+ gf_proc_dump_write ("num_allocs", "%u",
+ xl->mem_acct.rec[i].num_allocs);
+ gf_proc_dump_write ("max_size", "%u",
+ xl->mem_acct.rec[i].max_size);
+ gf_proc_dump_write ("max_num_allocs", "%u",
+ xl->mem_acct.rec[i].max_num_allocs);
+ gf_proc_dump_write ("total_allocs", "%u",
+ xl->mem_acct.rec[i].total_allocs);
+ }
+
+ return;
+}
+
+static void
+gf_proc_dump_xlator_mem_info_only_in_use (xlator_t *xl)
+{
+ int i = 0;
+
+ if (!xl)
+ return;
+
+ if (!xl->mem_acct.rec)
+ return;
+
+ gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type, xl->name);
+ gf_proc_dump_write ("num_types", "%d", xl->mem_acct.num_types);
+
+ for (i = 0; i < xl->mem_acct.num_types; i++) {
+ if (!xl->mem_acct.rec[i].size)
+ continue;
+
gf_proc_dump_add_section ("%s.%s - usage-type %d", xl->type,
xl->name,i);
- gf_proc_dump_build_key (prefix, "memusage", "%s.%s.type.%d",
- xl->type, xl->name, i);
- gf_proc_dump_build_key (key, prefix, "size");
- gf_proc_dump_write (key, "%u", xl->mem_acct.rec[i].size);
- gf_proc_dump_build_key (key, prefix, "num_allocs");
- gf_proc_dump_write (key, "%u", xl->mem_acct.rec[i].num_allocs);
- gf_proc_dump_build_key (key, prefix, "max_size");
- gf_proc_dump_write (key, "%u", xl->mem_acct.rec[i].max_size);
- gf_proc_dump_build_key (key, prefix, "max_num_allocs");
- gf_proc_dump_write (key, "%u", xl->mem_acct.rec[i].max_num_allocs);
+
+ gf_proc_dump_write ("size", "%u",
+ xl->mem_acct.rec[i].size);
+ gf_proc_dump_write ("max_size", "%u",
+ xl->mem_acct.rec[i].max_size);
+ gf_proc_dump_write ("num_allocs", "%u",
+ xl->mem_acct.rec[i].num_allocs);
+ gf_proc_dump_write ("max_num_allocs", "%u",
+ xl->mem_acct.rec[i].max_num_allocs);
+ gf_proc_dump_write ("total_allocs", "%u",
+ xl->mem_acct.rec[i].total_allocs);
}
return;
@@ -202,125 +222,248 @@ gf_proc_dump_mem_info ()
}
-void gf_proc_dump_latency_info (xlator_t *xl);
-
void
-gf_proc_dump_xlator_info (xlator_t *this_xl)
+gf_proc_dump_mem_info_to_dict (dict_t *dict)
{
- glusterfs_ctx_t *ctx = NULL;
- xlator_t *fuse_xlator, *this_xlator;
+ if (!dict)
+ return;
+#ifdef HAVE_MALLOC_STATS
+ struct mallinfo info;
+ int ret = -1;
+
+ memset (&info, 0, sizeof(struct mallinfo));
+ info = mallinfo ();
- if (!this_xl)
+ ret = dict_set_int32 (dict, "mallinfo.arena", info.arena);
+ if (ret)
return;
- ctx = glusterfs_ctx_get ();
- if (!ctx)
+ ret = dict_set_int32 (dict, "mallinfo.ordblks", info.ordblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.smblks", info.smblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.hblks", info.hblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.hblkhd", info.hblkhd);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.usmblks", info.usmblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.fsmblks", info.fsmblks);
+ if (ret)
return;
- if (ctx->master){
+ ret = dict_set_int32 (dict, "mallinfo.uordblks", info.uordblks);
+ if (ret)
+ return;
- fuse_xlator = (xlator_t *) ctx->master;
+ ret = dict_set_int32 (dict, "mallinfo.fordblks", info.fordblks);
+ if (ret)
+ return;
- if (!fuse_xlator->dumpops)
+ ret = dict_set_int32 (dict, "mallinfo.keepcost", info.keepcost);
+ if (ret)
+ return;
+#endif
+ return;
+}
+
+void
+gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx)
+{
+ struct mem_pool *pool = NULL;
+
+ gf_proc_dump_add_section ("mempool");
+
+ list_for_each_entry (pool, &ctx->mempool_list, global_list) {
+ gf_proc_dump_write ("-----", "-----");
+ gf_proc_dump_write ("pool-name", "%s", pool->name);
+ gf_proc_dump_write ("hot-count", "%d", pool->hot_count);
+ gf_proc_dump_write ("cold-count", "%d", pool->cold_count);
+ gf_proc_dump_write ("padded_sizeof", "%lu",
+ pool->padded_sizeof_type);
+ gf_proc_dump_write ("alloc-count", "%"PRIu64, pool->alloc_count);
+ gf_proc_dump_write ("max-alloc", "%d", pool->max_alloc);
+
+ gf_proc_dump_write ("pool-misses", "%"PRIu64, pool->pool_misses);
+ gf_proc_dump_write ("max-stdalloc", "%d", pool->max_stdalloc);
+ }
+}
+
+void
+gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict)
+{
+ struct mem_pool *pool = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int count = 0;
+ int ret = -1;
+
+ if (!ctx || !dict)
+ return;
+
+ list_for_each_entry (pool, &ctx->mempool_list, global_list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.name", count);
+ ret = dict_set_str (dict, key, pool->name);
+ if (ret)
return;
- if (fuse_xlator->dumpops->priv &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (priv))
- fuse_xlator->dumpops->priv (fuse_xlator);
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.hotcount", count);
+ ret = dict_set_int32 (dict, key, pool->hot_count);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.coldcount", count);
+ ret = dict_set_int32 (dict, key, pool->cold_count);
+ if (ret)
+ return;
- if (fuse_xlator->dumpops->inode &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode)) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.paddedsizeof", count);
+ ret = dict_set_uint64 (dict, key, pool->padded_sizeof_type);
+ if (ret)
+ return;
- if (!ctx->active)
- return;
- this_xlator = (xlator_t *) ctx->active->top;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.alloccount", count);
+ ret = dict_set_uint64 (dict, key, pool->alloc_count);
+ if (ret)
+ return;
- if (this_xlator && this_xlator->itable)
- inode_table_dump (this_xlator->itable,
- "xlator.mount.fuse.itable");
- else
- return;
- }
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.max_alloc", count);
+ ret = dict_set_int32 (dict, key, pool->max_alloc);
+ if (ret)
+ return;
- if (fuse_xlator->dumpops->fd &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))
- fuse_xlator->dumpops->fd (fuse_xlator);
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.max-stdalloc", count);
+ ret = dict_set_int32 (dict, key, pool->max_stdalloc);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.pool-misses", count);
+ ret = dict_set_uint64 (dict, key, pool->pool_misses);
+ if (ret)
+ return;
+ count++;
}
+ ret = dict_set_int32 (dict, "mempool-count", count);
+
+ return;
+}
+
+void gf_proc_dump_latency_info (xlator_t *xl);
+
+void
+gf_proc_dump_xlator_info (xlator_t *top)
+{
+ xlator_t *trav = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char itable_key[1024] = {0,};
+ if (!top)
+ return;
- while (this_xl) {
+ ctx = glusterfs_ctx_get ();
+
+ trav = top;
+ while (trav) {
if (ctx->measure_latency)
- gf_proc_dump_latency_info (this_xl);
+ gf_proc_dump_latency_info (trav);
+
+ gf_proc_dump_xlator_mem_info(trav);
+
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
+ (trav->itable)) {
+ snprintf (itable_key, 1024, "%d.%s.itable",
+ ctx->graph_id, trav->name);
- gf_proc_dump_xlator_mem_info(this_xl);
+ inode_table_dump (trav->itable, itable_key);
+ }
- if (!this_xl->dumpops) {
- this_xl = this_xl->next;
+ if (!trav->dumpops) {
+ trav = trav->next;
continue;
}
- if (this_xl->dumpops->priv &&
+ if (trav->dumpops->priv &&
GF_PROC_DUMP_IS_XL_OPTION_ENABLED (priv))
- this_xl->dumpops->priv (this_xl);
-
- if (this_xl->dumpops->inode &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode))
- this_xl->dumpops->inode (this_xl);
+ trav->dumpops->priv (trav);
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
+ (trav->dumpops->inode))
+ trav->dumpops->inode (trav);
- if (this_xl->dumpops->fd &&
+ if (trav->dumpops->fd &&
GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))
- this_xl->dumpops->fd (this_xl);
+ trav->dumpops->fd (trav);
+
+ if (trav->dumpops->history &&
+ GF_PROC_DUMP_IS_XL_OPTION_ENABLED (history))
+ trav->dumpops->history (trav);
- this_xl = this_xl->next;
+ trav = trav->next;
}
return;
}
-static int
-gf_proc_dump_parse_set_option (char *key, char *value)
+
+static void
+gf_proc_dump_oldgraph_xlator_info (xlator_t *top)
{
- gf_boolean_t *opt_key = NULL;
- gf_boolean_t opt_value = _gf_false;
- char buf[GF_DUMP_MAX_BUF_LEN];
- int ret = -1;
+ xlator_t *trav = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char itable_key[1024] = {0,};
- if (!strncasecmp (key, "mem", 3)) {
- opt_key = &dump_options.dump_mem;
- } else if (!strncasecmp (key, "iobuf", 5)) {
- opt_key = &dump_options.dump_iobuf;
- } else if (!strncasecmp (key, "callpool", 8)) {
- opt_key = &dump_options.dump_callpool;
- } else if (!strncasecmp (key, "priv", 4)) {
- opt_key = &dump_options.xl_options.dump_priv;
- } else if (!strncasecmp (key, "fd", 2)) {
- opt_key = &dump_options.xl_options.dump_fd;
- } else if (!strncasecmp (key, "inode", 5)) {
- opt_key = &dump_options.xl_options.dump_inode;
- } else if (!strncasecmp (key, "inodectx", strlen ("inodectx"))) {
- opt_key = &dump_options.xl_options.dump_inodectx;
- } else if (!strncasecmp (key, "fdctx", strlen ("fdctx"))) {
- opt_key = &dump_options.xl_options.dump_fdctx;
- }
+ if (!top)
+ return;
- if (!opt_key) {
- //None of dump options match the key, return back
- snprintf (buf, sizeof (buf), "[Warning]:None of the options "
- "matched key : %s\n", key);
- ret = write (gf_dump_fd, buf, strlen (buf));
+ ctx = glusterfs_ctx_get ();
- return -1;
- }
+ trav = top;
+ while (trav) {
+ gf_proc_dump_xlator_mem_info_only_in_use (trav);
- opt_value = (strncasecmp (value, "yes", 3) ?
- _gf_false: _gf_true);
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
+ (trav->itable)) {
+ snprintf (itable_key, 1024, "%d.%s.itable",
+ ctx->graph_id, trav->name);
- GF_PROC_DUMP_SET_OPTION (*opt_key, opt_value);
+ inode_table_dump (trav->itable, itable_key);
+ }
- return 0;
-}
+ if (!trav->dumpops) {
+ trav = trav->next;
+ continue;
+ }
+
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
+ (trav->dumpops->inode))
+ trav->dumpops->inode (trav);
+ if (trav->dumpops->fd &&
+ GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))
+ trav->dumpops->fd (trav);
+
+ trav = trav->next;
+ }
+
+ return;
+}
static int
gf_proc_dump_enable_all_options ()
@@ -335,6 +478,8 @@ gf_proc_dump_enable_all_options ()
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx,
_gf_true);
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_true);
+ GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_history,
+ _gf_true);
return 0;
}
@@ -353,11 +498,65 @@ gf_proc_dump_disable_all_options ()
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx,
_gf_false);
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_false);
-
+ GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_history,
+ _gf_false);
return 0;
}
static int
+gf_proc_dump_parse_set_option (char *key, char *value)
+{
+ gf_boolean_t *opt_key = NULL;
+ gf_boolean_t opt_value = _gf_false;
+ char buf[GF_DUMP_MAX_BUF_LEN];
+ int ret = -1;
+
+ if (!strcasecmp (key, "all")) {
+ (void)gf_proc_dump_enable_all_options ();
+ return 0;
+ } else if (!strcasecmp (key, "mem")) {
+ opt_key = &dump_options.dump_mem;
+ } else if (!strcasecmp (key, "iobuf")) {
+ opt_key = &dump_options.dump_iobuf;
+ } else if (!strcasecmp (key, "callpool")) {
+ opt_key = &dump_options.dump_callpool;
+ } else if (!strcasecmp (key, "priv")) {
+ opt_key = &dump_options.xl_options.dump_priv;
+ } else if (!strcasecmp (key, "fd")) {
+ opt_key = &dump_options.xl_options.dump_fd;
+ } else if (!strcasecmp (key, "inode")) {
+ opt_key = &dump_options.xl_options.dump_inode;
+ } else if (!strcasecmp (key, "inodectx")) {
+ opt_key = &dump_options.xl_options.dump_inodectx;
+ } else if (!strcasecmp (key, "fdctx")) {
+ opt_key = &dump_options.xl_options.dump_fdctx;
+ } else if (!strcasecmp (key, "history")) {
+ opt_key = &dump_options.xl_options.dump_history;
+ }
+
+ if (!opt_key) {
+ //None of dump options match the key, return back
+ snprintf (buf, sizeof (buf), "[Warning]:None of the options "
+ "matched key : %s\n", key);
+ ret = write (gf_dump_fd, buf, strlen (buf));
+
+ if (ret >= 0)
+ ret = -1;
+ goto out;
+
+ }
+
+ opt_value = (strncasecmp (value, "yes", 3) ?
+ _gf_false: _gf_true);
+
+ GF_PROC_DUMP_SET_OPTION (*opt_key, opt_value);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static int
gf_proc_dump_options_init ()
{
int ret = -1;
@@ -366,9 +565,13 @@ gf_proc_dump_options_init ()
char dumpbuf[GF_DUMP_MAX_BUF_LEN];
char *key = NULL, *value = NULL;
char *saveptr = NULL;
+ char dump_option_file[PATH_MAX];
+ snprintf (dump_option_file, sizeof (dump_option_file),
+ DEFAULT_VAR_RUN_DIRECTORY
+ "glusterdump.%d.options", getpid ());
- fp = fopen (GF_DUMP_OPTIONFILE, "r");
+ fp = fopen (dump_option_file, "r");
if (!fp) {
//ENOENT, return success
@@ -408,37 +611,77 @@ gf_proc_dump_options_init ()
void
gf_proc_dump_info (int signum)
{
- int ret = -1;
- glusterfs_ctx_t *ctx = NULL;
-
+ int i = 0;
+ int ret = -1;
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *trav = NULL;
+ char brick_name[PATH_MAX] = {0,};
+ char tmp_dump_name[PATH_MAX] = {0,};
+ char path[PATH_MAX] = {0,};
gf_proc_dump_lock ();
- ret = gf_proc_dump_open ();
+
+ ctx = glusterfs_ctx_get ();
+ if (!ctx)
+ goto out;
+
+ if (ctx->cmd_args.brick_name) {
+ GF_REMOVE_SLASH_FROM_PATH (ctx->cmd_args.brick_name, brick_name);
+ } else
+ strncpy (brick_name, "glusterdump", sizeof (brick_name));
+
+ snprintf (path, sizeof (path), "%s/%s.%d.dump",
+ ((ctx->statedump_path != NULL)?ctx->statedump_path:
+ DEFAULT_VAR_RUN_DIRECTORY),
+ brick_name, getpid());
+
+ snprintf (tmp_dump_name, PATH_MAX, "%s/dumpXXXXXX",
+ ((ctx->statedump_path != NULL)?ctx->statedump_path:
+ DEFAULT_VAR_RUN_DIRECTORY));
+
+ ret = gf_proc_dump_open (tmp_dump_name);
if (ret < 0)
goto out;
ret = gf_proc_dump_options_init ();
-
if (ret < 0)
goto out;
- if (GF_PROC_DUMP_IS_OPTION_ENABLED (mem))
+ if (GF_PROC_DUMP_IS_OPTION_ENABLED (mem)) {
gf_proc_dump_mem_info ();
+ gf_proc_dump_mempool_info (ctx);
+ }
- ctx = glusterfs_ctx_get ();
+ if (GF_PROC_DUMP_IS_OPTION_ENABLED (iobuf))
+ iobuf_stats_dump (ctx->iobuf_pool);
+ if (GF_PROC_DUMP_IS_OPTION_ENABLED (callpool))
+ gf_proc_dump_pending_frames (ctx->pool);
+
+ if (ctx->master) {
+ gf_proc_dump_add_section ("fuse");
+ gf_proc_dump_xlator_info (ctx->master);
+ }
+
+ if (ctx->active) {
+ gf_proc_dump_add_section ("active graph - %d", ctx->graph_id);
+ gf_proc_dump_xlator_info (ctx->active->top);
+ }
+
+ i = 0;
+ list_for_each_entry (trav, &ctx->graphs, list) {
+ if (trav == ctx->active)
+ continue;
- if (ctx) {
- if (GF_PROC_DUMP_IS_OPTION_ENABLED (iobuf))
- iobuf_stats_dump (ctx->iobuf_pool);
- if (GF_PROC_DUMP_IS_OPTION_ENABLED (callpool))
- gf_proc_dump_pending_frames (ctx->pool);
- if (ctx->active)
- gf_proc_dump_xlator_info (ctx->active->top);
+ gf_proc_dump_add_section ("oldgraph[%d]", i);
+ gf_proc_dump_oldgraph_xlator_info (trav->top);
+ i++;
}
- gf_proc_dump_close ();
out:
+ if (gf_dump_fd != -1)
+ gf_proc_dump_close ();
+ rename (tmp_dump_name, path);
gf_proc_dump_unlock ();
return;
diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h
index bb537c305..dc56bda0c 100644
--- a/libglusterfs/src/statedump.h
+++ b/libglusterfs/src/statedump.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -26,17 +17,13 @@
#define GF_DUMP_MAX_BUF_LEN 4096
-#define GF_DUMP_LOGFILE_ROOT "/tmp/glusterdump"
-#define GF_DUMP_LOGFILE_ROOT_LEN 256
-
-#define GF_DUMP_OPTIONFILE "/tmp/glusterdump.input"
-
typedef struct gf_dump_xl_options_ {
gf_boolean_t dump_priv;
gf_boolean_t dump_inode;
gf_boolean_t dump_fd;
gf_boolean_t dump_inodectx;
gf_boolean_t dump_fdctx;
+ gf_boolean_t dump_history;
} gf_dump_xl_options_t;
typedef struct gf_dump_options_ {
@@ -76,15 +63,23 @@ void gf_proc_dump_cleanup(void);
void gf_proc_dump_info(int signum);
-void gf_proc_dump_add_section(char *key,...);
+int gf_proc_dump_add_section(char *key,...);
-void gf_proc_dump_write(char *key, char *value,...);
+int gf_proc_dump_write(char *key, char *value,...);
void inode_table_dump(inode_table_t *itable, char *prefix);
+void inode_table_dump_to_dict (inode_table_t *itable, char *prefix, dict_t *dict);
+
void fdtable_dump(fdtable_t *fdtable, char *prefix);
+void fdtable_dump_to_dict (fdtable_t *fdtable, char *prefix, dict_t *dict);
+
void inode_dump(inode_t *inode, char *prefix);
+void gf_proc_dump_mem_info_to_dict (dict_t *dict);
+
+void gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict);
+
void glusterd_init (int sig);
#endif /* STATEDUMP_H */
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index 267e4b3a2..0c4620643 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -24,57 +15,82 @@
#include "syncop.h"
-call_frame_t *
-syncop_create_frame ()
+static void
+__run (struct synctask *task)
{
- struct synctask *task = NULL;
- struct call_frame_t *frame = NULL;
-
- task = synctask_get ();
-
- if (task) {
- frame = task->opaque;
- }
-
- return (call_frame_t *)frame;
-}
-
-void
-synctask_yield (struct synctask *task)
-{
- struct syncenv *env = NULL;
+ struct syncenv *env = NULL;
env = task->env;
- if (swapcontext (&task->ctx, &env->sched) < 0) {
- gf_log ("syncop", GF_LOG_ERROR,
- "swapcontext failed (%s)", strerror (errno));
- }
+ list_del_init (&task->all_tasks);
+ switch (task->state) {
+ case SYNCTASK_INIT:
+ case SYNCTASK_SUSPEND:
+ break;
+ case SYNCTASK_RUN:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "re-running already running task");
+ env->runcount--;
+ break;
+ case SYNCTASK_WAIT:
+ env->waitcount--;
+ break;
+ case SYNCTASK_DONE:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "running completed task");
+ break;
+ }
+
+ list_add_tail (&task->all_tasks, &env->runq);
+ env->runcount++;
+ task->state = SYNCTASK_RUN;
}
-void
-synctask_yawn (struct synctask *task)
+static void
+__wait (struct synctask *task)
{
- struct syncenv *env = NULL;
+ struct syncenv *env = NULL;
- env = task->env;
+ env = task->env;
- pthread_mutex_lock (&env->mutex);
- {
- list_del_init (&task->all_tasks);
- list_add (&task->all_tasks, &env->waitq);
- }
- pthread_mutex_unlock (&env->mutex);
+ list_del_init (&task->all_tasks);
+ switch (task->state) {
+ case SYNCTASK_INIT:
+ case SYNCTASK_SUSPEND:
+ break;
+ case SYNCTASK_RUN:
+ env->runcount--;
+ break;
+ case SYNCTASK_WAIT:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "re-waiting already waiting task");
+ env->waitcount--;
+ break;
+ case SYNCTASK_DONE:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "running completed task");
+ break;
+ }
+
+ list_add_tail (&task->all_tasks, &env->waitq);
+ env->waitcount++;
+ task->state = SYNCTASK_WAIT;
}
void
-synctask_zzzz (struct synctask *task)
+synctask_yield (struct synctask *task)
{
- synctask_yawn (task);
+#if defined(__NetBSD__) && defined(_UC_TLSBASE)
+ /* Preserve pthread private pointer through swapcontex() */
+ task->proc->sched.uc_flags &= ~_UC_TLSBASE;
+#endif
- synctask_yield (task);
+ if (swapcontext (&task->ctx, &task->proc->sched) < 0) {
+ gf_log ("syncop", GF_LOG_ERROR,
+ "swapcontext failed (%s)", strerror (errno));
+ }
}
@@ -87,28 +103,30 @@ synctask_wake (struct synctask *task)
pthread_mutex_lock (&env->mutex);
{
- list_del_init (&task->all_tasks);
- list_add_tail (&task->all_tasks, &env->runq);
+ task->woken = 1;
+
+ if (task->slept)
+ __run (task);
}
pthread_mutex_unlock (&env->mutex);
pthread_cond_broadcast (&env->cond);
}
-
void
-synctask_wrap (struct synctask *task)
+synctask_wrap (struct synctask *old_task)
{
- int ret;
+ struct synctask *task = NULL;
+
+ /* Do not trust the pointer received. It may be
+ wrong and can lead to crashes. */
- ret = task->syncfn (task->opaque);
- task->synccbk (ret, task->opaque);
+ task = synctask_get ();
+ task->ret = task->syncfn (task->opaque);
+ if (task->synccbk)
+ task->synccbk (task->ret, task->frame, task->opaque);
- /* cannot destroy @task right here as we are
- in the execution stack of @task itself
- */
- task->complete = 1;
- synctask_wake (task);
+ task->state = SYNCTASK_DONE;
synctask_yield (task);
}
@@ -122,24 +140,62 @@ synctask_destroy (struct synctask *task)
if (task->stack)
FREE (task->stack);
+
+ if (task->opframe)
+ STACK_DESTROY (task->opframe->root);
+
+ pthread_mutex_destroy (&task->mutex);
+
+ pthread_cond_destroy (&task->cond);
+
FREE (task);
}
+void
+synctask_done (struct synctask *task)
+{
+ if (task->synccbk) {
+ synctask_destroy (task);
+ return;
+ }
+
+ pthread_mutex_lock (&task->mutex);
+ {
+ task->done = 1;
+ pthread_cond_broadcast (&task->cond);
+ }
+ pthread_mutex_unlock (&task->mutex);
+}
+
+
int
synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
- void *opaque)
+ call_frame_t *frame, void *opaque)
{
struct synctask *newtask = NULL;
+ xlator_t *this = THIS;
+ int ret = 0;
+
+ VALIDATE_OR_GOTO (env, err);
+ VALIDATE_OR_GOTO (fn, err);
newtask = CALLOC (1, sizeof (*newtask));
if (!newtask)
return -ENOMEM;
+ newtask->frame = frame;
+ if (!frame) {
+ newtask->opframe = create_frame (this, this->ctx->pool);
+ } else {
+ newtask->opframe = copy_frame (frame);
+ }
+ if (!newtask->opframe)
+ goto err;
newtask->env = env;
- newtask->xl = THIS;
+ newtask->xl = this;
newtask->syncfn = fn;
- newtask->synccbk = cbk;
+ newtask->synccbk = cbk;
newtask->opaque = opaque;
INIT_LIST_HEAD (&newtask->all_tasks);
@@ -163,13 +219,39 @@ synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
makecontext (&newtask->ctx, (void *) synctask_wrap, 2, newtask);
+ newtask->state = SYNCTASK_INIT;
+
+ newtask->slept = 1;
+
+ if (!cbk) {
+ pthread_mutex_init (&newtask->mutex, NULL);
+ pthread_cond_init (&newtask->cond, NULL);
+ newtask->done = 0;
+ }
+
synctask_wake (newtask);
- return 0;
+ if (!cbk) {
+ pthread_mutex_lock (&newtask->mutex);
+ {
+ while (!newtask->done) {
+ pthread_cond_wait (&newtask->cond, &newtask->mutex);
+ }
+ }
+ pthread_mutex_unlock (&newtask->mutex);
+
+ ret = newtask->ret;
+
+ synctask_destroy (newtask);
+ }
+
+ return ret;
err:
if (newtask) {
if (newtask->stack)
FREE (newtask->stack);
+ if (newtask->opframe)
+ STACK_DESTROY (newtask->opframe->root);
FREE (newtask);
}
return -1;
@@ -177,10 +259,13 @@ err:
struct synctask *
-syncenv_task (struct syncenv *env)
+syncenv_task (struct syncproc *proc)
{
+ struct syncenv *env = NULL;
struct synctask *task = NULL;
+ env = proc->env;
+
pthread_mutex_lock (&env->mutex);
{
while (list_empty (&env->runq))
@@ -189,6 +274,9 @@ syncenv_task (struct syncenv *env)
task = list_entry (env->runq.next, struct synctask, all_tasks);
list_del_init (&task->all_tasks);
+ env->runcount--;
+
+ task->proc = proc;
}
pthread_mutex_unlock (&env->mutex);
@@ -206,30 +294,52 @@ synctask_switchto (struct synctask *task)
synctask_set (task);
THIS = task->xl;
- if (swapcontext (&env->sched, &task->ctx) < 0) {
+ task->woken = 0;
+ task->slept = 0;
+
+#if defined(__NetBSD__) && defined(_UC_TLSBASE)
+ /* Preserve pthread private pointer through swapcontex() */
+ task->ctx.uc_flags &= ~_UC_TLSBASE;
+#endif
+
+ if (swapcontext (&task->proc->sched, &task->ctx) < 0) {
gf_log ("syncop", GF_LOG_ERROR,
"swapcontext failed (%s)", strerror (errno));
}
-}
+ if (task->state == SYNCTASK_DONE) {
+ synctask_done (task);
+ return;
+ }
+
+ pthread_mutex_lock (&env->mutex);
+ {
+ if (task->woken) {
+ __run (task);
+ } else {
+ task->slept = 1;
+ __wait (task);
+ }
+ }
+ pthread_mutex_unlock (&env->mutex);
+}
void *
syncenv_processor (void *thdata)
{
struct syncenv *env = NULL;
+ struct syncproc *proc = NULL;
struct synctask *task = NULL;
- env = thdata;
+ proc = thdata;
+ env = proc->env;
for (;;) {
- task = syncenv_task (env);
-
- if (task->complete) {
- synctask_destroy (task);
- continue;
- }
+ task = syncenv_task (proc);
synctask_switchto (task);
+
+ syncenv_scale (env);
}
return NULL;
@@ -237,6 +347,33 @@ syncenv_processor (void *thdata)
void
+syncenv_scale (struct syncenv *env)
+{
+ int thmax = 0;
+ int i = 0;
+ int ret = 0;
+
+ pthread_mutex_lock (&env->mutex);
+ {
+ if (env->procs > env->runcount)
+ goto unlock;
+
+ thmax = min (env->runcount, SYNCENV_PROC_MAX);
+ for (i = env->procs; i < thmax; i++) {
+ env->proc[i].env = env;
+ ret = pthread_create (&env->proc[i].processor, NULL,
+ syncenv_processor, &env->proc[i]);
+ if (ret)
+ break;
+ env->procs++;
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&env->mutex);
+}
+
+
+void
syncenv_destroy (struct syncenv *env)
{
@@ -248,6 +385,7 @@ syncenv_new (size_t stacksize)
{
struct syncenv *newenv = NULL;
int ret = 0;
+ int i = 0;
newenv = CALLOC (1, sizeof (*newenv));
@@ -264,8 +402,14 @@ syncenv_new (size_t stacksize)
if (stacksize)
newenv->stacksize = stacksize;
- ret = pthread_create (&newenv->processor, NULL,
- syncenv_processor, newenv);
+ for (i = 0; i < SYNCENV_PROC_MIN; i++) {
+ newenv->proc[i].env = newenv;
+ ret = pthread_create (&newenv->proc[i].processor, NULL,
+ syncenv_processor, &newenv->proc[i]);
+ if (ret)
+ break;
+ newenv->procs++;
+ }
if (ret != 0)
syncenv_destroy (newenv);
@@ -280,7 +424,7 @@ syncenv_new (size_t stacksize)
int
syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode,
- struct iatt *iatt, dict_t *xattr, struct iatt *parent)
+ struct iatt *iatt, dict_t *xdata, struct iatt *parent)
{
struct syncargs *args = NULL;
@@ -291,8 +435,9 @@ syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
args->iatt1 = *iatt;
- args->xattr = xattr;
args->iatt2 = *parent;
+ if (xdata)
+ args->xdata = dict_ref (xdata);
}
__wake (args);
@@ -302,20 +447,22 @@ syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
-syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req,
- struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent)
+syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xdata_req,
+ struct iatt *iatt, dict_t **xdata_rsp, struct iatt *parent)
{
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_lookup_cbk, subvol->fops->lookup,
- loc, xattr_req);
+ loc, xdata_req);
if (iatt)
*iatt = args.iatt1;
- if (xattr_rsp)
- *xattr_rsp = args.xattr;
if (parent)
*parent = args.iatt2;
+ if (xdata_rsp)
+ *xdata_rsp = args.xdata;
+ else if (args.xdata)
+ dict_unref (args.xdata);
errno = args.op_errno;
return args.op_ret;
@@ -331,6 +478,7 @@ entry_copy (gf_dirent_t *source)
sink->d_off = source->d_off;
sink->d_ino = source->d_ino;
sink->d_type = source->d_type;
+ sink->d_stat = source->d_stat;
return sink;
}
@@ -341,7 +489,7 @@ syncop_readdirp_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- gf_dirent_t *entries)
+ gf_dirent_t *entries, dict_t *xdata)
{
struct syncargs *args = NULL;
gf_dirent_t *entry = NULL;
@@ -378,15 +526,76 @@ syncop_readdirp (xlator_t *subvol,
fd_t *fd,
size_t size,
off_t off,
+ dict_t *dict,
gf_dirent_t *entries)
{
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_readdirp_cbk, subvol->fops->readdirp,
- fd, size, off);
+ fd, size, off, dict);
+
+ if (entries)
+ list_splice_init (&args.entries.list, &entries->list);
+ /* TODO: need to free all the 'args.entries' in 'else' case */
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int32_t
+syncop_readdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ gf_dirent_t *entries, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+
+ int count = 0;
+
+ args = cookie;
+
+ INIT_LIST_HEAD (&args->entries.list);
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (op_ret >= 0) {
+ list_for_each_entry (entry, &entries->list, list) {
+ tmp = entry_copy (entry);
+ gf_log (this->name, GF_LOG_TRACE,
+ "adding entry=%s, count=%d",
+ tmp->d_name, count);
+ list_add_tail (&tmp->list, &(args->entries.list));
+ count++;
+ }
+ }
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_readdir (xlator_t *subvol,
+ fd_t *fd,
+ size_t size,
+ off_t off,
+ gf_dirent_t *entries)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_readdir_cbk, subvol->fops->readdir,
+ fd, size, off, NULL);
if (entries)
list_splice_init (&args.entries.list, &entries->list);
+ /* TODO: need to free all the 'args.entries' in 'else' case */
errno = args.op_errno;
return args.op_ret;
@@ -399,7 +608,7 @@ syncop_opendir_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -421,17 +630,72 @@ syncop_opendir (xlator_t *subvol,
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_opendir_cbk, subvol->fops->opendir,
- loc, fd);
+ loc, fd, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_removexattr_cbk, subvol->fops->removexattr,
+ loc, name, NULL);
errno = args.op_errno;
return args.op_ret;
+}
+int
+syncop_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
}
+int
+syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fremovexattr_cbk,
+ subvol->fops->fremovexattr, fd, name, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
int
syncop_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno)
+ int op_ret, int op_errno, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -452,7 +716,105 @@ syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags)
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_setxattr_cbk, subvol->fops->setxattr,
- loc, dict, flags);
+ loc, dict, flags, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+
+int
+syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fsetxattr_cbk, subvol->fops->fsetxattr,
+ fd, dict, flags, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0)
+ args->xattr = dict_ref (dict);
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_listxattr (xlator_t *subvol, loc_t *loc, dict_t **dict)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr,
+ loc, NULL, NULL);
+
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref (args.xattr);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_getxattr (xlator_t *subvol, loc_t *loc, dict_t **dict, const char *key)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr,
+ loc, key, NULL);
+
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref (args.xattr);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_fgetxattr (xlator_t *subvol, fd_t *fd, dict_t **dict, const char *key)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->fgetxattr,
+ fd, key, NULL);
+
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref (args.xattr);
errno = args.op_errno;
return args.op_ret;
@@ -461,7 +823,7 @@ syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags)
int
syncop_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct statvfs *buf)
+ struct statvfs *buf, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -488,7 +850,7 @@ syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf)
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_statfs_cbk, subvol->fops->statfs,
- loc);
+ loc, NULL);
if (buf)
*buf = args.statvfs_buf;
@@ -500,7 +862,7 @@ syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf)
int
syncop_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno,
- struct iatt *preop, struct iatt *postop)
+ struct iatt *preop, struct iatt *postop, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -527,7 +889,26 @@ syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->setattr,
- loc, iatt, valid);
+ loc, iatt, valid, NULL);
+
+ if (preop)
+ *preop = args.iatt1;
+ if (postop)
+ *postop = args.iatt2;
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
+syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
+ struct iatt *preop, struct iatt *postop)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->fsetattr,
+ fd, iatt, valid, NULL);
if (preop)
*preop = args.iatt1;
@@ -537,3 +918,463 @@ syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
errno = args.op_errno;
return args.op_ret;
}
+
+
+int32_t
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_open_cbk, subvol->fops->open,
+ loc, flags, fd, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+
+int32_t
+syncop_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iovec *vector,
+ int32_t count, struct iatt *stbuf, struct iobref *iobref,
+ dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ INIT_LIST_HEAD (&args->entries.list);
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (args->op_ret >= 0) {
+ if (iobref)
+ args->iobref = iobref_ref (iobref);
+ args->vector = iov_dup (vector, count);
+ args->count = count;
+ }
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ uint32_t flags, struct iovec **vector, int *count,
+ struct iobref **iobref)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_readv_cbk, subvol->fops->readv,
+ fd, size, off, flags, NULL);
+
+ if (vector)
+ *vector = args.vector;
+ else if (args.vector)
+ GF_FREE (args.vector);
+
+ if (count)
+ *count = args.count;
+
+ /* Do we need a 'ref' here? */
+ if (iobref)
+ *iobref = args.iobref;
+ else if (args.iobref)
+ iobref_unref (args.iobref);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_writev (xlator_t *subvol, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t offset, struct iobref *iobref,
+ uint32_t flags)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev,
+ fd, vector, count, offset, flags, iobref, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int syncop_write (xlator_t *subvol, fd_t *fd, const char *buf, int size,
+ off_t offset, struct iobref *iobref, uint32_t flags)
+{
+ struct syncargs args = {0,};
+ struct iovec vec = {0,};
+
+ vec.iov_len = size;
+ vec.iov_base = (void *)buf;
+
+ SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev,
+ fd, &vec, 1, offset, flags, iobref, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
+syncop_close (fd_t *fd)
+{
+ if (fd)
+ fd_unref (fd);
+ return 0;
+}
+
+int32_t
+syncop_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
+ fd_t *fd, dict_t *xdata)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_create_cbk, subvol->fops->create,
+ loc, flags, mode, 0, fd, xdata);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_unlink (xlator_t *subvol, loc_t *loc)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_unlink_cbk, subvol->fops->unlink, loc,
+ 0, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+
+int
+syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_link_cbk, subvol->fops->link,
+ oldloc, newloc, NULL);
+
+ errno = args.op_errno;
+
+ return args.op_ret;
+}
+
+int
+syncop_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_ftruncate_cbk, subvol->fops->ftruncate,
+ fd, offset, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_ftruncate_cbk, subvol->fops->truncate,
+ loc, offset, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_fsync (xlator_t *subvol, fd_t *fd)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fsync_cbk, subvol->fops->fsync,
+ fd, 0, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->iatt1 = *stbuf;
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fstat_cbk, subvol->fops->fstat,
+ fd, NULL);
+
+ if (stbuf)
+ *stbuf = args.iatt1;
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fstat_cbk, subvol->fops->stat,
+ loc, NULL);
+
+ if (stbuf)
+ *stbuf = args.iatt1;
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int32_t
+syncop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_symlink (xlator_t *subvol, loc_t *loc, char *newpath, dict_t *dict)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_symlink_cbk, subvol->fops->symlink,
+ newpath, loc, 0, dict);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, const char *path,
+ struct iatt *stbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if ((op_ret != -1) && path)
+ args->buffer = gf_strdup (path);
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_readlink (xlator_t *subvol, loc_t *loc, char **buffer, size_t size)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_readlink_cbk, subvol->fops->readlink,
+ loc, size, NULL);
+
+ if (buffer)
+ *buffer = args.buffer;
+ else if (args.buffer)
+ GF_FREE (args.buffer);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
+ dict_t *dict)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_mknod_cbk, subvol->fops->mknod,
+ loc, mode, rdev, 0, dict);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
index 939f44d6b..726e8c49a 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _SYNCOP_H
@@ -30,42 +21,72 @@
#include <pthread.h>
#include <ucontext.h>
+#define SYNCENV_PROC_MAX 16
+#define SYNCENV_PROC_MIN 2
struct synctask;
+struct syncproc;
struct syncenv;
-typedef int (*synctask_cbk_t) (int ret, void *opaque);
+typedef int (*synctask_cbk_t) (int ret, call_frame_t *frame, void *opaque);
typedef int (*synctask_fn_t) (void *opaque);
+typedef enum {
+ SYNCTASK_INIT = 0,
+ SYNCTASK_RUN,
+ SYNCTASK_SUSPEND,
+ SYNCTASK_WAIT,
+ SYNCTASK_DONE,
+} synctask_state_t;
+
/* for one sequential execution of @syncfn */
struct synctask {
struct list_head all_tasks;
struct syncenv *env;
xlator_t *xl;
+ call_frame_t *frame;
+ call_frame_t *opframe;
synctask_cbk_t synccbk;
synctask_fn_t syncfn;
+ synctask_state_t state;
void *opaque;
void *stack;
- int complete;
+ int woken;
+ int slept;
+ int ret;
ucontext_t ctx;
+ struct syncproc *proc;
+
+ pthread_mutex_t mutex; /* for synchronous spawning of synctask */
+ pthread_cond_t cond;
+ int done;
};
-/* hosts the scheduler thread and framework for executing synctasks */
-struct syncenv {
+
+struct syncproc {
pthread_t processor;
+ ucontext_t sched;
+ struct syncenv *env;
struct synctask *current;
+};
+
+/* hosts the scheduler thread and framework for executing synctasks */
+struct syncenv {
+ struct syncproc proc[SYNCENV_PROC_MAX];
+ int procs;
struct list_head runq;
+ int runcount;
struct list_head waitq;
+ int waitcount;
pthread_mutex_t mutex;
pthread_cond_t cond;
- ucontext_t sched;
size_t stacksize;
};
@@ -78,80 +99,45 @@ struct syncargs {
dict_t *xattr;
gf_dirent_t entries;
struct statvfs statvfs_buf;
+ struct iovec *vector;
+ int count;
+ struct iobref *iobref;
+ char *buffer;
+ dict_t *xdata;
+
+ /* some more _cbk needs */
+ uuid_t uuid;
+ char *errstr;
+ dict_t *dict;
/* do not touch */
- pthread_mutex_t mutex;
- char complete;
- pthread_cond_t cond;
struct synctask *task;
};
-
-#define __yawn(args) do { \
- struct synctask *task = NULL; \
- \
- task = synctask_get (); \
- if (task) { \
- args->task = task; \
- synctask_yawn (task); \
- } else { \
- pthread_mutex_init (&args->mutex, NULL); \
- pthread_cond_init (&args->cond, NULL); \
- } \
- } while (0)
-
-
-#define __yield(args) do { \
- if (args->task) { \
- synctask_yield (args->task); \
- } else { \
- pthread_mutex_lock (&args->mutex); \
- { \
- while (!args->complete) \
- pthread_cond_wait (&args->cond, \
- &args->mutex); \
- } \
- pthread_mutex_unlock (&args->mutex); \
- \
- pthread_mutex_destroy (&args->mutex); \
- pthread_cond_destroy (&args->cond); \
- } \
- } while (0)
-
-
-#define __wake(args) do { \
- if (args->task) { \
- synctask_wake (args->task); \
- } else { \
- pthread_mutex_lock (&args->mutex); \
- { \
- args->complete = 1; \
- pthread_cond_broadcast (&args->cond); \
- } \
- pthread_mutex_unlock (&args->mutex); \
- } \
- } while (0)
+#define __wake(args) synctask_wake(args->task)
#define SYNCOP(subvol, stb, cbk, op, params ...) do { \
- call_frame_t *frame = NULL; \
+ struct synctask *task = NULL; \
\
- frame = syncop_create_frame (); \
+ task = synctask_get (); \
+ stb->task = task; \
\
- __yawn (stb); \
- STACK_WIND_COOKIE (frame, cbk, (void *)stb, subvol, op, params); \
- __yield (stb); \
+ STACK_WIND_COOKIE (task->opframe, cbk, (void *)stb, \
+ subvol, op, params); \
+ task->state = SYNCTASK_SUSPEND; \
+ synctask_yield (stb->task); \
+ STACK_RESET (task->opframe->root); \
} while (0)
-#define SYNCENV_DEFAULT_STACKSIZE (16 * 1024)
+#define SYNCENV_DEFAULT_STACKSIZE (2 * 1024 * 1024)
struct syncenv * syncenv_new ();
void syncenv_destroy (struct syncenv *);
+void syncenv_scale (struct syncenv *env);
-int synctask_new (struct syncenv *, synctask_fn_t, synctask_cbk_t, void *);
-void synctask_zzzz (struct synctask *task);
-void synctask_yawn (struct synctask *task);
+int synctask_new (struct syncenv *, synctask_fn_t, synctask_cbk_t, call_frame_t* frame, void *);
void synctask_wake (struct synctask *task);
void synctask_yield (struct synctask *task);
@@ -160,17 +146,60 @@ int syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req,
struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent);
int syncop_readdirp (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ dict_t *dict,
/* out */
gf_dirent_t *entries);
+int syncop_readdir (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ gf_dirent_t *entries);
+
int syncop_opendir (xlator_t *subvol, loc_t *loc, fd_t *fd);
int syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
/* out */
struct iatt *preop, struct iatt *postop);
+int syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
+ /* out */
+ struct iatt *preop, struct iatt *postop);
+
int syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf);
int syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags);
-
+int syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags);
+int syncop_listxattr (xlator_t *subvol, loc_t *loc, dict_t **dict);
+int syncop_getxattr (xlator_t *xl, loc_t *loc, dict_t **dict, const char *key);
+int syncop_fgetxattr (xlator_t *xl, fd_t *fd, dict_t **dict, const char *key);
+int syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name);
+int syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name);
+
+int syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
+ fd_t *fd, dict_t *dict);
+int syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd);
+int syncop_close (fd_t *fd);
+
+int syncop_write (xlator_t *subvol, fd_t *fd, const char *buf, int size,
+ off_t offset, struct iobref *iobref, uint32_t flags);
+int syncop_writev (xlator_t *subvol, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t offset, struct iobref *iobref,
+ uint32_t flags);
+int syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ uint32_t flags,
+ /* out */
+ struct iovec **vector, int *count, struct iobref **iobref);
+
+int syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset);
+int syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset);
+
+int syncop_unlink (xlator_t *subvol, loc_t *loc);
+
+int syncop_fsync (xlator_t *subvol, fd_t *fd);
+int syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf);
+int syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf);
+
+int syncop_symlink (xlator_t *subvol, loc_t *loc, char *newpath, dict_t *dict);
+int syncop_readlink (xlator_t *subvol, loc_t *loc, char **buffer, size_t size);
+int syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
+ dict_t *dict);
+int syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc);
#endif /* _SYNCOP_H */
diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c
index b8ee38de8..bb834dbfd 100644
--- a/libglusterfs/src/syscall.c
+++ b/libglusterfs/src/syscall.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -241,7 +232,12 @@ sys_statvfs (const char *path, struct statvfs *buf)
int
sys_close (int fd)
{
- return close (fd);
+ int ret = -1;
+
+ if (fd >= 0)
+ ret = close (fd);
+
+ return ret;
}
@@ -268,7 +264,7 @@ sys_lsetxattr (const char *path, const char *name, const void *value,
size_t size, int flags)
{
-#ifdef GF_LINUX_HOST_OS
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return lsetxattr (path, name, value, size, flags);
#endif
@@ -293,7 +289,7 @@ ssize_t
sys_llistxattr (const char *path, char *list, size_t size)
{
-#ifdef GF_LINUX_HOST_OS
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return llistxattr (path, list, size);
#endif
@@ -316,7 +312,7 @@ ssize_t
sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
{
-#ifdef GF_LINUX_HOST_OS
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return lgetxattr (path, name, value, size);
#endif
@@ -340,7 +336,7 @@ ssize_t
sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
{
-#ifdef GF_LINUX_HOST_OS
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return fgetxattr (filedes, name, value, size);
#endif
@@ -361,11 +357,37 @@ sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
int
+sys_fremovexattr (int filedes, const char *name)
+{
+
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
+ return fremovexattr (filedes, name);
+#endif
+
+ errno = ENOSYS;
+ return -1;
+#if 0 /* TODO: to port to other OSes, fill in each of below */
+#ifdef GF_BSD_HOST_OS
+ return extattr_remove_fd (filedes, EXTATTR_NAMESPACE_USER, name);
+#endif
+
+#ifdef GF_SOLARIS_HOST_OS
+ return solaris_fremovexattr (filedes, name);
+#endif
+
+#ifdef GF_DARWIN_HOST_OS
+ return fremovexattr (filedes, name, 0);
+#endif
+#endif
+}
+
+
+int
sys_fsetxattr (int filedes, const char *name, const void *value,
size_t size, int flags)
{
-#ifdef GF_LINUX_HOST_OS
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return fsetxattr (filedes, name, value, size, flags);
#endif
@@ -389,7 +411,7 @@ ssize_t
sys_flistxattr (int filedes, char *list, size_t size)
{
-#ifdef GF_LINUX_HOST_OS
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return flistxattr (filedes, list, size);
#endif
@@ -412,7 +434,7 @@ int
sys_lremovexattr (const char *path, const char *name)
{
-#ifdef GF_LINUX_HOST_OS
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return lremovexattr (path, name);
#endif
diff --git a/libglusterfs/src/syscall.h b/libglusterfs/src/syscall.h
index de1044cdb..d5c6ce5f6 100644
--- a/libglusterfs/src/syscall.h
+++ b/libglusterfs/src/syscall.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __SYSCALL_H__
@@ -140,6 +131,9 @@ int
sys_lremovexattr (const char *path, const char *name);
int
+sys_fremovexattr (int filedes, const char *name);
+
+int
sys_access (const char *pathname, int mode);
int
diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c
index d8766d38b..ae40142ad 100644
--- a/libglusterfs/src/timer.c
+++ b/libglusterfs/src/timer.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -136,6 +127,7 @@ void *
gf_timer_proc (void *ctx)
{
gf_timer_registry_t *reg = NULL;
+ const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };
if (ctx == NULL)
{
@@ -178,7 +170,7 @@ gf_timer_proc (void *ctx)
else
break;
}
- usleep (1000000);
+ nanosleep (&sleepts, NULL);
}
pthread_mutex_lock (&reg->lock);
diff --git a/libglusterfs/src/timer.h b/libglusterfs/src/timer.h
index 74abe52a2..2954f6aff 100644
--- a/libglusterfs/src/timer.h
+++ b/libglusterfs/src/timer.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _TIMER_H
diff --git a/libglusterfs/src/trie-mem-types.h b/libglusterfs/src/trie-mem-types.h
deleted file mode 100644
index 98a1766da..000000000
--- a/libglusterfs/src/trie-mem-types.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __TRIE_MEM_TYPES_H__
-#define __TRIE_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-#define GF_MEM_TYPE_START (gf_common_mt_end + 1)
-
-enum gf_trie_mem_types_ {
- gf_trie_mt_trie = GF_MEM_TYPE_START,
- gf_trie_mt_data,
- gf_trie_mt_node,
- gf_trie_mt_buf,
- gf_trie_mt_end,
-};
-#endif
diff --git a/libglusterfs/src/trie.c b/libglusterfs/src/trie.c
index 2501e71a5..b7c597842 100644
--- a/libglusterfs/src/trie.c
+++ b/libglusterfs/src/trie.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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>
@@ -23,7 +14,6 @@
#include <ctype.h>
#include "common-utils.h"
-#include "trie-mem-types.h"
#include "trie.h"
#define DISTANCE_EDIT 1
@@ -53,7 +43,7 @@ trie_new ()
{
trie_t *trie = NULL;
- trie = GF_CALLOC (1, sizeof (*trie), gf_trie_mt_trie);
+ trie = GF_CALLOC (1, sizeof (*trie), gf_common_mt_trie_trie);
if (!trie)
return NULL;
@@ -70,7 +60,8 @@ trie_subnode (trienode_t *node, int id)
subnode = node->subnodes[id];
if (!subnode) {
- subnode = GF_CALLOC (1, sizeof (*subnode), gf_trie_mt_node);
+ subnode = GF_CALLOC (1, sizeof (*subnode),
+ gf_common_mt_trie_node);
if (!subnode)
return NULL;
@@ -202,7 +193,7 @@ trienode_get_word (trienode_t *node, char **bufp)
{
char *buf = NULL;
- buf = GF_CALLOC (1, node->depth + 1, gf_trie_mt_buf);
+ buf = GF_CALLOC (1, node->depth + 1, gf_common_mt_trie_buf);
if (!buf)
return -1;
*bufp = buf;
@@ -226,7 +217,8 @@ calc_dist (trienode_t *node, void *data)
word = data;
- node->data = GF_CALLOC (node->trie->len, sizeof (int), gf_trie_mt_data);
+ node->data = GF_CALLOC (node->trie->len, sizeof (int),
+ gf_common_mt_trie_data);
if (!node->data)
return -1;
row = node->data;
diff --git a/libglusterfs/src/trie.h b/libglusterfs/src/trie.h
index a670c2a27..0356e6621 100644
--- a/libglusterfs/src/trie.h
+++ b/libglusterfs/src/trie.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _TRIE_H_
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index b8f800c70..470087df9 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -29,1160 +20,174 @@
#include "defaults.h"
#define SET_DEFAULT_FOP(fn) do { \
- if (!xl->fops->fn) \
- xl->fops->fn = default_##fn; \
- } while (0)
+ if (!xl->fops->fn) \
+ xl->fops->fn = default_##fn; \
+ } while (0)
#define SET_DEFAULT_CBK(fn) do { \
- if (!xl->cbks->fn) \
- xl->cbks->fn = default_##fn; \
- } while (0)
-
+ if (!xl->cbks->fn) \
+ xl->cbks->fn = default_##fn; \
+ } while (0)
-#define GF_OPTION_LIST_EMPTY(_opt) (_opt->value[0] == NULL)
static void
fill_defaults (xlator_t *xl)
{
- if (xl == NULL) {
- gf_log_callingfn ("xlator", GF_LOG_WARNING, "invalid argument");
- return;
- }
-
- SET_DEFAULT_FOP (create);
- SET_DEFAULT_FOP (open);
- SET_DEFAULT_FOP (stat);
- SET_DEFAULT_FOP (readlink);
- SET_DEFAULT_FOP (mknod);
- SET_DEFAULT_FOP (mkdir);
- SET_DEFAULT_FOP (unlink);
- SET_DEFAULT_FOP (rmdir);
- SET_DEFAULT_FOP (symlink);
- SET_DEFAULT_FOP (rename);
- SET_DEFAULT_FOP (link);
- SET_DEFAULT_FOP (truncate);
- SET_DEFAULT_FOP (readv);
- SET_DEFAULT_FOP (writev);
- SET_DEFAULT_FOP (statfs);
- SET_DEFAULT_FOP (flush);
- SET_DEFAULT_FOP (fsync);
- SET_DEFAULT_FOP (setxattr);
- SET_DEFAULT_FOP (getxattr);
- SET_DEFAULT_FOP (fsetxattr);
- SET_DEFAULT_FOP (fgetxattr);
- SET_DEFAULT_FOP (removexattr);
- SET_DEFAULT_FOP (opendir);
- SET_DEFAULT_FOP (readdir);
- SET_DEFAULT_FOP (readdirp);
- SET_DEFAULT_FOP (fsyncdir);
- SET_DEFAULT_FOP (access);
- SET_DEFAULT_FOP (ftruncate);
- SET_DEFAULT_FOP (fstat);
- SET_DEFAULT_FOP (lk);
- SET_DEFAULT_FOP (inodelk);
- SET_DEFAULT_FOP (finodelk);
- SET_DEFAULT_FOP (entrylk);
- SET_DEFAULT_FOP (fentrylk);
- SET_DEFAULT_FOP (lookup);
- SET_DEFAULT_FOP (rchecksum);
- SET_DEFAULT_FOP (xattrop);
- SET_DEFAULT_FOP (fxattrop);
+ if (xl == NULL) {
+ gf_log_callingfn ("xlator", GF_LOG_WARNING, "invalid argument");
+ return;
+ }
+
+ SET_DEFAULT_FOP (create);
+ SET_DEFAULT_FOP (open);
+ SET_DEFAULT_FOP (stat);
+ SET_DEFAULT_FOP (readlink);
+ SET_DEFAULT_FOP (mknod);
+ SET_DEFAULT_FOP (mkdir);
+ SET_DEFAULT_FOP (unlink);
+ SET_DEFAULT_FOP (rmdir);
+ SET_DEFAULT_FOP (symlink);
+ SET_DEFAULT_FOP (rename);
+ SET_DEFAULT_FOP (link);
+ SET_DEFAULT_FOP (truncate);
+ SET_DEFAULT_FOP (readv);
+ SET_DEFAULT_FOP (writev);
+ SET_DEFAULT_FOP (statfs);
+ SET_DEFAULT_FOP (flush);
+ SET_DEFAULT_FOP (fsync);
+ SET_DEFAULT_FOP (setxattr);
+ SET_DEFAULT_FOP (getxattr);
+ SET_DEFAULT_FOP (fsetxattr);
+ SET_DEFAULT_FOP (fgetxattr);
+ SET_DEFAULT_FOP (removexattr);
+ SET_DEFAULT_FOP (fremovexattr);
+ SET_DEFAULT_FOP (opendir);
+ SET_DEFAULT_FOP (readdir);
+ SET_DEFAULT_FOP (readdirp);
+ SET_DEFAULT_FOP (fsyncdir);
+ SET_DEFAULT_FOP (access);
+ SET_DEFAULT_FOP (ftruncate);
+ SET_DEFAULT_FOP (fstat);
+ SET_DEFAULT_FOP (lk);
+ SET_DEFAULT_FOP (inodelk);
+ SET_DEFAULT_FOP (finodelk);
+ SET_DEFAULT_FOP (entrylk);
+ SET_DEFAULT_FOP (fentrylk);
+ SET_DEFAULT_FOP (lookup);
+ SET_DEFAULT_FOP (rchecksum);
+ SET_DEFAULT_FOP (xattrop);
+ SET_DEFAULT_FOP (fxattrop);
SET_DEFAULT_FOP (setattr);
SET_DEFAULT_FOP (fsetattr);
SET_DEFAULT_FOP (getspec);
- SET_DEFAULT_CBK (release);
- SET_DEFAULT_CBK (releasedir);
- SET_DEFAULT_CBK (forget);
+ SET_DEFAULT_CBK (release);
+ SET_DEFAULT_CBK (releasedir);
+ SET_DEFAULT_CBK (forget);
- if (!xl->notify)
- xl->notify = default_notify;
+ if (!xl->notify)
+ xl->notify = default_notify;
if (!xl->mem_acct_init)
xl->mem_acct_init = default_mem_acct_init;
- return;
+ return;
}
-int
-_volume_option_value_validate_attacherr (xlator_t *xl,
- data_pair_t *pair,
- volume_option_t *opt,
- char **op_errstr)
-{
- int i = 0;
- int ret = -1;
- uint64_t input_size = 0;
- long long inputll = 0;
- char errstr[256] = {0, };
-
- /* Key is valid, validate the option */
- switch (opt->type) {
- case GF_OPTION_TYPE_PATH:
- {
- if (strstr (pair->value->data, "../")) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid path given '%s'",
- pair->value->data);
- snprintf (errstr, 256,
- "invalid path given '%s'",
- pair->value->data);
-
- *op_errstr = gf_strdup (errstr);
- ret = -1;
- goto out;
- }
-
- /* Make sure the given path is valid */
- if (pair->value->data[0] != '/') {
- gf_log (xl->name, GF_LOG_WARNING,
- "option %s %s: '%s' is not an "
- "absolute path name",
- pair->key, pair->value->data,
- pair->value->data);
- snprintf (errstr, 256,
- "option %s %s: '%s' is not an "
- "absolute path name",
- pair->key, pair->value->data,
- pair->value->data);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INT:
- {
- /* Check the range */
- if (gf_string2longlong (pair->value->data,
- &inputll) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- snprintf (errstr, 256,
- "invalid number format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((inputll < opt->min) ||
- (inputll > opt->max)) {
- gf_log (xl->name, GF_LOG_WARNING,
- "'%lld' in 'option %s %s' is out of "
- "range [%"PRId64" - %"PRId64"]",
- inputll, pair->key,
- pair->value->data,
- opt->min, opt->max);
- snprintf (errstr, 256,
- "'%lld' in 'option %s %s' is out of "
- "range [%"PRId64" - %"PRId64"]",
- inputll, pair->key,
- pair->value->data,
- opt->min, opt->max);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_SIZET:
- {
- /* Check the range */
- if (gf_string2bytesize (pair->value->data,
- &input_size) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid size format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- snprintf (errstr, 256,
- "invalid size format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- snprintf (errstr, 256,
- "'%"PRId64"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_BOOL:
- {
- /* Check if the value is one of
- '0|1|on|off|no|yes|true|false|enable|disable' */
- gf_boolean_t bool_value;
- if (gf_string2boolean (pair->value->data,
- &bool_value) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a valid "
- "boolean value",
- pair->key, pair->value->data,
- pair->value->data);
- snprintf (errstr, 256,
- "option %s %s: '%s' is not a valid "
- "boolean value",
- pair->key, pair->value->data,
- pair->value->data);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_XLATOR:
- {
- /* Check if the value is one of the xlators */
- xlator_t *xlopt = xl;
- while (xlopt->prev)
- xlopt = xlopt->prev;
-
- while (xlopt) {
- if (strcmp (pair->value->data,
- xlopt->name) == 0) {
- ret = 0;
- break;
- }
- xlopt = xlopt->next;
- }
- if (!xlopt) {
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a "
- "valid volume name",
- pair->key, pair->value->data,
- pair->value->data);
- snprintf (errstr, 256,
- "option %s %s: '%s' is not a "
- "valid volume name",
- pair->key, pair->value->data,
- pair->value->data);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_STR:
- {
- /* Check if the '*str' is valid */
- if (GF_OPTION_LIST_EMPTY(opt)) {
- ret = 0;
- goto out;
- }
-
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- if (fnmatch (opt->value[i], pair->value->data,
- FNM_EXTMATCH) == 0) {
- ret = 0;
- break;
- }
- }
-
- if ((i == ZR_OPTION_MAX_ARRAY_SIZE)
- || ((i < ZR_OPTION_MAX_ARRAY_SIZE)
- && (!opt->value[i]))) {
- /* enter here only if
- * 1. reached end of opt->value array and haven't
- * validated input
- * OR
- * 2. valid input list is less than
- * ZR_OPTION_MAX_ARRAY_SIZE and input has not
- * matched all possible input values.
- */
- char given_array[4096] = {0,};
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- strcat (given_array, opt->value[i]);
- strcat (given_array, ", ");
- }
-
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not valid "
- "(possible options are %s)",
- pair->key, pair->value->data,
- pair->value->data, given_array);
- snprintf (errstr, 256,
- "option %s %s: '%s' is not valid "
- "(possible options are %s)",
- pair->key, pair->value->data,
- pair->value->data, given_array);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- }
- break;
- case GF_OPTION_TYPE_PERCENT:
- {
- uint32_t percent = 0;
-
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid percent format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- snprintf (errstr, 256,
- "invalid percent format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
-
- if ((percent < 0) || (percent > 100)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%d' in 'option %s %s' is out of "
- "range [0 - 100]",
- percent, pair->key,
- pair->value->data);
- snprintf (errstr, 256,
- "'%d' in 'option %s %s' is out of "
- "range [0 - 100]",
- percent, pair->key,
- pair->value->data);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_PERCENT_OR_SIZET:
- {
- uint32_t percent = 0;
- uint64_t input_size = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) == 0) {
- if (percent > 100) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "value given was greater than 100, "
- "assuming this is actually a size");
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) &&
- (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check "
- "required for "
- "'option %s %s'",
- pair->key,
- pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in "
- "'option %s %s' is out"
- " of range [%"PRId64""
- "- %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- snprintf (errstr, 256,
- "'%"PRId64"' in "
- "'option %s %s' is "
- " out of range ["
- "%"PRId64"- %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- // It is a size
- ret = 0;
- goto out;
- } else {
- // It's not a percent or size
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
-
- snprintf (errstr, 256,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
-
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
-
- }
- // It is a percent
- ret = 0;
- goto out;
- } else {
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in 'option %s %s'"
- " is out of range [%"PRId64" -"
- " %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- snprintf (errstr, 256,
- "'%"PRId64"' in 'option %s %s'"
- " is out of range [%"PRId64" -"
- " %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- } else {
- // It's not a percent or size
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- snprintf (errstr, 256,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- //It is a size
- ret = 0;
- goto out;
- }
-
- }
- break;
- case GF_OPTION_TYPE_TIME:
- {
- uint32_t input_time = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2time (pair->value->data,
- &input_time) != 0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
-
- snprintf (errstr, 256,
- "invalid time format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- if ((input_time < opt->min) ||
- (input_time > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRIu32"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_time, pair->key,
- pair->value->data,
- opt->min, opt->max);
-
- snprintf (errstr, 256,
- "'%"PRIu32"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_time, pair->key,
- pair->value->data,
- opt->min, opt->max);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_DOUBLE:
- {
- double input_time = 0.0;
-
- /* Check if the value is valid double */
- if (gf_string2double (pair->value->data,
- &input_time) != 0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid double \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
-
- snprintf (errstr, 256,
- "invalid double \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
-
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
-
- if (input_time < 0.0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
-
- snprintf (errstr, 256,
- "invalid double \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
+int
+xlator_set_type_virtual (xlator_t *xl, const char *type)
+{
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
+ GF_VALIDATE_OR_GOTO ("xlator", type, out);
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
+ xl->type = gf_strdup (type);
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for 'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INTERNET_ADDRESS:
- {
- if (!valid_internet_address (pair->value->data)) {
- gf_log (xl->name, GF_LOG_WARNING, "internet address '%s'"
- " does not conform to standards.",
- pair->value->data);
-
- snprintf (errstr, 256,
- "internet address '%s'"
- " does not conform to standards.",
- pair->value->data);
-
- *op_errstr = gf_strdup (errstr);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_ANY:
- /* NO CHECK */
- ret = 0;
- break;
- }
+ if (xl->type)
+ return 0;
out:
- return ret;
+ return -1;
}
int
-_volume_option_value_validate (xlator_t *xl,
- data_pair_t *pair,
- volume_option_t *opt)
+xlator_volopt_dynload (char *xlator_type, void **dl_handle,
+ volume_opt_list_t *opt_list)
{
- int i = 0;
- int ret = -1;
- uint64_t input_size = 0;
- long long inputll = 0;
-
- /* Key is valid, validate the option */
- switch (opt->type) {
- case GF_OPTION_TYPE_PATH:
- {
- if (strstr (pair->value->data, "../")) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid path given '%s'",
- pair->value->data);
- ret = -1;
- goto out;
- }
-
- /* Make sure the given path is valid */
- if (pair->value->data[0] != '/') {
- gf_log (xl->name, GF_LOG_WARNING,
- "option %s %s: '%s' is not an "
- "absolute path name",
- pair->key, pair->value->data,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INT:
- {
- /* Check the range */
- if (gf_string2longlong (pair->value->data,
- &inputll) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((inputll < opt->min) ||
- (inputll > opt->max)) {
- gf_log (xl->name, GF_LOG_WARNING,
- "'%lld' in 'option %s %s' is out of "
- "range [%"PRId64" - %"PRId64"]",
- inputll, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_SIZET:
- {
- /* Check the range */
- if (gf_string2bytesize (pair->value->data,
- &input_size) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid size format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_WARNING,
- "'%"PRId64"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_BOOL:
- {
- /* Check if the value is one of
- '0|1|on|off|no|yes|true|false|enable|disable' */
- gf_boolean_t bool_value;
- if (gf_string2boolean (pair->value->data,
- &bool_value) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a valid "
- "boolean value",
- pair->key, pair->value->data,
- pair->value->data);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_XLATOR:
- {
- /* Check if the value is one of the xlators */
- xlator_t *xlopt = xl;
- while (xlopt->prev)
- xlopt = xlopt->prev;
-
- while (xlopt) {
- if (strcmp (pair->value->data,
- xlopt->name) == 0) {
- ret = 0;
- break;
- }
- xlopt = xlopt->next;
- }
- if (!xlopt) {
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a "
- "valid volume name",
- pair->key, pair->value->data,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_STR:
- {
- /* Check if the '*str' is valid */
- if (GF_OPTION_LIST_EMPTY(opt)) {
- ret = 0;
- goto out;
- }
+ int ret = -1;
+ char *name = NULL;
+ void *handle = NULL;
+ volume_opt_list_t *vol_opt = NULL;
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- #ifdef GF_DARWIN_HOST_OS
- if (fnmatch (opt->value[i],
- pair->value->data, 0) == 0) {
- #else
- if (fnmatch (opt->value[i],
- pair->value->data, FNM_EXTMATCH) == 0) {
- #endif
- ret = 0;
- break;
- }
- }
-
- if ((i == ZR_OPTION_MAX_ARRAY_SIZE)
- || ((i < ZR_OPTION_MAX_ARRAY_SIZE)
- && (!opt->value[i]))) {
- /* enter here only if
- * 1. reached end of opt->value array and haven't
- * validated input
- * OR
- * 2. valid input list is less than
- * ZR_OPTION_MAX_ARRAY_SIZE and input has not
- * matched all possible input values.
- */
- char given_array[4096] = {0,};
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- strcat (given_array, opt->value[i]);
- strcat (given_array, ", ");
- }
-
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not valid "
- "(possible options are %s)",
- pair->key, pair->value->data,
- pair->value->data, given_array);
-
- goto out;
- }
- }
- break;
- case GF_OPTION_TYPE_PERCENT:
- {
- uint32_t percent = 0;
-
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid percent format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((percent < 0) || (percent > 100)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%d' in 'option %s %s' is out of "
- "range [0 - 100]",
- percent, pair->key,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_PERCENT_OR_SIZET:
- {
- uint32_t percent = 0;
- uint64_t input_size = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) == 0) {
- if (percent > 100) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "value given was greater than 100, "
- "assuming this is actually a size");
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check "
- "required for "
- "'option %s %s'",
- pair->key,
- pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in "
- "'option %s %s' is out"
- " of range [%"PRId64""
- "- %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- // It is a size
- ret = 0;
- goto out;
- } else {
- // It's not a percent or size
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- }
-
- }
- // It is a percent
- ret = 0;
- goto out;
- } else {
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in 'option %s %s'"
- " is out of range [%"PRId64" -"
- " %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- } else {
- // It's not a percent or size
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- }
- //It is a size
- ret = 0;
- goto out;
- }
-
- }
- break;
- case GF_OPTION_TYPE_TIME:
- {
- uint32_t input_time = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2time (pair->value->data,
- &input_time) != 0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- if ((input_time < opt->min) ||
- (input_time > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRIu32"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_time, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_DOUBLE:
- {
- double input_time = 0.0;
-
- /* Check if the value is valid double */
- if (gf_string2double (pair->value->data,
- &input_time) != 0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if (input_time < 0.0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for 'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INTERNET_ADDRESS:
- {
- if (!valid_internet_address (pair->value->data)) {
- gf_log (xl->name, GF_LOG_WARNING, "internet address '%s'"
- " does not conform to standards.",
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_ANY:
- /* NO CHECK */
- ret = 0;
- break;
- }
+ GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out);
-out:
- return ret;
-}
+ GF_ASSERT (dl_handle);
-int
-validate_xlator_volume_options_attacherr (xlator_t *xl,
- volume_option_t *opt,
- char **op_errstr)
-{
- int i = 0;
- int ret = -1;
- int index = 0;
- volume_option_t *trav = NULL;
- data_pair_t *pairs = NULL;
+ if (*dl_handle)
+ if (dlclose (*dl_handle))
+ gf_log ("xlator", GF_LOG_WARNING, "Unable to close "
+ "previously opened handle( may be stale)."
+ "Ignoring the invalid handle");
- if (!opt) {
- ret = 0;
+ ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xlator_type);
+ if (-1 == ret) {
+ gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
goto out;
}
- /* First search for not supported options, if any report error */
- pairs = xl->options->members_list;
- while (pairs) {
- ret = -1;
- for (index = 0;
- opt[index].key && opt[index].key[0] ; index++) {
- trav = &(opt[index]);
- for (i = 0 ;
- (i < ZR_VOLUME_MAX_NUM_KEY) &&
- trav->key[i]; i++) {
- /* Check if the key is valid */
- if (fnmatch (trav->key[i],
- pairs->key, FNM_NOESCAPE) == 0) {
- ret = 0;
- break;
- }
- }
- if (!ret) {
- if (i) {
- gf_log (xl->name, GF_LOG_WARNING,
- "option '%s' is deprecated, "
- "preferred is '%s', continuing"
- " with correction",
- trav->key[i], trav->key[0]);
- /* TODO: some bytes lost */
- pairs->key = gf_strdup (trav->key[0]);
- }
- break;
- }
- }
- if (!ret) {
- ret = _volume_option_value_validate_attacherr (xl,
- pairs,
- trav,
- op_errstr);
- if (-1 == ret) {
- goto out;
- }
- }
+ ret = -1;
+
+ gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
- pairs = pairs->next;
+ handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
+ if (!handle) {
+ gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
+ goto out;
}
+ *dl_handle = handle;
- ret = 0;
- out:
- return ret;
-}
+ vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
+ gf_common_mt_volume_opt_list_t);
-int
-validate_xlator_volume_options (xlator_t *xl, volume_option_t *opt)
-{
- int i = 0;
- int ret = -1;
- int index = 0;
- volume_option_t *trav = NULL;
- data_pair_t *pairs = NULL;
-
- if (!opt) {
- ret = 0;
- goto out;
- }
-
- /* First search for not supported options, if any report error */
- pairs = xl->options->members_list;
- while (pairs) {
- ret = -1;
- for (index = 0; opt[index].key && opt[index].key[0] ; index++) {
- trav = &(opt[index]);
- for (i = 0 ; (i < ZR_VOLUME_MAX_NUM_KEY) && trav->key[i]; i++) {
- /* Check if the key is valid */
- if (fnmatch (trav->key[i],
- pairs->key, FNM_NOESCAPE) == 0) {
- ret = 0;
- break;
- }
- }
- if (!ret) {
- if (i) {
- gf_log (xl->name, GF_LOG_WARNING,
- "option '%s' is deprecated, "
- "preferred is '%s', continuing"
- " with correction",
- trav->key[i], trav->key[0]);
- /* TODO: some bytes lost */
- pairs->key = gf_strdup (trav->key[0]);
- }
- break;
- }
- }
- if (!ret) {
- ret = _volume_option_value_validate (xl, pairs, trav);
- if (-1 == ret) {
- goto out;
- }
- }
-
- pairs = pairs->next;
- }
-
- ret = 0;
- out:
- return ret;
-}
+ if (!vol_opt) {
+ goto out;
+ }
-int32_t
-xlator_set_type_virtual (xlator_t *xl, const char *type)
-{
- GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- GF_VALIDATE_OR_GOTO ("xlator", type, out);
+ if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
+ dlerror ();
+ gf_log ("xlator", GF_LOG_DEBUG,
+ "Strict option validation not enforced -- neglecting");
+ }
+ opt_list->given_opt = vol_opt->given_opt;
- xl->type = gf_strdup (type);
+ INIT_LIST_HEAD (&vol_opt->list);
+ list_add_tail (&vol_opt->list, &opt_list->list);
- if (xl->type)
- return 0;
+ ret = 0;
+ out:
+ gf_log ("xlator", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
-out:
- return -1;
}
-int32_t
+int
xlator_dynload (xlator_t *xl)
{
- int ret = -1;
- char *name = NULL;
- void *handle = NULL;
- volume_opt_list_t *vol_opt = NULL;
+ int ret = -1;
+ char *name = NULL;
+ void *handle = NULL;
+ volume_opt_list_t *vol_opt = NULL;
+
GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type);
+ INIT_LIST_HEAD (&xl->volume_options);
+
+ ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type);
if (-1 == ret) {
gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
goto out;
@@ -1190,96 +195,87 @@ xlator_dynload (xlator_t *xl)
ret = -1;
- gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
+ gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
- handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
- if (!handle) {
- gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
+ handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
+ if (!handle) {
+ gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
goto out;
- }
+ }
xl->dlhandle = handle;
- if (!(xl->fops = dlsym (handle, "fops"))) {
- gf_log ("xlator", GF_LOG_WARNING, "dlsym(fops) on %s",
- dlerror ());
+ if (!(xl->fops = dlsym (handle, "fops"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(fops) on %s",
+ dlerror ());
goto out;
- }
+ }
- if (!(xl->cbks = dlsym (handle, "cbks"))) {
- gf_log ("xlator", GF_LOG_WARNING, "dlsym(cbks) on %s",
- dlerror ());
+ if (!(xl->cbks = dlsym (handle, "cbks"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(cbks) on %s",
+ dlerror ());
goto out;
- }
+ }
- if (!(xl->init = dlsym (handle, "init"))) {
- gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s",
- dlerror ());
+ if (!(xl->init = dlsym (handle, "init"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s",
+ dlerror ());
goto out;
- }
+ }
- if (!(xl->fini = dlsym (handle, "fini"))) {
- gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s",
- dlerror ());
+ if (!(xl->fini = dlsym (handle, "fini"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s",
+ dlerror ());
goto out;
- }
+ }
- if (!(xl->notify = dlsym (handle, "notify"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(notify) on %s -- neglecting", dlerror ());
- }
+ if (!(xl->notify = dlsym (handle, "notify"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(notify) on %s -- neglecting", dlerror ());
+ }
- if (!(xl->dumpops = dlsym (handle, "dumpops"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(dumpops) on %s -- neglecting", dlerror ());
- }
+ if (!(xl->dumpops = dlsym (handle, "dumpops"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(dumpops) on %s -- neglecting", dlerror ());
+ }
if (!(xl->mem_acct_init = dlsym (handle, "mem_acct_init"))) {
- gf_log (xl->name, GF_LOG_DEBUG,
+ gf_log (xl->name, GF_LOG_TRACE,
"dlsym(mem_acct_init) on %s -- neglecting",
dlerror ());
}
- if (!(xl->reconfigure = dlsym (handle, "reconfigure"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(reconfigure) on %s -- neglecting",
- dlerror());
- }
-
- if (!(xl->validate_options = dlsym (handle, "validate_options"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(validate_options) on %s -- neglecting",
+ if (!(xl->reconfigure = dlsym (handle, "reconfigure"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(reconfigure) on %s -- neglecting",
dlerror());
}
-
- INIT_LIST_HEAD (&xl->volume_options);
-
- vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
+ vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
gf_common_mt_volume_opt_list_t);
if (!vol_opt) {
goto out;
}
- if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
- dlerror ();
- gf_log (xl->name, GF_LOG_DEBUG,
- "Strict option validation not enforced -- neglecting");
- }
- list_add_tail (&vol_opt->list, &xl->volume_options);
+ if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
+ dlerror ();
+ gf_log (xl->name, GF_LOG_TRACE,
+ "Strict option validation not enforced -- neglecting");
+ }
+ list_add_tail (&vol_opt->list, &xl->volume_options);
- fill_defaults (xl);
+ fill_defaults (xl);
ret = 0;
out:
if (name)
GF_FREE (name);
- return ret;
+ return ret;
}
-int32_t
+int
xlator_set_type (xlator_t *xl, const char *type)
{
int ret = 0;
@@ -1294,31 +290,30 @@ xlator_set_type (xlator_t *xl, const char *type)
void
xlator_foreach (xlator_t *this,
- void (*fn)(xlator_t *each,
- void *data),
- void *data)
+ void (*fn)(xlator_t *each,
+ void *data),
+ void *data)
{
- xlator_t *first = NULL;
+ xlator_t *first = NULL;
xlator_t *old_THIS = NULL;
GF_VALIDATE_OR_GOTO ("xlator", this, out);
GF_VALIDATE_OR_GOTO ("xlator", fn, out);
- GF_VALIDATE_OR_GOTO ("xlator", data, out);
- first = this;
+ first = this;
- while (first->prev)
- first = first->prev;
+ while (first->prev)
+ first = first->prev;
- while (first) {
+ while (first) {
old_THIS = THIS;
THIS = first;
- fn (first, data);
+ fn (first, data);
THIS = old_THIS;
- first = first->next;
- }
+ first = first->next;
+ }
out:
return;
@@ -1328,24 +323,24 @@ out:
xlator_t *
xlator_search_by_name (xlator_t *any, const char *name)
{
- xlator_t *search = NULL;
+ xlator_t *search = NULL;
GF_VALIDATE_OR_GOTO ("xlator", any, out);
GF_VALIDATE_OR_GOTO ("xlator", name, out);
- search = any;
+ search = any;
- while (search->prev)
- search = search->prev;
+ while (search->prev)
+ search = search->prev;
- while (search) {
- if (!strcmp (search->name, name))
- break;
- search = search->next;
- }
+ while (search) {
+ if (!strcmp (search->name, name))
+ break;
+ search = search->next;
+ }
out:
- return search;
+ return search;
}
@@ -1369,7 +364,7 @@ __xlator_init(xlator_t *xl)
int
xlator_init (xlator_t *xl)
{
- int32_t ret = -1;
+ int32_t ret = -1;
GF_VALIDATE_OR_GOTO ("xlator", xl, out);
@@ -1395,145 +390,52 @@ xlator_init (xlator_t *xl)
ret = 0;
out:
- return ret;
+ return ret;
}
static void
xlator_fini_rec (xlator_t *xl)
{
- xlator_list_t *trav = NULL;
+ xlator_list_t *trav = NULL;
xlator_t *old_THIS = NULL;
GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- trav = xl->children;
-
- while (trav) {
- if (!trav->xlator->init_succeeded) {
- break;
- }
-
- xlator_fini_rec (trav->xlator);
- gf_log (trav->xlator->name, GF_LOG_DEBUG, "fini done");
- trav = trav->next;
- }
-
- if (xl->init_succeeded) {
- if (xl->fini) {
- old_THIS = THIS;
- THIS = xl;
-
- xl->fini (xl);
-
- THIS = old_THIS;
- } else {
- gf_log (xl->name, GF_LOG_DEBUG, "No fini() found");
- }
- xl->init_succeeded = 0;
- }
-
-out:
- return;
-}
-
-static int
-xlator_reconfigure_rec (xlator_t *old_xl, xlator_t *new_xl)
-{
- xlator_list_t *trav1 = NULL;
- xlator_list_t *trav2 = NULL;
- int32_t ret = -1;
- xlator_t *old_THIS = NULL;
-
- GF_VALIDATE_OR_GOTO ("xlator", old_xl, out);
- GF_VALIDATE_OR_GOTO ("xlator", new_xl, out);
-
- trav1 = old_xl->children;
- trav2 = new_xl->children;
-
- while (trav1 && trav2) {
- ret = xlator_reconfigure_rec (trav1->xlator, trav2->xlator);
- if (ret)
- goto out;
-
- gf_log (trav1->xlator->name, GF_LOG_DEBUG, "reconfigured");
-
- trav1 = trav1->next;
- trav2 = trav2->next;
- }
-
- if (old_xl->reconfigure) {
- old_THIS = THIS;
- THIS = old_xl;
-
- ret = old_xl->reconfigure (old_xl, new_xl->options);
-
- THIS = old_THIS;
-
- if (ret)
- goto out;
- } else {
- gf_log (old_xl->name, GF_LOG_DEBUG, "No reconfigure() found");
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-xlator_validate_rec (xlator_t *xlator, char **op_errstr)
-{
- int ret = -1;
- xlator_list_t *trav = NULL;
-
- GF_VALIDATE_OR_GOTO ("xlator", xlator, out);
-
- trav = xlator->children;
+ trav = xl->children;
while (trav) {
- if (xlator_validate_rec (trav->xlator, op_errstr)) {
- gf_log ("xlator", GF_LOG_WARNING, "validate_rec failed");
- goto out;
+ if (!trav->xlator->init_succeeded) {
+ break;
}
+ xlator_fini_rec (trav->xlator);
+ gf_log (trav->xlator->name, GF_LOG_DEBUG, "fini done");
trav = trav->next;
}
- if (xlator_dynload (xlator))
- gf_log ("", GF_LOG_DEBUG, "Did not load the symbols");
+ if (xl->init_succeeded) {
+ if (xl->fini) {
+ old_THIS = THIS;
+ THIS = xl;
- if (xlator->validate_options) {
- if (xlator->validate_options (xlator, op_errstr)) {
- gf_log ("", GF_LOG_INFO, "%s", *op_errstr);
- goto out;
- }
- gf_log (xlator->name, GF_LOG_DEBUG, "Validated option");
+ xl->fini (xl);
- }
+ if (xl->local_pool)
+ mem_pool_destroy (xl->local_pool);
- gf_log (xlator->name, GF_LOG_DEBUG, "No validate_options() found");
+ THIS = old_THIS;
+ } else {
+ gf_log (xl->name, GF_LOG_DEBUG, "No fini() found");
+ }
+ xl->init_succeeded = 0;
+ }
- ret = 0;
out:
- return ret;
+ return;
}
-int
-graph_reconf_validateopt (glusterfs_graph_t *graph,
- char **op_errstr)
-{
- xlator_t *xlator = NULL;
- int ret = -1;
-
- GF_ASSERT (graph);
- xlator = graph->first;
-
- ret = xlator_validate_rec (xlator, op_errstr);
-
- return ret;
-}
int
xlator_notify (xlator_t *xl, int event, void *data, ...)
{
@@ -1581,40 +483,27 @@ xlator_mem_acct_init (xlator_t *xl, int num_types)
return 0;
}
+
void
xlator_tree_fini (xlator_t *xl)
{
- xlator_t *top = NULL;
+ xlator_t *top = NULL;
GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- top = xl;
- xlator_fini_rec (top);
+ top = xl;
+ xlator_fini_rec (top);
out:
return;
}
-int
-xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl)
-{
- xlator_t *new_top = NULL;
- xlator_t *old_top = NULL;
-
- GF_ASSERT (old_xl);
- GF_ASSERT (new_xl);
-
- old_top = old_xl;
- new_top = new_xl;
-
- return xlator_reconfigure_rec (old_top, new_top);
-}
-
int
xlator_tree_free (xlator_t *tree)
{
- xlator_t *trav = tree, *prev = tree;
+ xlator_t *trav = tree;
+ xlator_t *prev = tree;
if (!tree) {
gf_log ("parser", GF_LOG_ERROR, "Translator tree not found");
@@ -1650,46 +539,84 @@ loc_wipe (loc_t *loc)
inode_unref (loc->parent);
loc->parent = NULL;
}
+
+ memset (loc, 0, sizeof (*loc));
}
+int
+loc_path (loc_t *loc, const char *bname)
+{
+ int ret = 0;
+
+ if (loc->path)
+ goto out;
+
+ ret = -1;
+
+ if (bname && !strlen (bname))
+ bname = NULL;
+
+ if (!bname)
+ goto inode_path;
+
+ if (loc->parent && !uuid_is_null (loc->parent->gfid)) {
+ ret = inode_path (loc->parent, bname, (char**)&loc->path);
+ } else if (!uuid_is_null (loc->pargfid)) {
+ ret = gf_asprintf ((char**)&loc->path, INODE_PATH_FMT"/%s",
+ uuid_utoa (loc->pargfid), bname);
+ }
+
+ if (loc->path)
+ goto out;
+
+inode_path:
+ if (loc->inode && !uuid_is_null (loc->inode->gfid)) {
+ ret = inode_path (loc->inode, NULL, (char **)&loc->path);
+ } else if (!uuid_is_null (loc->gfid)) {
+ ret = gf_asprintf ((char**)&loc->path, INODE_PATH_FMT,
+ uuid_utoa (loc->gfid));
+ }
+out:
+ return ret;
+}
int
loc_copy (loc_t *dst, loc_t *src)
{
- int ret = -1;
+ int ret = -1;
GF_VALIDATE_OR_GOTO ("xlator", dst, err);
GF_VALIDATE_OR_GOTO ("xlator", src, err);
- dst->ino = src->ino;
+ uuid_copy (dst->gfid, src->gfid);
+ uuid_copy (dst->pargfid, src->pargfid);
+ uuid_copy (dst->gfid, src->gfid);
- if (src->inode)
- dst->inode = inode_ref (src->inode);
+ if (src->inode)
+ dst->inode = inode_ref (src->inode);
- if (src->parent)
- dst->parent = inode_ref (src->parent);
+ if (src->parent)
+ dst->parent = inode_ref (src->parent);
- dst->path = gf_strdup (src->path);
+ if (src->path) {
+ dst->path = gf_strdup (src->path);
- if (!dst->path)
- goto out;
+ if (!dst->path)
+ goto out;
- dst->name = strrchr (dst->path, '/');
- if (dst->name)
- dst->name++;
+ if (src->name)
+ dst->name = strrchr (dst->path, '/');
+ if (dst->name)
+ dst->name++;
+ }
- ret = 0;
+ ret = 0;
out:
- if (ret == -1) {
- if (dst->inode)
- inode_unref (dst->inode);
-
- if (dst->parent)
- inode_unref (dst->parent);
- }
+ if (ret == -1)
+ loc_wipe (dst);
err:
- return ret;
+ return ret;
}
@@ -1739,6 +666,8 @@ xlator_destroy (xlator_t *xl)
return 0;
}
+
+
int
is_gf_log_command (xlator_t *this, const char *name, char *value)
{
@@ -1782,6 +711,7 @@ is_gf_log_command (xlator_t *this, const char *name, char *value)
ret = 0;
goto out;
}
+
if (!strcmp (name, "trusted.glusterfs.fuse.set-log-level")) {
/* */
gf_log (this->name, gf_log_get_xl_loglevel (this),
@@ -1815,6 +745,7 @@ out:
return ret;
}
+
int
glusterd_check_log_level (const char *value)
{
@@ -1837,8 +768,9 @@ glusterd_check_log_level (const char *value)
}
if (log_level == -1)
- gf_log ("", GF_LOG_ERROR, "Invalid log-level. possible values "
+ gf_log (THIS->name, GF_LOG_ERROR, "Invalid log-level. possible values "
"are DEBUG|WARNING|ERROR|CRITICAL|NONE|TRACE");
return log_level;
}
+
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
index e587ae578..2fce7dc47 100644
--- a/libglusterfs/src/xlator.h
+++ b/libglusterfs/src/xlator.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _XLATOR_H
@@ -29,7 +20,7 @@
#include <stdint.h>
#include <inttypes.h>
-
+#include "event-history.h"
#include "logging.h"
#include "common-utils.h"
#include "dict.h"
@@ -74,13 +65,22 @@ typedef int32_t (*event_notify_fn_t) (xlator_t *this, int32_t event, void *data,
#include "fd.h"
#include "globals.h"
#include "iatt.h"
+#include "options.h"
+
struct _loc {
const char *path;
const char *name;
- ino_t ino;
inode_t *inode;
inode_t *parent;
+ /* Currently all location based operations are through 'gfid' of inode.
+ * But the 'inode->gfid' only gets set in higher most layer (as in,
+ * 'fuse', 'protocol/server', or 'nfs/server'). So if translators want
+ * to send fops on a inode before the 'inode->gfid' is set, they have to
+ * make use of below 'gfid' fields
+ */
+ uuid_t gfid;
+ uuid_t pargfid;
};
@@ -97,7 +97,8 @@ typedef int32_t (*fop_rchecksum_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
uint32_t weak_checksum,
- uint8_t *strong_checksum);
+ uint8_t *strong_checksum,
+ dict_t *xdata);
typedef int32_t (*fop_getspec_t) (call_frame_t *frame,
@@ -108,7 +109,7 @@ typedef int32_t (*fop_getspec_t) (call_frame_t *frame,
typedef int32_t (*fop_rchecksum_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd, off_t offset,
- int32_t len);
+ int32_t len, dict_t *xdata);
typedef int32_t (*fop_lookup_cbk_t) (call_frame_t *frame,
@@ -118,7 +119,7 @@ typedef int32_t (*fop_lookup_cbk_t) (call_frame_t *frame,
int32_t op_errno,
inode_t *inode,
struct iatt *buf,
- dict_t *xattr,
+ dict_t *xdata,
struct iatt *postparent);
typedef int32_t (*fop_stat_cbk_t) (call_frame_t *frame,
@@ -126,14 +127,14 @@ typedef int32_t (*fop_stat_cbk_t) (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
typedef int32_t (*fop_fstat_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
typedef int32_t (*fop_truncate_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -141,7 +142,7 @@ typedef int32_t (*fop_truncate_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_ftruncate_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -149,13 +150,13 @@ typedef int32_t (*fop_ftruncate_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_access_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_readlink_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -163,7 +164,7 @@ typedef int32_t (*fop_readlink_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *path,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
typedef int32_t (*fop_mknod_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -173,7 +174,7 @@ typedef int32_t (*fop_mknod_cbk_t) (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_mkdir_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -183,7 +184,7 @@ typedef int32_t (*fop_mkdir_cbk_t) (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_unlink_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -191,7 +192,7 @@ typedef int32_t (*fop_unlink_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_rmdir_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -199,7 +200,7 @@ typedef int32_t (*fop_rmdir_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_symlink_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -209,7 +210,7 @@ typedef int32_t (*fop_symlink_cbk_t) (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_rename_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -220,7 +221,7 @@ typedef int32_t (*fop_rename_cbk_t) (call_frame_t *frame,
struct iatt *preoldparent,
struct iatt *postoldparent,
struct iatt *prenewparent,
- struct iatt *postnewparent);
+ struct iatt *postnewparent, dict_t *xdata);
typedef int32_t (*fop_link_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -230,7 +231,7 @@ typedef int32_t (*fop_link_cbk_t) (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_create_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -241,14 +242,14 @@ typedef int32_t (*fop_create_cbk_t) (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_open_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_readv_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -258,7 +259,7 @@ typedef int32_t (*fop_readv_cbk_t) (call_frame_t *frame,
struct iovec *vector,
int32_t count,
struct iatt *stbuf,
- struct iobref *iobref);
+ struct iobref *iobref, dict_t *xdata);
typedef int32_t (*fop_writev_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -266,13 +267,13 @@ typedef int32_t (*fop_writev_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_flush_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_fsync_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -280,118 +281,124 @@ typedef int32_t (*fop_fsync_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_opendir_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_fsyncdir_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_statfs_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct statvfs *buf);
+ struct statvfs *buf, dict_t *xdata);
typedef int32_t (*fop_setxattr_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_getxattr_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
typedef int32_t (*fop_fsetxattr_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_fgetxattr_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
typedef int32_t (*fop_removexattr_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
+
+typedef int32_t (*fop_fremovexattr_cbk_t) (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_lk_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_inodelk_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_finodelk_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_entrylk_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_fentrylk_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_readdir_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- gf_dirent_t *entries);
+ gf_dirent_t *entries, dict_t *xdata);
typedef int32_t (*fop_readdirp_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- gf_dirent_t *entries);
+ gf_dirent_t *entries, dict_t *xdata);
typedef int32_t (*fop_xattrop_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- dict_t *xattr);
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_fxattrop_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- dict_t *xattr);
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_setattr_cbk_t) (call_frame_t *frame,
@@ -400,7 +407,7 @@ typedef int32_t (*fop_setattr_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preop_stbuf,
- struct iatt *postop_stbuf);
+ struct iatt *postop_stbuf, dict_t *xdata);
typedef int32_t (*fop_fsetattr_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -408,72 +415,71 @@ typedef int32_t (*fop_fsetattr_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preop_stbuf,
- struct iatt *postop_stbuf);
+ struct iatt *postop_stbuf, dict_t *xdata);
typedef int32_t (*fop_lookup_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- dict_t *xattr_req);
+ dict_t *xdata);
typedef int32_t (*fop_stat_t) (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
typedef int32_t (*fop_fstat_t) (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_truncate_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- off_t offset);
+ off_t offset, dict_t *xdata);
typedef int32_t (*fop_ftruncate_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- off_t offset);
+ off_t offset, dict_t *xdata);
typedef int32_t (*fop_access_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- int32_t mask);
+ int32_t mask, dict_t *xdata);
typedef int32_t (*fop_readlink_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- size_t size);
+ size_t size, dict_t *xdata);
typedef int32_t (*fop_mknod_t) (call_frame_t *frame, xlator_t *this,
loc_t *loc, mode_t mode, dev_t rdev,
- dict_t *params);
+ mode_t umask, dict_t *xdata);
-typedef int32_t (*fop_mkdir_t) (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
+typedef int32_t (*fop_mkdir_t) (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, mode_t umask, dict_t *xdata);
-typedef int32_t (*fop_unlink_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
+typedef int32_t (*fop_unlink_t) (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int xflags, dict_t *xdata);
typedef int32_t (*fop_rmdir_t) (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
+ loc_t *loc, int xflags, dict_t *xdata);
typedef int32_t (*fop_symlink_t) (call_frame_t *frame, xlator_t *this,
const char *linkname, loc_t *loc,
- dict_t *params);
+ mode_t umask, dict_t *xdata);
typedef int32_t (*fop_rename_t) (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
typedef int32_t (*fop_link_t) (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
typedef int32_t (*fop_create_t) (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
+ mode_t umask, fd_t *fd, dict_t *xdata);
/* Tell subsequent writes on the fd_t to fsync after every writev fop without
* requiring a fsync fop.
@@ -484,18 +490,16 @@ typedef int32_t (*fop_create_t) (call_frame_t *frame, xlator_t *this,
*/
#define GF_OPEN_NOWB 0x02
-typedef int32_t (*fop_open_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags,
- fd_t *fd,
- int32_t wbflags);
+typedef int32_t (*fop_open_t) (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_readv_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t offset);
+ off_t offset,
+ uint32_t flags, dict_t *xdata);
typedef int32_t (*fop_writev_t) (call_frame_t *frame,
xlator_t *this,
@@ -503,125 +507,132 @@ typedef int32_t (*fop_writev_t) (call_frame_t *frame,
struct iovec *vector,
int32_t count,
off_t offset,
- struct iobref *iobref);
+ uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
typedef int32_t (*fop_flush_t) (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_fsync_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
typedef int32_t (*fop_opendir_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_fsyncdir_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
typedef int32_t (*fop_statfs_t) (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
typedef int32_t (*fop_setxattr_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
typedef int32_t (*fop_getxattr_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
typedef int32_t (*fop_fsetxattr_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
typedef int32_t (*fop_fgetxattr_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- const char *name);
+ const char *name, dict_t *xdata);
typedef int32_t (*fop_removexattr_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
+
+typedef int32_t (*fop_fremovexattr_t) (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ const char *name, dict_t *xdata);
typedef int32_t (*fop_lk_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_inodelk_t) (call_frame_t *frame,
xlator_t *this,
const char *volume,
loc_t *loc,
int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_finodelk_t) (call_frame_t *frame,
xlator_t *this,
const char *volume,
fd_t *fd,
int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_entrylk_t) (call_frame_t *frame,
xlator_t *this,
const char *volume, loc_t *loc,
const char *basename, entrylk_cmd cmd,
- entrylk_type type);
+ entrylk_type type, dict_t *xdata);
typedef int32_t (*fop_fentrylk_t) (call_frame_t *frame,
xlator_t *this,
const char *volume, fd_t *fd,
const char *basename, entrylk_cmd cmd,
- entrylk_type type);
+ entrylk_type type, dict_t *xdata);
typedef int32_t (*fop_readdir_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t offset);
+ off_t offset, dict_t *xdata);
typedef int32_t (*fop_readdirp_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t offset);
+ off_t offset,
+ dict_t *xdata);
typedef int32_t (*fop_xattrop_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
gf_xattrop_flags_t optype,
- dict_t *xattr);
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_fxattrop_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
gf_xattrop_flags_t optype,
- dict_t *xattr);
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_setattr_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
typedef int32_t (*fop_fsetattr_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
struct xlator_fops {
@@ -655,6 +666,7 @@ struct xlator_fops {
fop_fsetxattr_t fsetxattr;
fop_fgetxattr_t fgetxattr;
fop_removexattr_t removexattr;
+ fop_fremovexattr_t fremovexattr;
fop_lk_t lk;
fop_inodelk_t inodelk;
fop_finodelk_t finodelk;
@@ -698,6 +710,7 @@ struct xlator_fops {
fop_fsetxattr_cbk_t fsetxattr_cbk;
fop_fgetxattr_cbk_t fgetxattr_cbk;
fop_removexattr_cbk_t removexattr_cbk;
+ fop_fremovexattr_cbk_t fremovexattr_cbk;
fop_lk_cbk_t lk_cbk;
fop_inodelk_cbk_t inodelk_cbk;
fop_finodelk_cbk_t finodelk_cbk;
@@ -733,12 +746,32 @@ typedef int32_t (*dumpop_inodectx_t) (xlator_t *this, inode_t *ino);
typedef int32_t (*dumpop_fdctx_t) (xlator_t *this, fd_t *fd);
+typedef int32_t (*dumpop_priv_to_dict_t) (xlator_t *this, dict_t *dict);
+
+typedef int32_t (*dumpop_inode_to_dict_t) (xlator_t *this, dict_t *dict);
+
+typedef int32_t (*dumpop_fd_to_dict_t) (xlator_t *this, dict_t *dict);
+
+typedef int32_t (*dumpop_inodectx_to_dict_t) (xlator_t *this, inode_t *ino,
+ dict_t *dict);
+
+typedef int32_t (*dumpop_fdctx_to_dict_t) (xlator_t *this, fd_t *fd,
+ dict_t *dict);
+
+typedef int32_t (*dumpop_eh_t) (xlator_t *this);
+
struct xlator_dumpops {
- dumpop_priv_t priv;
- dumpop_inode_t inode;
- dumpop_fd_t fd;
- dumpop_inodectx_t inodectx;
- dumpop_fdctx_t fdctx;
+ dumpop_priv_t priv;
+ dumpop_inode_t inode;
+ dumpop_fd_t fd;
+ dumpop_inodectx_t inodectx;
+ dumpop_fdctx_t fdctx;
+ dumpop_priv_to_dict_t priv_to_dict;
+ dumpop_inode_to_dict_t inode_to_dict;
+ dumpop_fd_to_dict_t fd_to_dict;
+ dumpop_inodectx_to_dict_t inodectx_to_dict;
+ dumpop_fdctx_to_dict_t fdctx_to_dict;
+ dumpop_eh_t history;
};
typedef struct xlator_list {
@@ -746,45 +779,6 @@ typedef struct xlator_list {
struct xlator_list *next;
} xlator_list_t;
-/* Add possible new type of option you may need */
-typedef enum {
- GF_OPTION_TYPE_ANY = 0,
- GF_OPTION_TYPE_STR,
- GF_OPTION_TYPE_INT,
- GF_OPTION_TYPE_SIZET,
- GF_OPTION_TYPE_PERCENT,
- GF_OPTION_TYPE_PERCENT_OR_SIZET,
- GF_OPTION_TYPE_BOOL,
- GF_OPTION_TYPE_XLATOR,
- GF_OPTION_TYPE_PATH,
- GF_OPTION_TYPE_TIME,
- GF_OPTION_TYPE_DOUBLE,
- GF_OPTION_TYPE_INTERNET_ADDRESS,
-} volume_option_type_t;
-
-
-#define ZR_VOLUME_MAX_NUM_KEY 4
-#define ZR_OPTION_MAX_ARRAY_SIZE 64
-
-/* Each translator should define this structure */
-typedef struct volume_options {
- char *key[ZR_VOLUME_MAX_NUM_KEY];
- /* different key, same meaning */
- volume_option_type_t type;
- int64_t min; /* 0 means no range */
- int64_t max; /* 0 means no range */
- char *value[ZR_OPTION_MAX_ARRAY_SIZE];
- /* If specified, will check for one of
- the value from this array */
- char *description; /* about the key */
-} volume_option_t;
-
-
-typedef struct vol_opt_list {
- struct list_head list;
- volume_option_t *given_opt;
-} volume_opt_list_t;
-
struct _xlator {
/* Built during parsing */
@@ -807,7 +801,6 @@ struct _xlator {
int32_t (*init) (xlator_t *this);
int32_t (*reconfigure) (xlator_t *this, dict_t *options);
int32_t (*mem_acct_init) (xlator_t *this);
- int32_t (*validate_options) (xlator_t *this, char **op_errstr);
event_notify_fn_t notify;
gf_loglevel_t loglevel; /* Log level for translator */
@@ -816,17 +809,33 @@ struct _xlator {
fop_latency_t latencies[GF_FOP_MAXVALUE];
/* Misc */
+ eh_t *history; /* event history context */
glusterfs_ctx_t *ctx;
glusterfs_graph_t *graph; /* not set for fuse */
inode_table_t *itable;
char init_succeeded;
void *private;
struct mem_acct mem_acct;
+ uint64_t winds;
+ char switched;
+
+ /* for the memory pool of 'frame->local' */
+ struct mem_pool *local_pool;
};
#define xlator_has_parent(xl) (xl->parents != NULL)
-int validate_xlator_volume_options (xlator_t *xl, volume_option_t *opt);
+#define XLATOR_NOTIFY(_xl, params ...) \
+ do { \
+ xlator_t *_old_THIS = NULL; \
+ \
+ _old_THIS = THIS; \
+ THIS = _xl; \
+ \
+ ret = _xl->notify (_xl, params);\
+ \
+ THIS = _old_THIS; \
+ } while (0);
int32_t xlator_set_type_virtual (xlator_t *xl, const char *type);
@@ -858,20 +867,14 @@ void inode_destroy_notify (inode_t *inode, const char *xlname);
int loc_copy (loc_t *dst, loc_t *src);
#define loc_dup(src, dst) loc_copy(dst, src)
void loc_wipe (loc_t *loc);
+int loc_path (loc_t *loc, const char *bname);
int xlator_mem_acct_init (xlator_t *xl, int num_types);
-int xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl);
int is_gf_log_command (xlator_t *trans, const char *name, char *value);
-int xlator_validate_rec (xlator_t *xlator, char **op_errstr);
-int graph_reconf_validateopt (glusterfs_graph_t *graph, char **op_errstr);
int glusterd_check_log_level (const char *value);
-int validate_xlator_volume_options_attacherr (xlator_t *xl,
- volume_option_t *opt,
- char **op_errstr);
-int _volume_option_value_validate_attacherr (xlator_t *xl,
- data_pair_t *pair,
- volume_option_t *opt,
- char **op_errstr);
-
-
-
+int xlator_volopt_dynload (char *xlator_type, void **dl_handle,
+ volume_opt_list_t *vol_opt_handle);
+enum gf_hdsk_event_notify_op {
+ GF_EN_DEFRAG_STATUS,
+ GF_EN_MAX,
+};
#endif /* _XLATOR_H */
diff --git a/libglusterfsclient/src/libglusterfsclient-dentry.c b/libglusterfsclient/src/libglusterfsclient-dentry.c
index b7a8e566a..3fa5f6e1e 100644
--- a/libglusterfsclient/src/libglusterfsclient-dentry.c
+++ b/libglusterfsclient/src/libglusterfsclient-dentry.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008, 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "libglusterfsclient.h"
diff --git a/libglusterfsclient/src/libglusterfsclient-internals.h b/libglusterfsclient/src/libglusterfsclient-internals.h
index ddc04c253..7b62ce8ef 100755
--- a/libglusterfsclient/src/libglusterfsclient-internals.h
+++ b/libglusterfsclient/src/libglusterfsclient-internals.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 __LIBGLUSTERFSCLIENT_INTERNALS_H
diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c
index ce1aeb8e6..39b5bea50 100755
--- a/libglusterfsclient/src/libglusterfsclient.c
+++ b/libglusterfsclient/src/libglusterfsclient.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _GNU_SOURCE
@@ -119,7 +110,6 @@ zr_build_process_uuid ()
char tmp_str[1024] = {0,};
char hostname[256] = {0,};
struct timeval tv = {0,};
- struct tm now = {0, };
char now_str[32];
if (-1 == gettimeofday(&tv, NULL)) {
@@ -134,9 +124,8 @@ zr_build_process_uuid ()
strerror (errno));
}
- localtime_r (&tv.tv_sec, &now);
- strftime (now_str, 32, "%Y/%m/%d-%H:%M:%S", &now);
- snprintf (tmp_str, 1024, "%s-%d-%s:%ld",
+ gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T);
+ snprintf (tmp_str, sizeof tmp_str, "%s-%d-%s:%ld",
hostname, getpid(), now_str, tv.tv_usec);
return strdup (tmp_str);
diff --git a/libglusterfsclient/src/libglusterfsclient.h b/libglusterfsclient/src/libglusterfsclient.h
index 129d8a437..1691a2faa 100755
--- a/libglusterfsclient/src/libglusterfsclient.h
+++ b/libglusterfsclient/src/libglusterfsclient.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008, 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _LIBGLUSTERFSCLIENT_H
diff --git a/mod_glusterfs/apache/1.3/src/mod_glusterfs.c b/mod_glusterfs/apache/1.3/src/mod_glusterfs.c
index 80e5da85f..c1380a4fd 100644
--- a/mod_glusterfs/apache/1.3/src/mod_glusterfs.c
+++ b/mod_glusterfs/apache/1.3/src/mod_glusterfs.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/mod_glusterfs/apache/2.2/src/mod_glusterfs.c b/mod_glusterfs/apache/2.2/src/mod_glusterfs.c
index 87dc62166..d2b9f3232 100644
--- a/mod_glusterfs/apache/2.2/src/mod_glusterfs.c
+++ b/mod_glusterfs/apache/2.2/src/mod_glusterfs.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/mod_glusterfs/lighttpd/1.4/mod_glusterfs.c b/mod_glusterfs/lighttpd/1.4/mod_glusterfs.c
index b0886e647..295c9704c 100644
--- a/mod_glusterfs/lighttpd/1.4/mod_glusterfs.c
+++ b/mod_glusterfs/lighttpd/1.4/mod_glusterfs.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/mod_glusterfs/lighttpd/1.4/mod_glusterfs.h b/mod_glusterfs/lighttpd/1.4/mod_glusterfs.h
index 8111d9b0b..9d73d6999 100644
--- a/mod_glusterfs/lighttpd/1.4/mod_glusterfs.h
+++ b/mod_glusterfs/lighttpd/1.4/mod_glusterfs.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/mod_glusterfs/lighttpd/1.5/mod_glusterfs.c b/mod_glusterfs/lighttpd/1.5/mod_glusterfs.c
index fddf5a3fe..67f7a7eac 100644
--- a/mod_glusterfs/lighttpd/1.5/mod_glusterfs.c
+++ b/mod_glusterfs/lighttpd/1.5/mod_glusterfs.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/mod_glusterfs/lighttpd/1.5/mod_glusterfs.h b/mod_glusterfs/lighttpd/1.5/mod_glusterfs.h
index 48743868b..5f9bb2c5b 100644
--- a/mod_glusterfs/lighttpd/1.5/mod_glusterfs.h
+++ b/mod_glusterfs/lighttpd/1.5/mod_glusterfs.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/rfc.sh b/rfc.sh
new file mode 100755
index 000000000..ad12af9bc
--- /dev/null
+++ b/rfc.sh
@@ -0,0 +1,111 @@
+#!/bin/sh -e
+
+
+branch="release-3.3";
+
+
+set_hooks_commit_msg()
+{
+ f=".git/hooks/commit-msg";
+ u="http://review.gluster.com/tools/hooks/commit-msg";
+
+ if [ -x "$f" ]; then
+ return;
+ fi
+
+ curl -o $f $u || wget -O $f $u;
+
+ chmod +x .git/hooks/commit-msg;
+}
+
+
+is_num()
+{
+ local num;
+
+ num="$1";
+
+ [ -z "$(echo $num | sed -e 's/[0-9]//g')" ]
+}
+
+
+rebase_changes()
+{
+ git fetch origin;
+
+ GIT_EDITOR=$0 git rebase -i origin/$branch;
+}
+
+
+editor_mode()
+{
+ if [ $(basename "$1") = "git-rebase-todo" ]; then
+ sed 's/^pick /reword /g' "$1" > $1.new && mv $1.new $1;
+ return;
+ fi
+
+ if [ $(basename "$1") = "COMMIT_EDITMSG" ]; then
+ if grep -qi '^BUG: ' $1; then
+ return;
+ fi
+ while true; do
+ echo Commit: "\"$(head -n 1 $1)\""
+ echo -n "Enter Bug ID: "
+ read bug
+ if [ -z "$bug" ]; then
+ return;
+ fi
+ if ! is_num "$bug"; then
+ echo "Invalid Bug ID ($bug)!!!";
+ continue;
+ fi
+
+ sed "/^Change-Id:/{p; s/^.*$/BUG: $bug/;}" $1 > $1.new && \
+ mv $1.new $1;
+ return;
+ done
+ fi
+
+ cat <<EOF
+$0 - editor_mode called on unrecognized file $1 with content:
+$(cat $1)
+EOF
+ return 1;
+}
+
+
+assert_diverge()
+{
+ git diff origin/$branch..HEAD | grep -q .;
+}
+
+
+main()
+{
+ if [ -e "$1" ]; then
+ editor_mode "$@";
+ return;
+ fi
+
+ set_hooks_commit_msg;
+
+ rebase_changes;
+
+ assert_diverge;
+
+ bug=$(git show --format='%b' | grep -i '^BUG: ' | awk '{print $2}');
+
+ if [ "$DRY_RUN" = 1 ]; then
+ drier='echo -e Please use the following command to send your commits to review:\n\n'
+ else
+ drier=
+ fi
+
+ if [ -z "$bug" ]; then
+ $drier git push origin HEAD:refs/for/$branch/rfc;
+ else
+ $drier git push origin HEAD:refs/for/$branch/bug-$bug;
+ fi
+}
+
+main "$@"
diff --git a/rpc/rpc-lib/src/Makefile.am b/rpc/rpc-lib/src/Makefile.am
index fcf091e9b..8b087301c 100644
--- a/rpc/rpc-lib/src/Makefile.am
+++ b/rpc/rpc-lib/src/Makefile.am
@@ -1,8 +1,8 @@
lib_LTLIBRARIES = libgfrpc.la
libgfrpc_la_SOURCES = auth-unix.c rpcsvc-auth.c rpcsvc.c auth-null.c \
- rpc-transport.c xdr-rpc.c xdr-rpcclnt.c rpc-clnt.c auth-glusterfs.c \
- rpc-common.c
+ rpc-transport.c xdr-rpc.c xdr-rpcclnt.c rpc-clnt.c auth-glusterfs.c
+
libgfrpc_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
noinst_HEADERS = rpcsvc.h rpc-transport.h xdr-common.h xdr-rpc.h xdr-rpcclnt.h \
diff --git a/rpc/rpc-lib/src/auth-glusterfs.c b/rpc/rpc-lib/src/auth-glusterfs.c
index bfa572b4f..5f41c8296 100644
--- a/rpc/rpc-lib/src/auth-glusterfs.c
+++ b/rpc/rpc-lib/src/auth-glusterfs.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -29,94 +20,9 @@
#include "dict.h"
#include "xdr-rpc.h"
#include "xdr-common.h"
+#include "rpc-common-xdr.h"
-bool_t
-xdr_auth_glusterfs_parms (XDR *xdrs, auth_glusterfs_parms *objp)
-{
- register int32_t *buf;
-
- int i;
-
- if (xdrs->x_op == XDR_ENCODE) {
- if (!xdr_u_quad_t (xdrs, &objp->lk_owner))
- return FALSE;
- buf = XDR_INLINE (xdrs, (4 + 16 )* BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->pid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->ngrps))
- return FALSE;
- if (!xdr_vector (xdrs, (char *)objp->groups, 16,
- sizeof (u_int), (xdrproc_t) xdr_u_int))
- return FALSE;
- } else {
- IXDR_PUT_U_LONG(buf, objp->pid);
- IXDR_PUT_U_LONG(buf, objp->uid);
- IXDR_PUT_U_LONG(buf, objp->gid);
- IXDR_PUT_U_LONG(buf, objp->ngrps);
- {
- register u_int *genp;
-
- for (i = 0, genp = objp->groups;
- i < 16; ++i) {
- IXDR_PUT_U_LONG(buf, *genp++);
- }
- }
- }
- return TRUE;
- } else if (xdrs->x_op == XDR_DECODE) {
- if (!xdr_u_quad_t (xdrs, &objp->lk_owner))
- return FALSE;
- buf = XDR_INLINE (xdrs, (4 + 16 )* BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->pid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->ngrps))
- return FALSE;
- if (!xdr_vector (xdrs, (char *)objp->groups, 16,
- sizeof (u_int), (xdrproc_t) xdr_u_int))
- return FALSE;
- } else {
- objp->pid = IXDR_GET_U_LONG(buf);
- objp->uid = IXDR_GET_U_LONG(buf);
- objp->gid = IXDR_GET_U_LONG(buf);
- objp->ngrps = IXDR_GET_U_LONG(buf);
- {
- register u_int *genp;
-
- for (i = 0, genp = objp->groups;
- i < 16; ++i) {
- *genp++ = IXDR_GET_U_LONG(buf);
- }
- }
- }
- return TRUE;
- }
-
- if (!xdr_u_quad_t (xdrs, &objp->lk_owner))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->pid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->ngrps))
- return FALSE;
- if (!xdr_vector (xdrs, (char *)objp->groups, 16,
- sizeof (u_int), (xdrproc_t) xdr_u_int))
- return FALSE;
- return TRUE;
-}
-
+/* V1 */
ssize_t
xdr_to_glusterfs_auth (char *buf, struct auth_glusterfs_parms *req)
@@ -146,7 +52,7 @@ auth_glusterfs_request_init (rpcsvc_request_t *req, void *priv)
{
if (!req)
return -1;
- memset (req->verf.authdata, 0, RPCSVC_MAX_AUTH_BYTES);
+ memset (req->verf.authdata, 0, GF_MAX_AUTH_BYTES);
req->verf.datalen = 0;
req->verf.flavour = AUTH_NULL;
@@ -155,9 +61,12 @@ auth_glusterfs_request_init (rpcsvc_request_t *req, void *priv)
int auth_glusterfs_authenticate (rpcsvc_request_t *req, void *priv)
{
- int ret = RPCSVC_AUTH_REJECT;
struct auth_glusterfs_parms au = {0,};
- int gidcount = 0;
+
+ int ret = RPCSVC_AUTH_REJECT;
+ int gidcount = 0;
+ int j = 0;
+ int i = 0;
if (!req)
return ret;
@@ -173,7 +82,11 @@ int auth_glusterfs_authenticate (rpcsvc_request_t *req, void *priv)
req->pid = au.pid;
req->uid = au.uid;
req->gid = au.gid;
- req->lk_owner = au.lk_owner;
+ req->lk_owner.len = 8;
+ {
+ for (i = 0; i < req->lk_owner.len; i++, j += 8)
+ req->lk_owner.data[i] = (char)((au.lk_owner >> j) & 0xff);
+ }
req->auxgidcount = au.ngrps;
if (req->auxgidcount > 16) {
@@ -187,8 +100,8 @@ int auth_glusterfs_authenticate (rpcsvc_request_t *req, void *priv)
req->auxgids[gidcount] = au.groups[gidcount];
gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth Info: pid: %u, uid: %d"
- ", gid: %d, owner: %"PRId64,
- req->pid, req->uid, req->gid, req->lk_owner);
+ ", gid: %d, owner: %s",
+ req->pid, req->uid, req->gid, lkowner_utoa (&req->lk_owner));
ret = RPCSVC_AUTH_ACCEPT;
err:
return ret;
@@ -213,3 +126,117 @@ rpcsvc_auth_glusterfs_init (rpcsvc_t *svc, dict_t *options)
{
return &rpcsvc_auth_glusterfs;
}
+
+/* V2 */
+
+ssize_t
+xdr_to_glusterfs_auth_v2 (char *buf, struct auth_glusterfs_parms_v2 *req)
+{
+ XDR xdr;
+ ssize_t ret = -1;
+
+ if ((!buf) || (!req))
+ return -1;
+
+ xdrmem_create (&xdr, buf, GF_MAX_AUTH_BYTES, XDR_DECODE);
+ if (!xdr_auth_glusterfs_parms_v2 (&xdr, req)) {
+ gf_log ("", GF_LOG_WARNING,
+ "failed to decode glusterfs v2 parameters");
+ ret = -1;
+ goto ret;
+ }
+
+ ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
+ret:
+ return ret;
+
+}
+int
+auth_glusterfs_v2_request_init (rpcsvc_request_t *req, void *priv)
+{
+ if (!req)
+ return -1;
+ memset (req->verf.authdata, 0, GF_MAX_AUTH_BYTES);
+ req->verf.datalen = 0;
+ req->verf.flavour = AUTH_NULL;
+
+ return 0;
+}
+
+int auth_glusterfs_v2_authenticate (rpcsvc_request_t *req, void *priv)
+{
+ struct auth_glusterfs_parms_v2 au = {0,};
+ int ret = RPCSVC_AUTH_REJECT;
+ int i = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_glusterfs_auth_v2 (req->cred.authdata, &au);
+ if (ret == -1) {
+ gf_log ("", GF_LOG_WARNING,
+ "failed to decode glusterfs credentials");
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ req->pid = au.pid;
+ req->uid = au.uid;
+ req->gid = au.gid;
+ req->lk_owner.len = au.lk_owner.lk_owner_len;
+ req->auxgidcount = au.groups.groups_len;
+
+ if (req->auxgidcount > GF_MAX_AUX_GROUPS) {
+ gf_log ("", GF_LOG_WARNING,
+ "more than max aux gids found (%d) , truncating it "
+ "to %d and continuing", au.groups.groups_len,
+ GF_MAX_AUX_GROUPS);
+ req->auxgidcount = GF_MAX_AUX_GROUPS;
+ }
+
+ if (req->lk_owner.len > GF_MAX_LOCK_OWNER_LEN) {
+ gf_log ("", GF_LOG_WARNING,
+ "lkowner field > 1k, failing authentication");
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ for (i = 0; i < req->auxgidcount; ++i)
+ req->auxgids[i] = au.groups.groups_val[i];
+
+ for (i = 0; i < au.lk_owner.lk_owner_len; ++i)
+ req->lk_owner.data[i] = au.lk_owner.lk_owner_val[i];
+
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth Info: pid: %u, uid: %d"
+ ", gid: %d, owner: %s",
+ req->pid, req->uid, req->gid, lkowner_utoa (&req->lk_owner));
+ ret = RPCSVC_AUTH_ACCEPT;
+err:
+ /* TODO: instead use alloca() for these variables */
+ if (au.groups.groups_val)
+ free (au.groups.groups_val);
+ if (au.lk_owner.lk_owner_val)
+ free (au.lk_owner.lk_owner_val);
+
+ return ret;
+}
+
+rpcsvc_auth_ops_t auth_glusterfs_ops_v2 = {
+ .transport_init = NULL,
+ .request_init = auth_glusterfs_v2_request_init,
+ .authenticate = auth_glusterfs_v2_authenticate
+};
+
+rpcsvc_auth_t rpcsvc_auth_glusterfs_v2 = {
+ .authname = "AUTH_GLUSTERFS-v2",
+ .authnum = AUTH_GLUSTERFS_v2,
+ .authops = &auth_glusterfs_ops_v2,
+ .authprivate = NULL
+};
+
+
+rpcsvc_auth_t *
+rpcsvc_auth_glusterfs_v2_init (rpcsvc_t *svc, dict_t *options)
+{
+ return &rpcsvc_auth_glusterfs_v2;
+}
diff --git a/rpc/rpc-lib/src/auth-null.c b/rpc/rpc-lib/src/auth-null.c
index 20dd7e77c..ebdcc8ff8 100644
--- a/rpc/rpc-lib/src/auth-null.c
+++ b/rpc/rpc-lib/src/auth-null.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -34,10 +25,10 @@ auth_null_request_init (rpcsvc_request_t *req, void *priv)
if (!req)
return -1;
- memset (req->cred.authdata, 0, RPCSVC_MAX_AUTH_BYTES);
+ memset (req->cred.authdata, 0, GF_MAX_AUTH_BYTES);
req->cred.datalen = 0;
- memset (req->verf.authdata, 0, RPCSVC_MAX_AUTH_BYTES);
+ memset (req->verf.authdata, 0, GF_MAX_AUTH_BYTES);
req->verf.datalen = 0;
return 0;
diff --git a/rpc/rpc-lib/src/auth-unix.c b/rpc/rpc-lib/src/auth-unix.c
index d3afbad63..6251d60a8 100644
--- a/rpc/rpc-lib/src/auth-unix.c
+++ b/rpc/rpc-lib/src/auth-unix.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -35,7 +26,7 @@ auth_unix_request_init (rpcsvc_request_t *req, void *priv)
{
if (!req)
return -1;
- memset (req->verf.authdata, 0, RPCSVC_MAX_AUTH_BYTES);
+ memset (req->verf.authdata, 0, GF_MAX_AUTH_BYTES);
req->verf.datalen = 0;
req->verf.flavour = AUTH_NULL;
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index a54c29fc5..dc93f07dc 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _PROTOCOL_COMMON_H
@@ -64,6 +55,7 @@ enum gf_fop_procnum {
GFS3_OP_READDIRP,
GFS3_OP_RELEASE,
GFS3_OP_RELEASEDIR,
+ GFS3_OP_FREMOVEXATTR,
GFS3_OP_MAXVALUE,
} ;
@@ -72,47 +64,11 @@ enum gf_handshake_procnum {
GF_HNDSK_SETVOLUME,
GF_HNDSK_GETSPEC,
GF_HNDSK_PING,
+ GF_HNDSK_SET_LK_VER,
+ GF_HNDSK_EVENT_NOTIFY,
GF_HNDSK_MAXVALUE,
};
-enum gf_mgmt_procnum_ {
- GD_MGMT_NULL, /* 0 */
- GD_MGMT_PROBE_QUERY,
- GD_MGMT_FRIEND_ADD,
- GD_MGMT_CLUSTER_LOCK,
- GD_MGMT_CLUSTER_UNLOCK,
- GD_MGMT_STAGE_OP,
- GD_MGMT_COMMIT_OP,
- GD_MGMT_FRIEND_REMOVE,
- GD_MGMT_FRIEND_UPDATE,
- GD_MGMT_CLI_PROBE,
- GD_MGMT_CLI_DEPROBE,
- GD_MGMT_CLI_LIST_FRIENDS,
- GD_MGMT_CLI_CREATE_VOLUME,
- GD_MGMT_CLI_GET_VOLUME,
- GD_MGMT_CLI_DELETE_VOLUME,
- GD_MGMT_CLI_START_VOLUME,
- GD_MGMT_CLI_STOP_VOLUME,
- GD_MGMT_CLI_RENAME_VOLUME,
- GD_MGMT_CLI_DEFRAG_VOLUME,
- GD_MGMT_CLI_SET_VOLUME,
- GD_MGMT_CLI_ADD_BRICK,
- GD_MGMT_CLI_REMOVE_BRICK,
- GD_MGMT_CLI_REPLACE_BRICK,
- GD_MGMT_CLI_LOG_FILENAME,
- GD_MGMT_CLI_LOG_LOCATE,
- GD_MGMT_CLI_LOG_ROTATE,
- GD_MGMT_CLI_SYNC_VOLUME,
- GD_MGMT_CLI_RESET_VOLUME,
- GD_MGMT_CLI_FSM_LOG,
- GD_MGMT_CLI_GSYNC_SET,
- GD_MGMT_CLI_PROFILE_VOLUME,
- GD_MGMT_BRICK_OP,
- GD_MGMT_MAXVALUE,
-};
-
-typedef enum gf_mgmt_procnum_ gf_mgmt_procnum;
-
enum gf_pmap_procnum {
GF_PMAP_NULL = 0,
GF_PMAP_PORTBYBRICK,
@@ -146,29 +102,18 @@ enum gf_deprobe_resp {
GF_DEPROBE_SUCCESS,
GF_DEPROBE_LOCALHOST,
GF_DEPROBE_NOT_FRIEND,
- GF_DEPROBE_BRICK_EXIST
+ GF_DEPROBE_BRICK_EXIST,
+ GF_DEPROBE_FRIEND_DOWN
};
enum gf_cbk_procnum {
GF_CBK_NULL = 0,
GF_CBK_FETCHSPEC,
GF_CBK_INO_FLUSH,
+ GF_CBK_EVENT_NOTIFY,
GF_CBK_MAXVALUE,
};
-enum glusterd_mgmt_procnum {
- GLUSTERD_MGMT_NULL, /* 0 */
- GLUSTERD_MGMT_PROBE_QUERY,
- GLUSTERD_MGMT_FRIEND_ADD,
- GLUSTERD_MGMT_CLUSTER_LOCK,
- GLUSTERD_MGMT_CLUSTER_UNLOCK,
- GLUSTERD_MGMT_STAGE_OP,
- GLUSTERD_MGMT_COMMIT_OP,
- GLUSTERD_MGMT_FRIEND_REMOVE,
- GLUSTERD_MGMT_FRIEND_UPDATE,
- GLUSTERD_MGMT_MAXVALUE,
-};
-
enum gluster_cli_procnum {
GLUSTER_CLI_NULL, /* 0 */
GLUSTER_CLI_PROBE,
@@ -186,8 +131,6 @@ enum gluster_cli_procnum {
GLUSTER_CLI_ADD_BRICK,
GLUSTER_CLI_REMOVE_BRICK,
GLUSTER_CLI_REPLACE_BRICK,
- GLUSTER_CLI_LOG_FILENAME,
- GLUSTER_CLI_LOG_LOCATE,
GLUSTER_CLI_LOG_ROTATE,
GLUSTER_CLI_GETSPEC,
GLUSTER_CLI_PMAP_PORTBYBRICK,
@@ -199,35 +142,60 @@ enum gluster_cli_procnum {
GLUSTER_CLI_QUOTA,
GLUSTER_CLI_TOP_VOLUME,
GLUSTER_CLI_GETWD,
+ GLUSTER_CLI_STATUS_VOLUME,
+ GLUSTER_CLI_STATUS_ALL,
+ GLUSTER_CLI_MOUNT,
+ GLUSTER_CLI_UMOUNT,
+ GLUSTER_CLI_HEAL_VOLUME,
+ GLUSTER_CLI_STATEDUMP_VOLUME,
+ GLUSTER_CLI_LIST_VOLUME,
+ GLUSTER_CLI_CLRLOCKS_VOLUME,
GLUSTER_CLI_MAXVALUE,
};
-enum gf_brick_procnum {
- GF_BRICK_NULL = 0,
- GF_BRICK_TERMINATE = 1,
- GF_BRICK_XLATOR_INFO = 2,
- GF_BRICK_MAX_VALUE
+enum glusterd_mgmt_procnum {
+ GLUSTERD_MGMT_NULL, /* 0 */
+ GLUSTERD_MGMT_CLUSTER_LOCK,
+ GLUSTERD_MGMT_CLUSTER_UNLOCK,
+ GLUSTERD_MGMT_STAGE_OP,
+ GLUSTERD_MGMT_COMMIT_OP,
+ GLUSTERD_MGMT_MAXVALUE,
};
+enum glusterd_friend_procnum {
+ GLUSTERD_FRIEND_NULL, /* 0 */
+ GLUSTERD_PROBE_QUERY,
+ GLUSTERD_FRIEND_ADD,
+ GLUSTERD_FRIEND_REMOVE,
+ GLUSTERD_FRIEND_UPDATE,
+ GLUSTERD_FRIEND_MAXVALUE,
+};
-#define GLUSTER3_1_FOP_PROGRAM 1298437 /* Completely random */
-#define GLUSTER3_1_FOP_VERSION 310 /* 3.1.0 */
-#define GLUSTER3_1_FOP_PROCCNT GFS3_OP_MAXVALUE
-
-#define GLUSTERD1_MGMT_PROGRAM 1298433 /* Completely random */
-#define GLUSTERD1_MGMT_VERSION 1 /* 0.0.1 */
-#define GLUSTERD1_MGMT_PROCCNT GD_MGMT_MAXVALUE
-
-#define GD_MGMT_PROGRAM 1238433 /* Completely random */
-#define GD_MGMT_VERSION 1 /* 0.0.1 */
-#define GD_MGMT_PROCCNT GLUSTERD_MGMT_MAXVALUE
+enum glusterd_brick_procnum {
+ GLUSTERD_BRICK_NULL, /* 0 */
+ GLUSTERD_BRICK_TERMINATE,
+ GLUSTERD_BRICK_XLATOR_INFO,
+ GLUSTERD_BRICK_XLATOR_OP,
+ GLUSTERD_BRICK_STATUS,
+ GLUSTERD_BRICK_OP,
+ GLUSTERD_BRICK_XLATOR_DEFRAG,
+ GLUSTERD_NODE_PROFILE,
+ GLUSTERD_NODE_STATUS,
+ GLUSTERD_BRICK_MAXVALUE,
+};
-#define GLUSTER_CLI_PROGRAM 1238463 /* Completely random */
-#define GLUSTER_CLI_VERSION 1 /* 0.0.1 */
-#define GLUSTER_CLI_PROCCNT GLUSTER_CLI_MAXVALUE
+typedef enum {
+ GF_AFR_OP_INVALID,
+ GF_AFR_OP_HEAL_INDEX,
+ GF_AFR_OP_HEAL_FULL,
+ GF_AFR_OP_INDEX_SUMMARY,
+ GF_AFR_OP_HEALED_FILES,
+ GF_AFR_OP_HEAL_FAILED_FILES,
+ GF_AFR_OP_SPLIT_BRAIN_FILES
+} gf_xl_afr_op_t ;
#define GLUSTER_HNDSK_PROGRAM 14398633 /* Completely random */
-#define GLUSTER_HNDSK_VERSION 1 /* 0.0.1 */
+#define GLUSTER_HNDSK_VERSION 2 /* 0.0.1 */
#define GLUSTER_PMAP_PROGRAM 34123456
#define GLUSTER_PMAP_VERSION 1
@@ -235,10 +203,21 @@ enum gf_brick_procnum {
#define GLUSTER_CBK_PROGRAM 52743234 /* Completely random */
#define GLUSTER_CBK_VERSION 1 /* 0.0.1 */
-#define GLUSTER_HNDSK_PROGRAM 14398633 /* Completely random */
-#define GLUSTER_HNDSK_VERSION 1 /* 0.0.1 */
+#define GLUSTER3_1_FOP_PROGRAM 1298437 /* Completely random */
+#define GLUSTER3_1_FOP_VERSION 330 /* 3.3.0 */
+#define GLUSTER3_1_FOP_PROCCNT GFS3_OP_MAXVALUE
+
+/* Second version */
+#define GD_MGMT_PROGRAM 1238433 /* Completely random */
+#define GD_MGMT_VERSION 2 /* 0.0.2 */
+
+#define GD_FRIEND_PROGRAM 1238437 /* Completely random */
+#define GD_FRIEND_VERSION 2 /* 0.0.2 */
+
+#define GLUSTER_CLI_PROGRAM 1238463 /* Completely random */
+#define GLUSTER_CLI_VERSION 2 /* 0.0.2 */
+
+#define GD_BRICK_PROGRAM 4867634 /*Completely random*/
+#define GD_BRICK_VERSION 2
-#define GLUSTERFS_PROGRAM 4867634 /*Completely random*/
-#define GLUSTERFS_VERSION 1
-#define GLUSTERFS_PROCCNT GF_BRICK_MAX_VALUE
#endif /* !_PROTOCOL_COMMON_H */
diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c
index 732a89062..c530698ee 100644
--- a/rpc/rpc-lib/src/rpc-clnt.c
+++ b/rpc/rpc-lib/src/rpc-clnt.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -23,7 +14,7 @@
#include "config.h"
#endif
-#define RPC_CLNT_DEFAULT_REQUEST_COUNT 4096
+#define RPC_CLNT_DEFAULT_REQUEST_COUNT 512
#include "rpc-clnt.h"
#include "byte-order.h"
@@ -32,6 +23,7 @@
#include "protocol-common.h"
#include "mem-pool.h"
#include "xdr-rpc.h"
+#include "rpc-common-xdr.h"
void
rpc_clnt_reply_deinit (struct rpc_req *req, struct mem_pool *pool);
@@ -69,6 +61,21 @@ __saved_frames_get_timedout (struct saved_frames *frames, uint32_t timeout,
return bailout_frame;
}
+static int
+_is_lock_fop (struct saved_frame *sframe)
+{
+ int fop = 0;
+
+ if (SFRAME_GET_PROGNUM (sframe) == GLUSTER3_1_FOP_PROGRAM &&
+ SFRAME_GET_PROGVER (sframe) == GLUSTER3_1_FOP_VERSION)
+ fop = SFRAME_GET_PROCNUM (sframe);
+
+ return ((fop == GFS3_OP_LK) ||
+ (fop == GFS3_OP_INODELK) ||
+ (fop == GFS3_OP_FINODELK) ||
+ (fop == GFS3_OP_ENTRYLK) ||
+ (fop == GFS3_OP_FENTRYLK));
+}
struct saved_frame *
__saved_frames_put (struct saved_frames *frames, void *frame,
@@ -90,7 +97,11 @@ __saved_frames_put (struct saved_frames *frames, void *frame,
saved_frame->rpcreq = rpcreq;
gettimeofday (&saved_frame->saved_at, NULL);
- list_add_tail (&saved_frame->list, &frames->sf.list);
+ if (_is_lock_fop (saved_frame))
+ list_add_tail (&saved_frame->list, &frames->lk_sf.list);
+ else
+ list_add_tail (&saved_frame->list, &frames->sf.list);
+
frames->count++;
out:
@@ -117,7 +128,7 @@ saved_frames_delete (struct saved_frame *saved_frame,
conn->rpc_clnt->reqpool);
}
- mem_put (conn->rpc_clnt->saved_frames_pool, saved_frame);
+ mem_put (saved_frame);
out:
return;
}
@@ -133,7 +144,6 @@ call_bail (void *data)
struct saved_frame *saved_frame = NULL;
struct saved_frame *trav = NULL;
struct saved_frame *tmp = NULL;
- struct tm frame_sent_tm;
char frame_sent[256] = {0,};
struct timeval timeout = {0,};
struct iovec iov = {0,};
@@ -180,8 +190,8 @@ call_bail (void *data)
pthread_mutex_unlock (&conn->lock);
list_for_each_entry_safe (trav, tmp, &list, list) {
- localtime_r (&trav->saved_at.tv_sec, &frame_sent_tm);
- strftime (frame_sent, 32, "%Y-%m-%d %H:%M:%S", &frame_sent_tm);
+ gf_time_fmt (frame_sent, sizeof frame_sent,
+ trav->saved_at.tv_sec, gf_timefmt_FT);
snprintf (frame_sent + strlen (frame_sent),
256 - strlen (frame_sent),
".%"GF_PRI_SUSECONDS, trav->saved_at.tv_usec);
@@ -196,12 +206,14 @@ call_bail (void *data)
trav->rpcreq->procnum, trav->rpcreq->xid, frame_sent,
conn->frame_timeout);
+ clnt = rpc_clnt_ref (clnt);
trav->rpcreq->rpc_status = -1;
trav->rpcreq->cbkfn (trav->rpcreq, &iov, 1, trav->frame);
rpc_clnt_reply_deinit (trav->rpcreq, clnt->reqpool);
+ clnt = rpc_clnt_unref (clnt);
list_del_init (&trav->list);
- mem_put (conn->rpc_clnt->saved_frames_pool, trav);
+ mem_put (trav);
}
out:
return;
@@ -252,6 +264,7 @@ saved_frames_new (void)
}
INIT_LIST_HEAD (&saved_frames->sf.list);
+ INIT_LIST_HEAD (&saved_frames->lk_sf.list);
return saved_frames;
}
@@ -273,7 +286,15 @@ __saved_frame_copy (struct saved_frames *frames, int64_t callid,
if (tmp->rpcreq->xid == callid) {
*saved_frame = *tmp;
ret = 0;
- break;
+ goto out;
+ }
+ }
+
+ list_for_each_entry (tmp, &frames->lk_sf.list, list) {
+ if (tmp->rpcreq->xid == callid) {
+ *saved_frame = *tmp;
+ ret = 0;
+ goto out;
}
}
@@ -293,10 +314,20 @@ __saved_frame_get (struct saved_frames *frames, int64_t callid)
list_del_init (&tmp->list);
frames->count--;
saved_frame = tmp;
- break;
+ goto out;
+ }
+ }
+
+ list_for_each_entry (tmp, &frames->lk_sf.list, list) {
+ if (tmp->rpcreq->xid == callid) {
+ list_del_init (&tmp->list);
+ frames->count--;
+ saved_frame = tmp;
+ goto out;
}
}
+out:
if (saved_frame) {
THIS = saved_frame->capital_this;
}
@@ -308,18 +339,18 @@ __saved_frame_get (struct saved_frames *frames, int64_t callid)
void
saved_frames_unwind (struct saved_frames *saved_frames)
{
+ struct rpc_clnt *clnt = NULL;
struct saved_frame *trav = NULL;
struct saved_frame *tmp = NULL;
- struct mem_pool *saved_frames_pool = NULL;
- struct tm *frame_sent_tm = NULL;
- char timestr[256] = {0,};
+ char timestr[1024] = {0,};
struct iovec iov = {0,};
+ list_splice_init (&saved_frames->lk_sf.list, &saved_frames->sf.list);
+
list_for_each_entry_safe (trav, tmp, &saved_frames->sf.list, list) {
- frame_sent_tm = localtime (&trav->saved_at.tv_sec);
- strftime (timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S",
- frame_sent_tm);
+ gf_time_fmt (timestr, sizeof timestr,
+ trav->saved_at.tv_sec, gf_timefmt_FT);
snprintf (timestr + strlen (timestr),
sizeof(timestr) - strlen (timestr),
".%"GF_PRI_SUSECONDS, trav->saved_at.tv_usec);
@@ -330,24 +361,25 @@ saved_frames_unwind (struct saved_frames *saved_frames)
gf_log_callingfn (trav->rpcreq->conn->trans->name,
GF_LOG_ERROR,
"forced unwinding frame type(%s) op(%s(%d)) "
- "called at %s",
+ "called at %s (xid=0x%ux)",
trav->rpcreq->prog->progname,
((trav->rpcreq->prog->procnames) ?
trav->rpcreq->prog->procnames[trav->rpcreq->procnum]
: "--"),
- trav->rpcreq->procnum, timestr);
+ trav->rpcreq->procnum, timestr,
+ trav->rpcreq->xid);
saved_frames->count--;
+ clnt = rpc_clnt_ref (trav->rpcreq->conn->rpc_clnt);
trav->rpcreq->rpc_status = -1;
trav->rpcreq->cbkfn (trav->rpcreq, &iov, 1, trav->frame);
- saved_frames_pool
- = trav->rpcreq->conn->rpc_clnt->saved_frames_pool;
rpc_clnt_reply_deinit (trav->rpcreq,
trav->rpcreq->conn->rpc_clnt->reqpool);
+ clnt = rpc_clnt_unref (clnt);
list_del_init (&trav->list);
- mem_put (saved_frames_pool, trav);
+ mem_put (trav);
}
}
@@ -392,7 +424,16 @@ rpc_clnt_reconnect (void *trans_ptr)
gf_log (trans->name, GF_LOG_TRACE,
"attempting reconnect");
- ret = rpc_transport_connect (trans, conn->config.remote_port);
+ ret = rpc_transport_connect (trans,
+ conn->config.remote_port);
+ /* Every time there is a disconnection, processes
+ should try to connect to 'glusterd' (ie, default
+ port) or whichever port given as 'option remote-port'
+ in volume file. */
+ /* Below code makes sure the (re-)configured port lasts
+ for just one successful attempt */
+ if (!ret)
+ conn->config.remote_port = 0;
conn->reconnect =
gf_timer_call_after (clnt->ctx, tv,
@@ -427,7 +468,8 @@ rpc_clnt_fill_request_info (struct rpc_clnt *clnt, rpc_request_info_t *info)
pthread_mutex_unlock (&clnt->conn.lock);
if (ret == -1) {
- gf_log (clnt->conn.trans->name, GF_LOG_CRITICAL, "cannot lookup the saved "
+ gf_log (clnt->conn.trans->name, GF_LOG_CRITICAL,
+ "cannot lookup the saved "
"frame corresponding to xid (%d)", info->xid);
goto out;
}
@@ -501,6 +543,12 @@ rpc_clnt_connection_cleanup (rpc_clnt_connection_t *conn)
}
conn->connected = 0;
+
+ if (conn->ping_timer) {
+ gf_timer_call_cancel (clnt->ctx, conn->ping_timer);
+ conn->ping_timer = NULL;
+ conn->ping_started = 0;
+ }
}
pthread_mutex_unlock (&conn->lock);
@@ -591,7 +639,7 @@ rpc_clnt_reply_deinit (struct rpc_req *req, struct mem_pool *pool)
iobref_unref (req->rsp_iobref);
}
- mem_put (pool, req);
+ mem_put (req);
out:
return;
}
@@ -625,15 +673,14 @@ rpc_clnt_reply_init (rpc_clnt_connection_t *conn, rpc_transport_pollin_t *msg,
goto out;
}
- gf_log (conn->trans->name, GF_LOG_TRACE, "received rpc message (RPC XID: 0x%ux"
+ gf_log (conn->trans->name, GF_LOG_TRACE,
+ "received rpc message (RPC XID: 0x%ux"
" Program: %s, ProgVers: %d, Proc: %d) from rpc-transport (%s)",
saved_frame->rpcreq->xid,
saved_frame->rpcreq->prog->progname,
saved_frame->rpcreq->prog->progver,
saved_frame->rpcreq->procnum, conn->trans->name);
- req->rpc_status = 0;
-
out:
if (ret != 0) {
req->rpc_status = -1;
@@ -741,7 +788,7 @@ rpc_clnt_handle_reply (struct rpc_clnt *clnt, rpc_transport_pollin_t *pollin)
out:
if (saved_frame) {
- mem_put (conn->rpc_clnt->saved_frames_pool, saved_frame);
+ mem_put (saved_frame);
}
clnt = rpc_clnt_unref (clnt);
@@ -784,17 +831,16 @@ out:
return;
}
-
int
rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
rpc_transport_event_t event, void *data, ...)
{
- rpc_clnt_connection_t *conn = NULL;
- struct rpc_clnt *clnt = NULL;
- int ret = -1;
- rpc_request_info_t *req_info = NULL;
- rpc_transport_pollin_t *pollin = NULL;
- struct timeval tv = {0, };
+ rpc_clnt_connection_t *conn = NULL;
+ struct rpc_clnt *clnt = NULL;
+ int ret = -1;
+ rpc_request_info_t *req_info = NULL;
+ rpc_transport_pollin_t *pollin = NULL;
+ struct timeval tv = {0, };
conn = mydata;
if (conn == NULL) {
@@ -811,7 +857,8 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
pthread_mutex_lock (&conn->lock);
{
- if (conn->reconnect == NULL) {
+ if (!conn->rpc_clnt->disabled
+ && (conn->reconnect == NULL)) {
tv.tv_sec = 10;
conn->reconnect =
@@ -823,8 +870,8 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
pthread_mutex_unlock (&conn->lock);
if (clnt->notifyfn)
- ret = clnt->notifyfn (clnt, clnt->mydata, RPC_CLNT_DISCONNECT,
- NULL);
+ ret = clnt->notifyfn (clnt, clnt->mydata,
+ RPC_CLNT_DISCONNECT, NULL);
break;
}
@@ -844,6 +891,12 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
case RPC_TRANSPORT_MSG_RECEIVED:
{
+ pthread_mutex_lock (&conn->lock);
+ {
+ gettimeofday (&conn->last_received, NULL);
+ }
+ pthread_mutex_unlock (&conn->lock);
+
pollin = data;
if (pollin->is_reply)
ret = rpc_clnt_handle_reply (clnt, pollin);
@@ -870,7 +923,8 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
case RPC_TRANSPORT_CONNECT:
{
if (clnt->notifyfn)
- ret = clnt->notifyfn (clnt, clnt->mydata, RPC_CLNT_CONNECT, NULL);
+ ret = clnt->notifyfn (clnt, clnt->mydata,
+ RPC_CLNT_CONNECT, NULL);
break;
}
@@ -919,6 +973,7 @@ rpc_clnt_connection_init (struct rpc_clnt *clnt, glusterfs_ctx_t *ctx,
if (!conn->trans) {
gf_log (name, GF_LOG_WARNING, "loading of new rpc-transport"
" failed");
+ ret = -1;
goto out;
}
@@ -950,8 +1005,8 @@ out:
}
struct rpc_clnt *
-rpc_clnt_new (dict_t *options,
- glusterfs_ctx_t *ctx, char *name)
+rpc_clnt_new (dict_t *options, glusterfs_ctx_t *ctx, char *name,
+ uint32_t reqpool_size)
{
int ret = -1;
struct rpc_clnt *rpc = NULL;
@@ -964,8 +1019,10 @@ rpc_clnt_new (dict_t *options,
pthread_mutex_init (&rpc->lock, NULL);
rpc->ctx = ctx;
- rpc->reqpool = mem_pool_new (struct rpc_req,
- RPC_CLNT_DEFAULT_REQUEST_COUNT);
+ if (!reqpool_size)
+ reqpool_size = RPC_CLNT_DEFAULT_REQUEST_COUNT;
+
+ rpc->reqpool = mem_pool_new (struct rpc_req, reqpool_size);
if (rpc->reqpool == NULL) {
pthread_mutex_destroy (&rpc->lock);
GF_FREE (rpc);
@@ -974,7 +1031,7 @@ rpc_clnt_new (dict_t *options,
}
rpc->saved_frames_pool = mem_pool_new (struct saved_frame,
- RPC_CLNT_DEFAULT_REQUEST_COUNT);
+ reqpool_size);
if (rpc->saved_frames_pool == NULL) {
pthread_mutex_destroy (&rpc->lock);
mem_pool_destroy (rpc->reqpool);
@@ -995,6 +1052,8 @@ rpc_clnt_new (dict_t *options,
goto out;
}
+ rpc->auth_null = dict_get_str_boolean (options, "auth-null", 0);
+
rpc = rpc_clnt_ref (rpc);
INIT_LIST_HEAD (&rpc->programs);
@@ -1030,7 +1089,7 @@ rpc_clnt_register_notify (struct rpc_clnt *rpc, rpc_clnt_notify_t fn,
}
ssize_t
-xdr_serialize_glusterfs_auth (char *dest, struct auth_glusterfs_parms *au)
+xdr_serialize_glusterfs_auth (char *dest, struct auth_glusterfs_parms_v2 *au)
{
ssize_t ret = -1;
XDR xdr;
@@ -1038,11 +1097,11 @@ xdr_serialize_glusterfs_auth (char *dest, struct auth_glusterfs_parms *au)
if ((!dest) || (!au))
return -1;
- xdrmem_create (&xdr, dest, 1024,
- XDR_ENCODE);
+ xdrmem_create (&xdr, dest, GF_MAX_AUTH_BYTES, XDR_ENCODE);
- if (!xdr_auth_glusterfs_parms (&xdr, au)) {
- gf_log ("", GF_LOG_WARNING, "failed to encode auth glusterfs elements");
+ if (!xdr_auth_glusterfs_parms_v2 (&xdr, au)) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "failed to encode auth glusterfs elements");
ret = -1;
goto ret;
}
@@ -1055,8 +1114,8 @@ ret:
int
-rpc_clnt_fill_request (int prognum, int progver, int procnum, int payload,
- uint64_t xid, struct auth_glusterfs_parms *au,
+rpc_clnt_fill_request (int prognum, int progver, int procnum,
+ uint64_t xid, struct auth_glusterfs_parms_v2 *au,
struct rpc_msg *request, char *auth_data)
{
int ret = -1;
@@ -1075,19 +1134,26 @@ rpc_clnt_fill_request (int prognum, int progver, int procnum, int payload,
request->rm_call.cb_vers = progver;
request->rm_call.cb_proc = procnum;
- /* TODO: Using AUTH_GLUSTERFS for time-being. Make it modular in
- * future so it is easy to plug-in new authentication schemes.
+ /* TODO: Using AUTH_(GLUSTERFS/NULL) in a kludgy way for time-being.
+ * Make it modular in future so it is easy to plug-in new
+ * authentication schemes.
*/
- ret = xdr_serialize_glusterfs_auth (auth_data, au);
- if (ret == -1) {
- gf_log ("rpc-clnt", GF_LOG_DEBUG, "cannot encode credentials");
- goto out;
- }
-
- request->rm_call.cb_cred.oa_flavor = AUTH_GLUSTERFS;
- request->rm_call.cb_cred.oa_base = auth_data;
- request->rm_call.cb_cred.oa_length = ret;
+ if (auth_data) {
+ ret = xdr_serialize_glusterfs_auth (auth_data, au);
+ if (ret == -1) {
+ gf_log ("rpc-clnt", GF_LOG_DEBUG,
+ "cannot encode credentials");
+ goto out;
+ }
+ request->rm_call.cb_cred.oa_flavor = AUTH_GLUSTERFS_v2;
+ request->rm_call.cb_cred.oa_base = auth_data;
+ request->rm_call.cb_cred.oa_length = ret;
+ } else {
+ request->rm_call.cb_cred.oa_flavor = AUTH_NULL;
+ request->rm_call.cb_cred.oa_base = NULL;
+ request->rm_call.cb_cred.oa_length = 0;
+ }
request->rm_call.cb_verf.oa_flavor = AUTH_NONE;
request->rm_call.cb_verf.oa_base = NULL;
request->rm_call.cb_verf.oa_length = 0;
@@ -1135,46 +1201,53 @@ out:
struct iobuf *
rpc_clnt_record_build_record (struct rpc_clnt *clnt, int prognum, int progver,
- int procnum, size_t payload, uint64_t xid,
- struct auth_glusterfs_parms *au, struct iovec *recbuf)
+ int procnum, size_t hdrsize, uint64_t xid,
+ struct auth_glusterfs_parms_v2 *au,
+ struct iovec *recbuf)
{
- struct rpc_msg request = {0, };
- struct iobuf *request_iob = NULL;
- char *record = NULL;
- struct iovec recordhdr = {0, };
- size_t pagesize = 0;
- int ret = -1;
- char auth_data[RPC_CLNT_MAX_AUTH_BYTES] = {0, };
+ struct rpc_msg request = {0, };
+ struct iobuf *request_iob = NULL;
+ char *record = NULL;
+ struct iovec recordhdr = {0, };
+ size_t pagesize = 0;
+ int ret = -1;
+ size_t xdr_size = 0;
+ char auth_data[GF_MAX_AUTH_BYTES] = {0, };
if ((!clnt) || (!recbuf) || (!au)) {
goto out;
}
+ /* Fill the rpc structure and XDR it into the buffer got above. */
+ if (clnt->auth_null)
+ ret = rpc_clnt_fill_request (prognum, progver, procnum,
+ xid, NULL, &request, NULL);
+ else
+ ret = rpc_clnt_fill_request (prognum, progver, procnum,
+ xid, au, &request, auth_data);
+
+ if (ret == -1) {
+ gf_log (clnt->conn.trans->name, GF_LOG_WARNING,
+ "cannot build a rpc-request xid (%"PRIu64")", xid);
+ goto out;
+ }
+
+ xdr_size = xdr_sizeof ((xdrproc_t)xdr_callmsg, &request);
+
/* First, try to get a pointer into the buffer which the RPC
* layer can use.
*/
- request_iob = iobuf_get (clnt->ctx->iobuf_pool);
+ request_iob = iobuf_get2 (clnt->ctx->iobuf_pool, (xdr_size + hdrsize));
if (!request_iob) {
goto out;
}
- pagesize = ((struct iobuf_pool *)clnt->ctx->iobuf_pool)->page_size;
+ pagesize = iobuf_pagesize (request_iob);
record = iobuf_ptr (request_iob); /* Now we have it. */
- /* Fill the rpc structure and XDR it into the buffer got above. */
- ret = rpc_clnt_fill_request (prognum, progver, procnum, payload, xid,
- au, &request, auth_data);
- if (ret == -1) {
- gf_log (clnt->conn.trans->name, GF_LOG_WARNING,
- "cannot build a rpc-request xid (%"PRIu64")", xid);
- goto out;
- }
-
recordhdr = rpc_clnt_record_build_header (record, pagesize, &request,
- payload);
-
- //GF_FREE (request.rm_call.cb_cred.oa_base);
+ hdrsize);
if (!recordhdr.iov_base) {
gf_log (clnt->conn.trans->name, GF_LOG_ERROR,
@@ -1195,39 +1268,45 @@ out:
struct iobuf *
rpc_clnt_record (struct rpc_clnt *clnt, call_frame_t *call_frame,
- rpc_clnt_prog_t *prog,int procnum, size_t payload_len,
+ rpc_clnt_prog_t *prog, int procnum, size_t hdrlen,
struct iovec *rpchdr, uint64_t callid)
{
- struct auth_glusterfs_parms au = {0, };
- struct iobuf *request_iob = NULL;
+ struct auth_glusterfs_parms_v2 au = {0, };
+ struct iobuf *request_iob = NULL;
+ char owner[4] = {0,};
if (!prog || !rpchdr || !call_frame) {
goto out;
}
- au.pid = call_frame->root->pid;
- au.uid = call_frame->root->uid;
- au.gid = call_frame->root->gid;
- au.ngrps = call_frame->root->ngrps;
- au.lk_owner = call_frame->root->lk_owner;
- if (!au.lk_owner)
- au.lk_owner = au.pid;
+ au.pid = call_frame->root->pid;
+ au.uid = call_frame->root->uid;
+ au.gid = call_frame->root->gid;
+ au.groups.groups_len = call_frame->root->ngrps;
+ au.lk_owner.lk_owner_len = call_frame->root->lk_owner.len;
- gf_log (clnt->conn.trans->name, GF_LOG_TRACE, "Auth Info: pid: %u, uid: %d"
- ", gid: %d, owner: %"PRId64,
- au.pid, au.uid, au.gid, au.lk_owner);
+ if (au.groups.groups_len)
+ au.groups.groups_val = call_frame->root->groups;
- memcpy (au.groups, call_frame->root->groups, 16);
+ if (call_frame->root->lk_owner.len)
+ au.lk_owner.lk_owner_val = call_frame->root->lk_owner.data;
+ else {
+ owner[0] = (char)(au.pid & 0xff);
+ owner[1] = (char)((au.pid >> 8) & 0xff);
+ owner[2] = (char)((au.pid >> 16) & 0xff);
+ owner[3] = (char)((au.pid >> 24) & 0xff);
- //rpc_transport_get_myname (clnt->conn.trans, myname, UNIX_PATH_MAX);
- //au.aup_machname = myname;
+ au.lk_owner.lk_owner_val = owner;
+ au.lk_owner.lk_owner_len = 4;
+ }
+
+ gf_log (clnt->conn.trans->name, GF_LOG_TRACE, "Auth Info: pid: %u, uid: %d"
+ ", gid: %d, owner: %s", au.pid, au.uid, au.gid,
+ lkowner_utoa (&call_frame->root->lk_owner));
- /* Assuming the client program would like to speak to the same versioned
- * program on server.
- */
request_iob = rpc_clnt_record_build_record (clnt, prog->prognum,
prog->progver,
- procnum, payload_len,
+ procnum, hdrlen,
callid, &au,
rpchdr);
if (!request_iob) {
@@ -1329,6 +1408,12 @@ rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog,
goto out;
}
+ conn = &rpc->conn;
+
+ if (conn->trans == NULL) {
+ goto out;
+ }
+
rpcreq = mem_get (rpc->reqpool);
if (rpcreq == NULL) {
goto out;
@@ -1348,57 +1433,54 @@ rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog,
callid = rpc_clnt_new_callid (rpc);
- conn = &rpc->conn;
-
rpcreq->prog = prog;
rpcreq->procnum = procnum;
rpcreq->conn = conn;
rpcreq->xid = callid;
rpcreq->cbkfn = cbkfn;
- pthread_mutex_lock (&conn->lock);
- {
- if (conn->connected == 0) {
- rpc_transport_connect (conn->trans,
- conn->config.remote_port);
- }
-
- ret = -1;
+ ret = -1;
- if (proghdr) {
- proglen += iov_length (proghdr, proghdrcount);
- }
+ if (proghdr) {
+ proglen += iov_length (proghdr, proghdrcount);
+ }
- if (progpayload) {
- proglen += iov_length (progpayload,
- progpayloadcount);
- }
+ request_iob = rpc_clnt_record (rpc, frame, prog,
+ procnum, proglen,
+ &rpchdr, callid);
+ if (!request_iob) {
+ gf_log (conn->trans->name, GF_LOG_WARNING,
+ "cannot build rpc-record");
+ goto out;
+ }
- request_iob = rpc_clnt_record (rpc, frame, prog,
- procnum, proglen,
- &rpchdr, callid);
- if (!request_iob) {
- gf_log (conn->trans->name, GF_LOG_WARNING,
- "cannot build rpc-record");
- goto unlock;
- }
+ iobref_add (iobref, request_iob);
- iobref_add (iobref, request_iob);
+ req.msg.rpchdr = &rpchdr;
+ req.msg.rpchdrcount = 1;
+ req.msg.proghdr = proghdr;
+ req.msg.proghdrcount = proghdrcount;
+ req.msg.progpayload = progpayload;
+ req.msg.progpayloadcount = progpayloadcount;
+ req.msg.iobref = iobref;
- req.msg.rpchdr = &rpchdr;
- req.msg.rpchdrcount = 1;
- req.msg.proghdr = proghdr;
- req.msg.proghdrcount = proghdrcount;
- req.msg.progpayload = progpayload;
- req.msg.progpayloadcount = progpayloadcount;
- req.msg.iobref = iobref;
+ req.rsp.rsphdr = rsphdr;
+ req.rsp.rsphdr_count = rsphdr_count;
+ req.rsp.rsp_payload = rsp_payload;
+ req.rsp.rsp_payload_count = rsp_payload_count;
+ req.rsp.rsp_iobref = rsp_iobref;
+ req.rpc_req = rpcreq;
- req.rsp.rsphdr = rsphdr;
- req.rsp.rsphdr_count = rsphdr_count;
- req.rsp.rsp_payload = rsp_payload;
- req.rsp.rsp_payload_count = rsp_payload_count;
- req.rsp.rsp_iobref = rsp_iobref;
- req.rpc_req = rpcreq;
+ pthread_mutex_lock (&conn->lock);
+ {
+ if (conn->connected == 0) {
+ ret = rpc_transport_connect (conn->trans,
+ conn->config.remote_port);
+ /* Below code makes sure the (re-)configured port lasts
+ for just one successful connect attempt */
+ if (!ret)
+ conn->config.remote_port = 0;
+ }
ret = rpc_transport_submit_request (rpc->conn.trans,
&req);
@@ -1412,7 +1494,6 @@ rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog,
}
if ((ret >= 0) && frame) {
- gettimeofday (&conn->last_sent, NULL);
/* Save the frame in queue */
__save_frame (rpc, frame, rpcreq);
@@ -1423,7 +1504,6 @@ rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog,
rpcreq->procnum, rpc->conn.trans->name);
}
}
-unlock:
pthread_mutex_unlock (&conn->lock);
if (ret == -1) {
@@ -1433,7 +1513,9 @@ unlock:
ret = 0;
out:
- iobuf_unref (request_iob);
+ if (request_iob) {
+ iobuf_unref (request_iob);
+ }
if (new_iobref && iobref) {
iobref_unref (iobref);
@@ -1443,7 +1525,7 @@ out:
if (rpcreq) {
rpcreq->rpc_status = -1;
cbkfn (rpcreq, NULL, 0, frame);
- mem_put (rpc->reqpool, rpcreq);
+ mem_put (rpcreq);
}
}
return ret;
@@ -1471,12 +1553,11 @@ rpc_clnt_destroy (struct rpc_clnt *rpc)
return;
if (rpc->conn.trans) {
- rpc->conn.trans->mydata = NULL;
+ rpc_transport_unregister_notify (rpc->conn.trans);
+ rpc_transport_disconnect (rpc->conn.trans);
rpc_transport_unref (rpc->conn.trans);
- //rpc_transport_destroy (rpc->conn.trans);
}
- rpc_clnt_connection_cleanup (&rpc->conn);
rpc_clnt_reconnect_cleanup (&rpc->conn);
saved_frames_destroy (rpc->conn.saved_frames);
pthread_mutex_destroy (&rpc->lock);
@@ -1512,6 +1593,48 @@ rpc_clnt_unref (struct rpc_clnt *rpc)
void
+rpc_clnt_disable (struct rpc_clnt *rpc)
+{
+ rpc_clnt_connection_t *conn = NULL;
+
+ if (!rpc) {
+ goto out;
+ }
+
+ conn = &rpc->conn;
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ rpc->disabled = 1;
+
+ if (conn->timer) {
+ gf_timer_call_cancel (rpc->ctx, conn->timer);
+ conn->timer = NULL;
+ }
+
+ if (conn->reconnect) {
+ gf_timer_call_cancel (rpc->ctx, conn->reconnect);
+ conn->reconnect = NULL;
+ }
+ conn->connected = 0;
+
+ if (conn->ping_timer) {
+ gf_timer_call_cancel (rpc->ctx, conn->ping_timer);
+ conn->ping_timer = NULL;
+ conn->ping_started = 0;
+ }
+
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ rpc_transport_disconnect (rpc->conn.trans);
+
+out:
+ return;
+}
+
+
+void
rpc_clnt_reconfig (struct rpc_clnt *rpc, struct rpc_clnt_config *config)
{
if (config->rpc_timeout) {
@@ -1553,7 +1676,8 @@ rpc_clnt_reconfig (struct rpc_clnt *rpc, struct rpc_clnt_config *config)
}
int
-rpc_clnt_transport_unix_options_build (dict_t **options, char *filepath)
+rpc_clnt_transport_unix_options_build (dict_t **options, char *filepath,
+ int frame_timeout)
{
dict_t *dict = NULL;
char *fpath = NULL;
@@ -1592,6 +1716,12 @@ rpc_clnt_transport_unix_options_build (dict_t **options, char *filepath)
if (ret)
goto out;
+ if (frame_timeout > 0) {
+ ret = dict_set_int32 (dict, "frame-timeout", frame_timeout);
+ if (ret)
+ goto out;
+ }
+
*options = dict;
out:
if (ret) {
diff --git a/rpc/rpc-lib/src/rpc-clnt.h b/rpc/rpc-lib/src/rpc-clnt.h
index d3e7f2f16..ca3c1d027 100644
--- a/rpc/rpc-lib/src/rpc-clnt.h
+++ b/rpc/rpc-lib/src/rpc-clnt.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __RPC_CLNT_H
@@ -31,8 +22,10 @@ typedef enum {
RPC_CLNT_MSG
} rpc_clnt_event_t;
-#define AUTH_GLUSTERFS 5
-#define RPC_CLNT_MAX_AUTH_BYTES 1024
+
+#define SFRAME_GET_PROGNUM(sframe) (sframe->rpcreq->prog->prognum)
+#define SFRAME_GET_PROGVER(sframe) (sframe->rpcreq->prog->progver)
+#define SFRAME_GET_PROCNUM(sframe) (sframe->rpcreq->procnum)
struct xptr_clnt;
struct rpc_req;
@@ -66,6 +59,7 @@ struct saved_frame {
struct saved_frames {
int64_t count;
struct saved_frame sf;
+ struct saved_frame lk_sf;
};
@@ -116,11 +110,10 @@ typedef struct rpcclnt_cb_program {
-#define RPC_MAX_AUTH_BYTES 400
typedef struct rpc_auth_data {
- int flavour;
- int datalen;
- char authdata[RPC_MAX_AUTH_BYTES];
+ int flavour;
+ int datalen;
+ char authdata[GF_MAX_AUTH_BYTES];
} rpc_auth_data_t;
@@ -167,7 +160,7 @@ struct rpc_req {
void *conn_private;
};
-struct rpc_clnt {
+typedef struct rpc_clnt {
pthread_mutex_t lock;
rpc_clnt_notify_t notifyfn;
rpc_clnt_connection_t conn;
@@ -184,11 +177,13 @@ struct rpc_clnt {
glusterfs_ctx_t *ctx;
int refcount;
-};
+ int auth_null;
+ char disabled;
+} rpc_clnt_t;
struct rpc_clnt *rpc_clnt_new (dict_t *options, glusterfs_ctx_t *ctx,
- char *name);
+ char *name, uint32_t reqpool_size);
int rpc_clnt_start (struct rpc_clnt *rpc);
@@ -224,10 +219,11 @@ rpc_clnt_ref (struct rpc_clnt *rpc);
struct rpc_clnt *
rpc_clnt_unref (struct rpc_clnt *rpc);
+int rpc_clnt_connection_cleanup (rpc_clnt_connection_t *conn);
+
void rpc_clnt_set_connected (rpc_clnt_connection_t *conn);
void rpc_clnt_unset_connected (rpc_clnt_connection_t *conn);
-
void rpc_clnt_reconnect (void *trans_ptr);
void rpc_clnt_reconfig (struct rpc_clnt *rpc, struct rpc_clnt_config *config);
@@ -239,5 +235,10 @@ int rpcclnt_cbk_program_register (struct rpc_clnt *svc,
rpcclnt_cb_program_t *program);
int
-rpc_clnt_transport_unix_options_build (dict_t **options, char *filepath);
+rpc_clnt_transport_unix_options_build (dict_t **options, char *filepath,
+ int frame_timeout);
+
+void
+rpc_clnt_disable (struct rpc_clnt *rpc);
+
#endif /* !_RPC_CLNT_H */
diff --git a/rpc/rpc-lib/src/rpc-common.c b/rpc/rpc-lib/src/rpc-common.c
deleted file mode 100644
index db7b92834..000000000
--- a/rpc/rpc-lib/src/rpc-common.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "logging.h"
-#include "xdr-common.h"
-
-ssize_t
-xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc)
-{
- ssize_t ret = -1;
- XDR xdr;
-
- if ((!outmsg.iov_base) || (!res) || (!proc))
- return -1;
-
- xdrmem_create (&xdr, outmsg.iov_base, (unsigned int)outmsg.iov_len,
- XDR_ENCODE);
-
- if (!proc (&xdr, res)) {
- gf_log_callingfn ("xdr", GF_LOG_WARNING,
- "XDR encoding failed");
- ret = -1;
- goto ret;
- }
-
- ret = xdr_encoded_length (xdr);
-
-ret:
- return ret;
-}
-
-
-ssize_t
-xdr_to_generic (struct iovec inmsg, void *args, xdrproc_t proc)
-{
- XDR xdr;
- ssize_t ret = -1;
-
- if ((!inmsg.iov_base) || (!args) || (!proc))
- return -1;
-
- xdrmem_create (&xdr, inmsg.iov_base, (unsigned int)inmsg.iov_len,
- XDR_DECODE);
-
- if (!proc (&xdr, args)) {
- gf_log_callingfn ("xdr", GF_LOG_WARNING,
- "XDR decoding failed");
- ret = -1;
- goto ret;
- }
-
- ret = xdr_decoded_length (xdr);
-ret:
- return ret;
-}
-
-
-bool_t
-xdr_gf_dump_req (XDR *xdrs, gf_dump_req *objp)
-{
- if (!xdr_u_quad_t (xdrs, &objp->gfs_id))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf_prog_detail (XDR *xdrs, gf_prog_detail *objp)
-{
- if (!xdr_string (xdrs, &objp->progname, ~0))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->prognum))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->progver))
- return FALSE;
- if (!xdr_pointer (xdrs, (char **)&objp->next, sizeof (gf_prog_detail), (xdrproc_t) xdr_gf_prog_detail))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf_dump_rsp (XDR *xdrs, gf_dump_rsp *objp)
-{
- if (!xdr_u_quad_t (xdrs, &objp->gfs_id))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_pointer (xdrs, (char **)&objp->prog, sizeof (gf_prog_detail), (xdrproc_t) xdr_gf_prog_detail))
- return FALSE;
- return TRUE;
-}
-
-
-ssize_t
-xdr_serialize_dump_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf_dump_rsp);
-}
-
-ssize_t
-xdr_to_dump_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf_dump_req);
-}
-
-
-ssize_t
-xdr_from_dump_req (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf_dump_req);
-}
-
-ssize_t
-xdr_to_dump_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf_dump_rsp);
-}
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
index 3db73f652..8da898b61 100644
--- a/rpc/rpc-lib/src/rpc-transport.c
+++ b/rpc/rpc-lib/src/rpc-transport.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <dlfcn.h>
@@ -42,431 +33,8 @@
#define GF_OPTION_LIST_EMPTY(_opt) (_opt->value[0] == NULL)
#endif
-int
-__volume_option_value_validate (char *name,
- data_pair_t *pair,
- volume_option_t *opt)
-{
- int i = 0;
- int ret = -1;
- uint64_t input_size = 0;
- long long inputll = 0;
-
- /* Key is valid, validate the option */
- switch (opt->type) {
- case GF_OPTION_TYPE_XLATOR:
- break;
-
- case GF_OPTION_TYPE_PATH:
- {
- if (strstr (pair->value->data, "../")) {
- gf_log (name, GF_LOG_ERROR,
- "invalid path given '%s'",
- pair->value->data);
- ret = -1;
- goto out;
- }
-
- /* Make sure the given path is valid */
- if (pair->value->data[0] != '/') {
- gf_log (name, GF_LOG_WARNING,
- "option %s %s: '%s' is not an "
- "absolute path name",
- pair->key, pair->value->data,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INT:
- {
- /* Check the range */
- if (gf_string2longlong (pair->value->data,
- &inputll) != 0) {
- gf_log (name, GF_LOG_ERROR,
- "invalid number format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((inputll < opt->min) ||
- (inputll > opt->max)) {
- gf_log (name, GF_LOG_WARNING,
- "'%lld' in 'option %s %s' is out of "
- "range [%"PRId64" - %"PRId64"]",
- inputll, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_SIZET:
- {
- /* Check the range */
- if (gf_string2bytesize (pair->value->data,
- &input_size) != 0) {
- gf_log (name, GF_LOG_ERROR,
- "invalid size format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (name, GF_LOG_ERROR,
- "'%"PRId64"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_BOOL:
- {
- /* Check if the value is one of
- '0|1|on|off|no|yes|true|false|enable|disable' */
- gf_boolean_t bool_value;
- if (gf_string2boolean (pair->value->data,
- &bool_value) != 0) {
- gf_log (name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a valid "
- "boolean value",
- pair->key, pair->value->data,
- pair->value->data);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_STR:
- {
- /* Check if the '*str' is valid */
- if (GF_OPTION_LIST_EMPTY(opt)) {
- ret = 0;
- goto out;
- }
-
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- if (strcasecmp (opt->value[i],
- pair->value->data) == 0) {
- ret = 0;
- break;
- }
- }
-
- if ((i == ZR_OPTION_MAX_ARRAY_SIZE)
- || ((i < ZR_OPTION_MAX_ARRAY_SIZE)
- && (!opt->value[i]))) {
- /* enter here only if
- * 1. reached end of opt->value array and haven't
- * validated input
- * OR
- * 2. valid input list is less than
- * ZR_OPTION_MAX_ARRAY_SIZE and input has not
- * matched all possible input values.
- */
- char given_array[4096] = {0,};
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- strcat (given_array, opt->value[i]);
- strcat (given_array, ", ");
- }
-
- gf_log (name, GF_LOG_ERROR,
- "option %s %s: '%s' is not valid "
- "(possible options are %s)",
- pair->key, pair->value->data,
- pair->value->data, given_array);
-
- goto out;
- }
- }
- break;
- case GF_OPTION_TYPE_PERCENT:
- {
- uint32_t percent = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) != 0) {
- gf_log (name, GF_LOG_ERROR,
- "invalid percent format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((percent < 0) || (percent > 100)) {
- gf_log (name, GF_LOG_ERROR,
- "'%d' in 'option %s %s' is out of "
- "range [0 - 100]",
- percent, pair->key,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_PERCENT_OR_SIZET:
- {
- uint32_t percent = 0;
- uint64_t input_size = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) == 0) {
- if (percent > 100) {
- gf_log (name, GF_LOG_DEBUG,
- "value given was greater than 100, "
- "assuming this is actually a size");
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) &&
- (opt->max == 0)) {
- gf_log (name, GF_LOG_DEBUG,
- "no range check "
- "required for "
- "'option %s %s'",
- pair->key,
- pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (name, GF_LOG_ERROR,
- "'%"PRId64"' in "
- "'option %s %s' is out"
- " of range [%"PRId64""
- "- %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- // It is a size
- ret = 0;
- goto out;
- } else {
- // It's not a percent or size
- gf_log (name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- }
-
- }
- // It is a percent
- ret = 0;
- goto out;
- } else {
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (name, GF_LOG_ERROR,
- "'%"PRId64"' in 'option %s %s'"
- " is out of range [%"PRId64" -"
- " %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- } else {
- // It's not a percent or size
- gf_log (name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- }
- //It is a size
- ret = 0;
- goto out;
- }
-
- }
- break;
- case GF_OPTION_TYPE_TIME:
- {
- uint32_t input_time = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2time (pair->value->data,
- &input_time) != 0) {
- gf_log (name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- if ((input_time < opt->min) ||
- (input_time > opt->max)) {
- gf_log (name, GF_LOG_ERROR,
- "'%"PRIu32"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_time, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_DOUBLE:
- {
- double input_time = 0.0;
-
- /* Check if the value is valid double */
- if (gf_string2double (pair->value->data,
- &input_time) != 0) {
- gf_log (name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if (input_time < 0.0) {
- gf_log (name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (name, GF_LOG_DEBUG,
- "no range check required for 'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INTERNET_ADDRESS:
- {
- if (!valid_internet_address (pair->value->data)) {
- gf_log (name, GF_LOG_ERROR,
- "internet address '%s' does not conform to"
- "standards.", pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_ANY:
- /* NO CHECK */
- ret = 0;
- break;
- }
-
-out:
- return ret;
-}
-
-/* FIXME: this procedure should be removed from transport */
int
-validate_volume_options (char *name, dict_t *options, volume_option_t *opt)
-{
- int i = 0;
- int ret = -1;
- int index = 0;
- volume_option_t *trav = NULL;
- data_pair_t *pairs = NULL;
-
- if (!opt) {
- ret = 0;
- goto out;
- }
-
- /* First search for not supported options, if any report error */
- pairs = options->members_list;
- while (pairs) {
- ret = -1;
- for (index = 0;
- opt[index].key && opt[index].key[0] ; index++) {
- trav = &(opt[index]);
- for (i = 0 ;
- (i < ZR_VOLUME_MAX_NUM_KEY) &&
- trav->key[i]; i++) {
- /* Check if the key is valid */
- if (fnmatch (trav->key[i],
- pairs->key, FNM_NOESCAPE) == 0) {
- ret = 0;
- break;
- }
- }
- if (!ret) {
- if (i) {
- gf_log (name, GF_LOG_WARNING,
- "option '%s' is deprecated, "
- "preferred is '%s', continuing"
- " with correction",
- trav->key[i], trav->key[0]);
- /* TODO: some bytes lost */
- pairs->key = gf_strdup (trav->key[0]);
- }
- break;
- }
- }
- if (!ret) {
- ret = __volume_option_value_validate (name, pairs, trav);
- if (-1 == ret) {
- goto out;
- }
- }
-
- pairs = pairs->next;
- }
-
- ret = 0;
- out:
- return ret;
-}
-
-int32_t
rpc_transport_get_myaddr (rpc_transport_t *this, char *peeraddr, int addrlen,
struct sockaddr_storage *sa, size_t salen)
{
@@ -521,7 +89,7 @@ rpc_transport_pollin_destroy (rpc_transport_pollin_t *pollin)
if (pollin->iobref) {
iobref_unref (pollin->iobref);
}
-
+
if (pollin->hdr_iobuf) {
iobuf_unref (pollin->hdr_iobuf);
}
@@ -556,7 +124,8 @@ rpc_transport_pollin_alloc (rpc_transport_t *this, struct iovec *vector,
msg->count = count;
msg->iobref = iobref_ref (iobref);
msg->private = private;
- msg->hdr_iobuf = iobuf_ref (hdr_iobuf);
+ if (hdr_iobuf)
+ msg->hdr_iobuf = iobuf_ref (hdr_iobuf);
out:
return msg;
@@ -575,7 +144,7 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
int32_t ret = -1;
int8_t is_tcp = 0, is_unix = 0, is_ibsdp = 0;
volume_opt_list_t *vol_opt = NULL;
- gf_boolean_t client_bind_insecure = _gf_false;
+ gf_boolean_t bind_insecure = _gf_false;
GF_VALIDATE_OR_GOTO("rpc-transport", options, fail);
GF_VALIDATE_OR_GOTO("rpc-transport", ctx, fail);
@@ -640,19 +209,26 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
}
}
+ /* client-bind-insecure is for clients protocol, and
+ * bind-insecure for glusterd. Both mutually exclusive
+ */
ret = dict_get_str (options, "client-bind-insecure", &type);
+ if (ret)
+ ret = dict_get_str (options, "bind-insecure", &type);
if (ret == 0) {
- ret = gf_string2boolean (type, &client_bind_insecure);
+ ret = gf_string2boolean (type, &bind_insecure);
if (ret < 0) {
gf_log ("rcp-transport", GF_LOG_WARNING,
- "client-bind-insecure option %s is not a"
+ "bind-insecure option %s is not a"
" valid bool option", type);
goto fail;
}
- if (_gf_true == client_bind_insecure)
- trans->client_bind_insecure = 1;
+ if (_gf_true == bind_insecure)
+ trans->bind_insecure = 1;
+ else
+ trans->bind_insecure = 0;
} else {
- trans->client_bind_insecure = 0;
+ trans->bind_insecure = 0;
}
ret = dict_get_str (options, "transport-type", &type);
@@ -719,11 +295,10 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
gf_log ("rpc-transport", GF_LOG_DEBUG,
"volume option validation not specified");
} else {
- /* FIXME: is adding really needed? */
- /* list_add_tail (&vol_opt->list, &xl->volume_options); */
- if (-1 ==
- validate_volume_options (trans_name, options,
- vol_opt->given_opt)) {
+ INIT_LIST_HEAD (&vol_opt->list);
+ list_add_tail (&vol_opt->list, &(THIS->volume_options));
+ if (xlator_options_validate_list (THIS, options, vol_opt,
+ NULL)) {
gf_log ("rpc-transport", GF_LOG_ERROR,
"volume option validation failed");
goto fail;
@@ -742,13 +317,12 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
goto fail;
}
- return_trans = trans;
+ return_trans = trans;
if (name) {
GF_FREE (name);
}
- GF_FREE (vol_opt);
return return_trans;
fail:
@@ -760,10 +334,6 @@ fail:
GF_FREE (trans);
}
- if (vol_opt) {
- GF_FREE (vol_opt);
- }
-
if (name) {
GF_FREE (name);
}
@@ -891,14 +461,15 @@ rpc_transport_unref (rpc_transport_t *this)
pthread_mutex_lock (&this->lock);
{
- refcount = --this->refcount;
+ refcount = --this->refcount;
}
pthread_mutex_unlock (&this->lock);
if (refcount == 0) {
if (this->mydata)
- this->notify (this, this->mydata, RPC_TRANSPORT_CLEANUP, NULL);
- rpc_transport_destroy (this);
+ this->notify (this, this->mydata, RPC_TRANSPORT_CLEANUP,
+ NULL);
+ rpc_transport_destroy (this);
}
ret = 0;
@@ -940,6 +511,20 @@ out:
return ret;
}
+
+inline int
+rpc_transport_unregister_notify (rpc_transport_t *trans)
+{
+ GF_VALIDATE_OR_GOTO ("rpc-transport", trans, out);
+
+ trans->notify = NULL;
+ trans->mydata = NULL;
+
+out:
+ return 0;
+}
+
+
//give negative values to skip setting that value
//this function asserts if both the values are negative.
//why call it if you dont set it.
@@ -966,7 +551,8 @@ out:
}
int
-rpc_transport_inet_options_build (dict_t **options, const char *hostname, int port)
+rpc_transport_inet_options_build (dict_t **options, const char *hostname,
+ int port)
{
dict_t *dict = NULL;
char *host = NULL;
@@ -988,27 +574,27 @@ rpc_transport_inet_options_build (dict_t **options, const char *hostname, int po
ret = dict_set_dynstr (dict, "remote-host", host);
if (ret) {
- gf_log ("", GF_LOG_WARNING, "failed to set remote-host with %s",
- host);
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "failed to set remote-host with %s", host);
goto out;
}
ret = dict_set_int32 (dict, "remote-port", port);
if (ret) {
- gf_log ("", GF_LOG_WARNING, "failed to set remote-port with %d",
- port);
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "failed to set remote-port with %d", port);
goto out;
}
ret = dict_set_str (dict, "transport.address-family", "inet");
if (ret) {
- gf_log ("", GF_LOG_WARNING,
+ gf_log (THIS->name, GF_LOG_WARNING,
"failed to set addr-family with inet");
goto out;
}
ret = dict_set_str (dict, "transport-type", "socket");
if (ret) {
- gf_log ("", GF_LOG_WARNING,
+ gf_log (THIS->name, GF_LOG_WARNING,
"failed to set trans-type with socket");
goto out;
}
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
index 59bec99fd..d9ab30dd8 100644
--- a/rpc/rpc-lib/src/rpc-transport.h
+++ b/rpc/rpc-lib/src/rpc-transport.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 __RPC_TRANSPORT_H__
@@ -40,11 +31,15 @@
#define MAX_IOVEC 16
#endif
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG 0
+#endif /* AI_ADDRCONFIG */
+
/* Given the 4-byte fragment header, returns non-zero if this fragment
- * is the last fragment for the RPC record being assemebled.
+ * is the last fragment for the RPC record being assembled.
* RPC Record marking standard defines a 32 bit value as the fragment
* header with the MSB signifying whether the fragment is the last
- * fragment for the record being asembled.
+ * fragment for the record being assembled.
*/
#define RPC_LASTFRAG(fraghdr) ((uint32_t)(fraghdr & 0x80000000U))
@@ -73,9 +68,9 @@ typedef struct rpc_transport rpc_transport_t;
#include "rpcsvc-common.h"
struct peer_info {
- struct sockaddr_storage sockaddr;
- socklen_t sockaddr_len;
- char identifier[UNIX_PATH_MAX];
+ struct sockaddr_storage sockaddr;
+ socklen_t sockaddr_len;
+ char identifier[UNIX_PATH_MAX];
};
typedef struct peer_info peer_info_t;
@@ -178,40 +173,38 @@ typedef int (*rpc_transport_notify_t) (rpc_transport_t *, void *mydata,
struct rpc_transport {
- struct rpc_transport_ops *ops;
+ struct rpc_transport_ops *ops;
rpc_transport_t *listener; /* listener transport to which
* request for creation of this
* transport came from. valid only
* on server process.
*/
-
- void *private;
+
+ void *private;
void *xl_private;
void *xl; /* Used for THIS */
- void *mydata;
- pthread_mutex_t lock;
- int32_t refcount;
+ void *mydata;
+ pthread_mutex_t lock;
+ int32_t refcount;
glusterfs_ctx_t *ctx;
dict_t *options;
char *name;
- void *dnscache;
- data_t *buf;
- int32_t (*init) (rpc_transport_t *this);
- void (*fini) (rpc_transport_t *this);
- int32_t (*validate_options) (rpc_transport_t *this,
- char **op_errstr);
+ void *dnscache;
+ data_t *buf;
+ int32_t (*init) (rpc_transport_t *this);
+ void (*fini) (rpc_transport_t *this);
int (*reconfigure) (rpc_transport_t *this, dict_t *options);
rpc_transport_notify_t notify;
void *notify_data;
- peer_info_t peerinfo;
- peer_info_t myinfo;
+ peer_info_t peerinfo;
+ peer_info_t myinfo;
uint64_t total_bytes_read;
uint64_t total_bytes_write;
struct list_head list;
- int client_bind_insecure;
+ int bind_insecure;
};
struct rpc_transport_ops {
@@ -222,9 +215,9 @@ struct rpc_transport_ops {
rpc_transport_req_t *req);
int32_t (*submit_reply) (rpc_transport_t *this,
rpc_transport_reply_t *reply);
- int32_t (*connect) (rpc_transport_t *this, int port);
- int32_t (*listen) (rpc_transport_t *this);
- int32_t (*disconnect) (rpc_transport_t *this);
+ int32_t (*connect) (rpc_transport_t *this, int port);
+ int32_t (*listen) (rpc_transport_t *this);
+ int32_t (*disconnect) (rpc_transport_t *this);
int32_t (*get_peername) (rpc_transport_t *this, char *hostname,
int hostlen);
int32_t (*get_peeraddr) (rpc_transport_t *this, char *peeraddr,
@@ -274,6 +267,9 @@ int
rpc_transport_register_notify (rpc_transport_t *trans, rpc_transport_notify_t,
void *mydata);
+int
+rpc_transport_unregister_notify (rpc_transport_t *trans);
+
int32_t
rpc_transport_get_peername (rpc_transport_t *this, char *hostname, int hostlen);
diff --git a/rpc/rpc-lib/src/rpcsvc-auth.c b/rpc/rpc-lib/src/rpcsvc-auth.c
index 567a78a43..3a46cc498 100644
--- a/rpc/rpc-lib/src/rpcsvc-auth.c
+++ b/rpc/rpc-lib/src/rpcsvc-auth.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "rpcsvc.h"
@@ -29,6 +20,8 @@ rpcsvc_auth_unix_init (rpcsvc_t *svc, dict_t *options);
extern rpcsvc_auth_t *
rpcsvc_auth_glusterfs_init (rpcsvc_t *svc, dict_t *options);
+extern rpcsvc_auth_t *
+rpcsvc_auth_glusterfs_v2_init (rpcsvc_t *svc, dict_t *options);
int
rpcsvc_auth_add_initer (struct list_head *list, char *idfier,
@@ -66,6 +59,16 @@ rpcsvc_auth_add_initers (rpcsvc_t *svc)
goto err;
}
+
+ ret = rpcsvc_auth_add_initer (&svc->authschemes, "auth-glusterfs-v2",
+ (rpcsvc_auth_initer_t)
+ rpcsvc_auth_glusterfs_v2_init);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR,
+ "Failed to add AUTH_GLUSTERFS-v2");
+ goto err;
+ }
+
ret = rpcsvc_auth_add_initer (&svc->authschemes, "auth-unix",
(rpcsvc_auth_initer_t)
rpcsvc_auth_unix_init);
@@ -318,8 +321,8 @@ rpcsvc_authenticate (rpcsvc_request_t *req)
if (!req)
return ret;
- //minauth = rpcsvc_request_prog_minauth (req);
- minauth = 1;
+ /* FIXME use rpcsvc_request_prog_minauth() */
+ minauth = 0;
if (minauth > rpcsvc_request_cred_flavour (req)) {
gf_log (GF_RPCSVC, GF_LOG_WARNING, "Auth too weak");
rpcsvc_request_set_autherr (req, AUTH_TOOWEAK);
@@ -339,6 +342,93 @@ err:
return ret;
}
+int
+rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen)
+{
+ int count = 0;
+ int gen = RPCSVC_AUTH_REJECT;
+ int spec = RPCSVC_AUTH_REJECT;
+ int final = RPCSVC_AUTH_REJECT;
+ char *srchstr = NULL;
+ char *valstr = NULL;
+ gf_boolean_t boolval = _gf_false;
+ int ret = 0;
+
+ struct rpcsvc_auth_list *auth = NULL;
+ struct rpcsvc_auth_list *tmp = NULL;
+
+ if ((!svc) || (!autharr) || (!volname))
+ return -1;
+
+ memset (autharr, 0, arrlen * sizeof(int));
+ if (list_empty (&svc->authschemes)) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "No authentication!");
+ goto err;
+ }
+
+ list_for_each_entry_safe (auth, tmp, &svc->authschemes, authlist) {
+ if (count >= arrlen)
+ break;
+
+ gen = gf_asprintf (&srchstr, "rpc-auth.%s", auth->name);
+ if (gen == -1) {
+ count = -1;
+ goto err;
+ }
+
+ gen = RPCSVC_AUTH_REJECT;
+ if (dict_get (svc->options, srchstr)) {
+ ret = dict_get_str (svc->options, srchstr, &valstr);
+ if (ret == 0) {
+ ret = gf_string2boolean (valstr, &boolval);
+ if (ret == 0) {
+ if (boolval == _gf_true)
+ gen = RPCSVC_AUTH_ACCEPT;
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile"
+ "d to read auth val");
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile"
+ "d to read auth val");
+ }
+
+ GF_FREE (srchstr);
+ spec = gf_asprintf (&srchstr, "rpc-auth.%s.%s", auth->name,
+ volname);
+ if (spec == -1) {
+ count = -1;
+ goto err;
+ }
+
+ spec = RPCSVC_AUTH_DONTCARE;
+ if (dict_get (svc->options, srchstr)) {
+ ret = dict_get_str (svc->options, srchstr, &valstr);
+ if (ret == 0) {
+ ret = gf_string2boolean (valstr, &boolval);
+ if (ret == 0) {
+ if (boolval == _gf_true)
+ spec = RPCSVC_AUTH_ACCEPT;
+ else
+ spec = RPCSVC_AUTH_REJECT;
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile"
+ "d to read auth val");
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile"
+ "d to read auth val");
+ }
+
+ GF_FREE (srchstr);
+ final = rpcsvc_combine_gen_spec_volume_checks (gen, spec);
+ if (final == RPCSVC_AUTH_ACCEPT) {
+ autharr[count] = auth->auth->authnum;
+ ++count;
+ }
+ }
+
+err:
+ return count;
+}
gid_t *
rpcsvc_auth_unix_auxgids (rpcsvc_request_t *req, int *arrlen)
@@ -346,9 +436,14 @@ rpcsvc_auth_unix_auxgids (rpcsvc_request_t *req, int *arrlen)
if ((!req) || (!arrlen))
return NULL;
- if ((req->cred.flavour != AUTH_UNIX) ||
- (req->cred.flavour != AUTH_GLUSTERFS)) {
- gf_log ("", GF_LOG_DEBUG, "auth type not unix or glusterfs");
+ /* In case of AUTH_NULL auxgids are not used */
+ switch (req->cred.flavour) {
+ case AUTH_UNIX:
+ case AUTH_GLUSTERFS:
+ case AUTH_GLUSTERFS_v2:
+ break;
+ default:
+ gf_log ("rpc", GF_LOG_DEBUG, "auth type not unix or glusterfs");
return NULL;
}
diff --git a/rpc/rpc-lib/src/rpcsvc-common.h b/rpc/rpc-lib/src/rpcsvc-common.h
index 442049433..81f798116 100644
--- a/rpc/rpc-lib/src/rpcsvc-common.h
+++ b/rpc/rpc-lib/src/rpcsvc-common.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _RPCSVC_COMMON_H
@@ -60,7 +51,7 @@ typedef struct rpcsvc_state {
/* Allow insecure ports. */
int allow_insecure;
-
+ gf_boolean_t register_portmap;
glusterfs_ctx_t *ctx;
/* list of connections which will listen for incoming connections */
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c
index 457d76d4e..98cc88d63 100644
--- a/rpc/rpc-lib/src/rpcsvc.c
+++ b/rpc/rpc-lib/src/rpcsvc.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -34,6 +25,8 @@
#include "iobuf.h"
#include "globals.h"
#include "xdr-common.h"
+#include "xdr-generic.h"
+#include "rpc-common-xdr.h"
#include <errno.h>
#include <pthread.h>
@@ -48,6 +41,8 @@
#include "xdr-rpcclnt.h"
+#define ACL_PROGRAM 100227
+
struct rpcsvc_program gluster_dump_prog;
#define rpcsvc_alloc_request(svc, request) \
@@ -105,8 +100,33 @@ out:
return;
}
+rpcsvc_vector_sizer
+rpcsvc_get_program_vector_sizer (rpcsvc_t *svc, uint32_t prognum,
+ uint32_t progver, uint32_t procnum)
+{
+ rpcsvc_program_t *program = NULL;
+ char found = 0;
+
+ if (!svc)
+ return NULL;
+ pthread_mutex_lock (&svc->rpclock);
+ {
+ list_for_each_entry (program, &svc->programs, program) {
+ if ((program->prognum == prognum)
+ && (program->progver == progver)) {
+ found = 1;
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock (&svc->rpclock);
+ if (found)
+ return program->actors[procnum].vector_sizer;
+ else
+ return NULL;
+}
/* This needs to change to returning errors, since
* we need to return RPC specific error messages when some
@@ -143,7 +163,11 @@ rpcsvc_program_actor (rpcsvc_request_t *req)
if (!found) {
if (err != PROG_MISMATCH) {
- gf_log (GF_RPCSVC, GF_LOG_WARNING,
+ /* log in DEBUG when nfs clients try to see if
+ * ACL requests are accepted by nfs server
+ */
+ gf_log (GF_RPCSVC, (req->prognum == ACL_PROGRAM) ?
+ GF_LOG_DEBUG : GF_LOG_WARNING,
"RPC program not available (req %u %u)",
req->prognum, req->progver);
err = PROG_UNAVAIL;
@@ -194,7 +218,7 @@ err:
/* this procedure can only pass 4 arguments to registered notifyfn. To send more
- * arguements call wrapper->notify directly.
+ * arguments call wrapper->notify directly.
*/
inline void
rpcsvc_program_notify (rpcsvc_listener_t *listener, rpcsvc_event_t event,
@@ -251,7 +275,7 @@ rpcsvc_request_destroy (rpcsvc_request_t *req)
rpc_transport_unref (req->trans);
- mem_put (req->svc->rxpool, req);
+ mem_put (req);
out:
return;
@@ -280,7 +304,9 @@ rpcsvc_request_init (rpcsvc_t *svc, rpc_transport_t *trans,
req->msg[0] = progmsg;
req->iobref = iobref_ref (msg->iobref);
if (msg->vectored) {
- for (i = 1; i < msg->count; i++) {
+ /* msg->vector[2] is defined in structure. prevent a
+ out of bound access */
+ for (i = 1; i < min (msg->count, 2); i++) {
req->msg[i] = msg->vector[i];
}
}
@@ -413,6 +439,7 @@ rpcsvc_handle_rpc_call (rpcsvc_t *svc, rpc_transport_t *trans,
int ret = -1;
uint16_t port = 0;
gf_boolean_t is_unix = _gf_false;
+ gf_boolean_t unprivileged = _gf_false;
if (!trans || !svc)
return -1;
@@ -442,11 +469,8 @@ rpcsvc_handle_rpc_call (rpcsvc_t *svc, rpc_transport_t *trans,
gf_log ("rpcsvc", GF_LOG_TRACE, "Client port: %d", (int)port);
- if ((port > 1024) && (0 == svc->allow_insecure)) { //Non-privileged user, fail request
- gf_log ("glusterd", GF_LOG_ERROR, "Request received from non-"
- "privileged port. Failing request");
- return -1;
- }
+ if (port > 1024)
+ unprivileged = _gf_true;
}
req = rpcsvc_request_create (svc, trans, msg);
@@ -460,7 +484,16 @@ rpcsvc_handle_rpc_call (rpcsvc_t *svc, rpc_transport_t *trans,
if (!actor)
goto err_reply;
- if (actor && (req->rpc_err == SUCCESS)) {
+ if (0 == svc->allow_insecure && unprivileged && !actor->unprivileged) {
+ /* Non-privileged user, fail request */
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Request received from non-"
+ "privileged port. Failing request");
+ rpcsvc_request_destroy (req);
+ return -1;
+ }
+
+ if (req->rpc_err == SUCCESS) {
/* Before going to xlator code, set the THIS properly */
THIS = svc->mydata;
@@ -505,46 +538,49 @@ rpcsvc_handle_disconnect (rpcsvc_t *svc, rpc_transport_t *trans)
rpcsvc_notify_wrapper_t *wrappers = NULL, *wrapper;
int32_t ret = -1, i = 0, wrapper_count = 0;
rpcsvc_listener_t *listener = NULL;
-
+
event = (trans->listener == NULL) ? RPCSVC_EVENT_LISTENER_DEAD
: RPCSVC_EVENT_DISCONNECT;
-
+
pthread_mutex_lock (&svc->rpclock);
{
+ if (!svc->notify_count)
+ goto unlock;
+
wrappers = GF_CALLOC (svc->notify_count, sizeof (*wrapper),
gf_common_mt_rpcsvc_wrapper_t);
if (!wrappers) {
goto unlock;
}
-
+
list_for_each_entry (wrapper, &svc->notify, list) {
if (wrapper->notify) {
wrappers[i++] = *wrapper;
}
}
-
+
wrapper_count = i;
}
unlock:
pthread_mutex_unlock (&svc->rpclock);
-
+
if (wrappers) {
for (i = 0; i < wrapper_count; i++) {
wrappers[i].notify (svc, wrappers[i].data,
event, trans);
}
-
+
GF_FREE (wrappers);
}
-
+
if (event == RPCSVC_EVENT_LISTENER_DEAD) {
listener = rpcsvc_get_listener (svc, -1, trans->listener);
rpcsvc_listener_destroy (listener);
}
-
+
return ret;
}
-
+
int
rpcsvc_notify (rpc_transport_t *trans, void *mydata,
@@ -734,33 +770,36 @@ rpcsvc_callback_build_record (rpcsvc_t *rpc, int prognum, int progver,
char *record = NULL;
struct iovec recordhdr = {0, };
size_t pagesize = 0;
+ size_t xdr_size = 0;
int ret = -1;
if ((!rpc) || (!recbuf)) {
goto out;
}
+ /* Fill the rpc structure and XDR it into the buffer got above. */
+ ret = rpcsvc_fill_callback (prognum, progver, procnum, payload, xid,
+ &request);
+ if (ret == -1) {
+ gf_log ("rpcsvc", GF_LOG_WARNING, "cannot build a rpc-request "
+ "xid (%"PRIu64")", xid);
+ goto out;
+ }
+
/* First, try to get a pointer into the buffer which the RPC
* layer can use.
*/
- request_iob = iobuf_get (rpc->ctx->iobuf_pool);
+ xdr_size = xdr_sizeof ((xdrproc_t)xdr_callmsg, &request);
+
+ request_iob = iobuf_get2 (rpc->ctx->iobuf_pool, (xdr_size + payload));
if (!request_iob) {
goto out;
}
- pagesize = ((struct iobuf_pool *)rpc->ctx->iobuf_pool)->page_size;
+ pagesize = iobuf_pagesize (request_iob);
record = iobuf_ptr (request_iob); /* Now we have it. */
- /* Fill the rpc structure and XDR it into the buffer got above. */
- ret = rpcsvc_fill_callback (prognum, progver, procnum, payload, xid,
- &request);
- if (ret == -1) {
- gf_log ("rpcsvc", GF_LOG_WARNING, "cannot build a rpc-request "
- "xid (%"PRIu64")", xid);
- goto out;
- }
-
recordhdr = rpcsvc_callback_build_header (record, pagesize, &request,
payload);
@@ -904,13 +943,14 @@ out:
*/
struct iobuf *
rpcsvc_record_build_record (rpcsvc_request_t *req, size_t payload,
- struct iovec *recbuf)
+ size_t hdrlen, struct iovec *recbuf)
{
struct rpc_msg reply;
struct iobuf *replyiob = NULL;
char *record = NULL;
struct iovec recordhdr = {0, };
size_t pagesize = 0;
+ size_t xdr_size = 0;
rpcsvc_t *svc = NULL;
int ret = -1;
@@ -918,19 +958,25 @@ rpcsvc_record_build_record (rpcsvc_request_t *req, size_t payload,
return NULL;
svc = req->svc;
- replyiob = iobuf_get (svc->ctx->iobuf_pool);
- pagesize = iobpool_pagesize ((struct iobuf_pool *)svc->ctx->iobuf_pool);
- if (!replyiob) {
- goto err_exit;
- }
-
- record = iobuf_ptr (replyiob); /* Now we have it. */
/* Fill the rpc structure and XDR it into the buffer got above. */
ret = rpcsvc_fill_reply (req, &reply);
if (ret)
goto err_exit;
+ xdr_size = xdr_sizeof ((xdrproc_t)xdr_replymsg, &reply);
+
+ /* Payload would include 'readv' size etc too, where as
+ that comes as another payload iobuf */
+ replyiob = iobuf_get2 (svc->ctx->iobuf_pool, (xdr_size + hdrlen));
+ if (!replyiob) {
+ goto err_exit;
+ }
+
+ pagesize = iobuf_pagesize (replyiob);
+
+ record = iobuf_ptr (replyiob); /* Now we have it. */
+
recordhdr = rpcsvc_record_build_header (record, pagesize, reply,
payload);
if (!recordhdr.iov_base) {
@@ -985,6 +1031,7 @@ rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec *proghdr,
struct iovec recordhdr = {0, };
rpc_transport_t *trans = NULL;
size_t msglen = 0;
+ size_t hdrlen = 0;
char new_iobref = 0;
if ((!req) || (!req->trans))
@@ -1003,7 +1050,7 @@ rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec *proghdr,
gf_log (GF_RPCSVC, GF_LOG_TRACE, "Tx message: %zu", msglen);
/* Build the buffer containing the encoded RPC reply. */
- replyiob = rpcsvc_record_build_record (req, msglen, &recordhdr);
+ replyiob = rpcsvc_record_build_record (req, msglen, hdrlen, &recordhdr);
if (!replyiob) {
gf_log (GF_RPCSVC, GF_LOG_ERROR,"Reply record creation failed");
goto disconnect_exit;
@@ -1063,7 +1110,7 @@ rpcsvc_error_reply (rpcsvc_request_t *req)
if (!req)
return -1;
- gf_log_callingfn ("", GF_LOG_WARNING, "sending a RPC error reply");
+ gf_log_callingfn ("", GF_LOG_DEBUG, "sending a RPC error reply");
/* At this point the req should already have been filled with the
* appropriate RPC error numbers.
@@ -1114,6 +1161,11 @@ out:
return ret;
}
+int
+rpcsvc_register_portmap_enabled (rpcsvc_t *svc)
+{
+ return svc->register_portmap;
+}
int32_t
rpcsvc_get_listener_port (rpcsvc_listener_t *listener)
@@ -1152,7 +1204,7 @@ rpcsvc_get_listener (rpcsvc_t *svc, uint16_t port, rpc_transport_t *trans)
{
rpcsvc_listener_t *listener = NULL;
char found = 0;
- uint32_t listener_port = 0;
+ uint32_t listener_port = 0;
if (!svc) {
goto out;
@@ -1215,28 +1267,44 @@ rpcsvc_submit_message (rpcsvc_request_t *req, struct iovec *proghdr,
int
-rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t *prog)
+rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t *program)
{
int ret = -1;
-
- if (!svc || !prog) {
+ rpcsvc_program_t *prog = NULL;
+ if (!svc || !program) {
goto out;
}
- ret = rpcsvc_program_unregister_portmap (prog);
+ ret = rpcsvc_program_unregister_portmap (program);
if (ret == -1) {
gf_log (GF_RPCSVC, GF_LOG_ERROR, "portmap unregistration of"
" program failed");
goto out;
}
+ pthread_mutex_lock (&svc->rpclock);
+ {
+ list_for_each_entry (prog, &svc->programs, program) {
+ if ((prog->prognum == program->prognum)
+ && (prog->progver == program->progver)) {
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock (&svc->rpclock);
+
+ if (prog == NULL) {
+ ret = -1;
+ goto out;
+ }
+
gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Program unregistered: %s, Num: %d,"
" Ver: %d, Port: %d", prog->progname, prog->prognum,
prog->progver, prog->progport);
pthread_mutex_lock (&svc->rpclock);
{
- list_del (&prog->program);
+ list_del_init (&prog->program);
}
pthread_mutex_unlock (&svc->rpclock);
@@ -1244,8 +1312,8 @@ rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t *prog)
out:
if (ret == -1) {
gf_log (GF_RPCSVC, GF_LOG_ERROR, "Program unregistration failed"
- ": %s, Num: %d, Ver: %d, Port: %d", prog->progname,
- prog->prognum, prog->progver, prog->progport);
+ ": %s, Num: %d, Ver: %d, Port: %d", program->progname,
+ program->prognum, program->progver, program->progport);
}
return ret;
@@ -1343,7 +1411,7 @@ rpcsvc_create_listener (rpcsvc_t *svc, dict_t *options, char *name)
{
rpc_transport_t *trans = NULL;
rpcsvc_listener_t *listener = NULL;
- int32_t ret = -1;
+ int32_t ret = -1;
if (!svc || !options) {
goto out;
@@ -1577,7 +1645,6 @@ out:
return ret;
}
-
static void
free_prog_details (gf_dump_rsp *rsp)
{
@@ -1651,7 +1718,7 @@ fail:
iov.iov_base = rsp_buf;
iov.iov_len = dump_rsp_len;
- ret = xdr_serialize_dump_rsp (iov, &rsp);
+ ret = xdr_serialize_generic (iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp);
if (ret < 0) {
if (req)
req->rpc_err = GARBAGE_ARGS;
@@ -1670,8 +1737,39 @@ fail:
int
rpcsvc_init_options (rpcsvc_t *svc, dict_t *options)
{
+ char *optstr = NULL;
+ int ret = -1;
+
+ if ((!svc) || (!options))
+ return -1;
+
svc->memfactor = RPCSVC_DEFAULT_MEMFACTOR;
- return 0;
+
+ svc->register_portmap = _gf_true;
+ if (dict_get (options, "rpc.register-with-portmap")) {
+ ret = dict_get_str (options, "rpc.register-with-portmap",
+ &optstr);
+ if (ret < 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse "
+ "dict");
+ goto out;
+ }
+
+ ret = gf_string2boolean (optstr, &svc->register_portmap);
+ if (ret < 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse bool "
+ "string");
+ goto out;
+ }
+ }
+
+ if (!svc->register_portmap)
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Portmap registration "
+ "disabled");
+
+ ret = 0;
+out:
+ return ret;
}
int
@@ -1724,10 +1822,11 @@ out:
/* The global RPC service initializer.
*/
rpcsvc_t *
-rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options)
+rpcsvc_init (xlator_t *xl, glusterfs_ctx_t *ctx, dict_t *options,
+ uint32_t poolcount)
{
rpcsvc_t *svc = NULL;
- int ret = -1, poolcount = 0;
+ int ret = -1;
if ((!ctx) || (!options))
return NULL;
@@ -1748,7 +1847,8 @@ rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options)
goto free_svc;
}
- poolcount = RPCSVC_POOLCOUNT_MULT * svc->memfactor;
+ if (!poolcount)
+ poolcount = RPCSVC_POOLCOUNT_MULT * svc->memfactor;
gf_log (GF_RPCSVC, GF_LOG_TRACE, "rx pool: %d", poolcount);
svc->rxpool = mem_pool_new (rpcsvc_request_t, poolcount);
@@ -1768,6 +1868,7 @@ rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options)
ret = -1;
svc->options = options;
svc->ctx = ctx;
+ svc->mydata = xl;
gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC service inited.");
gluster_dump_prog.options = options;
@@ -1789,10 +1890,552 @@ free_svc:
}
+int
+rpcsvc_transport_peer_check_search (dict_t *options, char *pattern, char *clstr)
+{
+ int ret = -1;
+ char *addrtok = NULL;
+ char *addrstr = NULL;
+ char *dup_addrstr = NULL;
+ char *svptr = NULL;
+
+ if ((!options) || (!clstr))
+ return -1;
+
+ if (!dict_get (options, pattern))
+ return -1;
+
+ ret = dict_get_str (options, pattern, &addrstr);
+ if (ret < 0) {
+ ret = -1;
+ goto err;
+ }
+
+ if (!addrstr) {
+ ret = -1;
+ goto err;
+ }
+
+ dup_addrstr = gf_strdup (addrstr);
+ addrtok = strtok_r (dup_addrstr, ",", &svptr);
+ while (addrtok) {
+
+ /* CASEFOLD not present on Solaris */
+#ifdef FNM_CASEFOLD
+ ret = fnmatch (addrtok, clstr, FNM_CASEFOLD);
+#else
+ ret = fnmatch (addrtok, clstr, 0);
+#endif
+ if (ret == 0)
+ goto err;
+
+ addrtok = strtok_r (NULL, ",", &svptr);
+ }
+
+ ret = -1;
+err:
+ if (dup_addrstr)
+ GF_FREE (dup_addrstr);
+
+ return ret;
+}
+
+
+int
+rpcsvc_transport_peer_check_allow (dict_t *options, char *volname, char *clstr)
+{
+ int ret = RPCSVC_AUTH_DONTCARE;
+ char *srchstr = NULL;
+ char globalrule[] = "rpc-auth.addr.allow";
+
+ if ((!options) || (!clstr))
+ return ret;
+
+ /* If volname is NULL, then we're searching for the general rule to
+ * determine the current address in clstr is allowed or not for all
+ * subvolumes.
+ */
+ if (volname) {
+ ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed");
+ ret = RPCSVC_AUTH_DONTCARE;
+ goto out;
+ }
+ } else
+ srchstr = globalrule;
+
+ ret = rpcsvc_transport_peer_check_search (options, srchstr, clstr);
+ if (volname)
+ GF_FREE (srchstr);
+
+ if (ret == 0)
+ ret = RPCSVC_AUTH_ACCEPT;
+ else
+ ret = RPCSVC_AUTH_DONTCARE;
+out:
+ return ret;
+}
+
+int
+rpcsvc_transport_peer_check_reject (dict_t *options, char *volname, char *clstr)
+{
+ int ret = RPCSVC_AUTH_DONTCARE;
+ char *srchstr = NULL;
+ char generalrule[] = "rpc-auth.addr.reject";
+
+ if ((!options) || (!clstr))
+ return ret;
+
+ if (volname) {
+ ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.reject",
+ volname);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed");
+ ret = RPCSVC_AUTH_REJECT;
+ goto out;
+ }
+ } else
+ srchstr = generalrule;
+
+ ret = rpcsvc_transport_peer_check_search (options, srchstr, clstr);
+ if (volname)
+ GF_FREE (srchstr);
+
+ if (ret == 0)
+ ret = RPCSVC_AUTH_REJECT;
+ else
+ ret = RPCSVC_AUTH_DONTCARE;
+out:
+ return ret;
+}
+
+
+/* This function tests the results of the allow rule and the reject rule to
+ * combine them into a single result that can be used to determine if the
+ * connection should be allowed to proceed.
+ * Heres the test matrix we need to follow in this function.
+ *
+ * A - Allow, the result of the allow test. Never returns R.
+ * R - Reject, result of the reject test. Never returns A.
+ * Both can return D or dont care if no rule was given.
+ *
+ * | @allow | @reject | Result |
+ * | A | R | R |
+ * | D | D | D |
+ * | A | D | A |
+ * | D | R | R |
+ */
+int
+rpcsvc_combine_allow_reject_volume_check (int allow, int reject)
+{
+ int final = RPCSVC_AUTH_REJECT;
+
+ /* If allowed rule allows but reject rule rejects, we stay cautious
+ * and reject. */
+ if ((allow == RPCSVC_AUTH_ACCEPT) && (reject == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ /* if both are dont care, that is user did not specify for either allow
+ * or reject, we leave it up to the general rule to apply, in the hope
+ * that there is one.
+ */
+ else if ((allow == RPCSVC_AUTH_DONTCARE) &&
+ (reject == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_DONTCARE;
+ /* If one is dont care, the other one applies. */
+ else if ((allow == RPCSVC_AUTH_ACCEPT) &&
+ (reject == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((allow == RPCSVC_AUTH_DONTCARE) &&
+ (reject == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+
+ return final;
+}
+
+
+/* Combines the result of the general rule test against, the specific rule
+ * to determine final permission for the client's address.
+ *
+ * | @gen | @spec | Result |
+ * | A | A | A |
+ * | A | R | R |
+ * | A | D | A |
+ * | D | A | A |
+ * | D | R | R |
+ * | D | D | D |
+ * | R | A | A |
+ * | R | D | R |
+ * | R | R | R |
+ */
+int
+rpcsvc_combine_gen_spec_addr_checks (int gen, int spec)
+{
+ int final = RPCSVC_AUTH_REJECT;
+
+ if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec== RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_DONTCARE;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+
+ return final;
+}
+
+
+
+/* Combines the result of the general rule test against, the specific rule
+ * to determine final test for the connection coming in for a given volume.
+ *
+ * | @gen | @spec | Result |
+ * | A | A | A |
+ * | A | R | R |
+ * | A | D | A |
+ * | D | A | A |
+ * | D | R | R |
+ * | D | D | R |, special case, we intentionally disallow this.
+ * | R | A | A |
+ * | R | D | R |
+ * | R | R | R |
+ */
+int
+rpcsvc_combine_gen_spec_volume_checks (int gen, int spec)
+{
+ int final = RPCSVC_AUTH_REJECT;
+
+ if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ /* On no rule, we reject. */
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec== RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+
+ return final;
+}
+
+
+int
+rpcsvc_transport_peer_check_name (dict_t *options, char *volname,
+ rpc_transport_t *trans)
+{
+ int ret = RPCSVC_AUTH_REJECT;
+ int aret = RPCSVC_AUTH_REJECT;
+ int rjret = RPCSVC_AUTH_REJECT;
+ char clstr[RPCSVC_PEER_STRLEN];
+
+ if (!trans)
+ return ret;
+
+ ret = rpcsvc_transport_peername (trans, clstr, RPCSVC_PEER_STRLEN);
+ if (ret != 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: "
+ "%s", gai_strerror (ret));
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ aret = rpcsvc_transport_peer_check_allow (options, volname, clstr);
+ rjret = rpcsvc_transport_peer_check_reject (options, volname, clstr);
+
+ ret = rpcsvc_combine_allow_reject_volume_check (aret, rjret);
+
+err:
+ return ret;
+}
+
+
+int
+rpcsvc_transport_peer_check_addr (dict_t *options, char *volname,
+ rpc_transport_t *trans)
+{
+ int ret = RPCSVC_AUTH_REJECT;
+ int aret = RPCSVC_AUTH_DONTCARE;
+ int rjret = RPCSVC_AUTH_REJECT;
+ char clstr[RPCSVC_PEER_STRLEN];
+ char *tmp = NULL;
+ struct sockaddr_storage sastorage = {0,};
+ struct sockaddr *sockaddr = NULL;
+
+ if (!trans)
+ return ret;
+
+ ret = rpcsvc_transport_peeraddr (trans, clstr, RPCSVC_PEER_STRLEN,
+ &sastorage, sizeof (sastorage));
+ if (ret != 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: "
+ "%s", gai_strerror (ret));
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ sockaddr = (struct sockaddr *) &sastorage;
+ switch (sockaddr->sa_family) {
+
+ case AF_INET:
+ case AF_INET6:
+ tmp = strrchr (clstr, ':');
+ if (tmp)
+ *tmp = '\0';
+ break;
+ }
+
+ aret = rpcsvc_transport_peer_check_allow (options, volname, clstr);
+ rjret = rpcsvc_transport_peer_check_reject (options, volname, clstr);
+
+ ret = rpcsvc_combine_allow_reject_volume_check (aret, rjret);
+err:
+ return ret;
+}
+
+
+int
+rpcsvc_transport_check_volume_specific (dict_t *options, char *volname,
+ rpc_transport_t *trans)
+{
+ int namechk = RPCSVC_AUTH_REJECT;
+ int addrchk = RPCSVC_AUTH_REJECT;
+ gf_boolean_t namelookup = _gf_false;
+ char *namestr = NULL;
+ int ret = 0;
+
+ if ((!options) || (!volname) || (!trans))
+ return RPCSVC_AUTH_REJECT;
+
+ /* Disabled by default */
+ if ((dict_get (options, "rpc-auth.addr.namelookup"))) {
+ ret = dict_get_str (options, "rpc-auth.addr.namelookup"
+ , &namestr);
+ if (ret == 0)
+ ret = gf_string2boolean (namestr, &namelookup);
+ }
+
+ /* We need two separate checks because the rules with addresses in them
+ * can be network addresses which can be general and names can be
+ * specific which will over-ride the network address rules.
+ */
+ if (namelookup)
+ namechk = rpcsvc_transport_peer_check_name (options, volname,
+ trans);
+ addrchk = rpcsvc_transport_peer_check_addr (options, volname, trans);
+
+ if (namelookup)
+ ret = rpcsvc_combine_gen_spec_addr_checks (addrchk,
+ namechk);
+ else
+ ret = addrchk;
+
+ return ret;
+}
+
+
+int
+rpcsvc_transport_check_volume_general (dict_t *options, rpc_transport_t *trans)
+{
+ int addrchk = RPCSVC_AUTH_REJECT;
+ int namechk = RPCSVC_AUTH_REJECT;
+ gf_boolean_t namelookup = _gf_false;
+ char *namestr = NULL;
+ int ret = 0;
+
+ if ((!options) || (!trans))
+ return RPCSVC_AUTH_REJECT;
+
+ /* Disabled by default */
+ if ((dict_get (options, "rpc-auth.addr.namelookup"))) {
+ ret = dict_get_str (options, "rpc-auth.addr.namelookup"
+ , &namestr);
+ if (ret == 0)
+ ret = gf_string2boolean (namestr, &namelookup);
+ }
+
+ /* We need two separate checks because the rules with addresses in them
+ * can be network addresses which can be general and names can be
+ * specific which will over-ride the network address rules.
+ */
+ if (namelookup)
+ namechk = rpcsvc_transport_peer_check_name (options, NULL, trans);
+ addrchk = rpcsvc_transport_peer_check_addr (options, NULL, trans);
+
+ if (namelookup)
+ ret = rpcsvc_combine_gen_spec_addr_checks (addrchk, namechk);
+ else
+ ret = addrchk;
+
+ return ret;
+}
+
+int
+rpcsvc_transport_peer_check (dict_t *options, char *volname,
+ rpc_transport_t *trans)
+{
+ int general_chk = RPCSVC_AUTH_REJECT;
+ int specific_chk = RPCSVC_AUTH_REJECT;
+
+ if ((!options) || (!volname) || (!trans))
+ return RPCSVC_AUTH_REJECT;
+
+ general_chk = rpcsvc_transport_check_volume_general (options, trans);
+ specific_chk = rpcsvc_transport_check_volume_specific (options, volname,
+ trans);
+
+ return rpcsvc_combine_gen_spec_volume_checks (general_chk,
+ specific_chk);
+}
+
+
+int
+rpcsvc_transport_privport_check (rpcsvc_t *svc, char *volname,
+ rpc_transport_t *trans)
+{
+ struct sockaddr_storage sastorage = {0,};
+ struct sockaddr_in *sa = NULL;
+ int ret = RPCSVC_AUTH_REJECT;
+ socklen_t sasize = sizeof (sa);
+ char *srchstr = NULL;
+ char *valstr = NULL;
+ int globalinsecure = RPCSVC_AUTH_REJECT;
+ int exportinsecure = RPCSVC_AUTH_DONTCARE;
+ uint16_t port = 0;
+ gf_boolean_t insecure = _gf_false;
+
+ if ((!svc) || (!volname) || (!trans))
+ return ret;
+
+ sa = (struct sockaddr_in*) &sastorage;
+ ret = rpcsvc_transport_peeraddr (trans, NULL, 0, &sastorage,
+ sasize);
+ if (ret != 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get peer addr: %s",
+ gai_strerror (ret));
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ port = ntohs (sa->sin_port);
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Client port: %d", (int)port);
+ /* If the port is already a privileged one, dont bother with checking
+ * options.
+ */
+ if (port <= 1024) {
+ ret = RPCSVC_AUTH_ACCEPT;
+ goto err;
+ }
+
+ /* Disabled by default */
+ if ((dict_get (svc->options, "rpc-auth.ports.insecure"))) {
+ ret = dict_get_str (svc->options, "rpc-auth.ports.insecure"
+ , &srchstr);
+ if (ret == 0) {
+ ret = gf_string2boolean (srchstr, &insecure);
+ if (ret == 0) {
+ if (insecure == _gf_true)
+ globalinsecure = RPCSVC_AUTH_ACCEPT;
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"
+ " read rpc-auth.ports.insecure value");
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"
+ " read rpc-auth.ports.insecure value");
+ }
+
+ /* Disabled by default */
+ ret = gf_asprintf (&srchstr, "rpc-auth.ports.%s.insecure", volname);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed");
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ if (dict_get (svc->options, srchstr)) {
+ ret = dict_get_str (svc->options, srchstr, &valstr);
+ if (ret == 0) {
+ ret = gf_string2boolean (valstr, &insecure);
+ if (ret == 0) {
+ if (insecure == _gf_true)
+ exportinsecure = RPCSVC_AUTH_ACCEPT;
+ else
+ exportinsecure = RPCSVC_AUTH_REJECT;
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"
+ " read rpc-auth.ports.insecure value");
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"
+ " read rpc-auth.ports.insecure value");
+ }
+
+ ret = rpcsvc_combine_gen_spec_volume_checks (globalinsecure,
+ exportinsecure);
+ if (ret == RPCSVC_AUTH_ACCEPT)
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port allowed");
+ else
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port not"
+ " allowed");
+
+err:
+ return ret;
+}
+
+
+char *
+rpcsvc_volume_allowed (dict_t *options, char *volname)
+{
+ char globalrule[] = "rpc-auth.addr.allow";
+ char *srchstr = NULL;
+ char *addrstr = NULL;
+ int ret = -1;
+
+ if ((!options) || (!volname))
+ return NULL;
+
+ ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed");
+ goto out;
+ }
+
+ if (!dict_get (options, srchstr))
+ ret = dict_get_str (options, globalrule, &addrstr);
+ else
+ ret = dict_get_str (options, srchstr, &addrstr);
+
+out:
+ if (srchstr)
+ GF_FREE (srchstr);
+
+ return addrstr;
+}
+
+
rpcsvc_actor_t gluster_dump_actors[] = {
- [GF_DUMP_NULL] = {"NULL", GF_DUMP_NULL, NULL, NULL, NULL },
- [GF_DUMP_DUMP] = {"DUMP", GF_DUMP_DUMP, rpcsvc_dump, NULL, NULL },
- [GF_DUMP_MAXVALUE] = {"MAXVALUE", GF_DUMP_MAXVALUE, NULL, NULL, NULL },
+ [GF_DUMP_NULL] = {"NULL", GF_DUMP_NULL, NULL, NULL, NULL, 0},
+ [GF_DUMP_DUMP] = {"DUMP", GF_DUMP_DUMP, rpcsvc_dump, NULL, NULL, 0},
+ [GF_DUMP_MAXVALUE] = {"MAXVALUE", GF_DUMP_MAXVALUE, NULL, NULL, NULL, 0},
};
diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h
index 17da800fa..95f2c4e84 100644
--- a/rpc/rpc-lib/src/rpcsvc.h
+++ b/rpc/rpc-lib/src/rpcsvc.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _RPCSVC_H
@@ -34,6 +25,7 @@
#include "iobuf.h"
#include "xdr-rpc.h"
#include "glusterfs.h"
+#include "xlator.h"
#include "rpcsvc-common.h"
#include <pthread.h>
@@ -42,10 +34,6 @@
#include <rpc/rpc_msg.h>
#include "compat.h"
-#ifndef NGRPS
-#define NGRPS 16
-#endif /* !NGRPS */
-
#ifndef MAX_IOVEC
#define MAX_IOVEC 16
#endif
@@ -55,9 +43,9 @@
#define RPCSVC_FRAGHDR_SIZE 4 /* 4-byte RPC fragment header size */
#define RPCSVC_DEFAULT_LISTEN_PORT GF_DEFAULT_BASE_PORT
-#define RPCSVC_DEFAULT_MEMFACTOR 15
+#define RPCSVC_DEFAULT_MEMFACTOR 8
#define RPCSVC_EVENTPOOL_SIZE_MULT 1024
-#define RPCSVC_POOLCOUNT_MULT 35
+#define RPCSVC_POOLCOUNT_MULT 64
#define RPCSVC_CONN_READ (128 * GF_UNIT_KB)
#define RPCSVC_PAGE_SIZE (128 * GF_UNIT_KB)
@@ -114,8 +102,6 @@
#define AUTH_KERB 4 /* kerberos style */
#endif /* */
-#define AUTH_GLUSTERFS 5
-
typedef struct rpcsvc_program rpcsvc_program_t;
struct rpcsvc_notify_wrapper {
@@ -142,11 +128,10 @@ struct rpcsvc_config {
int max_block_size;
};
-#define RPCSVC_MAX_AUTH_BYTES 400
typedef struct rpcsvc_auth_data {
int flavour;
int datalen;
- char authdata[RPCSVC_MAX_AUTH_BYTES];
+ char authdata[GF_MAX_AUTH_BYTES];
} rpcsvc_auth_data_t;
#define rpcsvc_auth_flavour(au) ((au).flavour)
@@ -183,13 +168,13 @@ struct rpcsvc_request {
gid_t gid;
pid_t pid;
- uint64_t lk_owner;
+ gf_lkowner_t lk_owner;
uint64_t gfs_id;
- /* Might want to move this to AUTH_UNIX specifix state since this array
- * is not available for every authenticatino scheme.
+ /* Might want to move this to AUTH_UNIX specific state since this array
+ * is not available for every authentication scheme.
*/
- gid_t auxgids[NGRPS];
+ gid_t auxgids[GF_MAX_AUX_GROUPS];
int auxgidcount;
@@ -216,8 +201,8 @@ struct rpcsvc_request {
int auth_err;
/* There can be cases of RPC requests where the reply needs to
- * be built from multiple sources. For eg. where even the NFS reply can
- * contain a payload, as in the NFSv3 read reply. Here the RPC header
+ * be built from multiple sources. E.g. where even the NFS reply
+ * can contain a payload, as in the NFSv3 read reply. Here the RPC header
* ,NFS header and the read data are brought together separately from
* different buffers, so we need to stage the buffers temporarily here
* before all of them get added to the connection's transmission list.
@@ -249,7 +234,8 @@ struct rpcsvc_request {
};
#define rpcsvc_request_program(req) ((rpcsvc_program_t *)((req)->prog))
-#define rpcsvc_request_program_private(req) (((rpcsvc_program_t *)((req)->program))->private)
+#define rpcsvc_request_procnum(req) (((req)->procnum))
+#define rpcsvc_request_program_private(req) (((rpcsvc_program_t *)((req)->prog))->private)
#define rpcsvc_request_accepted(req) ((req)->rpc_status == MSG_ACCEPTED)
#define rpcsvc_request_accepted_success(req) ((req)->rpc_err == SUCCESS)
#define rpcsvc_request_uid(req) ((req)->uid)
@@ -257,18 +243,25 @@ struct rpcsvc_request {
#define rpcsvc_request_prog_minauth(req) (rpcsvc_request_program(req)->min_auth)
#define rpcsvc_request_cred_flavour(req) (rpcsvc_auth_flavour(req->cred))
#define rpcsvc_request_verf_flavour(req) (rpcsvc_auth_flavour(req->verf))
-
+#define rpcsvc_request_service(req) ((req)->svc)
#define rpcsvc_request_uid(req) ((req)->uid)
#define rpcsvc_request_gid(req) ((req)->gid)
#define rpcsvc_request_private(req) ((req)->private)
#define rpcsvc_request_xid(req) ((req)->xid)
#define rpcsvc_request_set_private(req,prv) (req)->private = (void *)(prv)
+#define rpcsvc_request_iobref_ref(req) (iobref_ref ((req)->iobref))
#define rpcsvc_request_record_ref(req) (iobuf_ref ((req)->recordiob))
#define rpcsvc_request_record_unref(req) (iobuf_unref ((req)->recordiob))
+#define rpcsvc_request_record_iob(req) ((req)->recordiob)
+#define rpcsvc_request_set_vecstate(req, state) ((req)->vecstate = state)
+#define rpcsvc_request_vecstate(req) ((req)->vecstate)
+#define rpcsvc_request_transport(req) ((req)->trans)
+#define rpcsvc_request_transport_ref(req) (rpc_transport_ref((req)->trans))
#define RPCSVC_ACTOR_SUCCESS 0
#define RPCSVC_ACTOR_ERROR (-1)
+#define RPCSVC_ACTOR_IGNORE (-2)
/* Functor for every type of protocol actor
* must be defined like this.
@@ -285,8 +278,7 @@ struct rpcsvc_request {
typedef int (*rpcsvc_actor) (rpcsvc_request_t *req);
typedef int (*rpcsvc_vector_actor) (rpcsvc_request_t *req, struct iovec *vec,
int count, struct iobref *iobref);
-typedef int (*rpcsvc_vector_sizer) (rpcsvc_request_t *req, ssize_t *readsize,
- int *newiob);
+typedef int (*rpcsvc_vector_sizer) (int state, ssize_t *readsize, char *addr);
/* Every protocol actor will also need to specify the function the RPC layer
* will use to serialize or encode the message into XDR format just before
@@ -316,11 +308,13 @@ typedef struct rpcsvc_actor_desc {
* the XDR scheme, RPC cannot guarantee memory aligned addresses for
* the resulting message-specific structures. Allowing a specialized
* handler for letting the RPC program read the data from the network
- * directly into its alligned buffers.
+ * directly into its aligned buffers.
*/
rpcsvc_vector_actor vector_actor;
rpcsvc_vector_sizer vector_sizer;
+ /* Can actor be ran on behalf an unprivileged requestor? */
+ gf_boolean_t unprivileged;
} rpcsvc_actor_t;
/* Describes a program and its version along with the function pointers
@@ -410,11 +404,15 @@ rpcsvc_listener_destroy (rpcsvc_listener_t *listener);
extern int
rpcsvc_program_register_portmap (rpcsvc_program_t *newprog, uint32_t port);
+extern int
+rpcsvc_register_portmap_enabled (rpcsvc_t *svc);
+
/* Inits the global RPC service data structures.
* Called in main.
*/
extern rpcsvc_t *
-rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options);
+rpcsvc_init (xlator_t *xl, glusterfs_ctx_t *ctx, dict_t *options,
+ uint32_t poolcount);
int
rpcsvc_register_notify (rpcsvc_t *svc, rpcsvc_notify_t notify, void *mydata);
@@ -542,4 +540,12 @@ int
rpcsvc_transport_unix_options_build (dict_t **options, char *filepath);
int
rpcsvc_set_allow_insecure (rpcsvc_t *svc, dict_t *options);
+int
+rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen);
+char *
+rpcsvc_volume_allowed (dict_t *options, char *volname);
+rpcsvc_vector_sizer
+rpcsvc_get_program_vector_sizer (rpcsvc_t *svc, uint32_t prognum,
+ uint32_t progver, uint32_t procnum);
+
#endif
diff --git a/rpc/rpc-lib/src/xdr-common.h b/rpc/rpc-lib/src/xdr-common.h
index e49aa4882..34dc9c6a2 100644
--- a/rpc/rpc-lib/src/xdr-common.h
+++ b/rpc/rpc-lib/src/xdr-common.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _XDR_COMMON_H_
@@ -30,6 +21,10 @@
#include <rpc/xdr.h>
#include <sys/uio.h>
+#ifdef __NetBSD__
+#include <dirent.h>
+#endif /* __NetBSD__ */
+
enum gf_dump_procnum {
GF_DUMP_NULL,
GF_DUMP_DUMP,
@@ -39,6 +34,7 @@ enum gf_dump_procnum {
#define GLUSTER_DUMP_PROGRAM 123451501 /* Completely random */
#define GLUSTER_DUMP_VERSION 1
+#define GF_MAX_AUTH_BYTES 2048
#if GF_DARWIN_HOST_OS
#define xdr_u_quad_t xdr_u_int64_t
@@ -47,6 +43,14 @@ enum gf_dump_procnum {
#define uint64_t u_int64_t
#endif
+#if defined(__NetBSD__)
+#define xdr_u_quad_t xdr_u_int64_t
+#define xdr_quad_t xdr_int64_t
+#define xdr_uint32_t xdr_u_int32_t
+#define xdr_uint64_t xdr_u_int64_t
+#endif
+
+
#if GF_SOLARIS_HOST_OS
#define u_quad_t uint64_t
#define quad_t int64_t
@@ -55,57 +59,9 @@ enum gf_dump_procnum {
#define xdr_uint32_t xdr_uint32_t
#endif
-struct auth_glusterfs_parms {
- uint64_t lk_owner;
- u_int pid;
- u_int uid;
- u_int gid;
- u_int ngrps;
- u_int groups[16];
-} __attribute__((packed));
-typedef struct auth_glusterfs_parms auth_glusterfs_parms;
-
-struct gf_dump_req {
- uint64_t gfs_id;
-} __attribute__((packed));
-typedef struct gf_dump_req gf_dump_req;
-
-struct gf_prog_detail {
- char *progname;
- uint64_t prognum;
- uint64_t progver;
- struct gf_prog_detail *next;
-} __attribute__((packed));
-typedef struct gf_prog_detail gf_prog_detail;
-
-struct gf_dump_rsp {
- uint64_t gfs_id;
- int op_ret;
- int op_errno;
- struct gf_prog_detail *prog;
-}__attribute__((packed));
-typedef struct gf_dump_rsp gf_dump_rsp;
-
-extern bool_t
-xdr_auth_glusterfs_parms (XDR *xdrs, auth_glusterfs_parms *objp);
-extern bool_t xdr_gf_dump_req (XDR *, gf_dump_req*);
-extern bool_t xdr_gf_prog_detail (XDR *, gf_prog_detail*);
-extern bool_t xdr_gf_dump_rsp (XDR *, gf_dump_rsp*);
-
-ssize_t
-xdr_serialize_dump_rsp (struct iovec outmsg, void *rsp);
-ssize_t
-xdr_to_dump_req (struct iovec inmsg, void *args);
-ssize_t
-xdr_from_dump_req (struct iovec outmsg, void *rsp);
-ssize_t
-xdr_to_dump_rsp (struct iovec inmsg, void *args);
-
-#define XDR_BYTES_PER_UNIT 4
-
/* Returns the address of the byte that follows the
* last byte used for decoding the previous xdr component.
- * For eg, once the RPC call for NFS has been decoded, thie macro will return
+ * E.g. once the RPC call for NFS has been decoded, the macro will return
* the address from which the NFS header starts.
*/
#define xdr_decoded_remaining_addr(xdr) ((&xdr)->x_private)
diff --git a/rpc/rpc-lib/src/xdr-rpc.c b/rpc/rpc-lib/src/xdr-rpc.c
index d26fb69ec..ef52764c3 100644
--- a/rpc/rpc-lib/src/xdr-rpc.c
+++ b/rpc/rpc-lib/src/xdr-rpc.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -117,7 +108,7 @@ rpc_fill_denied_reply (struct rpc_msg *reply, int rjstat, int auth_err)
reply->rm_reply.rp_stat = MSG_DENIED;
reply->rjcted_rply.rj_stat = rjstat;
if (rjstat == RPC_MISMATCH) {
- /* No problem with hardocoding
+ /* No problem with hardcoding
* RPC version numbers. We only support
* v2 anyway.
*/
diff --git a/rpc/rpc-lib/src/xdr-rpc.h b/rpc/rpc-lib/src/xdr-rpc.h
index d504391d5..f5f4a941e 100644
--- a/rpc/rpc-lib/src/xdr-rpc.h
+++ b/rpc/rpc-lib/src/xdr-rpc.h
@@ -1,23 +1,14 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _XDR_RPC_H
+#ifndef _XDR_RPC_H_
#define _XDR_RPC_H_
#ifndef _CONFIG_H
@@ -39,6 +30,14 @@
#include <rpc/xdr.h>
#include <sys/uio.h>
+#include "xdr-common.h"
+
+typedef enum {
+ AUTH_GLUSTERFS = 5,
+ AUTH_GLUSTERFS_v2 = 390039, /* using a number from 'unused' range,
+ from the list available in RFC5531 */
+} gf_rpc_authtype_t;
+
/* Converts a given network buffer from its XDR format to a structure
* that contains everything an RPC call needs to work.
*/
@@ -62,7 +61,7 @@ rpc_reply_to_xdr (struct rpc_msg *reply, char *dest, size_t len,
extern int
xdr_to_auth_unix_cred (char *msgbuf, int msglen, struct authunix_parms *au,
char *machname, gid_t *gids);
-/* Macros that simplify accesing the members of an RPC call structure. */
+/* Macros that simplify accessing the members of an RPC call structure. */
#define rpc_call_xid(call) ((call)->rm_xid)
#define rpc_call_direction(call) ((call)->rm_direction)
#define rpc_call_rpcvers(call) ((call)->ru.RM_cmb.cb_rpcvers)
diff --git a/rpc/rpc-lib/src/xdr-rpcclnt.c b/rpc/rpc-lib/src/xdr-rpcclnt.c
index 416d19ffb..810d1961b 100644
--- a/rpc/rpc-lib/src/xdr-rpcclnt.c
+++ b/rpc/rpc-lib/src/xdr-rpcclnt.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
diff --git a/rpc/rpc-lib/src/xdr-rpcclnt.h b/rpc/rpc-lib/src/xdr-rpcclnt.h
index c0d925ee7..c08d872f8 100644
--- a/rpc/rpc-lib/src/xdr-rpcclnt.h
+++ b/rpc/rpc-lib/src/xdr-rpcclnt.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _XDR_RPCCLNT_H
@@ -33,7 +24,7 @@
#include <rpc/rpc_msg.h>
#include <rpc/auth_unix.h>
-/* Macros that simplify accesing the members of an RPC call structure. */
+/* Macros that simplify accessing the members of an RPC call structure. */
#define rpc_reply_xid(reply) ((reply)->rm_xid)
#define rpc_reply_status(reply) ((reply)->ru.RM_rmb.rp_stat)
#define rpc_accepted_reply_status(reply) ((reply)->acpted_rply.ar_stat)
diff --git a/rpc/rpc-transport/rdma/src/Makefile.am b/rpc/rpc-transport/rdma/src/Makefile.am
index bc888b175..b4b940bca 100644
--- a/rpc/rpc-transport/rdma/src/Makefile.am
+++ b/rpc/rpc-transport/rdma/src/Makefile.am
@@ -15,6 +15,6 @@ noinst_HEADERS = rdma.h name.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
-I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/rpc-lib/src/ \
- -I$(top_srcdir)/xlators/protocol/lib/src -shared -nostartfiles $(GF_CFLAGS)
+ -I$(top_srcdir)/rpc/xdr/src -shared -nostartfiles $(GF_CFLAGS)
CLEANFILES = *~
diff --git a/rpc/rpc-transport/rdma/src/name.c b/rpc/rpc-transport/rdma/src/name.c
index bc9b97e90..2085894b0 100644
--- a/rpc/rpc-transport/rdma/src/name.c
+++ b/rpc/rpc-transport/rdma/src/name.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <sys/types.h>
@@ -95,7 +86,7 @@ af_unix_client_bind (rpc_transport_t *this,
char *path = data_to_str (path_data);
if (!path || strlen (path) > UNIX_PATH_MAX) {
gf_log (this->name, GF_LOG_DEBUG,
- "transport.rdma.bind-path not specfied "
+ "transport.rdma.bind-path not specified "
"for unix socket, letting connect to assign "
"default value");
goto err;
@@ -162,13 +153,11 @@ client_fill_address_family (rpc_transport_t *this, struct sockaddr *sockaddr)
sockaddr->sa_family = AF_INET6;
} else if (!strcasecmp (address_family, "inet-sdp")) {
sockaddr->sa_family = AF_INET_SDP;
- } else if (!strcasecmp (address_family, "inet/inet6")
- || !strcasecmp (address_family, "inet6/inet")) {
- sockaddr->sa_family = AF_UNSPEC;
} else {
gf_log (this->name, GF_LOG_ERROR,
"unknown address-family (%s) specified",
address_family);
+ sockaddr->sa_family = AF_UNSPEC;
return -1;
}
}
@@ -363,6 +352,8 @@ af_inet_server_get_local_sockaddr (rpc_transport_t *this,
if (listen_port_data) {
listen_port = data_to_uint16 (listen_port_data);
} else {
+ listen_port = GF_DEFAULT_RDMA_LISTEN_PORT;
+
if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr;
in->sin6_addr = in6addr_any;
@@ -530,21 +521,19 @@ gf_rdma_server_get_local_sockaddr (rpc_transport_t *this,
addr->sa_family = AF_INET_SDP;
} else if (!strcasecmp (address_family, "unix")) {
addr->sa_family = AF_UNIX;
- } else if (!strcasecmp (address_family, "inet/inet6")
- || !strcasecmp (address_family, "inet6/inet")) {
- addr->sa_family = AF_UNSPEC;
} else {
gf_log (this->name, GF_LOG_ERROR,
"unknown address family (%s) specified",
address_family);
+ addr->sa_family = AF_UNSPEC;
ret = -1;
goto err;
}
} else {
gf_log (this->name, GF_LOG_DEBUG,
"option address-family not specified, defaulting "
- "to inet/inet6");
- addr->sa_family = AF_UNSPEC;
+ "to inet");
+ addr->sa_family = AF_INET;
}
switch (addr->sa_family)
@@ -577,40 +566,33 @@ fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *add
{
int32_t ret = 0, tmpaddr_len = 0;
char service[NI_MAXSERV], host[NI_MAXHOST];
- struct sockaddr_storage tmpaddr;
+ union gf_sock_union sock_union;
- memset (&tmpaddr, 0, sizeof (tmpaddr));
- tmpaddr = *addr;
+ memset (&sock_union, 0, sizeof (sock_union));
+ sock_union.storage = *addr;
tmpaddr_len = addr_len;
- if (((struct sockaddr *) &tmpaddr)->sa_family == AF_INET6) {
+ if (sock_union.sa.sa_family == AF_INET6) {
int32_t one_to_four, four_to_eight, twelve_to_sixteen;
int16_t eight_to_ten, ten_to_twelve;
one_to_four = four_to_eight = twelve_to_sixteen = 0;
eight_to_ten = ten_to_twelve = 0;
- one_to_four = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr32[0];
- four_to_eight = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr32[1];
+ one_to_four = sock_union.sin6.sin6_addr.s6_addr32[0];
+ four_to_eight = sock_union.sin6.sin6_addr.s6_addr32[1];
#ifdef GF_SOLARIS_HOST_OS
- eight_to_ten = S6_ADDR16(((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr)[4];
+ eight_to_ten = S6_ADDR16(sock_union.sin6.sin6_addr)[4];
#else
- eight_to_ten = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr16[4];
+ eight_to_ten = sock_union.sin6.sin6_addr.s6_addr16[4];
#endif
#ifdef GF_SOLARIS_HOST_OS
- ten_to_twelve = S6_ADDR16(((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr)[5];
+ ten_to_twelve = S6_ADDR16(sock_union.sin6.sin6_addr)[5];
#else
- ten_to_twelve = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr16[5];
+ ten_to_twelve = sock_union.sin6.sin6_addr.s6_addr16[5];
#endif
- twelve_to_sixteen = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr32[3];
+ twelve_to_sixteen = sock_union.sin6.sin6_addr.s6_addr32[3];
/* ipv4 mapped ipv6 address has
bits 0-80: 0
@@ -622,8 +604,8 @@ fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *add
four_to_eight == 0 &&
eight_to_ten == 0 &&
ten_to_twelve == -1) {
- struct sockaddr_in *in_ptr = (struct sockaddr_in *)&tmpaddr;
- memset (&tmpaddr, 0, sizeof (tmpaddr));
+ struct sockaddr_in *in_ptr = &sock_union.sin;
+ memset (&sock_union, 0, sizeof (sock_union));
in_ptr->sin_family = AF_INET;
in_ptr->sin_port = ((struct sockaddr_in6 *)addr)->sin6_port;
@@ -632,7 +614,7 @@ fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *add
}
}
- ret = getnameinfo ((struct sockaddr *) &tmpaddr,
+ ret = getnameinfo (&sock_union.sa,
tmpaddr_len,
host, sizeof (host),
service, sizeof (service),
diff --git a/rpc/rpc-transport/rdma/src/name.h b/rpc/rpc-transport/rdma/src/name.h
index adde7788e..114ed1661 100644
--- a/rpc/rpc-transport/rdma/src/name.h
+++ b/rpc/rpc-transport/rdma/src/name.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _IB_VERBS_NAME_H
diff --git a/rpc/rpc-transport/rdma/src/rdma.c b/rpc/rpc-transport/rdma/src/rdma.c
index 7d2bfc0ad..a014a9ead 100644
--- a/rpc/rpc-transport/rdma/src/rdma.c
+++ b/rpc/rpc-transport/rdma/src/rdma.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -30,18 +21,19 @@
#include "name.h"
#include "byte-order.h"
#include "xlator.h"
+#include "xdr-rpc.h"
#include <signal.h>
-#define RDMA_LOG_NAME "rpc-transport/rdma"
+#define GF_RDMA_LOG_NAME "rpc-transport/rdma"
static int32_t
-__rdma_ioq_churn (rdma_peer_t *peer);
+__gf_rdma_ioq_churn (gf_rdma_peer_t *peer);
-rdma_post_t *
-rdma_post_ref (rdma_post_t *post);
+gf_rdma_post_t *
+gf_rdma_post_ref (gf_rdma_post_t *post);
int
-rdma_post_unref (rdma_post_t *post);
+gf_rdma_post_unref (gf_rdma_post_t *post);
int32_t
gf_resolve_ip6 (const char *hostname,
@@ -51,8 +43,8 @@ gf_resolve_ip6 (const char *hostname,
struct addrinfo **addr_info);
static uint16_t
-rdma_get_local_lid (struct ibv_context *context,
- int32_t port)
+gf_rdma_get_local_lid (struct ibv_context *context,
+ int32_t port)
{
struct ibv_port_attr attr;
@@ -78,13 +70,12 @@ get_port_state_str(enum ibv_port_state pstate)
static int32_t
ib_check_active_port (struct ibv_context *ctx, uint8_t port)
{
- struct ibv_port_attr port_attr;
-
- int32_t ret = 0;
- const char *state_str = NULL;
+ struct ibv_port_attr port_attr = {0, };
+ int32_t ret = 0;
+ const char *state_str = NULL;
if (!ctx) {
- gf_log_callingfn (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log_callingfn (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"Error in supplied context");
return -1;
}
@@ -92,13 +83,13 @@ ib_check_active_port (struct ibv_context *ctx, uint8_t port)
ret = ibv_query_port (ctx, port, &port_attr);
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"Failed to query port %u properties", port);
return -1;
}
state_str = get_port_state_str (port_attr.state);
- gf_log (RDMA_LOG_NAME, GF_LOG_TRACE,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_TRACE,
"Infiniband PORT: (%u) STATE: (%s)",
port, state_str);
@@ -111,18 +102,17 @@ ib_check_active_port (struct ibv_context *ctx, uint8_t port)
static int32_t
ib_get_active_port (struct ibv_context *ib_ctx)
{
- struct ibv_device_attr ib_device_attr;
-
- int32_t ret = -1;
- uint8_t ib_port = 0;
+ struct ibv_device_attr ib_device_attr = {{0, }, };
+ int32_t ret = -1;
+ uint8_t ib_port = 0;
if (!ib_ctx) {
- gf_log_callingfn (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log_callingfn (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"Error in supplied context");
return -1;
}
if (ibv_query_device (ib_ctx, &ib_device_attr)) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"Failed to query device properties");
return -1;
}
@@ -132,7 +122,7 @@ ib_get_active_port (struct ibv_context *ib_ctx)
if (ret == 0)
return ib_port;
- gf_log (RDMA_LOG_NAME, GF_LOG_TRACE,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_TRACE,
"Port:(%u) not active", ib_port);
continue;
}
@@ -141,8 +131,7 @@ ib_get_active_port (struct ibv_context *ib_ctx)
static void
-rdma_put_post (rdma_queue_t *queue,
- rdma_post_t *post)
+gf_rdma_put_post (gf_rdma_queue_t *queue, gf_rdma_post_t *post)
{
post->ctx.is_request = 0;
@@ -167,14 +156,15 @@ rdma_put_post (rdma_queue_t *queue,
}
-static rdma_post_t *
-rdma_new_post (rdma_device_t *device, int32_t len, rdma_post_type_t type)
+static gf_rdma_post_t *
+gf_rdma_new_post (gf_rdma_device_t *device, int32_t len,
+ gf_rdma_post_type_t type)
{
- rdma_post_t *post = NULL;
- int ret = -1;
+ gf_rdma_post_t *post = NULL;
+ int ret = -1;
- post = (rdma_post_t *) GF_CALLOC (1, sizeof (*post),
- gf_common_mt_rdma_post_t);
+ post = (gf_rdma_post_t *) GF_CALLOC (1, sizeof (*post),
+ gf_common_mt_rdma_post_t);
if (post == NULL) {
goto out;
}
@@ -185,7 +175,7 @@ rdma_new_post (rdma_device_t *device, int32_t len, rdma_post_type_t type)
post->buf = valloc (len);
if (!post->buf) {
- gf_log_nomem (RDMA_LOG_NAME, GF_LOG_ERROR, len);
+ gf_log_nomem (GF_RDMA_LOG_NAME, GF_LOG_ERROR, len);
goto out;
}
@@ -194,8 +184,9 @@ rdma_new_post (rdma_device_t *device, int32_t len, rdma_post_type_t type)
post->buf_size,
IBV_ACCESS_LOCAL_WRITE);
if (!post->mr) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
- "memory registration failed");
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "memory registration failed (%s)",
+ strerror (errno));
goto out;
}
@@ -217,10 +208,10 @@ out:
}
-static rdma_post_t *
-rdma_get_post (rdma_queue_t *queue)
+static gf_rdma_post_t *
+gf_rdma_get_post (gf_rdma_queue_t *queue)
{
- rdma_post_t *post;
+ gf_rdma_post_t *post = NULL;
pthread_mutex_lock (&queue->lock);
{
@@ -247,7 +238,7 @@ rdma_get_post (rdma_queue_t *queue)
}
void
-rdma_destroy_post (rdma_post_t *post)
+gf_rdma_destroy_post (gf_rdma_post_t *post)
{
ibv_dereg_mr (post->mr);
free (post->buf);
@@ -256,10 +247,12 @@ rdma_destroy_post (rdma_post_t *post)
static int32_t
-__rdma_quota_get (rdma_peer_t *peer)
+__gf_rdma_quota_get (gf_rdma_peer_t *peer)
{
- int32_t ret = -1;
- rdma_private_t *priv = peer->trans->private;
+ int32_t ret = -1;
+ gf_rdma_private_t *priv = NULL;
+
+ priv = peer->trans->private;
if (priv->connected && peer->quota > 0) {
ret = peer->quota--;
@@ -270,14 +263,14 @@ __rdma_quota_get (rdma_peer_t *peer)
/*
static int32_t
- rdma_quota_get (rdma_peer_t *peer)
+ gf_rdma_quota_get (gf_rdma_peer_t *peer)
{
int32_t ret = -1;
- rdma_private_t *priv = peer->trans->private;
+ gf_rdma_private_t *priv = peer->trans->private;
pthread_mutex_lock (&priv->write_mutex);
{
- ret = __rdma_quota_get (peer);
+ ret = __gf_rdma_quota_get (peer);
}
pthread_mutex_unlock (&priv->write_mutex);
@@ -286,7 +279,7 @@ __rdma_quota_get (rdma_peer_t *peer)
*/
static void
-__rdma_ioq_entry_free (rdma_ioq_t *entry)
+__gf_rdma_ioq_entry_free (gf_rdma_ioq_t *entry)
{
list_del_init (&entry->list);
@@ -299,36 +292,38 @@ __rdma_ioq_entry_free (rdma_ioq_t *entry)
iobref_unref (entry->msg.request.rsp_iobref);
entry->msg.request.rsp_iobref = NULL;
}
- /* TODO: use mem-pool */
- mem_put (entry->pool, entry);
+ mem_put (entry);
}
static void
-__rdma_ioq_flush (rdma_peer_t *peer)
+__gf_rdma_ioq_flush (gf_rdma_peer_t *peer)
{
- rdma_ioq_t *entry = NULL, *dummy = NULL;
+ gf_rdma_ioq_t *entry = NULL, *dummy = NULL;
list_for_each_entry_safe (entry, dummy, &peer->ioq, list) {
- __rdma_ioq_entry_free (entry);
+ __gf_rdma_ioq_entry_free (entry);
}
}
static int32_t
-__rdma_disconnect (rpc_transport_t *this)
+__gf_rdma_disconnect (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- int32_t ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ int32_t ret = 0;
+
+ priv = this->private;
if (priv->connected || priv->tcp_connected) {
fcntl (priv->sock, F_SETFL, O_NONBLOCK);
if (shutdown (priv->sock, SHUT_RDWR) != 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
"shutdown () - error: %s",
strerror (errno));
ret = -errno;
priv->tcp_connected = 0;
+ priv->connected = 0;
}
}
@@ -337,9 +332,7 @@ __rdma_disconnect (rpc_transport_t *this)
static int32_t
-rdma_post_send (struct ibv_qp *qp,
- rdma_post_t *post,
- int32_t len)
+gf_rdma_post_send (struct ibv_qp *qp, gf_rdma_post_t *post, int32_t len)
{
struct ibv_sge list = {
.addr = (unsigned long) post->buf,
@@ -362,63 +355,64 @@ rdma_post_send (struct ibv_qp *qp,
}
int
-__rdma_encode_error(rdma_peer_t *peer, rdma_reply_info_t *reply_info,
- struct iovec *rpchdr, uint32_t *ptr,
- rdma_errcode_t err)
+__gf_rdma_encode_error(gf_rdma_peer_t *peer, gf_rdma_reply_info_t *reply_info,
+ struct iovec *rpchdr, gf_rdma_header_t *hdr,
+ gf_rdma_errcode_t err)
{
- uint32_t *startp = NULL;
struct rpc_msg *rpc_msg = NULL;
- startp = ptr;
if (reply_info != NULL) {
- *ptr++ = hton32(reply_info->rm_xid);
+ hdr->rm_xid = hton32(reply_info->rm_xid);
} else {
rpc_msg = rpchdr[0].iov_base; /* assume rpchdr contains
* only one vector.
* (which is true)
*/
- *ptr++ = rpc_msg->rm_xid;
+ hdr->rm_xid = rpc_msg->rm_xid;
}
- *ptr++ = hton32(RDMA_VERSION);
- *ptr++ = hton32(peer->send_count);
- *ptr++ = hton32(RDMA_ERROR);
- *ptr++ = hton32(err);
+ hdr->rm_vers = hton32(GF_RDMA_VERSION);
+ hdr->rm_credit = hton32(peer->send_count);
+ hdr->rm_type = hton32(GF_RDMA_ERROR);
+ hdr->rm_body.rm_error.rm_type = hton32(err);
if (err == ERR_VERS) {
- *ptr++ = hton32(RDMA_VERSION);
- *ptr++ = hton32(RDMA_VERSION);
+ hdr->rm_body.rm_error.rm_version.gf_rdma_vers_low
+ = hton32(GF_RDMA_VERSION);
+ hdr->rm_body.rm_error.rm_version.gf_rdma_vers_high
+ = hton32(GF_RDMA_VERSION);
}
- return (int)((unsigned long)ptr - (unsigned long)startp);
+ return sizeof (*hdr);
}
int32_t
-__rdma_send_error (rdma_peer_t *peer, rdma_ioq_t *entry, rdma_post_t *post,
- rdma_reply_info_t *reply_info, rdma_errcode_t err)
+__gf_rdma_send_error (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry,
+ gf_rdma_post_t *post, gf_rdma_reply_info_t *reply_info,
+ gf_rdma_errcode_t err)
{
- int32_t ret = -1, len;
+ int32_t ret = -1, len = 0;
- len = __rdma_encode_error (peer, reply_info, entry->rpchdr,
- (uint32_t *)post->buf, err);
+ len = __gf_rdma_encode_error (peer, reply_info, entry->rpchdr,
+ (gf_rdma_header_t *)post->buf, err);
if (len == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"encode error returned -1");
goto out;
}
- rdma_post_ref (post);
+ gf_rdma_post_ref (post);
- ret = rdma_post_send (peer->qp, post, len);
+ ret = gf_rdma_post_send (peer->qp, post, len);
if (!ret) {
ret = len;
} else {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
- "rdma_post_send (to %s) failed with ret = %d (%s)",
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "gf_rdma_post_send (to %s) failed with ret = %d (%s)",
peer->trans->peerinfo.identifier, ret,
(ret > 0) ? strerror (ret) : "");
- rdma_post_unref (post);
- __rdma_disconnect (peer->trans);
+ gf_rdma_post_unref (post);
+ __gf_rdma_disconnect (peer->trans);
ret = -1;
}
@@ -428,24 +422,24 @@ out:
int32_t
-__rdma_create_read_chunks_from_vector (rdma_peer_t *peer,
- rdma_read_chunk_t **readch_ptr,
- int32_t *pos, struct iovec *vector,
- int count,
- rdma_request_context_t *request_ctx)
+__gf_rdma_create_read_chunks_from_vector (gf_rdma_peer_t *peer,
+ gf_rdma_read_chunk_t **readch_ptr,
+ int32_t *pos, struct iovec *vector,
+ int count,
+ gf_rdma_request_context_t *request_ctx)
{
- int i = 0;
- rdma_private_t *priv = NULL;
- rdma_device_t *device = NULL;
- struct ibv_mr *mr = NULL;
- rdma_read_chunk_t *readch = NULL;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, peer, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, readch_ptr, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, *readch_ptr, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, request_ctx, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, vector, out);
+ int i = 0;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_device_t *device = NULL;
+ struct ibv_mr *mr = NULL;
+ gf_rdma_read_chunk_t *readch = NULL;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, peer, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, readch_ptr, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, *readch_ptr, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, request_ctx, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, vector, out);
priv = peer->trans->private;
device = priv->device;
@@ -459,8 +453,10 @@ __rdma_create_read_chunks_from_vector (rdma_peer_t *peer,
vector[i].iov_len,
IBV_ACCESS_REMOTE_READ);
if (!mr) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
- "memory registration failed");
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "memory registration failed (%s) (peer:%s)",
+ strerror (errno),
+ peer->trans->peerinfo.identifier);
goto out;
}
@@ -485,77 +481,72 @@ out:
int32_t
-__rdma_create_read_chunks (rdma_peer_t *peer, rdma_ioq_t *entry,
- rdma_chunktype_t type, uint32_t **ptr,
- rdma_request_context_t *request_ctx)
+__gf_rdma_create_read_chunks (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry,
+ gf_rdma_chunktype_t type, uint32_t **ptr,
+ gf_rdma_request_context_t *request_ctx)
{
int32_t ret = -1;
- rdma_device_t *device = NULL;
- rdma_private_t *priv = NULL;
int pos = 0;
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, peer, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, entry, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, ptr, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, *ptr, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, request_ctx, out);
-
- priv = peer->trans->private;
- device = priv->device;
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, peer, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, entry, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, ptr, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, *ptr, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, request_ctx, out);
request_ctx->iobref = iobref_ref (entry->iobref);
- if (type == rdma_areadch) {
+ if (type == gf_rdma_areadch) {
pos = 0;
- ret = __rdma_create_read_chunks_from_vector (peer,
- (rdma_read_chunk_t **)ptr,
- &pos,
- entry->rpchdr,
- entry->rpchdr_count,
- request_ctx);
+ ret = __gf_rdma_create_read_chunks_from_vector (peer,
+ (gf_rdma_read_chunk_t **)ptr,
+ &pos,
+ entry->rpchdr,
+ entry->rpchdr_count,
+ request_ctx);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
- "cannot create read chunks from vector, "
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot create read chunks from vector "
"entry->rpchdr");
goto out;
}
- ret = __rdma_create_read_chunks_from_vector (peer,
- (rdma_read_chunk_t **)ptr,
- &pos,
- entry->proghdr,
- entry->proghdr_count,
- request_ctx);
+ ret = __gf_rdma_create_read_chunks_from_vector (peer,
+ (gf_rdma_read_chunk_t **)ptr,
+ &pos,
+ entry->proghdr,
+ entry->proghdr_count,
+ request_ctx);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
- "cannot create read chunks from vector, "
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot create read chunks from vector "
"entry->proghdr");
}
if (entry->prog_payload_count != 0) {
- ret = __rdma_create_read_chunks_from_vector (peer,
- (rdma_read_chunk_t **)ptr,
- &pos,
- entry->prog_payload,
- entry->prog_payload_count,
- request_ctx);
+ ret = __gf_rdma_create_read_chunks_from_vector (peer,
+ (gf_rdma_read_chunk_t **)ptr,
+ &pos,
+ entry->prog_payload,
+ entry->prog_payload_count,
+ request_ctx);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
- "cannot create read chunks from vector,"
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot create read chunks from vector"
" entry->prog_payload");
}
}
} else {
pos = iov_length (entry->rpchdr, entry->rpchdr_count);
- ret = __rdma_create_read_chunks_from_vector (peer,
- (rdma_read_chunk_t **)ptr,
- &pos,
- entry->prog_payload,
- entry->prog_payload_count,
- request_ctx);
+ ret = __gf_rdma_create_read_chunks_from_vector (peer,
+ (gf_rdma_read_chunk_t **)ptr,
+ &pos,
+ entry->prog_payload,
+ entry->prog_payload_count,
+ request_ctx);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
- "cannot create read chunks from vector, "
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot create read chunks from vector "
"entry->prog_payload");
}
}
@@ -569,23 +560,23 @@ out:
int32_t
-__rdma_create_write_chunks_from_vector (rdma_peer_t *peer,
- rdma_write_chunk_t **writech_ptr,
- struct iovec *vector, int count,
- rdma_request_context_t *request_ctx)
+__gf_rdma_create_write_chunks_from_vector (gf_rdma_peer_t *peer,
+ gf_rdma_write_chunk_t **writech_ptr,
+ struct iovec *vector, int count,
+ gf_rdma_request_context_t *request_ctx)
{
- int i = 0;
- rdma_private_t *priv = NULL;
- rdma_device_t *device = NULL;
- struct ibv_mr *mr = NULL;
- rdma_write_chunk_t *writech = NULL;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, peer, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, writech_ptr, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, *writech_ptr, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, request_ctx, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, vector, out);
+ int i = 0;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_device_t *device = NULL;
+ struct ibv_mr *mr = NULL;
+ gf_rdma_write_chunk_t *writech = NULL;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, peer, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, writech_ptr, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, *writech_ptr, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, request_ctx, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, vector, out);
writech = *writech_ptr;
@@ -598,8 +589,10 @@ __rdma_create_write_chunks_from_vector (rdma_peer_t *peer,
IBV_ACCESS_REMOTE_WRITE
| IBV_ACCESS_LOCAL_WRITE);
if (!mr) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
- "memory registration failed");
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "memory registration failed (%s) (peer:%s)",
+ strerror (errno),
+ peer->trans->peerinfo.identifier);
goto out;
}
@@ -622,23 +615,23 @@ out:
int32_t
-__rdma_create_write_chunks (rdma_peer_t *peer, rdma_ioq_t *entry,
- rdma_chunktype_t chunk_type, uint32_t **ptr,
- rdma_request_context_t *request_ctx)
+__gf_rdma_create_write_chunks (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry,
+ gf_rdma_chunktype_t chunk_type, uint32_t **ptr,
+ gf_rdma_request_context_t *request_ctx)
{
- int32_t ret = -1;
- rdma_write_array_t *warray = NULL;
+ int32_t ret = -1;
+ gf_rdma_write_array_t *warray = NULL;
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, peer, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, ptr, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, *ptr, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, request_ctx, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, entry, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, peer, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, ptr, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, *ptr, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, request_ctx, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, entry, out);
- if ((chunk_type == rdma_replych)
+ if ((chunk_type == gf_rdma_replych)
&& ((entry->msg.request.rsphdr_count != 1) ||
(entry->msg.request.rsphdr_vec[0].iov_base == NULL))) {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
(entry->msg.request.rsphdr_count == 1)
? "chunktype specified as reply chunk but the vector "
"specifying the buffer to be used for holding reply"
@@ -649,10 +642,10 @@ __rdma_create_write_chunks (rdma_peer_t *peer, rdma_ioq_t *entry,
}
/*
- if ((chunk_type == rdma_writech)
+ if ((chunk_type == gf_rdma_writech)
&& ((entry->msg.request.rsphdr_count == 0)
|| (entry->msg.request.rsphdr_vec[0].iov_base == NULL))) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
"vector specifying buffer to hold the program's reply "
"header should also be provided when buffers are "
"provided for holding the program's payload in reply");
@@ -660,21 +653,21 @@ __rdma_create_write_chunks (rdma_peer_t *peer, rdma_ioq_t *entry,
}
*/
- if (chunk_type == rdma_writech) {
- warray = (rdma_write_array_t *)*ptr;
+ if (chunk_type == gf_rdma_writech) {
+ warray = (gf_rdma_write_array_t *)*ptr;
warray->wc_discrim = hton32 (1);
warray->wc_nchunks
= hton32 (entry->msg.request.rsp_payload_count);
*ptr = (uint32_t *)&warray->wc_array[0];
- ret = __rdma_create_write_chunks_from_vector (peer,
- (rdma_write_chunk_t **)ptr,
- entry->msg.request.rsp_payload,
- entry->msg.request.rsp_payload_count,
- request_ctx);
+ ret = __gf_rdma_create_write_chunks_from_vector (peer,
+ (gf_rdma_write_chunk_t **)ptr,
+ entry->msg.request.rsp_payload,
+ entry->msg.request.rsp_payload_count,
+ request_ctx);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"cannot create write chunks from vector "
"entry->rpc_payload");
goto out;
@@ -692,19 +685,19 @@ __rdma_create_write_chunks (rdma_peer_t *peer, rdma_ioq_t *entry,
**ptr = 0;
*ptr = *ptr + 1;
- warray = (rdma_write_array_t *)*ptr;
+ warray = (gf_rdma_write_array_t *)*ptr;
warray->wc_discrim = hton32 (1);
warray->wc_nchunks = hton32 (entry->msg.request.rsphdr_count);
*ptr = (uint32_t *)&warray->wc_array[0];
- ret = __rdma_create_write_chunks_from_vector (peer,
- (rdma_write_chunk_t **)ptr,
- entry->msg.request.rsphdr_vec,
- entry->msg.request.rsphdr_count,
- request_ctx);
+ ret = __gf_rdma_create_write_chunks_from_vector (peer,
+ (gf_rdma_write_chunk_t **)ptr,
+ entry->msg.request.rsphdr_vec,
+ entry->msg.request.rsphdr_count,
+ request_ctx);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"cannot create write chunks from vector "
"entry->rpchdr");
goto out;
@@ -721,7 +714,7 @@ out:
inline void
-__rdma_deregister_mr (struct ibv_mr **mr, int count)
+__gf_rdma_deregister_mr (struct ibv_mr **mr, int count)
{
int i = 0;
@@ -739,15 +732,15 @@ out:
static int32_t
-__rdma_quota_put (rdma_peer_t *peer)
+__gf_rdma_quota_put (gf_rdma_peer_t *peer)
{
- int32_t ret;
+ int32_t ret = 0;
peer->quota++;
ret = peer->quota;
if (!list_empty (&peer->ioq)) {
- ret = __rdma_ioq_churn (peer);
+ ret = __gf_rdma_ioq_churn (peer);
}
return ret;
@@ -755,14 +748,15 @@ __rdma_quota_put (rdma_peer_t *peer)
static int32_t
-rdma_quota_put (rdma_peer_t *peer)
+gf_rdma_quota_put (gf_rdma_peer_t *peer)
{
- int32_t ret;
- rdma_private_t *priv = peer->trans->private;
+ int32_t ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ priv = peer->trans->private;
pthread_mutex_lock (&priv->write_mutex);
{
- ret = __rdma_quota_put (peer);
+ ret = __gf_rdma_quota_put (peer);
}
pthread_mutex_unlock (&priv->write_mutex);
@@ -772,11 +766,11 @@ rdma_quota_put (rdma_peer_t *peer)
/* to be called with priv->mutex held */
void
-__rdma_request_context_destroy (rdma_request_context_t *context)
+__gf_rdma_request_context_destroy (gf_rdma_request_context_t *context)
{
- rdma_peer_t *peer = NULL;
- rdma_private_t *priv = NULL;
- int32_t ret = 0;
+ gf_rdma_peer_t *peer = NULL;
+ gf_rdma_private_t *priv = NULL;
+ int32_t ret = 0;
if (context == NULL) {
goto out;
@@ -784,18 +778,18 @@ __rdma_request_context_destroy (rdma_request_context_t *context)
peer = context->peer;
- __rdma_deregister_mr (context->mr, context->mr_count);
+ __gf_rdma_deregister_mr (context->mr, context->mr_count);
priv = peer->trans->private;
if (priv->connected) {
- ret = __rdma_quota_put (peer);
+ ret = __gf_rdma_quota_put (peer);
if (ret < 0) {
gf_log ("rdma", GF_LOG_DEBUG,
"failed to send "
"message");
- mem_put (context->pool, context);
- __rdma_disconnect (peer->trans);
+ mem_put (context);
+ __gf_rdma_disconnect (peer->trans);
goto out;
}
}
@@ -810,22 +804,21 @@ __rdma_request_context_destroy (rdma_request_context_t *context)
context->rsp_iobref = NULL;
}
- mem_put (context->pool, context);
+ mem_put (context);
out:
return;
}
-
void
-rdma_post_context_destroy (rdma_post_context_t *ctx)
+gf_rdma_post_context_destroy (gf_rdma_post_context_t *ctx)
{
if (ctx == NULL) {
goto out;
}
- __rdma_deregister_mr (ctx->mr, ctx->mr_count);
+ __gf_rdma_deregister_mr (ctx->mr, ctx->mr_count);
if (ctx->iobref != NULL) {
iobref_unref (ctx->iobref);
@@ -842,8 +835,8 @@ out:
static int32_t
-rdma_post_recv (struct ibv_srq *srq,
- rdma_post_t *post)
+gf_rdma_post_recv (struct ibv_srq *srq,
+ gf_rdma_post_t *post)
{
struct ibv_sge list = {
.addr = (unsigned long) post->buf,
@@ -857,14 +850,14 @@ rdma_post_recv (struct ibv_srq *srq,
.num_sge = 1,
}, *bad_wr;
- rdma_post_ref (post);
+ gf_rdma_post_ref (post);
return ibv_post_srq_recv (srq, &wr, &bad_wr);
}
int
-rdma_post_unref (rdma_post_t *post)
+gf_rdma_post_unref (gf_rdma_post_t *post)
{
int refcount = -1;
@@ -879,11 +872,11 @@ rdma_post_unref (rdma_post_t *post)
pthread_mutex_unlock (&post->lock);
if (refcount == 0) {
- rdma_post_context_destroy (&post->ctx);
- if (post->type == RDMA_SEND_POST) {
- rdma_put_post (&post->device->sendq, post);
+ gf_rdma_post_context_destroy (&post->ctx);
+ if (post->type == GF_RDMA_SEND_POST) {
+ gf_rdma_put_post (&post->device->sendq, post);
} else {
- rdma_post_recv (post->device->srq, post);
+ gf_rdma_post_recv (post->device->srq, post);
}
}
out:
@@ -892,7 +885,7 @@ out:
int
-rdma_post_get_refcount (rdma_post_t *post)
+gf_rdma_post_get_refcount (gf_rdma_post_t *post)
{
int refcount = -1;
@@ -910,8 +903,8 @@ out:
return refcount;
}
-rdma_post_t *
-rdma_post_ref (rdma_post_t *post)
+gf_rdma_post_t *
+gf_rdma_post_ref (gf_rdma_post_t *post)
{
if (post == NULL) {
goto out;
@@ -929,31 +922,32 @@ out:
int32_t
-__rdma_ioq_churn_request (rdma_peer_t *peer, rdma_ioq_t *entry,
- rdma_post_t *post)
+__gf_rdma_ioq_churn_request (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry,
+ gf_rdma_post_t *post)
{
- rdma_chunktype_t rtype = rdma_noch, wtype = rdma_noch;
- uint64_t send_size = 0;
- rdma_header_t *hdr = NULL;
- struct rpc_msg *rpc_msg = NULL;
- uint32_t *chunkptr = NULL;
- char *buf = NULL;
- int32_t ret = 0;
- rdma_private_t *priv = NULL;
- rdma_device_t *device = NULL;
- int chunk_count = 0;
- rdma_request_context_t *request_ctx = NULL;
- uint32_t prog_payload_length = 0, len = 0;
- struct rpc_req *rpc_req = NULL;
-
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, peer, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, entry, out);
- GF_VALIDATE_OR_GOTO (RDMA_LOG_NAME, post, out);
+ gf_rdma_chunktype_t rtype = gf_rdma_noch;
+ gf_rdma_chunktype_t wtype = gf_rdma_noch;
+ uint64_t send_size = 0;
+ gf_rdma_header_t *hdr = NULL;
+ struct rpc_msg *rpc_msg = NULL;
+ uint32_t *chunkptr = NULL;
+ char *buf = NULL;
+ int32_t ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_device_t *device = NULL;
+ int chunk_count = 0;
+ gf_rdma_request_context_t *request_ctx = NULL;
+ uint32_t prog_payload_length = 0, len = 0;
+ struct rpc_req *rpc_req = NULL;
+
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, peer, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, entry, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, post, out);
if ((entry->msg.request.rsphdr_count != 0)
&& (entry->msg.request.rsp_payload_count != 0)) {
ret = -1;
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"both write-chunklist and reply-chunk cannot be "
"present");
goto out;
@@ -963,7 +957,7 @@ __rdma_ioq_churn_request (rdma_peer_t *peer, rdma_ioq_t *entry,
priv = peer->trans->private;
device = priv->device;
- hdr = (rdma_header_t *)post->buf;
+ hdr = (gf_rdma_header_t *)post->buf;
send_size = iov_length (entry->rpchdr, entry->rpchdr_count)
+ iov_length (entry->proghdr, entry->proghdr_count)
@@ -976,43 +970,43 @@ __rdma_ioq_churn_request (rdma_peer_t *peer, rdma_ioq_t *entry,
}
if (send_size > GLUSTERFS_RDMA_INLINE_THRESHOLD) {
- rtype = rdma_areadch;
+ rtype = gf_rdma_areadch;
} else if ((send_size + prog_payload_length)
< GLUSTERFS_RDMA_INLINE_THRESHOLD) {
- rtype = rdma_noch;
+ rtype = gf_rdma_noch;
} else if (entry->prog_payload_count != 0) {
- rtype = rdma_readch;
+ rtype = gf_rdma_readch;
}
if (entry->msg.request.rsphdr_count != 0) {
- wtype = rdma_replych;
+ wtype = gf_rdma_replych;
} else if (entry->msg.request.rsp_payload_count != 0) {
- wtype = rdma_writech;
+ wtype = gf_rdma_writech;
}
- if (rtype == rdma_readch) {
+ if (rtype == gf_rdma_readch) {
chunk_count += entry->prog_payload_count;
- } else if (rtype == rdma_areadch) {
+ } else if (rtype == gf_rdma_areadch) {
chunk_count += entry->rpchdr_count;
chunk_count += entry->proghdr_count;
}
- if (wtype == rdma_writech) {
+ if (wtype == gf_rdma_writech) {
chunk_count += entry->msg.request.rsp_payload_count;
- } else if (wtype == rdma_replych) {
+ } else if (wtype == gf_rdma_replych) {
chunk_count += entry->msg.request.rsphdr_count;
}
- if (chunk_count > RDMA_MAX_SEGMENTS) {
+ if (chunk_count > GF_RDMA_MAX_SEGMENTS) {
ret = -1;
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"chunk count(%d) exceeding maximum allowed RDMA "
- "segment count(%d)", chunk_count, RDMA_MAX_SEGMENTS);
+ "segment count(%d)", chunk_count, GF_RDMA_MAX_SEGMENTS);
goto out;
}
- if ((wtype != rdma_noch) || (rtype != rdma_noch)) {
- request_ctx = mem_get (priv->device->request_ctx_pool);
+ if ((wtype != gf_rdma_noch) || (rtype != gf_rdma_noch)) {
+ request_ctx = mem_get (device->request_ctx_pool);
if (request_ctx == NULL) {
ret = -1;
goto out;
@@ -1020,7 +1014,7 @@ __rdma_ioq_churn_request (rdma_peer_t *peer, rdma_ioq_t *entry,
memset (request_ctx, 0, sizeof (*request_ctx));
- request_ctx->pool = priv->device->request_ctx_pool;
+ request_ctx->pool = device->request_ctx_pool;
request_ctx->peer = peer;
entry->msg.request.rpc_req->conn_private = request_ctx;
@@ -1037,20 +1031,21 @@ __rdma_ioq_churn_request (rdma_peer_t *peer, rdma_ioq_t *entry,
* since rpc_msg->rm_xid is already
* hton32ed value of actual xid
*/
- hdr->rm_vers = hton32 (RDMA_VERSION);
+ hdr->rm_vers = hton32 (GF_RDMA_VERSION);
hdr->rm_credit = hton32 (peer->send_count);
- if (rtype == rdma_areadch) {
- hdr->rm_type = hton32 (RDMA_NOMSG);
+ if (rtype == gf_rdma_areadch) {
+ hdr->rm_type = hton32 (GF_RDMA_NOMSG);
} else {
- hdr->rm_type = hton32 (RDMA_MSG);
+ hdr->rm_type = hton32 (GF_RDMA_MSG);
}
chunkptr = &hdr->rm_body.rm_chunks[0];
- if (rtype != rdma_noch) {
- ret = __rdma_create_read_chunks (peer, entry, rtype, &chunkptr,
- request_ctx);
+ if (rtype != gf_rdma_noch) {
+ ret = __gf_rdma_create_read_chunks (peer, entry, rtype,
+ &chunkptr,
+ request_ctx);
if (ret != 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"creation of read chunks failed");
goto out;
}
@@ -1058,11 +1053,12 @@ __rdma_ioq_churn_request (rdma_peer_t *peer, rdma_ioq_t *entry,
*chunkptr++ = 0; /* no read chunks */
}
- if (wtype != rdma_noch) {
- ret = __rdma_create_write_chunks (peer, entry, wtype, &chunkptr,
- request_ctx);
+ if (wtype != gf_rdma_noch) {
+ ret = __gf_rdma_create_write_chunks (peer, entry, wtype,
+ &chunkptr,
+ request_ctx);
if (ret != 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"creation of write/reply chunk failed");
goto out;
}
@@ -1073,14 +1069,14 @@ __rdma_ioq_churn_request (rdma_peer_t *peer, rdma_ioq_t *entry,
buf = (char *)chunkptr;
- if (rtype != rdma_areadch) {
+ if (rtype != gf_rdma_areadch) {
iov_unload (buf, entry->rpchdr, entry->rpchdr_count);
buf += iov_length (entry->rpchdr, entry->rpchdr_count);
iov_unload (buf, entry->proghdr, entry->proghdr_count);
buf += iov_length (entry->proghdr, entry->proghdr_count);
- if (rtype != rdma_readch) {
+ if (rtype != gf_rdma_readch) {
iov_unload (buf, entry->prog_payload,
entry->prog_payload_count);
buf += iov_length (entry->prog_payload,
@@ -1090,18 +1086,18 @@ __rdma_ioq_churn_request (rdma_peer_t *peer, rdma_ioq_t *entry,
len = buf - post->buf;
- rdma_post_ref (post);
+ gf_rdma_post_ref (post);
- ret = rdma_post_send (peer->qp, post, len);
+ ret = gf_rdma_post_send (peer->qp, post, len);
if (!ret) {
ret = len;
} else {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
- "rdma_post_send (to %s) failed with ret = %d (%s)",
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "gf_rdma_post_send (to %s) failed with ret = %d (%s)",
peer->trans->peerinfo.identifier, ret,
(ret > 0) ? strerror (ret) : "");
- rdma_post_unref (post);
- __rdma_disconnect (peer->trans);
+ gf_rdma_post_unref (post);
+ __gf_rdma_disconnect (peer->trans);
ret = -1;
}
@@ -1110,7 +1106,7 @@ out:
rpc_req = entry->msg.request.rpc_req;
if (request_ctx != NULL) {
- __rdma_request_context_destroy (rpc_req->conn_private);
+ __gf_rdma_request_context_destroy (rpc_req->conn_private);
}
rpc_req->conn_private = NULL;
@@ -1121,8 +1117,8 @@ out:
inline void
-__rdma_fill_reply_header (rdma_header_t *header, struct iovec *rpchdr,
- rdma_reply_info_t *reply_info, int credits)
+__gf_rdma_fill_reply_header (gf_rdma_header_t *header, struct iovec *rpchdr,
+ gf_rdma_reply_info_t *reply_info, int credits)
{
struct rpc_msg *rpc_msg = NULL;
@@ -1136,8 +1132,8 @@ __rdma_fill_reply_header (rdma_header_t *header, struct iovec *rpchdr,
header->rm_xid = rpc_msg->rm_xid;
}
- header->rm_type = hton32 (RDMA_MSG);
- header->rm_vers = hton32 (RDMA_VERSION);
+ header->rm_type = hton32 (GF_RDMA_MSG);
+ header->rm_vers = hton32 (GF_RDMA_VERSION);
header->rm_credit = hton32 (credits);
header->rm_body.rm_chunks[0] = 0; /* no read chunks */
@@ -1149,36 +1145,36 @@ __rdma_fill_reply_header (rdma_header_t *header, struct iovec *rpchdr,
int32_t
-__rdma_send_reply_inline (rdma_peer_t *peer, rdma_ioq_t *entry,
- rdma_post_t *post, rdma_reply_info_t *reply_info)
+__gf_rdma_send_reply_inline (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry,
+ gf_rdma_post_t *post,
+ gf_rdma_reply_info_t *reply_info)
{
- rdma_header_t *header = NULL;
- int32_t send_size = 0, ret = 0;
- char *buf = NULL;
- rdma_private_t *priv = NULL;
- rdma_device_t *device = NULL;
-
- priv = peer->trans->private;
- device = priv->device;
+ gf_rdma_header_t *header = NULL;
+ int32_t send_size = 0, ret = 0;
+ char *buf = NULL;
send_size = iov_length (entry->rpchdr, entry->rpchdr_count)
+ iov_length (entry->proghdr, entry->proghdr_count)
+ iov_length (entry->prog_payload, entry->prog_payload_count)
- + sizeof (rdma_header_t); /*
- * remember, no chunklists in the
- * reply
- */
+ + sizeof (gf_rdma_header_t); /*
+ * remember, no chunklists in the
+ * reply
+ */
if (send_size > GLUSTERFS_RDMA_INLINE_THRESHOLD) {
- ret = __rdma_send_error (peer, entry, post, reply_info,
- ERR_CHUNK);
+ ret = __gf_rdma_send_error (peer, entry, post, reply_info,
+ ERR_CHUNK);
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "msg size (%d) is greater than maximum size "
+ "of msg that can be sent inlined (%d)",
+ send_size, GLUSTERFS_RDMA_INLINE_THRESHOLD);
goto out;
}
- header = (rdma_header_t *)post->buf;
+ header = (gf_rdma_header_t *)post->buf;
- __rdma_fill_reply_header (header, entry->rpchdr, reply_info,
- peer->send_count);
+ __gf_rdma_fill_reply_header (header, entry->rpchdr, reply_info,
+ peer->send_count);
buf = (char *)&header->rm_body.rm_chunks[3];
@@ -1199,18 +1195,18 @@ __rdma_send_reply_inline (rdma_peer_t *peer, rdma_ioq_t *entry,
entry->prog_payload_count);
}
- rdma_post_ref (post);
+ gf_rdma_post_ref (post);
- ret = rdma_post_send (peer->qp, post, (buf - post->buf));
+ ret = gf_rdma_post_send (peer->qp, post, (buf - post->buf));
if (!ret) {
ret = send_size;
} else {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
- "rdma_post_send (to %s) failed with ret = %d (%s)",
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "posting send (to %s) failed with ret = %d (%s)",
peer->trans->peerinfo.identifier, ret,
(ret > 0) ? strerror (ret) : "");
- rdma_post_unref (post);
- __rdma_disconnect (peer->trans);
+ gf_rdma_post_unref (post);
+ __gf_rdma_disconnect (peer->trans);
ret = -1;
}
@@ -1220,17 +1216,18 @@ out:
int32_t
-__rdma_reply_encode_write_chunks (rdma_peer_t *peer, uint32_t payload_size,
- rdma_post_t *post,
- rdma_reply_info_t *reply_info,
- uint32_t **ptr)
+__gf_rdma_reply_encode_write_chunks (gf_rdma_peer_t *peer,
+ uint32_t payload_size,
+ gf_rdma_post_t *post,
+ gf_rdma_reply_info_t *reply_info,
+ uint32_t **ptr)
{
- uint32_t chunk_size = 0;
- int32_t ret = -1;
- rdma_write_array_t *target_array = NULL;
- int i = 0;
+ uint32_t chunk_size = 0;
+ int32_t ret = -1;
+ gf_rdma_write_array_t *target_array = NULL;
+ int i = 0;
- target_array = (rdma_write_array_t *)*ptr;
+ target_array = (gf_rdma_write_array_t *)*ptr;
for (i = 0; i < reply_info->wc_array->wc_nchunks; i++) {
chunk_size +=
@@ -1238,7 +1235,7 @@ __rdma_reply_encode_write_chunks (rdma_peer_t *peer, uint32_t payload_size,
}
if (chunk_size < payload_size) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
"length of payload (%d) is exceeding the total "
"write chunk length (%d)", payload_size, chunk_size);
goto out;
@@ -1269,18 +1266,17 @@ out:
inline int32_t
-__rdma_register_local_mr_for_rdma (rdma_peer_t *peer,
- struct iovec *vector, int count,
- rdma_post_context_t *ctx)
+__gf_rdma_register_local_mr_for_rdma (gf_rdma_peer_t *peer,
+ struct iovec *vector, int count,
+ gf_rdma_post_context_t *ctx)
{
- int i = 0;
- int32_t ret = -1;
- rdma_private_t *priv = NULL;
- rdma_device_t *device = NULL;
+ int i = 0;
+ int32_t ret = -1;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_device_t *device = NULL;
- if ((ctx == NULL) || (vector == NULL)) {
- goto out;
- }
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, ctx, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, vector, out);
priv = peer->trans->private;
device = priv->device;
@@ -1301,6 +1297,9 @@ __rdma_register_local_mr_for_rdma (rdma_peer_t *peer,
vector[i].iov_len,
IBV_ACCESS_LOCAL_WRITE);
if (ctx->mr[ctx->mr_count] == NULL) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "registering memory for IBV_ACCESS_LOCAL_WRITE "
+ "failed (%s)", strerror (errno));
goto out;
}
@@ -1316,15 +1315,15 @@ out:
* 2. modifies vec
*/
int32_t
-__rdma_write (rdma_peer_t *peer, rdma_post_t *post, struct iovec *vec,
- uint32_t xfer_len, int *idx, rdma_write_chunk_t *writech)
+__gf_rdma_write (gf_rdma_peer_t *peer, gf_rdma_post_t *post, struct iovec *vec,
+ uint32_t xfer_len, int *idx, gf_rdma_write_chunk_t *writech)
{
- int size = 0, num_sge = 0, i = 0;
- int32_t ret = -1;
- struct ibv_sge *sg_list = NULL;
- struct ibv_send_wr wr = {
- .opcode = IBV_WR_RDMA_WRITE,
- .send_flags = IBV_SEND_SIGNALED,
+ int size = 0, num_sge = 0, i = 0;
+ int32_t ret = -1;
+ struct ibv_sge *sg_list = NULL;
+ struct ibv_send_wr wr = {
+ .opcode = IBV_WR_RDMA_WRITE,
+ .send_flags = IBV_SEND_SIGNALED,
}, *bad_wr;
if ((peer == NULL) || (writech == NULL) || (idx == NULL)
@@ -1338,7 +1337,8 @@ __rdma_write (rdma_peer_t *peer, rdma_post_t *post, struct iovec *vec,
num_sge = i - *idx;
- sg_list = GF_CALLOC (num_sge, sizeof (struct ibv_sge), gf_common_mt_sge);
+ sg_list = GF_CALLOC (num_sge, sizeof (struct ibv_sge),
+ gf_common_mt_sge);
if (sg_list == NULL) {
ret = -1;
goto out;
@@ -1364,13 +1364,14 @@ __rdma_write (rdma_peer_t *peer, rdma_post_t *post, struct iovec *vec,
wr.sg_list = sg_list;
wr.num_sge = num_sge;
- wr.wr_id = (unsigned long) rdma_post_ref (post);
+ wr.wr_id = (unsigned long) gf_rdma_post_ref (post);
wr.wr.rdma.rkey = writech->wc_target.rs_handle;
wr.wr.rdma.remote_addr = writech->wc_target.rs_offset;
ret = ibv_post_send(peer->qp, &wr, &bad_wr);
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING, "rdma write to "
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "rdma write to "
"client (%s) failed with ret = %d (%s)",
peer->trans->peerinfo.identifier, ret,
(ret > 0) ? strerror (ret) : "");
@@ -1384,13 +1385,14 @@ out:
int32_t
-__rdma_do_rdma_write (rdma_peer_t *peer, rdma_post_t *post,
- struct iovec *vector, int count, struct iobref *iobref,
- rdma_reply_info_t *reply_info)
+__gf_rdma_do_gf_rdma_write (gf_rdma_peer_t *peer, gf_rdma_post_t *post,
+ struct iovec *vector, int count,
+ struct iobref *iobref,
+ gf_rdma_reply_info_t *reply_info)
{
- int i = 0, payload_idx = 0;
- uint32_t payload_size = 0, xfer_len = 0;
- int32_t ret = -1;
+ int i = 0, payload_idx = 0;
+ uint32_t payload_size = 0, xfer_len = 0;
+ int32_t ret = -1;
if (count != 0) {
payload_size = iov_length (vector, count);
@@ -1401,9 +1403,11 @@ __rdma_do_rdma_write (rdma_peer_t *peer, rdma_post_t *post,
goto out;
}
- ret = __rdma_register_local_mr_for_rdma (peer, vector, count,
- &post->ctx);
+ ret = __gf_rdma_register_local_mr_for_rdma (peer, vector, count,
+ &post->ctx);
if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "registering memory region for rdma failed");
goto out;
}
@@ -1415,9 +1419,13 @@ __rdma_do_rdma_write (rdma_peer_t *peer, rdma_post_t *post,
xfer_len = min (payload_size,
reply_info->wc_array->wc_array[i].wc_target.rs_length);
- ret = __rdma_write (peer, post, vector, xfer_len, &payload_idx,
- &reply_info->wc_array->wc_array[i]);
+ ret = __gf_rdma_write (peer, post, vector, xfer_len,
+ &payload_idx,
+ &reply_info->wc_array->wc_array[i]);
if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "rdma write to client (%s) failed",
+ peer->trans->peerinfo.identifier);
goto out;
}
@@ -1432,44 +1440,41 @@ out:
int32_t
-__rdma_send_reply_type_nomsg (rdma_peer_t *peer, rdma_ioq_t *entry,
- rdma_post_t *post, rdma_reply_info_t *reply_info)
+__gf_rdma_send_reply_type_nomsg (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry,
+ gf_rdma_post_t *post,
+ gf_rdma_reply_info_t *reply_info)
{
- rdma_header_t *header = NULL;
- char *buf = NULL;
- uint32_t payload_size = 0;
- int count = 0, i = 0;
- rdma_private_t *priv = NULL;
- rdma_device_t *device = NULL;
- int32_t ret = 0;
- struct iovec vector[MAX_IOVEC];
+ gf_rdma_header_t *header = NULL;
+ char *buf = NULL;
+ uint32_t payload_size = 0;
+ int count = 0, i = 0;
+ int32_t ret = 0;
+ struct iovec vector[MAX_IOVEC];
- priv = peer->trans->private;
- device = priv->device;
-
- header = (rdma_header_t *)post->buf;
+ header = (gf_rdma_header_t *)post->buf;
- __rdma_fill_reply_header (header, entry->rpchdr, reply_info,
- peer->send_count);
+ __gf_rdma_fill_reply_header (header, entry->rpchdr, reply_info,
+ peer->send_count);
- header->rm_type = hton32 (RDMA_NOMSG);
+ header->rm_type = hton32 (GF_RDMA_NOMSG);
payload_size = iov_length (entry->rpchdr, entry->rpchdr_count) +
iov_length (entry->proghdr, entry->proghdr_count);
/* encode reply chunklist */
buf = (char *)&header->rm_body.rm_chunks[2];
- ret = __rdma_reply_encode_write_chunks (peer, payload_size, post,
- reply_info, (uint32_t **)&buf);
+ ret = __gf_rdma_reply_encode_write_chunks (peer, payload_size, post,
+ reply_info,
+ (uint32_t **)&buf);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"encoding write chunks failed");
- ret = __rdma_send_error (peer, entry, post, reply_info,
- ERR_CHUNK);
+ ret = __gf_rdma_send_error (peer, entry, post, reply_info,
+ ERR_CHUNK);
goto out;
}
- rdma_post_ref (post);
+ gf_rdma_post_ref (post);
for (i = 0; i < entry->rpchdr_count; i++) {
vector[count++] = entry->rpchdr[i];
@@ -1479,21 +1484,24 @@ __rdma_send_reply_type_nomsg (rdma_peer_t *peer, rdma_ioq_t *entry,
vector[count++] = entry->proghdr[i];
}
- ret = __rdma_do_rdma_write (peer, post, vector, count, entry->iobref,
- reply_info);
+ ret = __gf_rdma_do_gf_rdma_write (peer, post, vector, count,
+ entry->iobref, reply_info);
if (ret == -1) {
- rdma_post_unref (post);
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "rdma write to peer (%s) failed",
+ peer->trans->peerinfo.identifier);
+ gf_rdma_post_unref (post);
goto out;
}
- ret = rdma_post_send (peer->qp, post, (buf - post->buf));
+ ret = gf_rdma_post_send (peer->qp, post, (buf - post->buf));
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
- "rdma_post_send to client (%s) failed with "
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "posting a send request to client (%s) failed with "
"ret = %d (%s)", peer->trans->peerinfo.identifier, ret,
(ret > 0) ? strerror (ret) : "");
ret = -1;
- rdma_post_unref (post);
+ gf_rdma_post_unref (post);
} else {
ret = payload_size;
}
@@ -1504,65 +1512,64 @@ out:
int32_t
-__rdma_send_reply_type_msg (rdma_peer_t *peer, rdma_ioq_t *entry,
- rdma_post_t *post, rdma_reply_info_t *reply_info)
+__gf_rdma_send_reply_type_msg (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry,
+ gf_rdma_post_t *post,
+ gf_rdma_reply_info_t *reply_info)
{
- rdma_header_t *header = NULL;
- int32_t send_size = 0, ret = 0;
- char *ptr = NULL;
- uint32_t payload_size = 0;
- rdma_private_t *priv = NULL;
- rdma_device_t *device = NULL;
-
- priv = peer->trans->private;
- device = priv->device;
+ gf_rdma_header_t *header = NULL;
+ int32_t send_size = 0, ret = 0;
+ char *ptr = NULL;
+ uint32_t payload_size = 0;
send_size = iov_length (entry->rpchdr, entry->rpchdr_count)
+ iov_length (entry->proghdr, entry->proghdr_count)
+ GLUSTERFS_RDMA_MAX_HEADER_SIZE;
if (send_size > GLUSTERFS_RDMA_INLINE_THRESHOLD) {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"client has provided only write chunks, but the "
"combined size of rpc and program header (%d) is "
"exceeding the size of msg that can be sent using "
"RDMA send (%d)", send_size,
GLUSTERFS_RDMA_INLINE_THRESHOLD);
- ret = __rdma_send_error (peer, entry, post, reply_info,
- ERR_CHUNK);
+ ret = __gf_rdma_send_error (peer, entry, post, reply_info,
+ ERR_CHUNK);
goto out;
}
- header = (rdma_header_t *)post->buf;
+ header = (gf_rdma_header_t *)post->buf;
- __rdma_fill_reply_header (header, entry->rpchdr, reply_info,
- peer->send_count);
+ __gf_rdma_fill_reply_header (header, entry->rpchdr, reply_info,
+ peer->send_count);
payload_size = iov_length (entry->prog_payload,
entry->prog_payload_count);
ptr = (char *)&header->rm_body.rm_chunks[1];
- ret = __rdma_reply_encode_write_chunks (peer, payload_size, post,
- reply_info, (uint32_t **)&ptr);
+ ret = __gf_rdma_reply_encode_write_chunks (peer, payload_size, post,
+ reply_info,
+ (uint32_t **)&ptr);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"encoding write chunks failed");
- ret = __rdma_send_error (peer, entry, post, reply_info,
- ERR_CHUNK);
+ ret = __gf_rdma_send_error (peer, entry, post, reply_info,
+ ERR_CHUNK);
goto out;
}
*(uint32_t *)ptr = 0; /* terminate reply chunklist */
ptr += sizeof (uint32_t);
- rdma_post_ref (post);
+ gf_rdma_post_ref (post);
- ret = __rdma_do_rdma_write (peer, post, entry->prog_payload,
- entry->prog_payload_count, entry->iobref,
- reply_info);
+ ret = __gf_rdma_do_gf_rdma_write (peer, post, entry->prog_payload,
+ entry->prog_payload_count,
+ entry->iobref, reply_info);
if (ret == -1) {
- rdma_post_unref (post);
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING, "rdma write to peer "
+ "(%s) failed", peer->trans->peerinfo.identifier);
+ gf_rdma_post_unref (post);
goto out;
}
@@ -1572,13 +1579,13 @@ __rdma_send_reply_type_msg (rdma_peer_t *peer, rdma_ioq_t *entry,
iov_unload (ptr, entry->proghdr, entry->proghdr_count);
ptr += iov_length (entry->proghdr, entry->proghdr_count);
- ret = rdma_post_send (peer->qp, post, (ptr - post->buf));
+ ret = gf_rdma_post_send (peer->qp, post, (ptr - post->buf));
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"rdma send to client (%s) failed with ret = %d (%s)",
peer->trans->peerinfo.identifier, ret,
(ret > 0) ? strerror (ret) : "");
- rdma_post_unref (post);
+ gf_rdma_post_unref (post);
ret = -1;
} else {
ret = send_size + payload_size;
@@ -1590,7 +1597,7 @@ out:
void
-rdma_reply_info_destroy (rdma_reply_info_t *reply_info)
+gf_rdma_reply_info_destroy (gf_rdma_reply_info_t *reply_info)
{
if (reply_info == NULL) {
goto out;
@@ -1601,17 +1608,17 @@ rdma_reply_info_destroy (rdma_reply_info_t *reply_info)
reply_info->wc_array = NULL;
}
- mem_put (reply_info->pool, reply_info);
+ mem_put (reply_info);
out:
return;
}
-rdma_reply_info_t *
-rdma_reply_info_alloc (rdma_peer_t *peer)
+gf_rdma_reply_info_t *
+gf_rdma_reply_info_alloc (gf_rdma_peer_t *peer)
{
- rdma_reply_info_t *reply_info = NULL;
- rdma_private_t *priv = NULL;
+ gf_rdma_reply_info_t *reply_info = NULL;
+ gf_rdma_private_t *priv = NULL;
priv = peer->trans->private;
@@ -1629,15 +1636,16 @@ out:
int32_t
-__rdma_ioq_churn_reply (rdma_peer_t *peer, rdma_ioq_t *entry, rdma_post_t *post)
+__gf_rdma_ioq_churn_reply (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry,
+ gf_rdma_post_t *post)
{
- rdma_reply_info_t *reply_info = NULL;
- int32_t ret = -1;
- rdma_chunktype_t type = rdma_noch;
+ gf_rdma_reply_info_t *reply_info = NULL;
+ int32_t ret = -1;
+ gf_rdma_chunktype_t type = gf_rdma_noch;
- if ((peer == NULL) || (entry == NULL) || (post == NULL)) {
- goto out;
- }
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, peer, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, entry, out);
+ GF_VALIDATE_OR_GOTO (GF_RDMA_LOG_NAME, post, out);
reply_info = entry->msg.reply_info;
if (reply_info != NULL) {
@@ -1645,29 +1653,47 @@ __rdma_ioq_churn_reply (rdma_peer_t *peer, rdma_ioq_t *entry, rdma_post_t *post)
}
switch (type) {
- case rdma_noch:
- ret = __rdma_send_reply_inline (peer, entry, post, reply_info);
+ case gf_rdma_noch:
+ ret = __gf_rdma_send_reply_inline (peer, entry, post,
+ reply_info);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "failed to send reply to peer (%s) as an "
+ "inlined rdma msg",
+ peer->trans->peerinfo.identifier);
+ }
break;
- case rdma_replych:
- ret = __rdma_send_reply_type_nomsg (peer, entry, post,
- reply_info);
+ case gf_rdma_replych:
+ ret = __gf_rdma_send_reply_type_nomsg (peer, entry, post,
+ reply_info);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "failed to send reply to peer (%s) as "
+ "RDMA_NOMSG", peer->trans->peerinfo.identifier);
+ }
break;
- case rdma_writech:
- ret = __rdma_send_reply_type_msg (peer, entry, post,
- reply_info);
+ case gf_rdma_writech:
+ ret = __gf_rdma_send_reply_type_msg (peer, entry, post,
+ reply_info);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "failed to send reply with write chunks "
+ "to peer (%s)",
+ peer->trans->peerinfo.identifier);
+ }
break;
default:
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
- "invalid chunktype (%d) specified for sending reply",
- type);
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "invalid chunktype (%d) specified for sending reply "
+ " (peer:%s)", type, peer->trans->peerinfo.identifier);
break;
}
if (reply_info != NULL) {
- rdma_reply_info_destroy (reply_info);
+ gf_rdma_reply_info_destroy (reply_info);
}
out:
return ret;
@@ -1675,40 +1701,54 @@ out:
int32_t
-__rdma_ioq_churn_entry (rdma_peer_t *peer, rdma_ioq_t *entry)
+__gf_rdma_ioq_churn_entry (gf_rdma_peer_t *peer, gf_rdma_ioq_t *entry)
{
- int32_t ret = 0, quota = 0;
- rdma_private_t *priv = NULL;
- rdma_device_t *device = NULL;
- rdma_options_t *options = NULL;
- rdma_post_t *post = NULL;
+ int32_t ret = 0, quota = 0;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_device_t *device = NULL;
+ gf_rdma_options_t *options = NULL;
+ gf_rdma_post_t *post = NULL;
priv = peer->trans->private;
options = &priv->options;
device = priv->device;
- quota = __rdma_quota_get (peer);
+ quota = __gf_rdma_quota_get (peer);
if (quota > 0) {
- post = rdma_get_post (&device->sendq);
+ post = gf_rdma_get_post (&device->sendq);
if (post == NULL) {
- post = rdma_new_post (device,
- (options->send_size + 2048),
- RDMA_SEND_POST);
+ post = gf_rdma_new_post (device,
+ (options->send_size + 2048),
+ GF_RDMA_SEND_POST);
}
if (post == NULL) {
ret = -1;
+ gf_log_callingfn (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "not able to get a post to send msg");
goto out;
}
if (entry->is_request) {
- ret = __rdma_ioq_churn_request (peer, entry, post);
+ ret = __gf_rdma_ioq_churn_request (peer, entry, post);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "failed to process request ioq entry "
+ "to peer(%s)",
+ peer->trans->peerinfo.identifier);
+ }
} else {
- ret = __rdma_ioq_churn_reply (peer, entry, post);
+ ret = __gf_rdma_ioq_churn_reply (peer, entry, post);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "failed to process reply ioq entry "
+ "to peer (%s)",
+ peer->trans->peerinfo.identifier);
+ }
}
if (ret != 0) {
- __rdma_ioq_entry_free (entry);
+ __gf_rdma_ioq_entry_free (entry);
}
} else {
ret = 0;
@@ -1720,17 +1760,17 @@ out:
static int32_t
-__rdma_ioq_churn (rdma_peer_t *peer)
+__gf_rdma_ioq_churn (gf_rdma_peer_t *peer)
{
- rdma_ioq_t *entry = NULL;
- int32_t ret = 0;
+ gf_rdma_ioq_t *entry = NULL;
+ int32_t ret = 0;
while (!list_empty (&peer->ioq))
{
/* pick next entry */
entry = peer->ioq_next;
- ret = __rdma_ioq_churn_entry (peer, entry);
+ ret = __gf_rdma_ioq_churn_entry (peer, entry);
if (ret <= 0)
break;
@@ -1738,7 +1778,7 @@ __rdma_ioq_churn (rdma_peer_t *peer)
/*
list_for_each_entry_safe (entry, dummy, &peer->ioq, list) {
- ret = __rdma_ioq_churn_entry (peer, entry);
+ ret = __gf_rdma_ioq_churn_entry (peer, entry);
if (ret <= 0) {
break;
}
@@ -1750,28 +1790,35 @@ __rdma_ioq_churn (rdma_peer_t *peer)
static int32_t
-rdma_writev (rpc_transport_t *this,
- rdma_ioq_t *entry)
+gf_rdma_writev (rpc_transport_t *this, gf_rdma_ioq_t *entry)
{
- int32_t ret = 0, need_append = 1;
- rdma_private_t *priv = this->private;
- rdma_peer_t *peer = NULL;
+ int32_t ret = 0, need_append = 1;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_peer_t *peer = NULL;
+ priv = this->private;
pthread_mutex_lock (&priv->write_mutex);
{
if (!priv->connected) {
- gf_log (this->name, GF_LOG_DEBUG,
- "rdma is not connected to post a "
- "send request");
+ gf_log (this->name, GF_LOG_WARNING,
+ "rdma is not connected to peer (%s)",
+ this->peerinfo.identifier);
ret = -1;
goto unlock;
}
peer = &priv->peer;
if (list_empty (&peer->ioq)) {
- ret = __rdma_ioq_churn_entry (peer, entry);
+ ret = __gf_rdma_ioq_churn_entry (peer, entry);
if (ret != 0) {
need_append = 0;
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "processing ioq entry destined "
+ "to (%s) failed",
+ this->peerinfo.identifier);
+ }
}
}
@@ -1785,20 +1832,20 @@ unlock:
}
-rdma_ioq_t *
-rdma_ioq_new (rpc_transport_t *this, rpc_transport_data_t *data)
+gf_rdma_ioq_t *
+gf_rdma_ioq_new (rpc_transport_t *this, rpc_transport_data_t *data)
{
- rdma_ioq_t *entry = NULL;
- int count = 0, i = 0;
- rpc_transport_msg_t *msg = NULL;
- rdma_private_t *priv = NULL;
+ gf_rdma_ioq_t *entry = NULL;
+ int count = 0, i = 0;
+ rpc_transport_msg_t *msg = NULL;
+ gf_rdma_private_t *priv = NULL;
if ((data == NULL) || (this == NULL)) {
goto out;
}
priv = this->private;
- /* TODO: use mem-pool */
+
entry = mem_get (priv->device->ioq_pool);
if (entry == NULL) {
goto out;
@@ -1876,12 +1923,11 @@ out:
int32_t
-rdma_submit_request (rpc_transport_t *this,
- rpc_transport_req_t *req)
+gf_rdma_submit_request (rpc_transport_t *this, rpc_transport_req_t *req)
{
- int32_t ret = 0;
- rdma_ioq_t *entry = NULL;
- rpc_transport_data_t data = {0, };
+ int32_t ret = 0;
+ gf_rdma_ioq_t *entry = NULL;
+ rpc_transport_data_t data = {0, };
if (req == NULL) {
goto out;
@@ -1890,16 +1936,22 @@ rdma_submit_request (rpc_transport_t *this,
data.is_request = 1;
data.data.req = *req;
- entry = rdma_ioq_new (this, &data);
+ entry = gf_rdma_ioq_new (this, &data);
if (entry == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "getting a new ioq entry failed (peer:%s)",
+ this->peerinfo.identifier);
goto out;
}
- ret = rdma_writev (this, entry);
+ ret = gf_rdma_writev (this, entry);
if (ret > 0) {
ret = 0;
} else if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "sending request to peer (%s) failed",
+ this->peerinfo.identifier);
rpc_transport_disconnect (this);
}
@@ -1908,11 +1960,11 @@ out:
}
int32_t
-rdma_submit_reply (rpc_transport_t *this, rpc_transport_reply_t *reply)
+gf_rdma_submit_reply (rpc_transport_t *this, rpc_transport_reply_t *reply)
{
- int32_t ret = 0;
- rdma_ioq_t *entry = NULL;
- rpc_transport_data_t data = {0, };
+ int32_t ret = 0;
+ gf_rdma_ioq_t *entry = NULL;
+ rpc_transport_data_t data = {0, };
if (reply == NULL) {
goto out;
@@ -1920,15 +1972,21 @@ rdma_submit_reply (rpc_transport_t *this, rpc_transport_reply_t *reply)
data.data.reply = *reply;
- entry = rdma_ioq_new (this, &data);
+ entry = gf_rdma_ioq_new (this, &data);
if (entry == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "getting a new ioq entry failed (peer:%s)",
+ this->peerinfo.identifier);
goto out;
}
- ret = rdma_writev (this, entry);
+ ret = gf_rdma_writev (this, entry);
if (ret > 0) {
ret = 0;
} else if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "sending request to peer (%s) failed",
+ this->peerinfo.identifier);
rpc_transport_disconnect (this);
}
@@ -1938,18 +1996,18 @@ out:
#if 0
static int
-rdma_receive (rpc_transport_t *this, char **hdr_p, size_t *hdrlen_p,
- struct iobuf **iobuf_p)
+gf_rdma_receive (rpc_transport_t *this, char **hdr_p, size_t *hdrlen_p,
+ struct iobuf **iobuf_p)
{
- rdma_private_t *priv = this->private;
+ gf_rdma_private_t *priv = this->private;
/* TODO: return error if !priv->connected, check with locks */
/* TODO: boundry checks for data_ptr/offset */
- char *copy_from = NULL;
- rdma_header_t *header = NULL;
- uint32_t size1, size2, data_len = 0;
- char *hdr = NULL;
- struct iobuf *iobuf = NULL;
- int32_t ret = 0;
+ char *copy_from = NULL;
+ gf_rdma_header_t *header = NULL;
+ uint32_t size1, size2, data_len = 0;
+ char *hdr = NULL;
+ struct iobuf *iobuf = NULL;
+ int32_t ret = 0;
pthread_mutex_lock (&priv->recv_mutex);
{
@@ -1966,9 +2024,9 @@ rdma_receive (rpc_transport_t *this, char **hdr_p, size_t *hdrlen_p,
}
pthread_mutex_unlock (&priv->recv_mutex);
- header = (rdma_header_t *)copy_from;
+ header = (gf_rdma_header_t *)copy_from;
if (strcmp (header->colonO, ":O")) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
"%s: corrupt header received", this->name);
ret = -1;
goto err;
@@ -1978,7 +2036,7 @@ rdma_receive (rpc_transport_t *this, char **hdr_p, size_t *hdrlen_p,
size2 = ntoh32 (header->size2);
if (data_len != (size1 + size2 + sizeof (*header))) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
"%s: sizeof data read from transport is not equal "
"to the size specified in the header",
this->name);
@@ -2004,7 +2062,7 @@ rdma_receive (rpc_transport_t *this, char **hdr_p, size_t *hdrlen_p,
*hdrlen_p = size1;
if (size2) {
- iobuf = iobuf_get (this->ctx->iobuf_pool);
+ iobuf = iobuf_get2 (this->ctx->iobuf_pool, size2);
if (!iobuf) {
gf_log (this->name, GF_LOG_ERROR,
"unable to allocate IO buffer for peer %s",
@@ -2023,10 +2081,13 @@ err:
static void
-rdma_destroy_cq (rpc_transport_t *this)
+gf_rdma_destroy_cq (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- rdma_device_t *device = priv->device;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_device_t *device = NULL;
+
+ priv = this->private;
+ device = priv->device;
if (device->recv_cq)
ibv_destroy_cq (device->recv_cq);
@@ -2041,14 +2102,14 @@ rdma_destroy_cq (rpc_transport_t *this)
static int32_t
-rdma_create_cq (rpc_transport_t *this)
+gf_rdma_create_cq (rpc_transport_t *this)
{
- rdma_private_t *priv = NULL;
- rdma_options_t *options = NULL;
- rdma_device_t *device = NULL;
- uint64_t send_cqe = 0;
- int32_t ret = 0;
- struct ibv_device_attr device_attr = {{0}, };
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_options_t *options = NULL;
+ gf_rdma_device_t *device = NULL;
+ uint64_t send_cqe = 0;
+ int32_t ret = 0;
+ struct ibv_device_attr device_attr = {{0}, };
priv = this->private;
options = &priv->options;
@@ -2060,13 +2121,13 @@ rdma_create_cq (rpc_transport_t *this)
device->recv_chan,
0);
if (!device->recv_cq) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: creation of CQ for device %s failed",
this->name, device->device_name);
ret = -1;
goto out;
} else if (ibv_req_notify_cq (device->recv_cq, 0)) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: ibv_req_notify_cq on recv CQ of device %s failed",
this->name, device->device_name);
ret = -1;
@@ -2076,7 +2137,7 @@ rdma_create_cq (rpc_transport_t *this)
do {
ret = ibv_query_device (priv->device->context, &device_attr);
if (ret != 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: ibv_query_device on %s returned %d (%s)",
this->name, priv->device->device_name, ret,
(ret > 0) ? strerror (ret) : "");
@@ -2093,7 +2154,7 @@ rdma_create_cq (rpc_transport_t *this)
send_cqe, device,
device->send_chan, 0);
if (!device->send_cq) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: creation of send_cq for device %s failed",
this->name, device->device_name);
ret = -1;
@@ -2101,7 +2162,7 @@ rdma_create_cq (rpc_transport_t *this)
}
if (ibv_req_notify_cq (device->send_cq, 0)) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: ibv_req_notify_cq on send_cq for device %s"
" failed", this->name, device->device_name);
ret = -1;
@@ -2111,21 +2172,20 @@ rdma_create_cq (rpc_transport_t *this)
out:
if (ret != 0)
- rdma_destroy_cq (this);
+ gf_rdma_destroy_cq (this);
return ret;
}
static int
-rdma_register_peer (rdma_device_t *device,
- int32_t qp_num,
- rdma_peer_t *peer)
+gf_rdma_register_peer (gf_rdma_device_t *device, int32_t qp_num,
+ gf_rdma_peer_t *peer)
{
- struct _qpent *ent = NULL;
- rdma_qpreg_t *qpreg = NULL;
- int32_t hash = 0;
- int ret = -1;
+ struct _qpent *ent = NULL;
+ gf_rdma_qpreg_t *qpreg = NULL;
+ int32_t hash = 0;
+ int ret = -1;
qpreg = &device->qpreg;
hash = qp_num % 42;
@@ -2166,37 +2226,41 @@ unlock:
static void
-rdma_unregister_peer (rdma_device_t *device,
- int32_t qp_num)
+gf_rdma_unregister_peer (gf_rdma_device_t *device, int32_t qp_num)
{
- struct _qpent *ent;
- rdma_qpreg_t *qpreg = &device->qpreg;
- int32_t hash = qp_num % 42;
+ struct _qpent *ent = NULL;
+ gf_rdma_qpreg_t *qpreg = NULL;
+ int32_t hash = 0;
+
+ qpreg = &device->qpreg;
+ hash = qp_num % 42;
pthread_mutex_lock (&qpreg->lock);
- ent = qpreg->ents[hash].next;
- while ((ent != &qpreg->ents[hash]) && (ent->qp_num != qp_num))
- ent = ent->next;
- if (ent->qp_num != qp_num) {
- pthread_mutex_unlock (&qpreg->lock);
- return;
- }
- ent->prev->next = ent->next;
- ent->next->prev = ent->prev;
- /* TODO: unref reg->peer */
- GF_FREE (ent);
- qpreg->count--;
+ {
+ ent = qpreg->ents[hash].next;
+ while ((ent != &qpreg->ents[hash]) && (ent->qp_num != qp_num))
+ ent = ent->next;
+ if (ent->qp_num != qp_num) {
+ pthread_mutex_unlock (&qpreg->lock);
+ return;
+ }
+ ent->prev->next = ent->next;
+ ent->next->prev = ent->prev;
+ /* TODO: unref reg->peer */
+ GF_FREE (ent);
+ qpreg->count--;
+ }
pthread_mutex_unlock (&qpreg->lock);
}
-static rdma_peer_t *
-__rdma_lookup_peer (rdma_device_t *device, int32_t qp_num)
+static gf_rdma_peer_t *
+__gf_rdma_lookup_peer (gf_rdma_device_t *device, int32_t qp_num)
{
- struct _qpent *ent = NULL;
- rdma_peer_t *peer = NULL;
- rdma_qpreg_t *qpreg = NULL;
- int32_t hash = 0;
+ struct _qpent *ent = NULL;
+ gf_rdma_peer_t *peer = NULL;
+ gf_rdma_qpreg_t *qpreg = NULL;
+ int32_t hash = 0;
qpreg = &device->qpreg;
hash = qp_num % 42;
@@ -2212,17 +2276,17 @@ __rdma_lookup_peer (rdma_device_t *device, int32_t qp_num)
}
/*
- static rdma_peer_t *
- rdma_lookup_peer (rdma_device_t *device,
+ static gf_rdma_peer_t *
+ gf_rdma_lookup_peer (gf_rdma_device_t *device,
int32_t qp_num)
{
- rdma_qpreg_t *qpreg = NULL;
- rdma_peer_t *peer = NULL;
+ gf_rdma_qpreg_t *qpreg = NULL;
+ gf_rdma_peer_t *peer = NULL;
qpreg = &device->qpreg;
pthread_mutex_lock (&qpreg->lock);
{
- peer = __rdma_lookup_peer (device, qp_num);
+ peer = __gf_rdma_lookup_peer (device, qp_num);
}
pthread_mutex_unlock (&qpreg->lock);
@@ -2232,12 +2296,13 @@ __rdma_lookup_peer (rdma_device_t *device, int32_t qp_num)
static void
-__rdma_destroy_qp (rpc_transport_t *this)
+__gf_rdma_destroy_qp (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
+ gf_rdma_private_t *priv = NULL;
+ priv = this->private;
if (priv->peer.qp) {
- rdma_unregister_peer (priv->device, priv->peer.qp->qp_num);
+ gf_rdma_unregister_peer (priv->device, priv->peer.qp->qp_num);
ibv_destroy_qp (priv->peer.qp);
}
priv->peer.qp = NULL;
@@ -2247,15 +2312,20 @@ __rdma_destroy_qp (rpc_transport_t *this)
static int32_t
-rdma_create_qp (rpc_transport_t *this)
+gf_rdma_create_qp (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- rdma_options_t *options = &priv->options;
- rdma_device_t *device = priv->device;
- int32_t ret = 0;
- rdma_peer_t *peer;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_options_t *options = NULL;
+ gf_rdma_device_t *device = NULL;
+ int32_t ret = 0;
+ gf_rdma_peer_t *peer = NULL;
+
+ priv = this->private;
+ options = &priv->options;
+ device = priv->device;
peer = &priv->peer;
+
struct ibv_qp_init_attr init_attr = {
.send_cq = device->send_cq,
.recv_cq = device->recv_cq,
@@ -2279,7 +2349,7 @@ rdma_create_qp (rpc_transport_t *this)
peer->qp = ibv_create_qp (device->pd, &init_attr);
if (!peer->qp) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_CRITICAL,
"%s: could not create QP",
this->name);
@@ -2290,7 +2360,7 @@ rdma_create_qp (rpc_transport_t *this)
IBV_QP_PKEY_INDEX |
IBV_QP_PORT |
IBV_QP_ACCESS_FLAGS)) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_ERROR,
"%s: failed to modify QP to INIT state",
this->name);
@@ -2298,77 +2368,84 @@ rdma_create_qp (rpc_transport_t *this)
goto out;
}
- peer->local_lid = rdma_get_local_lid (device->context,
- options->port);
+ peer->local_lid = gf_rdma_get_local_lid (device->context,
+ options->port);
peer->local_qpn = peer->qp->qp_num;
peer->local_psn = lrand48 () & 0xffffff;
- ret = rdma_register_peer (device, peer->qp->qp_num, peer);
+ ret = gf_rdma_register_peer (device, peer->qp->qp_num, peer);
out:
if (ret == -1)
- __rdma_destroy_qp (this);
+ __gf_rdma_destroy_qp (this);
return ret;
}
static void
-rdma_destroy_posts (rpc_transport_t *this)
+gf_rdma_destroy_posts (rpc_transport_t *this)
{
}
static int32_t
-__rdma_create_posts (rpc_transport_t *this, int32_t count, int32_t size,
- rdma_queue_t *q, rdma_post_type_t type)
+__gf_rdma_create_posts (rpc_transport_t *this, int32_t count, int32_t size,
+ gf_rdma_queue_t *q, gf_rdma_post_type_t type)
{
- int32_t i;
- int32_t ret = 0;
- rdma_private_t *priv = this->private;
- rdma_device_t *device = priv->device;
+ int32_t i = 0;
+ int32_t ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_device_t *device = NULL;
+
+ priv = this->private;
+ device = priv->device;
for (i=0 ; i<count ; i++) {
- rdma_post_t *post;
+ gf_rdma_post_t *post = NULL;
- post = rdma_new_post (device, size + 2048, type);
+ post = gf_rdma_new_post (device, size + 2048, type);
if (!post) {
- gf_log (RDMA_LOG_NAME,
- GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: post creation failed",
this->name);
ret = -1;
break;
}
- rdma_put_post (q, post);
+ gf_rdma_put_post (q, post);
}
return ret;
}
static int32_t
-rdma_create_posts (rpc_transport_t *this)
+gf_rdma_create_posts (rpc_transport_t *this)
{
- int32_t i, ret;
- rdma_post_t *post = NULL;
- rdma_private_t *priv = this->private;
- rdma_options_t *options = &priv->options;
- rdma_device_t *device = priv->device;
-
- ret = __rdma_create_posts (this, options->send_count,
- options->send_size,
- &device->sendq, RDMA_SEND_POST);
+ int32_t i = 0, ret = 0;
+ gf_rdma_post_t *post = NULL;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_options_t *options = NULL;
+ gf_rdma_device_t *device = NULL;
+
+ priv = this->private;
+ options = &priv->options;
+ device = priv->device;
+
+ ret = __gf_rdma_create_posts (this, options->send_count,
+ options->send_size,
+ &device->sendq, GF_RDMA_SEND_POST);
if (!ret)
- ret = __rdma_create_posts (this, options->recv_count,
- options->recv_size,
- &device->recvq, RDMA_RECV_POST);
+ ret = __gf_rdma_create_posts (this, options->recv_count,
+ options->recv_size,
+ &device->recvq,
+ GF_RDMA_RECV_POST);
if (!ret) {
for (i=0 ; i<options->recv_count ; i++) {
- post = rdma_get_post (&device->recvq);
- if (rdma_post_recv (device->srq, post) != 0) {
+ post = gf_rdma_get_post (&device->recvq);
+ if (gf_rdma_post_recv (device->srq, post) != 0) {
ret = -1;
break;
}
@@ -2376,17 +2453,17 @@ rdma_create_posts (rpc_transport_t *this)
}
if (ret)
- rdma_destroy_posts (this);
+ gf_rdma_destroy_posts (this);
return ret;
}
static int32_t
-rdma_connect_qp (rpc_transport_t *this)
+gf_rdma_connect_qp (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- rdma_options_t *options = &priv->options;
+ gf_rdma_private_t *priv = this->private;
+ gf_rdma_options_t *options = &priv->options;
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_RTR,
.path_mtu = options->mtu,
@@ -2412,17 +2489,16 @@ rdma_connect_qp (rpc_transport_t *this)
IBV_QP_RQ_PSN |
IBV_QP_MAX_DEST_RD_ATOMIC |
IBV_QP_MIN_RNR_TIMER)) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_CRITICAL,
"Failed to modify QP to RTR\n");
return -1;
}
- /* TODO: make timeout and retry_cnt configurable from options */
attr.qp_state = IBV_QPS_RTS;
- attr.timeout = 14;
- attr.retry_cnt = 7;
- attr.rnr_retry = 7;
+ attr.timeout = options->attr_timeout;
+ attr.retry_cnt = options->attr_retry_cnt;
+ attr.rnr_retry = options->attr_rnr_retry;
attr.sq_psn = priv->peer.local_psn;
attr.max_rd_atomic = 1;
if (ibv_modify_qp (priv->peer.qp, &attr,
@@ -2432,7 +2508,7 @@ rdma_connect_qp (rpc_transport_t *this)
IBV_QP_RNR_RETRY |
IBV_QP_SQ_PSN |
IBV_QP_MAX_QP_RD_ATOMIC)) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_CRITICAL,
"Failed to modify QP to RTS\n");
return -1;
@@ -2442,14 +2518,15 @@ rdma_connect_qp (rpc_transport_t *this)
}
static int32_t
-__rdma_teardown (rpc_transport_t *this)
+__gf_rdma_teardown (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
+ gf_rdma_private_t *priv = NULL;
- __rdma_destroy_qp (this);
+ priv = this->private;
+ __gf_rdma_destroy_qp (this);
if (!list_empty (&priv->peer.ioq)) {
- __rdma_ioq_flush (&priv->peer);
+ __gf_rdma_ioq_flush (&priv->peer);
}
/* TODO: decrement cq size */
@@ -2468,15 +2545,17 @@ __tcp_rwv (rpc_transport_t *this, struct iovec *vector, int count,
struct iovec **pending_vector, int *pending_count,
int write)
{
- rdma_private_t *priv = NULL;
- int sock = -1;
- int ret = -1;
- struct iovec *opvector = vector;
- int opcount = count;
- int moved = 0;
+ gf_rdma_private_t *priv = NULL;
+ int sock = -1;
+ int ret = -1;
+ struct iovec *opvector = NULL;
+ int opcount = 0;
+ int moved = 0;
priv = this->private;
sock = priv->sock;
+ opvector = vector;
+ opcount = count;
while (opcount)
{
@@ -2579,8 +2658,10 @@ static int
__tcp_writev (rpc_transport_t *this, struct iovec *vector, int count,
struct iovec **pending_vector, int *pending_count)
{
- int ret = -1;
- rdma_private_t *priv = this->private;
+ int ret = -1;
+ gf_rdma_private_t *priv = NULL;
+
+ priv = this->private;
ret = __tcp_rwv (this, vector, count, pending_vector,
pending_count, 1);
@@ -2607,12 +2688,12 @@ __tcp_writev (rpc_transport_t *this, struct iovec *vector, int count,
* event is sent to upper layers.
*/
int32_t
-rdma_get_write_chunklist (char **ptr, rdma_write_array_t **write_ary)
+gf_rdma_get_write_chunklist (char **ptr, gf_rdma_write_array_t **write_ary)
{
- rdma_write_array_t *from = NULL, *to = NULL;
- int32_t ret = -1, size = 0, i = 0;
+ gf_rdma_write_array_t *from = NULL, *to = NULL;
+ int32_t ret = -1, size = 0, i = 0;
- from = (rdma_write_array_t *) *ptr;
+ from = (gf_rdma_write_array_t *) *ptr;
if (from->wc_discrim == 0) {
ret = 0;
goto out;
@@ -2621,7 +2702,7 @@ rdma_get_write_chunklist (char **ptr, rdma_write_array_t **write_ary)
from->wc_nchunks = ntoh32 (from->wc_nchunks);
size = sizeof (*from)
- + (sizeof (rdma_write_chunk_t) * from->wc_nchunks);
+ + (sizeof (gf_rdma_write_chunk_t) * from->wc_nchunks);
to = GF_CALLOC (1, size, gf_common_mt_char);
if (to == NULL) {
@@ -2655,13 +2736,13 @@ out:
* rdma-reads and hence readchunk-list can point to memory held by post.
*/
int32_t
-rdma_get_read_chunklist (char **ptr, rdma_read_chunk_t **readch)
+gf_rdma_get_read_chunklist (char **ptr, gf_rdma_read_chunk_t **readch)
{
- int32_t ret = -1;
- rdma_read_chunk_t *chunk = NULL;
- int i = 0;
+ int32_t ret = -1;
+ gf_rdma_read_chunk_t *chunk = NULL;
+ int i = 0;
- chunk = (rdma_read_chunk_t *)*ptr;
+ chunk = (gf_rdma_read_chunk_t *)*ptr;
if (chunk[0].rc_discrim == 0) {
ret = 0;
goto out;
@@ -2687,25 +2768,30 @@ out:
inline int32_t
-rdma_decode_error_msg (rdma_peer_t *peer, rdma_post_t *post,
- size_t bytes_in_post)
+gf_rdma_decode_error_msg (gf_rdma_peer_t *peer, gf_rdma_post_t *post,
+ size_t bytes_in_post)
{
- rdma_header_t *header = NULL;
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- int32_t ret = -1;
+ gf_rdma_header_t *header = NULL;
+ struct iobuf *iobuf = NULL;
+ struct iobref *iobref = NULL;
+ int32_t ret = -1;
+ struct rpc_msg rpc_msg = {0, };
- header = (rdma_header_t *)post->buf;
+ header = (gf_rdma_header_t *)post->buf;
header->rm_body.rm_error.rm_type
= ntoh32 (header->rm_body.rm_error.rm_type);
if (header->rm_body.rm_error.rm_type == ERR_VERS) {
- header->rm_body.rm_error.rm_version.rdma_vers_low =
- ntoh32 (header->rm_body.rm_error.rm_version.rdma_vers_low);
- header->rm_body.rm_error.rm_version.rdma_vers_high =
- ntoh32 (header->rm_body.rm_error.rm_version.rdma_vers_high);
+ header->rm_body.rm_error.rm_version.gf_rdma_vers_low =
+ ntoh32 (header->rm_body.rm_error.rm_version.gf_rdma_vers_low);
+ header->rm_body.rm_error.rm_version.gf_rdma_vers_high =
+ ntoh32 (header->rm_body.rm_error.rm_version.gf_rdma_vers_high);
}
- iobuf = iobuf_get (peer->trans->ctx->iobuf_pool);
+ rpc_msg.rm_xid = header->rm_xid;
+ rpc_msg.rm_direction = REPLY;
+ rpc_msg.rm_reply.rp_stat = MSG_DENIED;
+
+ iobuf = iobuf_get2 (peer->trans->ctx->iobuf_pool, bytes_in_post);
if (iobuf == NULL) {
ret = -1;
goto out;
@@ -2719,15 +2805,15 @@ rdma_decode_error_msg (rdma_peer_t *peer, rdma_post_t *post,
iobref_add (iobref, iobuf);
iobuf_unref (iobuf);
- /*
- * FIXME: construct an appropriate rpc-msg here, what is being sent
- * to rpc is not correct.
- */
- post->ctx.vector[0].iov_base = iobuf_ptr (iobuf);
- post->ctx.vector[0].iov_len = bytes_in_post;
-
- memcpy (post->ctx.vector[0].iov_base, (char *)post->buf,
- post->ctx.vector[0].iov_len);
+
+ ret = rpc_reply_to_xdr (&rpc_msg, iobuf_ptr (iobuf),
+ iobuf_pagesize (iobuf), &post->ctx.vector[0]);
+ if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "Failed to create RPC reply");
+ goto out;
+ }
+
post->ctx.count = 1;
iobuf = NULL;
@@ -2749,30 +2835,34 @@ out:
int32_t
-rdma_decode_msg (rdma_peer_t *peer, rdma_post_t *post,
- rdma_read_chunk_t **readch, size_t bytes_in_post)
+gf_rdma_decode_msg (gf_rdma_peer_t *peer, gf_rdma_post_t *post,
+ gf_rdma_read_chunk_t **readch, size_t bytes_in_post)
{
- int32_t ret = -1;
- rdma_header_t *header = NULL;
- rdma_reply_info_t *reply_info = NULL;
- char *ptr = NULL;
- rdma_write_array_t *write_ary = NULL;
- size_t header_len = 0;
+ int32_t ret = -1;
+ gf_rdma_header_t *header = NULL;
+ gf_rdma_reply_info_t *reply_info = NULL;
+ char *ptr = NULL;
+ gf_rdma_write_array_t *write_ary = NULL;
+ size_t header_len = 0;
- header = (rdma_header_t *)post->buf;
+ header = (gf_rdma_header_t *)post->buf;
ptr = (char *)&header->rm_body.rm_chunks[0];
- ret = rdma_get_read_chunklist (&ptr, readch);
+ ret = gf_rdma_get_read_chunklist (&ptr, readch);
if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot get read chunklist from msg");
goto out;
}
/* skip terminator of read-chunklist */
ptr = ptr + sizeof (uint32_t);
- ret = rdma_get_write_chunklist (&ptr, &write_ary);
+ ret = gf_rdma_get_write_chunklist (&ptr, &write_ary);
if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot get write chunklist from msg");
goto out;
}
@@ -2780,29 +2870,35 @@ rdma_decode_msg (rdma_peer_t *peer, rdma_post_t *post,
ptr = ptr + sizeof (uint32_t);
if (write_ary != NULL) {
- reply_info = rdma_reply_info_alloc (peer);
+ reply_info = gf_rdma_reply_info_alloc (peer);
if (reply_info == NULL) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "reply_info_alloc failed");
ret = -1;
goto out;
}
- reply_info->type = rdma_writech;
+ reply_info->type = gf_rdma_writech;
reply_info->wc_array = write_ary;
reply_info->rm_xid = header->rm_xid;
} else {
- ret = rdma_get_write_chunklist (&ptr, &write_ary);
+ ret = gf_rdma_get_write_chunklist (&ptr, &write_ary);
if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot get reply chunklist from msg");
goto out;
}
if (write_ary != NULL) {
- reply_info = rdma_reply_info_alloc (peer);
+ reply_info = gf_rdma_reply_info_alloc (peer);
if (reply_info == NULL) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "reply_info_alloc_failed");
ret = -1;
goto out;
}
- reply_info->type = rdma_replych;
+ reply_info->type = gf_rdma_replych;
reply_info->wc_array = write_ary;
reply_info->rm_xid = header->rm_xid;
}
@@ -2810,16 +2906,18 @@ rdma_decode_msg (rdma_peer_t *peer, rdma_post_t *post,
/* skip terminator of reply chunk */
ptr = ptr + sizeof (uint32_t);
- if (header->rm_type != RDMA_NOMSG) {
- post->ctx.hdr_iobuf = iobuf_get (peer->trans->ctx->iobuf_pool);
+ if (header->rm_type != GF_RDMA_NOMSG) {
+ header_len = (long)ptr - (long)post->buf;
+ post->ctx.vector[0].iov_len = (bytes_in_post - header_len);
+
+ post->ctx.hdr_iobuf = iobuf_get2 (peer->trans->ctx->iobuf_pool,
+ (bytes_in_post - header_len));
if (post->ctx.hdr_iobuf == NULL) {
ret = -1;
goto out;
}
- header_len = (long)ptr - (long)post->buf;
post->ctx.vector[0].iov_base = iobuf_ptr (post->ctx.hdr_iobuf);
- post->ctx.vector[0].iov_len = bytes_in_post - header_len;
memcpy (post->ctx.vector[0].iov_base, ptr,
post->ctx.vector[0].iov_len);
post->ctx.count = 1;
@@ -2844,13 +2942,13 @@ out:
/* Assumes only one of either write-chunklist or a reply chunk is present */
int32_t
-rdma_decode_header (rdma_peer_t *peer, rdma_post_t *post,
- rdma_read_chunk_t **readch, size_t bytes_in_post)
+gf_rdma_decode_header (gf_rdma_peer_t *peer, gf_rdma_post_t *post,
+ gf_rdma_read_chunk_t **readch, size_t bytes_in_post)
{
- int32_t ret = -1;
- rdma_header_t *header = NULL;
+ int32_t ret = -1;
+ gf_rdma_header_t *header = NULL;
- header = (rdma_header_t *)post->buf;
+ header = (gf_rdma_header_t *)post->buf;
header->rm_xid = ntoh32 (header->rm_xid);
header->rm_vers = ntoh32 (header->rm_vers);
@@ -2858,31 +2956,39 @@ rdma_decode_header (rdma_peer_t *peer, rdma_post_t *post,
header->rm_type = ntoh32 (header->rm_type);
switch (header->rm_type) {
- case RDMA_MSG:
- case RDMA_NOMSG:
- ret = rdma_decode_msg (peer, post, readch, bytes_in_post);
+ case GF_RDMA_MSG:
+ case GF_RDMA_NOMSG:
+ ret = gf_rdma_decode_msg (peer, post, readch, bytes_in_post);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot decode msg of type (%d)",
+ header->rm_type);
+ }
+
break;
- case RDMA_MSGP:
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
- "rdma msg of msg-type RDMA_MSGP should not have been "
- "received");
+ case GF_RDMA_MSGP:
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "rdma msg of msg-type GF_RDMA_MSGP should not have "
+ "been received");
ret = -1;
break;
- case RDMA_DONE:
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
- "rdma msg of msg-type RDMA_DONE should not have been "
- "received");
+ case GF_RDMA_DONE:
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "rdma msg of msg-type GF_RDMA_DONE should not have "
+ "been received");
ret = -1;
break;
- case RDMA_ERROR:
- /* ret = rdma_decode_error_msg (peer, post, bytes_in_post); */
+ case GF_RDMA_ERROR:
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "received a msg of type RDMA_ERROR");
+ ret = gf_rdma_decode_error_msg (peer, post, bytes_in_post);
break;
default:
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"unknown rdma msg-type (%d)", header->rm_type);
}
@@ -2891,15 +2997,17 @@ rdma_decode_header (rdma_peer_t *peer, rdma_post_t *post,
int32_t
-__rdma_read (rdma_peer_t *peer, rdma_post_t *post, struct iovec *to,
- rdma_read_chunk_t *readch)
+__gf_rdma_read (gf_rdma_peer_t *peer, gf_rdma_post_t *post, struct iovec *to,
+ gf_rdma_read_chunk_t *readch)
{
- int32_t ret = -1;
+ int32_t ret = -1;
struct ibv_sge list = {0, };
- struct ibv_send_wr wr = {0, }, *bad_wr = NULL;
+ struct ibv_send_wr wr = {0, }, *bad_wr = NULL;
- ret = __rdma_register_local_mr_for_rdma (peer, to, 1, &post->ctx);
+ ret = __gf_rdma_register_local_mr_for_rdma (peer, to, 1, &post->ctx);
if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "registering local memory for rdma read failed");
goto out;
}
@@ -2907,7 +3015,7 @@ __rdma_read (rdma_peer_t *peer, rdma_post_t *post, struct iovec *to,
list.length = to->iov_len;
list.lkey = post->ctx.mr[post->ctx.mr_count - 1]->lkey;
- wr.wr_id = (unsigned long) rdma_post_ref (post);
+ wr.wr_id = (unsigned long) gf_rdma_post_ref (post);
wr.sg_list = &list;
wr.num_sge = 1;
wr.opcode = IBV_WR_RDMA_READ;
@@ -2917,12 +3025,13 @@ __rdma_read (rdma_peer_t *peer, rdma_post_t *post, struct iovec *to,
ret = ibv_post_send (peer->qp, &wr, &bad_wr);
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG, "rdma read from client "
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "rdma read from client "
"(%s) failed with ret = %d (%s)",
peer->trans->peerinfo.identifier,
ret, (ret > 0) ? strerror (ret) : "");
ret = -1;
- rdma_post_unref (post);
+ gf_rdma_post_unref (post);
}
out:
return ret;
@@ -2930,13 +3039,14 @@ out:
int32_t
-rdma_do_reads (rdma_peer_t *peer, rdma_post_t *post, rdma_read_chunk_t *readch)
+gf_rdma_do_reads (gf_rdma_peer_t *peer, gf_rdma_post_t *post,
+ gf_rdma_read_chunk_t *readch)
{
- int32_t ret = -1, i = 0, count = 0;
- size_t size = 0;
- char *ptr = NULL;
- struct iobuf *iobuf = NULL;
- rdma_private_t *priv = NULL;
+ int32_t ret = -1, i = 0, count = 0;
+ size_t size = 0;
+ char *ptr = NULL;
+ struct iobuf *iobuf = NULL;
+ gf_rdma_private_t *priv = NULL;
priv = peer->trans->private;
@@ -2945,24 +3055,15 @@ rdma_do_reads (rdma_peer_t *peer, rdma_post_t *post, rdma_read_chunk_t *readch)
}
if (i == 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"message type specified as rdma-read but there are no "
"rdma read-chunks present");
goto out;
}
- post->ctx.rdma_reads = i;
+ post->ctx.gf_rdma_reads = i;
- if (size > peer->trans->ctx->page_size) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
- "total size of rdma-read (%lu) is greater than "
- "page-size (%lu). This is not supported till variable "
- "sized iobufs are implemented", (unsigned long)size,
- (unsigned long)peer->trans->ctx->page_size);
- goto out;
- }
-
- iobuf = iobuf_get (peer->trans->ctx->iobuf_pool);
+ iobuf = iobuf_get2 (peer->trans->ctx->iobuf_pool, size);
if (iobuf == NULL) {
goto out;
}
@@ -2984,6 +3085,10 @@ rdma_do_reads (rdma_peer_t *peer, rdma_post_t *post, rdma_read_chunk_t *readch)
pthread_mutex_lock (&priv->write_mutex);
{
if (!priv->connected) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "transport not connected to peer (%s), "
+ "not doing rdma reads",
+ peer->trans->peerinfo.identifier);
goto unlock;
}
@@ -2993,10 +3098,13 @@ rdma_do_reads (rdma_peer_t *peer, rdma_post_t *post, rdma_read_chunk_t *readch)
post->ctx.vector[count].iov_len
= readch[i].rc_target.rs_length;
- ret = __rdma_read (peer, post,
- &post->ctx.vector[count],
- &readch[i]);
+ ret = __gf_rdma_read (peer, post,
+ &post->ctx.vector[count],
+ &readch[i]);
if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "rdma read from peer (%s) failed",
+ peer->trans->peerinfo.identifier);
goto unlock;
}
@@ -3020,16 +3128,16 @@ out:
int32_t
-rdma_pollin_notify (rdma_peer_t *peer, rdma_post_t *post)
+gf_rdma_pollin_notify (gf_rdma_peer_t *peer, gf_rdma_post_t *post)
{
- int32_t ret = -1;
- enum msg_type msg_type = 0;
- struct rpc_req *rpc_req = NULL;
- rdma_request_context_t *request_context = NULL;
- rpc_request_info_t request_info = {0, };
- rdma_private_t *priv = NULL;
- uint32_t *ptr = NULL;
- rpc_transport_pollin_t *pollin = NULL;
+ int32_t ret = -1;
+ enum msg_type msg_type = 0;
+ struct rpc_req *rpc_req = NULL;
+ gf_rdma_request_context_t *request_context = NULL;
+ rpc_request_info_t request_info = {0, };
+ gf_rdma_private_t *priv = NULL;
+ uint32_t *ptr = NULL;
+ rpc_transport_pollin_t *pollin = NULL;
if ((peer == NULL) || (post == NULL)) {
goto out;
@@ -3046,7 +3154,8 @@ rdma_pollin_notify (rdma_peer_t *peer, rdma_post_t *post)
* because of server sending entire msg as inline without
* doing rdma writes.
*/
- iobref_add (post->ctx.iobref, post->ctx.hdr_iobuf);
+ if (post->ctx.hdr_iobuf)
+ iobref_add (post->ctx.iobref, post->ctx.hdr_iobuf);
}
pollin = rpc_transport_pollin_alloc (peer->trans,
@@ -3069,7 +3178,7 @@ rdma_pollin_notify (rdma_peer_t *peer, rdma_post_t *post)
RPC_TRANSPORT_MAP_XID_REQUEST,
&request_info);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
"cannot get request information from rpc "
"layer");
goto out;
@@ -3077,7 +3186,7 @@ rdma_pollin_notify (rdma_peer_t *peer, rdma_post_t *post)
rpc_req = request_info.rpc_req;
if (rpc_req == NULL) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
"rpc request structure not found");
ret = -1;
goto out;
@@ -3090,11 +3199,11 @@ rdma_pollin_notify (rdma_peer_t *peer, rdma_post_t *post)
if (request_context != NULL) {
pthread_mutex_lock (&priv->write_mutex);
{
- __rdma_request_context_destroy (request_context);
+ __gf_rdma_request_context_destroy (request_context);
}
pthread_mutex_unlock (&priv->write_mutex);
} else {
- rdma_quota_put (peer);
+ gf_rdma_quota_put (peer);
}
pollin->is_reply = 1;
@@ -3102,6 +3211,10 @@ rdma_pollin_notify (rdma_peer_t *peer, rdma_post_t *post)
ret = rpc_transport_notify (peer->trans, RPC_TRANSPORT_MSG_RECEIVED,
pollin);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "transport_notify failed");
+ }
out:
if (pollin != NULL) {
@@ -3114,19 +3227,19 @@ out:
int32_t
-rdma_recv_reply (rdma_peer_t *peer, rdma_post_t *post)
+gf_rdma_recv_reply (gf_rdma_peer_t *peer, gf_rdma_post_t *post)
{
- int32_t ret = -1;
- rdma_header_t *header = NULL;
- rdma_reply_info_t *reply_info = NULL;
- rdma_write_array_t *wc_array = NULL;
- int i = 0;
- uint32_t *ptr = NULL;
- rdma_request_context_t *ctx = NULL;
- rpc_request_info_t request_info = {0, };
- struct rpc_req *rpc_req = NULL;
-
- header = (rdma_header_t *)post->buf;
+ int32_t ret = -1;
+ gf_rdma_header_t *header = NULL;
+ gf_rdma_reply_info_t *reply_info = NULL;
+ gf_rdma_write_array_t *wc_array = NULL;
+ int i = 0;
+ uint32_t *ptr = NULL;
+ gf_rdma_request_context_t *ctx = NULL;
+ rpc_request_info_t request_info = {0, };
+ struct rpc_req *rpc_req = NULL;
+
+ header = (gf_rdma_header_t *)post->buf;
reply_info = post->ctx.reply_info;
/* no write chunklist, just notify upper layers */
@@ -3137,7 +3250,7 @@ rdma_recv_reply (rdma_peer_t *peer, rdma_post_t *post)
wc_array = reply_info->wc_array;
- if (header->rm_type == RDMA_NOMSG) {
+ if (header->rm_type == GF_RDMA_NOMSG) {
post->ctx.vector[0].iov_base
= (void *)(long)wc_array->wc_array[0].wc_target.rs_offset;
post->ctx.vector[0].iov_len
@@ -3162,32 +3275,36 @@ rdma_recv_reply (rdma_peer_t *peer, rdma_post_t *post)
RPC_TRANSPORT_MAP_XID_REQUEST,
&request_info);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
- "cannot get request information from rpc "
- "layer");
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "cannot get request information (peer:%s) from rpc "
+ "layer", peer->trans->peerinfo.identifier);
goto out;
}
rpc_req = request_info.rpc_req;
if (rpc_req == NULL) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"rpc request structure not found");
ret = -1;
goto out;
}
ctx = rpc_req->conn_private;
- if (post->ctx.iobref == NULL) {
+ if ((post->ctx.iobref == NULL) && ctx->rsp_iobref) {
post->ctx.iobref = iobref_ref (ctx->rsp_iobref);
}
ret = 0;
- rdma_reply_info_destroy (reply_info);
+ gf_rdma_reply_info_destroy (reply_info);
out:
if (ret == 0) {
- ret = rdma_pollin_notify (peer, post);
+ ret = gf_rdma_pollin_notify (peer, post);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "pollin notify failed");
+ }
}
return ret;
@@ -3195,17 +3312,22 @@ out:
inline int32_t
-rdma_recv_request (rdma_peer_t *peer, rdma_post_t *post,
- rdma_read_chunk_t *readch)
+gf_rdma_recv_request (gf_rdma_peer_t *peer, gf_rdma_post_t *post,
+ gf_rdma_read_chunk_t *readch)
{
int32_t ret = -1;
if (readch != NULL) {
- ret = rdma_do_reads (peer, post, readch);
+ ret = gf_rdma_do_reads (peer, post, readch);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "rdma read from peer (%s) failed",
+ peer->trans->peerinfo.identifier);
+ }
} else {
- ret = rdma_pollin_notify (peer, post);
+ ret = gf_rdma_pollin_notify (peer, post);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"pollin notification failed");
}
}
@@ -3214,38 +3336,38 @@ rdma_recv_request (rdma_peer_t *peer, rdma_post_t *post,
}
void
-rdma_process_recv (rdma_peer_t *peer, struct ibv_wc *wc)
+gf_rdma_process_recv (gf_rdma_peer_t *peer, struct ibv_wc *wc)
{
- rdma_post_t *post = NULL;
- rdma_read_chunk_t *readch = NULL;
- int ret = -1;
- uint32_t *ptr = NULL;
- enum msg_type msg_type = 0;
- rdma_header_t *header = NULL;
-
- post = (rdma_post_t *) (long) wc->wr_id;
+ gf_rdma_post_t *post = NULL;
+ gf_rdma_read_chunk_t *readch = NULL;
+ int ret = -1;
+ uint32_t *ptr = NULL;
+ enum msg_type msg_type = 0;
+ gf_rdma_header_t *header = NULL;
+
+ post = (gf_rdma_post_t *) (long) wc->wr_id;
if (post == NULL) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"no post found in successful work completion element");
goto out;
}
- ret = rdma_decode_header (peer, post, &readch, wc->byte_len);
+ ret = gf_rdma_decode_header (peer, post, &readch, wc->byte_len);
if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"decoding of header failed");
goto out;
}
- header = (rdma_header_t *)post->buf;
+ header = (gf_rdma_header_t *)post->buf;
switch (header->rm_type) {
- case RDMA_MSG:
+ case GF_RDMA_MSG:
ptr = (uint32_t *)post->ctx.vector[0].iov_base;
msg_type = ntoh32 (*(ptr + 1));
break;
- case RDMA_NOMSG:
+ case GF_RDMA_NOMSG:
if (readch != NULL) {
msg_type = CALL;
} else {
@@ -3253,31 +3375,48 @@ rdma_process_recv (rdma_peer_t *peer, struct ibv_wc *wc)
}
break;
- case RDMA_ERROR:
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
- "an error has happened while transmission of msg, "
- "disconnecting the transport");
- rpc_transport_disconnect (peer->trans);
- goto out;
-
-/* ret = rdma_pollin_notify (peer, post);
- if (ret == -1) {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
- "pollin notification failed");
- }
- goto out;
-*/
+ case GF_RDMA_ERROR:
+ if (header->rm_body.rm_error.rm_type == ERR_CHUNK) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "peer (%s), couldn't encode or decode the msg "
+ "properly or write chunks were not provided "
+ "for replies that were bigger than "
+ "RDMA_INLINE_THRESHOLD (%d)",
+ peer->trans->peerinfo.identifier,
+ GLUSTERFS_RDMA_INLINE_THRESHOLD);
+ ret = gf_rdma_pollin_notify (peer, post);
+ if (ret == -1) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
+ "pollin notification failed");
+ }
+ goto out;
+ } else {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
+ "an error has happened while transmission of "
+ "msg, disconnecting the transport");
+ goto out;
+ }
default:
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"invalid rdma msg-type (%d)", header->rm_type);
- break;
+ goto out;
}
if (msg_type == CALL) {
- ret = rdma_recv_request (peer, post, readch);
+ ret = gf_rdma_recv_request (peer, post, readch);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "receiving a request from peer (%s) failed",
+ peer->trans->peerinfo.identifier);
+ }
} else {
- ret = rdma_recv_reply (peer, post);
+ ret = gf_rdma_recv_reply (peer, post);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "receiving a reply from peer (%s) failed",
+ peer->trans->peerinfo.identifier);
+ }
}
out:
@@ -3290,12 +3429,12 @@ out:
static void *
-rdma_recv_completion_proc (void *data)
+gf_rdma_recv_completion_proc (void *data)
{
struct ibv_comp_channel *chan = NULL;
- rdma_device_t *device = NULL;;
- rdma_post_t *post = NULL;
- rdma_peer_t *peer = NULL;
+ gf_rdma_device_t *device = NULL;;
+ gf_rdma_post_t *post = NULL;
+ gf_rdma_peer_t *peer = NULL;
struct ibv_cq *event_cq = NULL;
struct ibv_wc wc = {0, };
void *event_ctx = NULL;
@@ -3306,7 +3445,7 @@ rdma_recv_completion_proc (void *data)
while (1) {
ret = ibv_get_cq_event (chan, &event_cq, &event_ctx);
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"ibv_get_cq_event failed, terminating recv "
"thread %d (%d)", ret, errno);
continue;
@@ -3316,26 +3455,26 @@ rdma_recv_completion_proc (void *data)
ret = ibv_req_notify_cq (event_cq, 0);
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"ibv_req_notify_cq on %s failed, terminating "
"recv thread: %d (%d)",
device->device_name, ret, errno);
continue;
}
- device = (rdma_device_t *) event_ctx;
+ device = (gf_rdma_device_t *) event_ctx;
while ((ret = ibv_poll_cq (event_cq, 1, &wc)) > 0) {
- post = (rdma_post_t *) (long) wc.wr_id;
+ post = (gf_rdma_post_t *) (long) wc.wr_id;
pthread_mutex_lock (&device->qpreg.lock);
{
- peer = __rdma_lookup_peer (device,
- wc.qp_num);
+ peer = __gf_rdma_lookup_peer (device,
+ wc.qp_num);
/*
* keep a refcount on transport so that it
- * doesnot get freed because of some error
+ * does not get freed because of some error
* indicated by wc.status till we are done
* with usage of peer and thereby that of trans.
*/
@@ -3346,7 +3485,7 @@ rdma_recv_completion_proc (void *data)
pthread_mutex_unlock (&device->qpreg.lock);
if (wc.status != IBV_WC_SUCCESS) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"recv work request on `%s' returned "
"error (%d)", device->device_name,
wc.status);
@@ -3356,26 +3495,26 @@ rdma_recv_completion_proc (void *data)
}
if (post) {
- rdma_post_unref (post);
+ gf_rdma_post_unref (post);
}
continue;
}
if (peer) {
- rdma_process_recv (peer, &wc);
+ gf_rdma_process_recv (peer, &wc);
rpc_transport_unref (peer->trans);
} else {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_DEBUG,
"could not lookup peer for qp_num: %d",
wc.qp_num);
}
- rdma_post_unref (post);
+ gf_rdma_post_unref (post);
}
if (ret < 0) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_ERROR,
"ibv_poll_cq on `%s' returned error "
"(ret = %d, errno = %d)",
@@ -3390,11 +3529,11 @@ rdma_recv_completion_proc (void *data)
void
-rdma_handle_failed_send_completion (rdma_peer_t *peer, struct ibv_wc *wc)
+gf_rdma_handle_failed_send_completion (gf_rdma_peer_t *peer, struct ibv_wc *wc)
{
- rdma_post_t *post = NULL;
- rdma_device_t *device = NULL;
- rdma_private_t *priv = NULL;
+ gf_rdma_post_t *post = NULL;
+ gf_rdma_device_t *device = NULL;
+ gf_rdma_private_t *priv = NULL;
if (peer != NULL) {
priv = peer->trans->private;
@@ -3404,9 +3543,9 @@ rdma_handle_failed_send_completion (rdma_peer_t *peer, struct ibv_wc *wc)
}
- post = (rdma_post_t *) (long) wc->wr_id;
+ post = (gf_rdma_post_t *) (long) wc->wr_id;
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"send work request on `%s' returned error "
"wc.status = %d, wc.vendor_err = %d, post->buf = %p, "
"wc.byte_len = %d, post->reused = %d",
@@ -3431,20 +3570,22 @@ rdma_handle_failed_send_completion (rdma_peer_t *peer, struct ibv_wc *wc)
void
-rdma_handle_successful_send_completion (rdma_peer_t *peer, struct ibv_wc *wc)
+gf_rdma_handle_successful_send_completion (gf_rdma_peer_t *peer,
+ struct ibv_wc *wc)
{
- rdma_post_t *post = NULL;
- int reads = 0, ret = 0;
+ gf_rdma_post_t *post = NULL;
+ int reads = 0, ret = 0;
+ gf_rdma_header_t *header = NULL;
if (wc->opcode != IBV_WC_RDMA_READ) {
goto out;
}
- post = (rdma_post_t *)(long) wc->wr_id;
+ post = (gf_rdma_post_t *)(long) wc->wr_id;
pthread_mutex_lock (&post->lock);
{
- reads = --post->ctx.rdma_reads;
+ reads = --post->ctx.gf_rdma_reads;
}
pthread_mutex_unlock (&post->lock);
@@ -3453,7 +3594,14 @@ rdma_handle_successful_send_completion (rdma_peer_t *peer, struct ibv_wc *wc)
goto out;
}
- ret = rdma_pollin_notify (peer, post);
+ header = (gf_rdma_header_t *)post->buf;
+
+ if (header->rm_type == GF_RDMA_NOMSG) {
+ post->ctx.count = 1;
+ post->ctx.vector[0].iov_len += post->ctx.vector[1].iov_len;
+ }
+
+ ret = gf_rdma_pollin_notify (peer, post);
if ((ret == -1) && (peer != NULL)) {
rpc_transport_disconnect (peer->trans);
}
@@ -3464,14 +3612,14 @@ out:
static void *
-rdma_send_completion_proc (void *data)
+gf_rdma_send_completion_proc (void *data)
{
struct ibv_comp_channel *chan = NULL;
- rdma_post_t *post = NULL;
- rdma_peer_t *peer = NULL;
+ gf_rdma_post_t *post = NULL;
+ gf_rdma_peer_t *peer = NULL;
struct ibv_cq *event_cq = NULL;
void *event_ctx = NULL;
- rdma_device_t *device = NULL;
+ gf_rdma_device_t *device = NULL;
struct ibv_wc wc = {0, };
char is_request = 0;
int32_t ret = 0, quota_ret = 0;
@@ -3480,7 +3628,7 @@ rdma_send_completion_proc (void *data)
while (1) {
ret = ibv_get_cq_event (chan, &event_cq, &event_ctx);
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"ibv_get_cq_event on failed, terminating "
"send thread: %d (%d)", ret, errno);
continue;
@@ -3490,7 +3638,7 @@ rdma_send_completion_proc (void *data)
ret = ibv_req_notify_cq (event_cq, 0);
if (ret) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"ibv_req_notify_cq on %s failed, terminating "
"send thread: %d (%d)",
device->device_name, ret, errno);
@@ -3498,11 +3646,11 @@ rdma_send_completion_proc (void *data)
}
while ((ret = ibv_poll_cq (event_cq, 1, &wc)) > 0) {
- post = (rdma_post_t *) (long) wc.wr_id;
+ post = (gf_rdma_post_t *) (long) wc.wr_id;
pthread_mutex_lock (&device->qpreg.lock);
{
- peer = __rdma_lookup_peer (device, wc.qp_num);
+ peer = __gf_rdma_lookup_peer (device, wc.qp_num);
/*
* keep a refcount on transport so that it
@@ -3517,32 +3665,32 @@ rdma_send_completion_proc (void *data)
pthread_mutex_unlock (&device->qpreg.lock);
if (wc.status != IBV_WC_SUCCESS) {
- rdma_handle_failed_send_completion (peer, &wc);
+ gf_rdma_handle_failed_send_completion (peer, &wc);
} else {
- rdma_handle_successful_send_completion (peer,
- &wc);
+ gf_rdma_handle_successful_send_completion (peer,
+ &wc);
}
if (post) {
is_request = post->ctx.is_request;
- ret = rdma_post_unref (post);
+ ret = gf_rdma_post_unref (post);
if ((ret == 0)
&& (wc.status == IBV_WC_SUCCESS)
&& !is_request
- && (post->type == RDMA_SEND_POST)
+ && (post->type == GF_RDMA_SEND_POST)
&& (peer != NULL)) {
- /* An RDMA_RECV_POST can end up in
- * rdma_send_completion_proc for
+ /* An GF_RDMA_RECV_POST can end up in
+ * gf_rdma_send_completion_proc for
* rdma-reads, and we do not take
- * quota for getting an RDMA_RECV_POST.
+ * quota for getting an GF_RDMA_RECV_POST.
*/
/*
* if it is request, quota is returned
* after reply has come.
*/
- quota_ret = rdma_quota_put (peer);
+ quota_ret = gf_rdma_quota_put (peer);
if (quota_ret < 0) {
gf_log ("rdma", GF_LOG_DEBUG,
"failed to send "
@@ -3554,14 +3702,14 @@ rdma_send_completion_proc (void *data)
if (peer) {
rpc_transport_unref (peer->trans);
} else {
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_DEBUG,
"could not lookup peer for qp_num: %d",
wc.qp_num);
}
}
if (ret < 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"ibv_poll_cq on `%s' returned error (ret = %d,"
" errno = %d)",
device->device_name, ret, errno);
@@ -3576,19 +3724,24 @@ rdma_send_completion_proc (void *data)
static void
-rdma_options_init (rpc_transport_t *this)
+gf_rdma_options_init (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- rdma_options_t *options = &priv->options;
- int32_t mtu;
- data_t *temp;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_options_t *options = NULL;
+ int32_t mtu = 0;
+ data_t *temp = NULL;
/* TODO: validate arguments from options below */
+ priv = this->private;
+ options = &priv->options;
options->send_size = GLUSTERFS_RDMA_INLINE_THRESHOLD;/*this->ctx->page_size * 4; 512 KB*/
options->recv_size = GLUSTERFS_RDMA_INLINE_THRESHOLD;/*this->ctx->page_size * 4; 512 KB*/
options->send_count = 4096;
options->recv_count = 4096;
+ options->attr_timeout = GF_RDMA_TIMEOUT;
+ options->attr_retry_cnt = GF_RDMA_RETRY_CNT;
+ options->attr_rnr_retry = GF_RDMA_RNR_RETRY;
temp = dict_get (this->options,
"transport.rdma.work-request-send-count");
@@ -3598,7 +3751,22 @@ rdma_options_init (rpc_transport_t *this)
temp = dict_get (this->options,
"transport.rdma.work-request-recv-count");
if (temp)
- options->recv_count = data_to_int32 (temp);
+ options->recv_count = data_to_int32 (temp);
+
+ temp = dict_get (this->options, "transport.rdma.attr-timeout");
+
+ if (temp)
+ options->attr_timeout = data_to_uint8 (temp);
+
+ temp = dict_get (this->options, "transport.rdma.attr-retry-cnt");
+
+ if (temp)
+ options->attr_retry_cnt = data_to_uint8 (temp);
+
+ temp = dict_get (this->options, "transport.rdma.attr-rnr-retry");
+
+ if (temp)
+ options->attr_rnr_retry = data_to_uint8 (temp);
options->port = 1;
temp = dict_get (this->options,
@@ -3624,12 +3792,12 @@ rdma_options_init (rpc_transport_t *this)
break;
default:
if (temp)
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"%s: unrecognized MTU value '%s', defaulting "
"to '2048'", this->name,
data_to_str (temp));
else
- gf_log (RDMA_LOG_NAME, GF_LOG_TRACE,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_TRACE,
"%s: defaulting MTU to '2048'",
this->name);
options->mtu = IBV_MTU_2048;
@@ -3645,7 +3813,7 @@ rdma_options_init (rpc_transport_t *this)
}
static void
-rdma_queue_init (rdma_queue_t *queue)
+gf_rdma_queue_init (gf_rdma_queue_t *queue)
{
pthread_mutex_init (&queue->lock, NULL);
@@ -3656,20 +3824,18 @@ rdma_queue_init (rdma_queue_t *queue)
}
-static rdma_device_t *
-rdma_get_device (rpc_transport_t *this,
- struct ibv_context *ibctx)
+static gf_rdma_device_t *
+gf_rdma_get_device (rpc_transport_t *this, struct ibv_context *ibctx)
{
- glusterfs_ctx_t *ctx = NULL;
- rdma_private_t *priv = NULL;
- rdma_options_t *options = NULL;
- char *device_name = NULL;
- uint32_t port = 0;
- uint8_t active_port = 0;
- int32_t ret = 0;
- int32_t i = 0;
-
- rdma_device_t *trav = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_options_t *options = NULL;
+ char *device_name = NULL;
+ uint32_t port = 0;
+ uint8_t active_port = 0;
+ int32_t ret = 0;
+ int32_t i = 0;
+ gf_rdma_device_t *trav = NULL;
priv = this->private;
options = &priv->options;
@@ -3701,7 +3867,7 @@ rdma_get_device (rpc_transport_t *this,
if (ret < 0) {
if (!port) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"Failed to find any active ports and "
"none specified in volume file,"
" exiting");
@@ -3710,20 +3876,20 @@ rdma_get_device (rpc_transport_t *this,
}
}
- trav->request_ctx_pool = mem_pool_new (rdma_request_context_t,
- RDMA_POOL_SIZE);
+ trav->request_ctx_pool = mem_pool_new (gf_rdma_request_context_t,
+ GF_RDMA_POOL_SIZE);
if (trav->request_ctx_pool == NULL) {
return NULL;
}
- trav->ioq_pool = mem_pool_new (rdma_ioq_t, RDMA_POOL_SIZE);
+ trav->ioq_pool = mem_pool_new (gf_rdma_ioq_t, GF_RDMA_POOL_SIZE);
if (trav->ioq_pool == NULL) {
mem_pool_destroy (trav->request_ctx_pool);
return NULL;
}
- trav->reply_info_pool = mem_pool_new (rdma_reply_info_t,
- RDMA_POOL_SIZE);
+ trav->reply_info_pool = mem_pool_new (gf_rdma_reply_info_t,
+ GF_RDMA_POOL_SIZE);
if (trav->reply_info_pool == NULL) {
mem_pool_destroy (trav->request_ctx_pool);
mem_pool_destroy (trav->ioq_pool);
@@ -3736,7 +3902,7 @@ rdma_get_device (rpc_transport_t *this,
if (port) {
ret = ib_check_active_port (trav->context, port);
if (ret < 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_WARNING,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
"On device %s: provided port:%u is "
"found to be offline, continuing to "
"use the same port", device_name, port);
@@ -3744,7 +3910,7 @@ rdma_get_device (rpc_transport_t *this,
} else {
priv->options.port = active_port;
port = active_port;
- gf_log (RDMA_LOG_NAME, GF_LOG_TRACE,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_TRACE,
"Port unspecified in volume file using active "
"port: %u", port);
}
@@ -3757,7 +3923,7 @@ rdma_get_device (rpc_transport_t *this,
trav->send_chan = ibv_create_comp_channel (trav->context);
if (!trav->send_chan) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: could not create send completion channel",
device_name);
mem_pool_destroy (trav->ioq_pool);
@@ -3776,13 +3942,13 @@ rdma_get_device (rpc_transport_t *this,
ibv_destroy_comp_channel (trav->send_chan);
GF_FREE ((char *)trav->device_name);
GF_FREE (trav);
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"could not create recv completion channel");
/* TODO: cleanup current mess */
return NULL;
}
- if (rdma_create_cq (this) < 0) {
+ if (gf_rdma_create_cq (this) < 0) {
mem_pool_destroy (trav->ioq_pool);
mem_pool_destroy (trav->request_ctx_pool);
mem_pool_destroy (trav->reply_info_pool);
@@ -3790,7 +3956,7 @@ rdma_get_device (rpc_transport_t *this,
ibv_destroy_comp_channel (trav->send_chan);
GF_FREE ((char *)trav->device_name);
GF_FREE (trav);
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: could not create CQ",
this->name);
return NULL;
@@ -3803,12 +3969,12 @@ rdma_get_device (rpc_transport_t *this,
mem_pool_destroy (trav->ioq_pool);
mem_pool_destroy (trav->request_ctx_pool);
mem_pool_destroy (trav->reply_info_pool);
- rdma_destroy_cq (this);
+ gf_rdma_destroy_cq (this);
ibv_destroy_comp_channel (trav->recv_chan);
ibv_destroy_comp_channel (trav->send_chan);
GF_FREE ((char *)trav->device_name);
GF_FREE (trav);
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: could not allocate protection domain",
this->name);
return NULL;
@@ -3827,34 +3993,34 @@ rdma_get_device (rpc_transport_t *this,
mem_pool_destroy (trav->request_ctx_pool);
mem_pool_destroy (trav->reply_info_pool);
ibv_dealloc_pd (trav->pd);
- rdma_destroy_cq (this);
+ gf_rdma_destroy_cq (this);
ibv_destroy_comp_channel (trav->recv_chan);
ibv_destroy_comp_channel (trav->send_chan);
GF_FREE ((char *)trav->device_name);
GF_FREE (trav);
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: could not create SRQ",
this->name);
return NULL;
}
/* queue init */
- rdma_queue_init (&trav->sendq);
- rdma_queue_init (&trav->recvq);
+ gf_rdma_queue_init (&trav->sendq);
+ gf_rdma_queue_init (&trav->recvq);
- if (rdma_create_posts (this) < 0) {
+ if (gf_rdma_create_posts (this) < 0) {
mem_pool_destroy (trav->ioq_pool);
mem_pool_destroy (trav->request_ctx_pool);
mem_pool_destroy (trav->reply_info_pool);
ibv_dealloc_pd (trav->pd);
- rdma_destroy_cq (this);
+ gf_rdma_destroy_cq (this);
ibv_destroy_comp_channel (trav->recv_chan);
ibv_destroy_comp_channel (trav->send_chan);
GF_FREE ((char *)trav->device_name);
GF_FREE (trav);
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: could not allocate posts",
this->name);
return NULL;
@@ -3863,41 +4029,41 @@ rdma_get_device (rpc_transport_t *this,
/* completion threads */
ret = pthread_create (&trav->send_thread,
NULL,
- rdma_send_completion_proc,
+ gf_rdma_send_completion_proc,
trav->send_chan);
if (ret) {
- rdma_destroy_posts (this);
+ gf_rdma_destroy_posts (this);
mem_pool_destroy (trav->ioq_pool);
mem_pool_destroy (trav->request_ctx_pool);
mem_pool_destroy (trav->reply_info_pool);
ibv_dealloc_pd (trav->pd);
- rdma_destroy_cq (this);
+ gf_rdma_destroy_cq (this);
ibv_destroy_comp_channel (trav->recv_chan);
ibv_destroy_comp_channel (trav->send_chan);
GF_FREE ((char *)trav->device_name);
GF_FREE (trav);
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"could not create send completion thread");
return NULL;
}
ret = pthread_create (&trav->recv_thread,
NULL,
- rdma_recv_completion_proc,
+ gf_rdma_recv_completion_proc,
trav->recv_chan);
if (ret) {
- rdma_destroy_posts (this);
+ gf_rdma_destroy_posts (this);
mem_pool_destroy (trav->ioq_pool);
mem_pool_destroy (trav->request_ctx_pool);
mem_pool_destroy (trav->reply_info_pool);
ibv_dealloc_pd (trav->pd);
- rdma_destroy_cq (this);
+ gf_rdma_destroy_cq (this);
ibv_destroy_comp_channel (trav->recv_chan);
ibv_destroy_comp_channel (trav->send_chan);
GF_FREE ((char *)trav->device_name);
GF_FREE (trav);
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"could not create recv completion thread");
return NULL;
}
@@ -3913,21 +4079,25 @@ rdma_get_device (rpc_transport_t *this,
}
static int32_t
-rdma_init (rpc_transport_t *this)
+gf_rdma_init (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- rdma_options_t *options = &priv->options;
- struct ibv_device **dev_list;
- struct ibv_context *ib_ctx = NULL;
- int32_t ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_options_t *options = NULL;
+ struct ibv_device **dev_list;
+ struct ibv_context *ib_ctx = NULL;
+ int32_t ret = 0;
- rdma_options_init (this);
+ priv = this->private;
+ options = &priv->options;
+
+ ibv_fork_init ();
+ gf_rdma_options_init (this);
{
dev_list = ibv_get_device_list (NULL);
if (!dev_list) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_CRITICAL,
"Failed to get IB devices");
ret = -1;
@@ -3935,7 +4105,7 @@ rdma_init (rpc_transport_t *this)
}
if (!*dev_list) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_CRITICAL,
"No IB devices found");
ret = -1;
@@ -3947,7 +4117,7 @@ rdma_init (rpc_transport_t *this)
options->device_name =
gf_strdup (ibv_get_device_name (*dev_list));
} else {
- gf_log (RDMA_LOG_NAME, GF_LOG_CRITICAL,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_CRITICAL,
"IB device list is empty. Check for "
"'ib_uverbs' module");
return -1;
@@ -3961,7 +4131,7 @@ rdma_init (rpc_transport_t *this)
ib_ctx = ibv_open_device (*dev_list);
if (!ib_ctx) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_ERROR,
"Failed to get infiniband"
"device context");
@@ -3973,10 +4143,10 @@ rdma_init (rpc_transport_t *this)
++dev_list;
}
- priv->device = rdma_get_device (this, ib_ctx);
+ priv->device = gf_rdma_get_device (this, ib_ctx);
if (!priv->device) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"could not create rdma device for %s",
options->device_name);
ret = -1;
@@ -4006,14 +4176,19 @@ cleanup:
static int32_t
-rdma_disconnect (rpc_transport_t *this)
+gf_rdma_disconnect (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- int32_t ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ int32_t ret = 0;
+
+ priv = this->private;
+ gf_log_callingfn (this->name, GF_LOG_WARNING,
+ "disconnect called (peer:%s)",
+ this->peerinfo.identifier);
pthread_mutex_lock (&priv->write_mutex);
{
- ret = __rdma_disconnect (this);
+ ret = __gf_rdma_disconnect (this);
}
pthread_mutex_unlock (&priv->write_mutex);
@@ -4024,8 +4199,8 @@ rdma_disconnect (rpc_transport_t *this)
static int32_t
__tcp_connect_finish (int fd)
{
- int ret = -1;
- int optval = 0;
+ int ret = -1;
+ int optval = 0;
socklen_t optlen = sizeof (int);
ret = getsockopt (fd, SOL_SOCKET, SO_ERROR,
@@ -4041,8 +4216,8 @@ __tcp_connect_finish (int fd)
}
static inline void
-rdma_fill_handshake_data (char *buf, struct rdma_nbio *nbio,
- rdma_private_t *priv)
+gf_rdma_fill_handshake_data (char *buf, struct gf_rdma_nbio *nbio,
+ gf_rdma_private_t *priv)
{
sprintf (buf,
"QP1:RECV_BLKSIZE=%08x:SEND_BLKSIZE=%08x\n"
@@ -4060,7 +4235,7 @@ rdma_fill_handshake_data (char *buf, struct rdma_nbio *nbio,
}
static inline void
-rdma_fill_handshake_ack (char *buf, struct rdma_nbio *nbio)
+gf_rdma_fill_handshake_ack (char *buf, struct gf_rdma_nbio *nbio)
{
sprintf (buf, "DONE\n");
nbio->vector.iov_base = buf;
@@ -4070,32 +4245,35 @@ rdma_fill_handshake_ack (char *buf, struct rdma_nbio *nbio)
}
static int
-rdma_handshake_pollin (rpc_transport_t *this)
+gf_rdma_handshake_pollin (rpc_transport_t *this)
{
- int ret = 0;
- rdma_private_t *priv = this->private;
- char *buf = priv->handshake.incoming.buf;
- int32_t recv_buf_size, send_buf_size;
- socklen_t sock_len;
+ int ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ char *buf = NULL;
+ int32_t recv_buf_size = 0, send_buf_size;
+ socklen_t sock_len = 0;
- if (priv->handshake.incoming.state == RDMA_HANDSHAKE_COMPLETE) {
+ priv = this->private;
+ buf = priv->handshake.incoming.buf;
+
+ if (priv->handshake.incoming.state == GF_RDMA_HANDSHAKE_COMPLETE) {
return -1;
}
pthread_mutex_lock (&priv->write_mutex);
{
- while (priv->handshake.incoming.state != RDMA_HANDSHAKE_COMPLETE)
+ while (priv->handshake.incoming.state != GF_RDMA_HANDSHAKE_COMPLETE)
{
switch (priv->handshake.incoming.state)
{
- case RDMA_HANDSHAKE_START:
+ case GF_RDMA_HANDSHAKE_START:
buf = priv->handshake.incoming.buf = GF_CALLOC (1, 256, gf_common_mt_char);
- rdma_fill_handshake_data (buf, &priv->handshake.incoming, priv);
+ gf_rdma_fill_handshake_data (buf, &priv->handshake.incoming, priv);
buf[0] = 0;
- priv->handshake.incoming.state = RDMA_HANDSHAKE_RECEIVING_DATA;
+ priv->handshake.incoming.state = GF_RDMA_HANDSHAKE_RECEIVING_DATA;
break;
- case RDMA_HANDSHAKE_RECEIVING_DATA:
+ case GF_RDMA_HANDSHAKE_RECEIVING_DATA:
ret = __tcp_readv (this,
&priv->handshake.incoming.vector,
priv->handshake.incoming.count,
@@ -4112,11 +4290,11 @@ rdma_handshake_pollin (rpc_transport_t *this)
}
if (!ret) {
- priv->handshake.incoming.state = RDMA_HANDSHAKE_RECEIVED_DATA;
+ priv->handshake.incoming.state = GF_RDMA_HANDSHAKE_RECEIVED_DATA;
}
break;
- case RDMA_HANDSHAKE_RECEIVED_DATA:
+ case GF_RDMA_HANDSHAKE_RECEIVED_DATA:
ret = sscanf (buf,
"QP1:RECV_BLKSIZE=%08x:SEND_BLKSIZE=%08x\n"
"QP1:LID=%04x:QPN=%06x:PSN=%06x\n",
@@ -4127,7 +4305,7 @@ rdma_handshake_pollin (rpc_transport_t *this)
&priv->peer.remote_psn);
if ((ret != 5) && (strncmp (buf, "QP1:", 4))) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_CRITICAL,
"%s: remote-host(%s)'s "
"transport type is different",
@@ -4142,7 +4320,7 @@ rdma_handshake_pollin (rpc_transport_t *this)
if (send_buf_size < priv->peer.send_size)
priv->peer.send_size = send_buf_size;
- gf_log (RDMA_LOG_NAME, GF_LOG_TRACE,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_TRACE,
"%s: transacted recv_size=%d "
"send_size=%d",
this->name, priv->peer.recv_size,
@@ -4150,20 +4328,20 @@ rdma_handshake_pollin (rpc_transport_t *this)
priv->peer.quota = priv->peer.send_count;
- if (rdma_connect_qp (this)) {
- gf_log (RDMA_LOG_NAME,
+ if (gf_rdma_connect_qp (this)) {
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_ERROR,
"%s: failed to connect with "
"remote QP", this->name);
ret = -1;
goto unlock;
}
- rdma_fill_handshake_ack (buf, &priv->handshake.incoming);
+ gf_rdma_fill_handshake_ack (buf, &priv->handshake.incoming);
buf[0] = 0;
- priv->handshake.incoming.state = RDMA_HANDSHAKE_RECEIVING_ACK;
+ priv->handshake.incoming.state = GF_RDMA_HANDSHAKE_RECEIVING_ACK;
break;
- case RDMA_HANDSHAKE_RECEIVING_ACK:
+ case GF_RDMA_HANDSHAKE_RECEIVING_ACK:
ret = __tcp_readv (this,
&priv->handshake.incoming.vector,
priv->handshake.incoming.count,
@@ -4181,13 +4359,13 @@ rdma_handshake_pollin (rpc_transport_t *this)
}
if (!ret) {
- priv->handshake.incoming.state = RDMA_HANDSHAKE_RECEIVED_ACK;
+ priv->handshake.incoming.state = GF_RDMA_HANDSHAKE_RECEIVED_ACK;
}
break;
- case RDMA_HANDSHAKE_RECEIVED_ACK:
+ case GF_RDMA_HANDSHAKE_RECEIVED_ACK:
if (strncmp (buf, "DONE", 4)) {
- gf_log (RDMA_LOG_NAME,
+ gf_log (GF_RDMA_LOG_NAME,
GF_LOG_DEBUG,
"%s: handshake-3 did not "
"return 'DONE' (%s)",
@@ -4204,7 +4382,7 @@ rdma_handshake_pollin (rpc_transport_t *this)
GF_FREE (priv->handshake.incoming.buf);
priv->handshake.incoming.buf = NULL;
- priv->handshake.incoming.state = RDMA_HANDSHAKE_COMPLETE;
+ priv->handshake.incoming.state = GF_RDMA_HANDSHAKE_COMPLETE;
}
}
}
@@ -4233,29 +4411,36 @@ unlock:
}
static int
-rdma_handshake_pollout (rpc_transport_t *this)
+gf_rdma_handshake_pollout (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- char *buf = priv->handshake.outgoing.buf;
- int32_t ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ char *buf = NULL;
+ int32_t ret = 0;
- if (priv->handshake.outgoing.state == RDMA_HANDSHAKE_COMPLETE) {
+ priv = this->private;
+ buf = priv->handshake.outgoing.buf;
+
+ if (priv->handshake.outgoing.state == GF_RDMA_HANDSHAKE_COMPLETE) {
return 0;
}
pthread_mutex_unlock (&priv->write_mutex);
{
- while (priv->handshake.outgoing.state != RDMA_HANDSHAKE_COMPLETE)
+ while (priv->handshake.outgoing.state
+ != GF_RDMA_HANDSHAKE_COMPLETE)
{
switch (priv->handshake.outgoing.state)
{
- case RDMA_HANDSHAKE_START:
- buf = priv->handshake.outgoing.buf = GF_CALLOC (1, 256, gf_common_mt_char);
- rdma_fill_handshake_data (buf, &priv->handshake.outgoing, priv);
- priv->handshake.outgoing.state = RDMA_HANDSHAKE_SENDING_DATA;
+ case GF_RDMA_HANDSHAKE_START:
+ buf = priv->handshake.outgoing.buf
+ = GF_CALLOC (1, 256, gf_common_mt_char);
+ gf_rdma_fill_handshake_data (buf,
+ &priv->handshake.outgoing, priv);
+ priv->handshake.outgoing.state
+ = GF_RDMA_HANDSHAKE_SENDING_DATA;
break;
- case RDMA_HANDSHAKE_SENDING_DATA:
+ case GF_RDMA_HANDSHAKE_SENDING_DATA:
ret = __tcp_writev (this,
&priv->handshake.outgoing.vector,
priv->handshake.outgoing.count,
@@ -4267,21 +4452,25 @@ rdma_handshake_pollout (rpc_transport_t *this)
if (ret > 0) {
gf_log (this->name, GF_LOG_TRACE,
- "partial header read on NB socket. continue later");
+ "partial header read on NB "
+ "socket. continue later");
goto unlock;
}
if (!ret) {
- priv->handshake.outgoing.state = RDMA_HANDSHAKE_SENT_DATA;
+ priv->handshake.outgoing.state
+ = GF_RDMA_HANDSHAKE_SENT_DATA;
}
break;
- case RDMA_HANDSHAKE_SENT_DATA:
- rdma_fill_handshake_ack (buf, &priv->handshake.outgoing);
- priv->handshake.outgoing.state = RDMA_HANDSHAKE_SENDING_ACK;
+ case GF_RDMA_HANDSHAKE_SENT_DATA:
+ gf_rdma_fill_handshake_ack (buf,
+ &priv->handshake.outgoing);
+ priv->handshake.outgoing.state
+ = GF_RDMA_HANDSHAKE_SENDING_ACK;
break;
- case RDMA_HANDSHAKE_SENDING_ACK:
+ case GF_RDMA_HANDSHAKE_SENDING_ACK:
ret = __tcp_writev (this,
&priv->handshake.outgoing.vector,
priv->handshake.outgoing.count,
@@ -4302,7 +4491,8 @@ rdma_handshake_pollout (rpc_transport_t *this)
if (!ret) {
GF_FREE (priv->handshake.outgoing.buf);
priv->handshake.outgoing.buf = NULL;
- priv->handshake.outgoing.state = RDMA_HANDSHAKE_COMPLETE;
+ priv->handshake.outgoing.state
+ = GF_RDMA_HANDSHAKE_COMPLETE;
}
break;
}
@@ -4321,19 +4511,18 @@ unlock:
}
static int
-rdma_handshake_pollerr (rpc_transport_t *this)
+gf_rdma_handshake_pollerr (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- int32_t ret = 0;
- char need_unref = 0, connected = 0;
+ gf_rdma_private_t *priv = this->private;
+ char need_unref = 0, connected = 0;
- gf_log (RDMA_LOG_NAME, GF_LOG_DEBUG,
- "%s: peer disconnected, cleaning up",
- this->name);
+ gf_log_callingfn (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "%s: peer (%s) disconnected, cleaning up",
+ this->name, this->peerinfo.identifier);
pthread_mutex_lock (&priv->write_mutex);
{
- __rdma_teardown (this);
+ __gf_rdma_teardown (this);
connected = priv->connected;
if (priv->sock != -1) {
@@ -4342,10 +4531,9 @@ rdma_handshake_pollerr (rpc_transport_t *this)
need_unref = 1;
if (close (priv->sock) != 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"close () - error: %s",
strerror (errno));
- ret = -errno;
}
priv->tcp_connected = priv->connected = 0;
priv->sock = -1;
@@ -4356,14 +4544,14 @@ rdma_handshake_pollerr (rpc_transport_t *this)
priv->handshake.incoming.buf = NULL;
}
- priv->handshake.incoming.state = RDMA_HANDSHAKE_START;
+ priv->handshake.incoming.state = GF_RDMA_HANDSHAKE_START;
if (priv->handshake.outgoing.buf) {
GF_FREE (priv->handshake.outgoing.buf);
priv->handshake.outgoing.buf = NULL;
}
- priv->handshake.outgoing.state = RDMA_HANDSHAKE_START;
+ priv->handshake.outgoing.state = GF_RDMA_HANDSHAKE_START;
}
pthread_mutex_unlock (&priv->write_mutex);
@@ -4381,9 +4569,10 @@ rdma_handshake_pollerr (rpc_transport_t *this)
static int
tcp_connect_finish (rpc_transport_t *this)
{
- rdma_private_t *priv = this->private;
- int error = 0, ret = 0;
+ gf_rdma_private_t *priv = NULL;
+ int error = 0, ret = 0;
+ priv = this->private;
pthread_mutex_lock (&priv->write_mutex);
{
ret = __tcp_connect_finish (priv->sock);
@@ -4427,14 +4616,16 @@ unlock:
}
static int
-rdma_event_handler (int fd, int idx, void *data,
- int poll_in, int poll_out, int poll_err)
+gf_rdma_event_handler (int fd, int idx, void *data,
+ int poll_in, int poll_out, int poll_err)
{
- rpc_transport_t *this = data;
- rdma_private_t *priv = this->private;
- rdma_options_t *options = NULL;
- int ret = 0;
+ rpc_transport_t *this = NULL;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_options_t *options = NULL;
+ int ret = 0;
+ this = data;
+ priv = this->private;
if (!priv->tcp_connected) {
ret = tcp_connect_finish (this);
if (priv->tcp_connected) {
@@ -4445,8 +4636,8 @@ rdma_event_handler (int fd, int idx, void *data,
priv->peer.send_size = options->send_size;
priv->peer.recv_size = options->recv_size;
- if ((ret = rdma_create_qp (this)) < 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ if ((ret = gf_rdma_create_qp (this)) < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: could not create QP",
this->name);
rpc_transport_disconnect (this);
@@ -4455,23 +4646,29 @@ rdma_event_handler (int fd, int idx, void *data,
}
if (!ret && poll_out && priv->tcp_connected) {
- ret = rdma_handshake_pollout (this);
+ ret = gf_rdma_handshake_pollout (this);
}
if (!ret && !poll_err && poll_in && priv->tcp_connected) {
- if (priv->handshake.incoming.state == RDMA_HANDSHAKE_COMPLETE) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ if (priv->handshake.incoming.state
+ == GF_RDMA_HANDSHAKE_COMPLETE) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: pollin received on tcp socket (peer: %s) "
"after handshake is complete",
this->name, this->peerinfo.identifier);
- rdma_handshake_pollerr (this);
+ gf_rdma_handshake_pollerr (this);
return 0;
}
- ret = rdma_handshake_pollin (this);
+
+ ret = gf_rdma_handshake_pollin (this);
+ if (ret < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_WARNING,
+ "handshake pollin failed");
+ }
}
if (ret < 0 || poll_err) {
- ret = rdma_handshake_pollerr (this);
+ ret = gf_rdma_handshake_pollerr (this);
}
return 0;
@@ -4481,7 +4678,7 @@ static int
__tcp_nonblock (int fd)
{
int flags = 0;
- int ret = -1;
+ int ret = -1;
flags = fcntl (fd, F_GETFL);
@@ -4492,35 +4689,18 @@ __tcp_nonblock (int fd)
}
static int32_t
-rdma_connect (struct rpc_transport *this, int port)
+gf_rdma_connect (struct rpc_transport *this, int port)
{
- dict_t *options = this->options;
+ gf_rdma_private_t *priv = NULL;
+ int32_t ret = 0;
+ gf_boolean_t non_blocking = 1;
+ union gf_sock_union sock_union = {{0, }, };
+ socklen_t sockaddr_len = 0;
- rdma_private_t *priv = this->private;
-
- int32_t ret = 0;
- gf_boolean_t non_blocking = 1;
- struct sockaddr_storage sockaddr;
- socklen_t sockaddr_len = 0;
-
- if (priv->connected) {
- return 0;
- }
-
- if (dict_get (options, "non-blocking-io")) {
- char *nb_connect = data_to_str (dict_get (this->options,
- "non-blocking-io"));
-
- if (gf_string2boolean (nb_connect, &non_blocking) == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "'non-blocking-io' takes only boolean "
- "options, not taking any action");
- non_blocking = 1;
- }
- }
+ priv = this->private;
ret = gf_rdma_client_get_remote_sockaddr (this,
- (struct sockaddr *)&sockaddr,
+ &sock_union.sa,
&sockaddr_len, port);
if (ret != 0) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -4528,6 +4708,7 @@ rdma_connect (struct rpc_transport *this, int port)
return ret;
}
+
pthread_mutex_lock (&priv->write_mutex);
{
if (priv->sock != -1) {
@@ -4535,8 +4716,7 @@ rdma_connect (struct rpc_transport *this, int port)
goto unlock;
}
- priv->sock = socket (((struct sockaddr *)&sockaddr)->sa_family,
- SOCK_STREAM, 0);
+ priv->sock = socket (sock_union.sa.sa_family, SOCK_STREAM, 0);
if (priv->sock == -1) {
gf_log (this->name, GF_LOG_ERROR,
@@ -4548,12 +4728,12 @@ rdma_connect (struct rpc_transport *this, int port)
gf_log (this->name, GF_LOG_TRACE,
"socket fd = %d", priv->sock);
- memcpy (&this->peerinfo.sockaddr, &sockaddr, sockaddr_len);
+ memcpy (&this->peerinfo.sockaddr, &sock_union.storage,
+ sockaddr_len);
this->peerinfo.sockaddr_len = sockaddr_len;
if (port > 0)
- ((struct sockaddr_in *) (&sockaddr))->sin_port
- = htons (port);
+ sock_union.sin.sin_port = htons (port);
((struct sockaddr *) &this->myinfo.sockaddr)->sa_family =
((struct sockaddr *)&this->peerinfo.sockaddr)->sa_family;
@@ -4576,7 +4756,8 @@ rdma_connect (struct rpc_transport *this, int port)
ret = gf_rdma_client_bind (this,
(struct sockaddr *)&this->myinfo.sockaddr,
- &this->myinfo.sockaddr_len, priv->sock);
+ &this->myinfo.sockaddr_len,
+ priv->sock);
if (ret == -1)
{
gf_log (this->name, GF_LOG_WARNING,
@@ -4603,11 +4784,11 @@ rdma_connect (struct rpc_transport *this, int port)
rpc_transport_ref (this);
- priv->handshake.incoming.state = RDMA_HANDSHAKE_START;
- priv->handshake.outgoing.state = RDMA_HANDSHAKE_START;
+ priv->handshake.incoming.state = GF_RDMA_HANDSHAKE_START;
+ priv->handshake.outgoing.state = GF_RDMA_HANDSHAKE_START;
priv->idx = event_register (this->ctx->event_pool,
- priv->sock, rdma_event_handler,
+ priv->sock, gf_rdma_event_handler,
this, 1, 1);
}
unlock:
@@ -4617,19 +4798,22 @@ unlock:
}
static int
-rdma_server_event_handler (int fd, int idx, void *data,
- int poll_in, int poll_out, int poll_err)
+gf_rdma_server_event_handler (int fd, int idx, void *data,
+ int poll_in, int poll_out, int poll_err)
{
- int32_t main_sock = -1;
- rpc_transport_t *this, *trans = data;
- rdma_private_t *priv = NULL;
- rdma_private_t *trans_priv = (rdma_private_t *) trans->private;
- rdma_options_t *options = NULL;
+ int32_t main_sock = -1;
+ rpc_transport_t *this = NULL, *trans = NULL;
+ gf_rdma_private_t *priv = NULL;
+ gf_rdma_private_t *trans_priv = NULL;
+ gf_rdma_options_t *options = NULL;
if (!poll_in) {
return 0;
}
+ trans = data;
+ trans_priv = (gf_rdma_private_t *) trans->private;
+
this = GF_CALLOC (1, sizeof (rpc_transport_t),
gf_common_mt_rpc_transport_t);
if (this == NULL) {
@@ -4638,7 +4822,7 @@ rdma_server_event_handler (int fd, int idx, void *data,
this->listener = trans;
- priv = GF_CALLOC (1, sizeof (rdma_private_t),
+ priv = GF_CALLOC (1, sizeof (gf_rdma_private_t),
gf_common_mt_rdma_private_t);
if (priv == NULL) {
GF_FREE (priv);
@@ -4686,8 +4870,8 @@ rdma_server_event_handler (int fd, int idx, void *data,
gf_rdma_get_transport_identifiers (this);
priv->tcp_connected = 1;
- priv->handshake.incoming.state = RDMA_HANDSHAKE_START;
- priv->handshake.outgoing.state = RDMA_HANDSHAKE_START;
+ priv->handshake.incoming.state = GF_RDMA_HANDSHAKE_START;
+ priv->handshake.outgoing.state = GF_RDMA_HANDSHAKE_START;
priv->peer.send_count = options->send_count;
priv->peer.recv_count = options->recv_count;
@@ -4695,8 +4879,8 @@ rdma_server_event_handler (int fd, int idx, void *data,
priv->peer.recv_size = options->recv_size;
INIT_LIST_HEAD (&priv->peer.ioq);
- if (rdma_create_qp (this) < 0) {
- gf_log (RDMA_LOG_NAME, GF_LOG_ERROR,
+ if (gf_rdma_create_qp (this) < 0) {
+ gf_log (GF_RDMA_LOG_NAME, GF_LOG_ERROR,
"%s: could not create QP",
this->name);
rpc_transport_disconnect (this);
@@ -4704,7 +4888,7 @@ rdma_server_event_handler (int fd, int idx, void *data,
}
priv->idx = event_register (this->ctx->event_pool, priv->sock,
- rdma_event_handler, this, 1, 1);
+ gf_rdma_event_handler, this, 1, 1);
pthread_mutex_init (&priv->read_mutex, NULL);
pthread_mutex_init (&priv->write_mutex, NULL);
@@ -4714,17 +4898,18 @@ rdma_server_event_handler (int fd, int idx, void *data,
}
static int32_t
-rdma_listen (rpc_transport_t *this)
+gf_rdma_listen (rpc_transport_t *this)
{
- struct sockaddr_storage sockaddr;
- socklen_t sockaddr_len;
- rdma_private_t *priv = this->private;
- int opt = 1, ret = 0;
- char service[NI_MAXSERV], host[NI_MAXHOST];
+ union gf_sock_union sock_union = {{0, }, };
+ socklen_t sockaddr_len = 0;
+ gf_rdma_private_t *priv = NULL;
+ int opt = 1, ret = 0;
+ char service[NI_MAXSERV], host[NI_MAXHOST];
- memset (&sockaddr, 0, sizeof (sockaddr));
+ priv = this->private;
+ memset (&sock_union, 0, sizeof (sock_union));
ret = gf_rdma_server_get_local_sockaddr (this,
- (struct sockaddr *)&sockaddr,
+ &sock_union.sa,
&sockaddr_len);
if (ret != 0) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -4732,8 +4917,7 @@ rdma_listen (rpc_transport_t *this)
goto err;
}
- priv->sock = socket (((struct sockaddr *)&sockaddr)->sa_family,
- SOCK_STREAM, 0);
+ priv->sock = socket (sock_union.sa.sa_family, SOCK_STREAM, 0);
if (priv->sock == -1) {
gf_log ("rdma/server", GF_LOG_CRITICAL,
"init: failed to create socket, error: %s",
@@ -4743,7 +4927,7 @@ rdma_listen (rpc_transport_t *this)
goto err;
}
- memcpy (&this->myinfo.sockaddr, &sockaddr, sockaddr_len);
+ memcpy (&this->myinfo.sockaddr, &sock_union.storage, sockaddr_len);
this->myinfo.sockaddr_len = sockaddr_len;
ret = getnameinfo ((struct sockaddr *)&this->myinfo.sockaddr,
@@ -4759,9 +4943,7 @@ rdma_listen (rpc_transport_t *this)
sprintf (this->myinfo.identifier, "%s:%s", host, service);
setsockopt (priv->sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
- if (bind (priv->sock,
- (struct sockaddr *)&sockaddr,
- sockaddr_len) != 0) {
+ if (bind (priv->sock, &sock_union.sa, sockaddr_len) != 0) {
ret = -1;
gf_log ("rdma/server", GF_LOG_ERROR,
"init: failed to bind to socket for %s (%s)",
@@ -4779,7 +4961,7 @@ rdma_listen (rpc_transport_t *this)
/* Register the main socket */
priv->idx = event_register (this->ctx->event_pool, priv->sock,
- rdma_server_event_handler,
+ gf_rdma_server_event_handler,
rpc_transport_ref (this), 1, 0);
err:
@@ -4787,17 +4969,17 @@ err:
}
struct rpc_transport_ops tops = {
- .submit_request = rdma_submit_request,
- .submit_reply = rdma_submit_reply,
- .connect = rdma_connect,
- .disconnect = rdma_disconnect,
- .listen = rdma_listen,
+ .submit_request = gf_rdma_submit_request,
+ .submit_reply = gf_rdma_submit_reply,
+ .connect = gf_rdma_connect,
+ .disconnect = gf_rdma_disconnect,
+ .listen = gf_rdma_listen,
};
int32_t
init (rpc_transport_t *this)
{
- rdma_private_t *priv = NULL;
+ gf_rdma_private_t *priv = NULL;
priv = GF_CALLOC (1, sizeof (*priv), gf_common_mt_rdma_private_t);
if (!priv)
@@ -4806,7 +4988,7 @@ init (rpc_transport_t *this)
this->private = priv;
priv->sock = -1;
- if (rdma_init (this)) {
+ if (gf_rdma_init (this)) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to initialize IB Device");
return -1;
@@ -4819,7 +5001,10 @@ void
fini (struct rpc_transport *this)
{
/* TODO: verify this function does graceful finish */
- rdma_private_t *priv = this->private;
+ gf_rdma_private_t *priv = NULL;
+
+ priv = this->private;
+
this->private = NULL;
if (priv) {
@@ -4871,6 +5056,18 @@ struct volume_options options[] = {
"transport.rdma.remote-port"},
.type = GF_OPTION_TYPE_INT
},
+ { .key = {"transport.rdma.attr-timeout",
+ "rdma-attr-timeout"},
+ .type = GF_OPTION_TYPE_INT
+ },
+ { .key = {"transport.rdma.attr-retry-cnt",
+ "rdma-attr-retry-cnt"},
+ .type = GF_OPTION_TYPE_INT
+ },
+ { .key = {"transport.rdma.attr-rnr-retry",
+ "rdma-attr-rnr-retry"},
+ .type = GF_OPTION_TYPE_INT
+ },
{ .key = {"transport.rdma.listen-port", "listen-port"},
.type = GF_OPTION_TYPE_INT
},
diff --git a/rpc/rpc-transport/rdma/src/rdma.h b/rpc/rpc-transport/rdma/src/rdma.h
index 61cf550d4..687d6005f 100644
--- a/rpc/rpc-transport/rdma/src/rdma.h
+++ b/rpc/rpc-transport/rdma/src/rdma.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _XPORT_RDMA_H
@@ -42,49 +33,54 @@
/* FIXME: give appropriate values to these macros */
#define GF_DEFAULT_RDMA_LISTEN_PORT (GF_DEFAULT_BASE_PORT + 1)
-/* If you are changing RDMA_MAX_SEGMENTS, please make sure to update
- * GLUSTERFS_RDMA_MAX_HEADER_SIZE defined in glusterfs.h .
+/* If you are changing GF_RDMA_MAX_SEGMENTS, please make sure to update
+ * GLUSTERFS_GF_RDMA_MAX_HEADER_SIZE defined in glusterfs.h .
*/
-#define RDMA_MAX_SEGMENTS 8
+#define GF_RDMA_MAX_SEGMENTS 8
+
+#define GF_RDMA_VERSION 1
+#define GF_RDMA_POOL_SIZE 512
-#define RDMA_VERSION 1
-#define RDMA_POOL_SIZE 512
+/* Additional attributes */
+#define GF_RDMA_TIMEOUT 14
+#define GF_RDMA_RETRY_CNT 7
+#define GF_RDMA_RNR_RETRY 7
-typedef enum rdma_errcode {
+typedef enum gf_rdma_errcode {
ERR_VERS = 1,
ERR_CHUNK = 2
-}rdma_errcode_t;
+}gf_rdma_errcode_t;
-struct rdma_err_vers {
- uint32_t rdma_vers_low; /* Version range supported by peer */
- uint32_t rdma_vers_high;
+struct gf_rdma_err_vers {
+ uint32_t gf_rdma_vers_low; /* Version range supported by peer */
+ uint32_t gf_rdma_vers_high;
}__attribute__ ((packed));
-typedef struct rdma_err_vers rdma_err_vers_t;
-
-typedef enum rdma_proc {
- RDMA_MSG = 0, /* An RPC call or reply msg */
- RDMA_NOMSG = 1, /* An RPC call or reply msg - separate body */
- RDMA_MSGP = 2, /* An RPC call or reply msg with padding */
- RDMA_DONE = 3, /* Client signals reply completion */
- RDMA_ERROR = 4 /* An RPC RDMA encoding error */
-}rdma_proc_t;
-
-typedef enum rdma_chunktype {
- rdma_noch = 0, /* no chunk */
- rdma_readch, /* some argument through rdma read */
- rdma_areadch, /* entire request through rdma read */
- rdma_writech, /* some result through rdma write */
- rdma_replych /* entire reply through rdma write */
-}rdma_chunktype_t;
-
-/* If you are modifying __rdma_header, please make sure to change
- * GLUSTERFS_RDMA_MAX_HEADER_SIZE defined in glusterfs.h to reflect your changes
+typedef struct gf_rdma_err_vers gf_rdma_err_vers_t;
+
+typedef enum gf_rdma_proc {
+ GF_RDMA_MSG = 0, /* An RPC call or reply msg */
+ GF_RDMA_NOMSG = 1, /* An RPC call or reply msg - separate body */
+ GF_RDMA_MSGP = 2, /* An RPC call or reply msg with padding */
+ GF_RDMA_DONE = 3, /* Client signals reply completion */
+ GF_RDMA_ERROR = 4 /* An RPC RDMA encoding error */
+}gf_rdma_proc_t;
+
+typedef enum gf_rdma_chunktype {
+ gf_rdma_noch = 0, /* no chunk */
+ gf_rdma_readch, /* some argument through rdma read */
+ gf_rdma_areadch, /* entire request through rdma read */
+ gf_rdma_writech, /* some result through rdma write */
+ gf_rdma_replych /* entire reply through rdma write */
+}gf_rdma_chunktype_t;
+
+/* If you are modifying __gf_rdma_header, please make sure to change
+ * GLUSTERFS_GF_RDMA_MAX_HEADER_SIZE defined in glusterfs.h to reflect your changes
*/
-struct __rdma_header {
+struct __gf_rdma_header {
uint32_t rm_xid; /* Mirrors the RPC header xid */
uint32_t rm_vers; /* Version of this protocol */
uint32_t rm_credit; /* Buffers requested/granted */
- uint32_t rm_type; /* Type of message (enum rdma_proc) */
+ uint32_t rm_type; /* Type of message (enum gf_rdma_proc) */
union {
struct { /* no chunks */
uint32_t rm_empty[3]; /* 3 empty chunk lists */
@@ -98,49 +94,49 @@ struct __rdma_header {
struct {
uint32_t rm_type;
- rdma_err_vers_t rm_version;
+ gf_rdma_err_vers_t rm_version;
}__attribute__ ((packed)) rm_error;
uint32_t rm_chunks[0]; /* read, write and reply chunks */
}__attribute__ ((packed)) rm_body;
} __attribute__((packed));
-typedef struct __rdma_header rdma_header_t;
+typedef struct __gf_rdma_header gf_rdma_header_t;
-/* If you are modifying __rdma_segment or __rdma_read_chunk, please make sure
- * to change GLUSTERFS_RDMA_MAX_HEADER_SIZE defined in glusterfs.h to reflect
+/* If you are modifying __gf_rdma_segment or __gf_rdma_read_chunk, please make sure
+ * to change GLUSTERFS_GF_RDMA_MAX_HEADER_SIZE defined in glusterfs.h to reflect
* your changes.
*/
-struct __rdma_segment {
+struct __gf_rdma_segment {
uint32_t rs_handle; /* Registered memory handle */
uint32_t rs_length; /* Length of the chunk in bytes */
uint64_t rs_offset; /* Chunk virtual address or offset */
} __attribute__((packed));
-typedef struct __rdma_segment rdma_segment_t;
+typedef struct __gf_rdma_segment gf_rdma_segment_t;
/* read chunk(s), encoded as a linked list. */
-struct __rdma_read_chunk {
+struct __gf_rdma_read_chunk {
uint32_t rc_discrim; /* 1 indicates presence */
uint32_t rc_position; /* Position in XDR stream */
- rdma_segment_t rc_target;
+ gf_rdma_segment_t rc_target;
} __attribute__((packed));
-typedef struct __rdma_read_chunk rdma_read_chunk_t;
+typedef struct __gf_rdma_read_chunk gf_rdma_read_chunk_t;
/* write chunk, and reply chunk. */
-struct __rdma_write_chunk {
- rdma_segment_t wc_target;
+struct __gf_rdma_write_chunk {
+ gf_rdma_segment_t wc_target;
} __attribute__((packed));
-typedef struct __rdma_write_chunk rdma_write_chunk_t;
+typedef struct __gf_rdma_write_chunk gf_rdma_write_chunk_t;
/* write chunk(s), encoded as a counted array. */
-struct __rdma_write_array {
+struct __gf_rdma_write_array {
uint32_t wc_discrim; /* 1 indicates presence */
uint32_t wc_nchunks; /* Array count */
- struct __rdma_write_chunk wc_array[0];
+ struct __gf_rdma_write_chunk wc_array[0];
} __attribute__((packed));
-typedef struct __rdma_write_array rdma_write_array_t;
+typedef struct __gf_rdma_write_array gf_rdma_write_array_t;
/* options per transport end point */
-struct __rdma_options {
+struct __gf_rdma_options {
int32_t port;
char *device_name;
enum ibv_mtu mtu;
@@ -148,26 +144,29 @@ struct __rdma_options {
int32_t recv_count;
uint64_t recv_size;
uint64_t send_size;
+ uint8_t attr_timeout;
+ uint8_t attr_retry_cnt;
+ uint8_t attr_rnr_retry;
};
-typedef struct __rdma_options rdma_options_t;
+typedef struct __gf_rdma_options gf_rdma_options_t;
-struct __rdma_reply_info {
+struct __gf_rdma_reply_info {
uint32_t rm_xid; /* xid in network endian */
- rdma_chunktype_t type; /*
- * can be either rdma_replych
- * or rdma_writech.
+ gf_rdma_chunktype_t type; /*
+ * can be either gf_rdma_replych
+ * or gf_rdma_writech.
*/
- rdma_write_array_t *wc_array;
+ gf_rdma_write_array_t *wc_array;
struct mem_pool *pool;
};
-typedef struct __rdma_reply_info rdma_reply_info_t;
+typedef struct __gf_rdma_reply_info gf_rdma_reply_info_t;
-struct __rdma_ioq {
+struct __gf_rdma_ioq {
union {
struct list_head list;
struct {
- struct __rdma_ioq *next;
- struct __rdma_ioq *prev;
+ struct __gf_rdma_ioq *next;
+ struct __gf_rdma_ioq *prev;
};
};
@@ -182,8 +181,8 @@ struct __rdma_ioq {
struct iobref *iobref;
union {
- struct __rdma_ioq_request {
- /* used to build reply_chunk for RDMA_NOMSG type msgs */
+ struct __gf_rdma_ioq_request {
+ /* used to build reply_chunk for GF_RDMA_NOMSG type msgs */
struct iovec rsphdr_vec[MAX_IOVEC];
int rsphdr_count;
@@ -200,37 +199,37 @@ struct __rdma_ioq {
struct iobref *rsp_iobref;
}request;
- rdma_reply_info_t *reply_info;
+ gf_rdma_reply_info_t *reply_info;
}msg;
struct mem_pool *pool;
};
-typedef struct __rdma_ioq rdma_ioq_t;
+typedef struct __gf_rdma_ioq gf_rdma_ioq_t;
-typedef enum __rdma_send_post_type {
- RDMA_SEND_POST_NO_CHUNKLIST, /* post which is sent using rdma-send
+typedef enum __gf_rdma_send_post_type {
+ GF_RDMA_SEND_POST_NO_CHUNKLIST, /* post which is sent using rdma-send
* and the msg carries no
* chunklists.
*/
- RDMA_SEND_POST_READ_CHUNKLIST, /* post which is sent using rdma-send
+ GF_RDMA_SEND_POST_READ_CHUNKLIST, /* post which is sent using rdma-send
* and the msg carries only read
* chunklist.
*/
- RDMA_SEND_POST_WRITE_CHUNKLIST, /* post which is sent using
+ GF_RDMA_SEND_POST_WRITE_CHUNKLIST, /* post which is sent using
* rdma-send and the msg carries
* only write chunklist.
*/
- RDMA_SEND_POST_READ_WRITE_CHUNKLIST, /* post which is sent using
+ GF_RDMA_SEND_POST_READ_WRITE_CHUNKLIST, /* post which is sent using
* rdma-send and the msg
* carries both read and
* write chunklists.
*/
- RDMA_SEND_POST_RDMA_READ, /* RDMA read */
- RDMA_SEND_POST_RDMA_WRITE, /* RDMA write */
-}rdma_send_post_type_t;
+ GF_RDMA_SEND_POST_GF_RDMA_READ, /* RDMA read */
+ GF_RDMA_SEND_POST_GF_RDMA_WRITE, /* RDMA write */
+}gf_rdma_send_post_type_t;
/* represents one communication peer, two per transport_t */
-struct __rdma_peer {
+struct __gf_rdma_peer {
rpc_transport_t *trans;
struct ibv_qp *qp;
@@ -243,8 +242,8 @@ struct __rdma_peer {
union {
struct list_head ioq;
struct {
- rdma_ioq_t *ioq_next;
- rdma_ioq_t *ioq_prev;
+ gf_rdma_ioq_t *ioq_next;
+ gf_rdma_ioq_t *ioq_prev;
};
};
@@ -256,91 +255,91 @@ struct __rdma_peer {
int32_t remote_psn;
int32_t remote_qpn;
};
-typedef struct __rdma_peer rdma_peer_t;
+typedef struct __gf_rdma_peer gf_rdma_peer_t;
-struct __rdma_post_context {
- struct ibv_mr *mr[RDMA_MAX_SEGMENTS];
+struct __gf_rdma_post_context {
+ struct ibv_mr *mr[GF_RDMA_MAX_SEGMENTS];
int mr_count;
struct iovec vector[MAX_IOVEC];
int count;
struct iobref *iobref;
struct iobuf *hdr_iobuf;
char is_request;
- int rdma_reads;
- rdma_reply_info_t *reply_info;
+ int gf_rdma_reads;
+ gf_rdma_reply_info_t *reply_info;
};
-typedef struct __rdma_post_context rdma_post_context_t;
+typedef struct __gf_rdma_post_context gf_rdma_post_context_t;
typedef enum {
- RDMA_SEND_POST,
- RDMA_RECV_POST
-} rdma_post_type_t;
+ GF_RDMA_SEND_POST,
+ GF_RDMA_RECV_POST
+} gf_rdma_post_type_t;
-struct __rdma_post {
- struct __rdma_post *next, *prev;
+struct __gf_rdma_post {
+ struct __gf_rdma_post *next, *prev;
struct ibv_mr *mr;
char *buf;
int32_t buf_size;
char aux;
int32_t reused;
- struct __rdma_device *device;
- rdma_post_type_t type;
- rdma_post_context_t ctx;
+ struct __gf_rdma_device *device;
+ gf_rdma_post_type_t type;
+ gf_rdma_post_context_t ctx;
int refcount;
pthread_mutex_t lock;
};
-typedef struct __rdma_post rdma_post_t;
+typedef struct __gf_rdma_post gf_rdma_post_t;
-struct __rdma_queue {
- rdma_post_t active_posts, passive_posts;
+struct __gf_rdma_queue {
+ gf_rdma_post_t active_posts, passive_posts;
int32_t active_count, passive_count;
pthread_mutex_t lock;
};
-typedef struct __rdma_queue rdma_queue_t;
+typedef struct __gf_rdma_queue gf_rdma_queue_t;
-struct __rdma_qpreg {
+struct __gf_rdma_qpreg {
pthread_mutex_t lock;
int32_t count;
struct _qpent {
struct _qpent *next, *prev;
int32_t qp_num;
- rdma_peer_t *peer;
+ gf_rdma_peer_t *peer;
} ents[42];
};
-typedef struct __rdma_qpreg rdma_qpreg_t;
+typedef struct __gf_rdma_qpreg gf_rdma_qpreg_t;
/* context per device, stored in global glusterfs_ctx_t->ib */
-struct __rdma_device {
- struct __rdma_device *next;
+struct __gf_rdma_device {
+ struct __gf_rdma_device *next;
const char *device_name;
struct ibv_context *context;
int32_t port;
struct ibv_pd *pd;
struct ibv_srq *srq;
- rdma_qpreg_t qpreg;
+ gf_rdma_qpreg_t qpreg;
struct ibv_comp_channel *send_chan, *recv_chan;
struct ibv_cq *send_cq, *recv_cq;
- rdma_queue_t sendq, recvq;
+ gf_rdma_queue_t sendq, recvq;
pthread_t send_thread, recv_thread;
struct mem_pool *request_ctx_pool;
struct mem_pool *ioq_pool;
struct mem_pool *reply_info_pool;
};
-typedef struct __rdma_device rdma_device_t;
+typedef struct __gf_rdma_device gf_rdma_device_t;
typedef enum {
- RDMA_HANDSHAKE_START = 0,
- RDMA_HANDSHAKE_SENDING_DATA,
- RDMA_HANDSHAKE_RECEIVING_DATA,
- RDMA_HANDSHAKE_SENT_DATA,
- RDMA_HANDSHAKE_RECEIVED_DATA,
- RDMA_HANDSHAKE_SENDING_ACK,
- RDMA_HANDSHAKE_RECEIVING_ACK,
- RDMA_HANDSHAKE_RECEIVED_ACK,
- RDMA_HANDSHAKE_COMPLETE,
-} rdma_handshake_state_t;
-
-struct rdma_nbio {
+ GF_RDMA_HANDSHAKE_START = 0,
+ GF_RDMA_HANDSHAKE_SENDING_DATA,
+ GF_RDMA_HANDSHAKE_RECEIVING_DATA,
+ GF_RDMA_HANDSHAKE_SENT_DATA,
+ GF_RDMA_HANDSHAKE_RECEIVED_DATA,
+ GF_RDMA_HANDSHAKE_SENDING_ACK,
+ GF_RDMA_HANDSHAKE_RECEIVING_ACK,
+ GF_RDMA_HANDSHAKE_RECEIVED_ACK,
+ GF_RDMA_HANDSHAKE_COMPLETE,
+} gf_rdma_handshake_state_t;
+
+struct gf_rdma_nbio {
int state;
char *buf;
int count;
@@ -349,17 +348,17 @@ struct rdma_nbio {
int pending_count;
};
-struct __rdma_request_context {
- struct ibv_mr *mr[RDMA_MAX_SEGMENTS];
+struct __gf_rdma_request_context {
+ struct ibv_mr *mr[GF_RDMA_MAX_SEGMENTS];
int mr_count;
struct mem_pool *pool;
- rdma_peer_t *peer;
+ gf_rdma_peer_t *peer;
struct iobref *iobref;
struct iobref *rsp_iobref;
};
-typedef struct __rdma_request_context rdma_request_context_t;
+typedef struct __gf_rdma_request_context gf_rdma_request_context_t;
-struct __rdma_private {
+struct __gf_rdma_private {
int32_t sock;
int32_t idx;
unsigned char connected;
@@ -369,9 +368,9 @@ struct __rdma_private {
unsigned short port;
/* IB Verbs Driver specific variables, pointers */
- rdma_peer_t peer;
- struct __rdma_device *device;
- rdma_options_t options;
+ gf_rdma_peer_t peer;
+ struct __gf_rdma_device *device;
+ gf_rdma_options_t options;
/* Used by trans->op->receive */
char *data_ptr;
@@ -389,16 +388,16 @@ struct __rdma_private {
pthread_mutex_t recv_mutex;
pthread_cond_t recv_cond;
- /* used during rdma_handshake */
+ /* used during gf_rdma_handshake */
struct {
- struct rdma_nbio incoming;
- struct rdma_nbio outgoing;
+ struct gf_rdma_nbio incoming;
+ struct gf_rdma_nbio outgoing;
int state;
- rdma_header_t header;
+ gf_rdma_header_t header;
char *buf;
size_t size;
} handshake;
};
-typedef struct __rdma_private rdma_private_t;
+typedef struct __gf_rdma_private gf_rdma_private_t;
-#endif /* _XPORT_RDMA_H */
+#endif /* _XPORT_GF_RDMA_H */
diff --git a/rpc/rpc-transport/socket/src/name.c b/rpc/rpc-transport/socket/src/name.c
index d310b0f8a..d37c83e18 100644
--- a/rpc/rpc-transport/socket/src/name.c
+++ b/rpc/rpc-transport/socket/src/name.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <sys/types.h>
@@ -36,6 +27,7 @@
#include "rpc-transport.h"
#include "socket.h"
+#include "common-utils.h"
int32_t
gf_resolve_ip6 (const char *hostname,
@@ -95,7 +87,7 @@ af_unix_client_bind (rpc_transport_t *this,
char *path = data_to_str (path_data);
if (!path || strlen (path) > UNIX_PATH_MAX) {
gf_log (this->name, GF_LOG_TRACE,
- "bind-path not specfied for unix socket, "
+ "bind-path not specified for unix socket, "
"letting connect to assign default value");
goto err;
}
@@ -111,7 +103,7 @@ af_unix_client_bind (rpc_transport_t *this,
}
} else {
gf_log (this->name, GF_LOG_TRACE,
- "bind-path not specfied for unix socket, "
+ "bind-path not specified for unix socket, "
"letting connect to assign default value");
}
@@ -142,24 +134,24 @@ client_fill_address_family (rpc_transport_t *this, sa_family_t *sa_family)
if (!(remote_host_data || connect_path_data) ||
(remote_host_data && connect_path_data)) {
gf_log (this->name, GF_LOG_ERROR,
- "transport.address-family not specified and "
- "not able to determine the "
- "same from other options (remote-host:%s and "
- "transport.unix.connect-path:%s)",
+ "transport.address-family not specified. "
+ "Could not guess default value from (remote-host:%s or "
+ "transport.unix.connect-path:%s) options",
data_to_str (remote_host_data),
data_to_str (connect_path_data));
+ *sa_family = AF_UNSPEC;
goto out;
}
if (remote_host_data) {
gf_log (this->name, GF_LOG_DEBUG,
"address-family not specified, guessing it "
- "to be inet/inet6");
- *sa_family = AF_UNSPEC;
+ "to be inet from (remote-host: %s)", data_to_str (remote_host_data));
+ *sa_family = AF_INET;
} else {
gf_log (this->name, GF_LOG_DEBUG,
"address-family not specified, guessing it "
- "to be unix");
+ "to be unix from (transport.unix.connect-path: %s)", data_to_str (connect_path_data));
*sa_family = AF_UNIX;
}
@@ -173,13 +165,11 @@ client_fill_address_family (rpc_transport_t *this, sa_family_t *sa_family)
*sa_family = AF_INET6;
} else if (!strcasecmp (address_family, "inet-sdp")) {
*sa_family = AF_INET_SDP;
- } else if (!strcasecmp (address_family, "inet/inet6")
- || !strcasecmp (address_family, "inet6/inet")) {
- *sa_family = AF_UNSPEC;
} else {
gf_log (this->name, GF_LOG_ERROR,
"unknown address-family (%s) specified",
address_family);
+ *sa_family = AF_UNSPEC;
goto out;
}
}
@@ -355,7 +345,7 @@ af_inet_server_get_local_sockaddr (rpc_transport_t *this,
struct sockaddr *addr,
socklen_t *addr_len)
{
- struct addrinfo hints, *res = 0;
+ struct addrinfo hints, *res = 0, *rp = NULL;
data_t *listen_port_data = NULL, *listen_host_data = NULL;
uint16_t listen_port = -1;
char service[NI_MAXSERV], *listen_host = NULL;
@@ -401,7 +391,7 @@ af_inet_server_get_local_sockaddr (rpc_transport_t *this,
memset (&hints, 0, sizeof (hints));
hints.ai_family = addr->sa_family;
hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
+ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
ret = getaddrinfo(listen_host, service, &hints, &res);
if (ret != 0) {
@@ -411,9 +401,20 @@ af_inet_server_get_local_sockaddr (rpc_transport_t *this,
ret = -1;
goto out;
}
+ /* IPV6 server can handle both ipv4 and ipv6 clients */
+ for (rp = res; rp != NULL; rp = rp->ai_next) {
+ if (rp->ai_addr == NULL)
+ continue;
+ if (rp->ai_family == AF_INET6) {
+ memcpy (addr, rp->ai_addr, rp->ai_addrlen);
+ *addr_len = rp->ai_addrlen;
+ }
+ }
- memcpy (addr, res->ai_addr, res->ai_addrlen);
- *addr_len = res->ai_addrlen;
+ if (!(*addr_len)) {
+ memcpy (addr, res->ai_addr, res->ai_addrlen);
+ *addr_len = res->ai_addrlen;
+ }
freeaddrinfo (res);
@@ -437,7 +438,7 @@ client_bind (rpc_transport_t *this,
*sockaddr_len = sizeof (struct sockaddr_in);
case AF_INET6:
- if (!this->client_bind_insecure) {
+ if (!this->bind_insecure) {
ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr,
*sockaddr_len, CLIENT_PORT_CEILING);
}
@@ -539,18 +540,16 @@ server_fill_address_family (rpc_transport_t *this, sa_family_t *sa_family)
*sa_family = AF_INET_SDP;
} else if (!strcasecmp (address_family, "unix")) {
*sa_family = AF_UNIX;
- } else if (!strcasecmp (address_family, "inet/inet6")
- || !strcasecmp (address_family, "inet6/inet")) {
- *sa_family = AF_UNSPEC;
} else {
gf_log (this->name, GF_LOG_ERROR,
"unknown address family (%s) specified", address_family);
+ *sa_family = AF_UNSPEC;
goto out;
}
} else {
gf_log (this->name, GF_LOG_DEBUG,
- "option address-family not specified, defaulting to inet/inet6");
- *sa_family = AF_UNSPEC;
+ "option address-family not specified, defaulting to inet");
+ *sa_family = AF_INET;
}
ret = 0;
@@ -604,7 +603,7 @@ int32_t
fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *addr,
int32_t addr_len, char *identifier)
{
- struct sockaddr_storage tmpaddr;
+ union gf_sock_union sock_union;
char service[NI_MAXSERV] = {0,};
char host[NI_MAXHOST] = {0,};
@@ -616,26 +615,26 @@ fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *add
int16_t eight_to_ten = 0;
int16_t ten_to_twelve = 0;
- memset (&tmpaddr, 0, sizeof (tmpaddr));
- tmpaddr = *addr;
+ memset (&sock_union, 0, sizeof (sock_union));
+ sock_union.storage = *addr;
tmpaddr_len = addr_len;
- if (((struct sockaddr *) &tmpaddr)->sa_family == AF_INET6) {
- one_to_four = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[0];
- four_to_eight = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[1];
+ if (sock_union.sa.sa_family == AF_INET6) {
+ one_to_four = sock_union.sin6.sin6_addr.s6_addr32[0];
+ four_to_eight = sock_union.sin6.sin6_addr.s6_addr32[1];
#ifdef GF_SOLARIS_HOST_OS
- eight_to_ten = S6_ADDR16(((struct sockaddr_in6 *) &tmpaddr)->sin6_addr)[4];
+ eight_to_ten = S6_ADDR16(sock_union.sin6.sin6_addr)[4];
#else
- eight_to_ten = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr16[4];
+ eight_to_ten = sock_union.sin6.sin6_addr.s6_addr16[4];
#endif
#ifdef GF_SOLARIS_HOST_OS
- ten_to_twelve = S6_ADDR16(((struct sockaddr_in6 *) &tmpaddr)->sin6_addr)[5];
+ ten_to_twelve = S6_ADDR16(sock_union.sin6.sin6_addr)[5];
#else
- ten_to_twelve = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr16[5];
+ ten_to_twelve = sock_union.sin6.sin6_addr.s6_addr16[5];
#endif
- twelve_to_sixteen = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[3];
+ twelve_to_sixteen = sock_union.sin6.sin6_addr.s6_addr32[3];
/* ipv4 mapped ipv6 address has
bits 0-80: 0
@@ -647,8 +646,8 @@ fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *add
four_to_eight == 0 &&
eight_to_ten == 0 &&
ten_to_twelve == -1) {
- struct sockaddr_in *in_ptr = (struct sockaddr_in *)&tmpaddr;
- memset (&tmpaddr, 0, sizeof (tmpaddr));
+ struct sockaddr_in *in_ptr = &sock_union.sin;
+ memset (&sock_union, 0, sizeof (sock_union));
in_ptr->sin_family = AF_INET;
in_ptr->sin_port = ((struct sockaddr_in6 *)addr)->sin6_port;
@@ -657,7 +656,7 @@ fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *add
}
}
- ret = getnameinfo ((struct sockaddr *) &tmpaddr,
+ ret = getnameinfo (&sock_union.sa,
tmpaddr_len,
host, sizeof (host),
service, sizeof (service),
diff --git a/rpc/rpc-transport/socket/src/name.h b/rpc/rpc-transport/socket/src/name.h
index 66eccf8d5..0a13d8a96 100644
--- a/rpc/rpc-transport/socket/src/name.h
+++ b/rpc/rpc-transport/socket/src/name.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _SOCKET_NAME_H
diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c
index 5b7d57b3d..d08cec650 100644
--- a/rpc/rpc-transport/socket/src/socket.c
+++ b/rpc/rpc-transport/socket/src/socket.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -37,13 +28,13 @@
/* ugly #includes below */
#include "protocol-common.h"
#include "glusterfs3-xdr.h"
-#include "glusterfs3.h"
+#include "xdr-nfs3.h"
+#include "rpcsvc.h"
#include <fcntl.h>
#include <errno.h>
#include <netinet/tcp.h>
#include <rpc/xdr.h>
-
#define GF_LOG_ERRNO(errno) ((errno == ENOTCONN) ? GF_LOG_DEBUG : GF_LOG_ERROR)
#define SA(ptr) ((struct sockaddr *)ptr)
@@ -82,7 +73,7 @@
priv->incoming.frag.bytes_read += bytes_read; \
\
if ((ret > 0) || (priv->incoming.frag.remaining_size != 0)) { \
- if (priv->incoming.frag.remaining_size != 0) { \
+ if (priv->incoming.frag.remaining_size != 0 && ret == 0) { \
__socket_proto_reset_pending (priv); \
} \
\
@@ -318,7 +309,7 @@ __socket_server_bind (rpc_transport_t *this)
strerror (errno));
}
- //reuse-address doesnt work for unix type sockets
+ /* reuse-address doesn't work for unix type sockets */
if (AF_UNIX == SA (&this->myinfo.sockaddr)->sa_family) {
memcpy (&unix_addr, SA (&this->myinfo.sockaddr),
this->myinfo.sockaddr_len);
@@ -375,7 +366,7 @@ __socket_nodelay (int fd)
ret = setsockopt (fd, IPPROTO_TCP, TCP_NODELAY,
&on, sizeof (on));
if (!ret)
- gf_log ("", GF_LOG_TRACE,
+ gf_log (THIS->name, GF_LOG_TRACE,
"NODELAY enabled for socket %d", fd);
return ret;
@@ -398,7 +389,7 @@ __socket_keepalive (int fd, int keepalive_intvl, int keepalive_idle)
if (keepalive_intvl == GF_USE_DEFAULT_KEEPALIVE)
goto done;
-#ifndef GF_LINUX_HOST_OS
+#if !defined(GF_LINUX_HOST_OS) && !defined(__NetBSD__)
#ifdef GF_SOLARIS_HOST_OS
ret = setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive_intvl,
sizeof (keepalive_intvl));
@@ -429,7 +420,7 @@ __socket_keepalive (int fd, int keepalive_intvl, int keepalive_idle)
#endif
done:
- gf_log ("", GF_LOG_TRACE, "Keep-alive enabled for socket %d, interval "
+ gf_log (THIS->name, GF_LOG_TRACE, "Keep-alive enabled for socket %d, interval "
"%d, idle: %d", fd, keepalive_intvl, keepalive_idle);
err:
@@ -807,9 +798,14 @@ __socket_read_simple_request (rpc_transport_t *this)
#define rpc_verf_addr(fragcurrent) (fragcurrent - 4)
+#define rpc_msgtype_addr(buf) (buf + 4)
+
+#define rpc_prognum_addr(buf) (buf + RPC_MSGTYPE_SIZE + 4)
+#define rpc_progver_addr(buf) (buf + RPC_MSGTYPE_SIZE + 8)
+#define rpc_procnum_addr(buf) (buf + RPC_MSGTYPE_SIZE + 12)
inline int
-__socket_read_vectored_request (rpc_transport_t *this)
+__socket_read_vectored_request (rpc_transport_t *this, rpcsvc_vector_sizer vector_sizer)
{
socket_private_t *priv = NULL;
int ret = 0;
@@ -817,8 +813,8 @@ __socket_read_vectored_request (rpc_transport_t *this)
char *addr = NULL;
struct iobuf *iobuf = NULL;
uint32_t remaining_size = 0;
- uint32_t gluster_write_proc_len = 0;
- gfs3_write_req write_req = {{0,},};
+ ssize_t readsize = 0;
+ size_t size = 0;
GF_VALIDATE_OR_GOTO ("socket", this, out);
GF_VALIDATE_OR_GOTO ("socket", this->private, out);
@@ -827,6 +823,7 @@ __socket_read_vectored_request (rpc_transport_t *this)
switch (priv->incoming.frag.call_body.request.vector_state) {
case SP_STATE_VECTORED_REQUEST_INIT:
+ priv->incoming.frag.call_body.request.vector_sizer_state = 0;
addr = rpc_cred_addr (iobuf_ptr (priv->incoming.iobuf));
/* also read verf flavour and verflen */
@@ -850,24 +847,13 @@ __socket_read_vectored_request (rpc_transport_t *this)
case SP_STATE_READ_CREDBYTES:
addr = rpc_verf_addr (priv->incoming.frag.fragcurrent);
+ verflen = ntoh32 (*((uint32_t *)addr));
- /* FIXME: Also handle procedures other than glusterfs-write
- * here
- */
- /* also read proc-header */
- gluster_write_proc_len = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req,
- &write_req);
-
- if (gluster_write_proc_len == 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "xdr_sizeof on gfs3_write_req failed");
- ret = -1;
- goto out;
+ if (verflen == 0) {
+ priv->incoming.frag.call_body.request.vector_state
+ = SP_STATE_READ_VERFBYTES;
+ goto sp_state_read_verfbytes;
}
-
- verflen = ntoh32 (*((uint32_t *)addr))
- + gluster_write_proc_len;
-
__socket_proto_init_pending (priv, verflen);
priv->incoming.frag.call_body.request.vector_state
@@ -884,8 +870,39 @@ __socket_read_vectored_request (rpc_transport_t *this)
/* fall through */
case SP_STATE_READ_VERFBYTES:
+sp_state_read_verfbytes:
+ priv->incoming.frag.call_body.request.vector_sizer_state =
+ vector_sizer (priv->incoming.frag.call_body.request.vector_sizer_state,
+ &readsize,
+ priv->incoming.frag.fragcurrent);
+ __socket_proto_init_pending (priv, readsize);
+ priv->incoming.frag.call_body.request.vector_state
+ = SP_STATE_READING_PROGHDR;
+
+ /* fall through */
+
+ case SP_STATE_READING_PROGHDR:
+ __socket_proto_read (priv, ret);
+sp_state_reading_proghdr:
+ priv->incoming.frag.call_body.request.vector_sizer_state =
+ vector_sizer (priv->incoming.frag.call_body.request.vector_sizer_state,
+ &readsize,
+ priv->incoming.frag.fragcurrent);
+ if (readsize == 0) {
+ priv->incoming.frag.call_body.request.vector_state =
+ SP_STATE_READ_PROGHDR;
+ } else {
+ __socket_proto_init_pending (priv, readsize);
+ __socket_proto_read (priv, ret);
+ goto sp_state_reading_proghdr;
+ }
+
+ case SP_STATE_READ_PROGHDR:
if (priv->incoming.payload_vector.iov_base == NULL) {
- iobuf = iobuf_get (this->ctx->iobuf_pool);
+
+ size = RPC_FRAGSIZE (priv->incoming.fraghdr) -
+ priv->incoming.frag.bytes_read;
+ iobuf = iobuf_get2 (this->ctx->iobuf_pool, size);
if (!iobuf) {
ret = -1;
break;
@@ -942,22 +959,15 @@ out:
return ret;
}
-
-#define rpc_msgtype_addr(buf) (buf + 4)
-
-#define rpc_prognum_addr(buf) (buf + RPC_MSGTYPE_SIZE + 4)
-
-#define rpc_procnum_addr(buf) (buf + RPC_MSGTYPE_SIZE + 12)
-
-
inline int
__socket_read_request (rpc_transport_t *this)
{
socket_private_t *priv = NULL;
- uint32_t prognum = 0, procnum = 0;
+ uint32_t prognum = 0, procnum = 0, progver = 0;
uint32_t remaining_size = 0;
int ret = -1;
char *buf = NULL;
+ rpcsvc_vector_sizer vector_sizer = NULL;
GF_VALIDATE_OR_GOTO ("socket", this, out);
GF_VALIDATE_OR_GOTO ("socket", this->private, out);
@@ -987,12 +997,21 @@ __socket_read_request (rpc_transport_t *this)
buf = rpc_prognum_addr (iobuf_ptr (priv->incoming.iobuf));
prognum = ntoh32 (*((uint32_t *)buf));
+ buf = rpc_progver_addr (iobuf_ptr (priv->incoming.iobuf));
+ progver = ntoh32 (*((uint32_t *)buf));
+
buf = rpc_procnum_addr (iobuf_ptr (priv->incoming.iobuf));
procnum = ntoh32 (*((uint32_t *)buf));
- if ((prognum == GLUSTER3_1_FOP_PROGRAM)
- && (procnum == GF_FOP_WRITE)) {
- ret = __socket_read_vectored_request (this);
+ if (this->listener) {
+ /* this check is needed as rpcsvc and rpc-clnt actor structures are
+ * not same */
+ vector_sizer = rpcsvc_get_program_vector_sizer ((rpcsvc_t *)this->mydata,
+ prognum, progver, procnum);
+ }
+
+ if (vector_sizer) {
+ ret = __socket_read_vectored_request (this, vector_sizer);
} else {
ret = __socket_read_simple_request (this);
}
@@ -1024,6 +1043,7 @@ __socket_read_accepted_successful_reply (rpc_transport_t *this)
struct iobuf *iobuf = NULL;
uint32_t gluster_read_rsp_hdr_len = 0;
gfs3_read_rsp read_rsp = {0, };
+ size_t size = 0;
GF_VALIDATE_OR_GOTO ("socket", this, out);
GF_VALIDATE_OR_GOTO ("socket", this->private, out);
@@ -1056,7 +1076,11 @@ __socket_read_accepted_successful_reply (rpc_transport_t *this)
= SP_STATE_READ_PROC_HEADER;
if (priv->incoming.payload_vector.iov_base == NULL) {
- iobuf = iobuf_get (this->ctx->iobuf_pool);
+
+ size = (RPC_FRAGSIZE (priv->incoming.fraghdr) -
+ priv->incoming.frag.bytes_read);
+
+ iobuf = iobuf_get2 (this->ctx->iobuf_pool, size);
if (iobuf == NULL) {
ret = -1;
goto out;
@@ -1076,6 +1100,8 @@ __socket_read_accepted_successful_reply (rpc_transport_t *this)
priv->incoming.payload_vector.iov_base
= iobuf_ptr (iobuf);
+
+ priv->incoming.payload_vector.iov_len = size;
}
priv->incoming.frag.fragcurrent
@@ -1323,7 +1349,7 @@ __socket_read_reply (rpc_transport_t *this)
pthread_mutex_lock (&priv->lock);
if (ret == -1) {
- gf_log ("", GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_WARNING,
"notify for event MAP_XID failed");
goto out;
}
@@ -1456,14 +1482,6 @@ __socket_proto_state_machine (rpc_transport_t *this,
switch (priv->incoming.record_state) {
case SP_STATE_NADA:
- iobuf = iobuf_get (this->ctx->iobuf_pool);
- if (!iobuf) {
- ret = -ENOMEM;
- goto out;
- }
-
- priv->incoming.iobuf = iobuf;
- priv->incoming.iobuf_size = 0;
priv->incoming.total_bytes_read = 0;
priv->incoming.payload_vector.iov_len = 0;
@@ -1471,7 +1489,6 @@ __socket_proto_state_machine (rpc_transport_t *this,
priv->incoming.pending_vector->iov_base =
&priv->incoming.fraghdr;
- priv->incoming.frag.fragcurrent = iobuf_ptr (iobuf);
priv->incoming.pending_vector->iov_len =
sizeof (priv->incoming.fraghdr);
@@ -1486,12 +1503,14 @@ __socket_proto_state_machine (rpc_transport_t *this,
&priv->incoming.pending_count,
NULL);
if (ret == -1) {
- gf_log (this->name,
- ((priv->connected == 1) ?
- GF_LOG_WARNING : GF_LOG_DEBUG),
- "reading from socket failed. Error (%s)"
- ", peer (%s)", strerror (errno),
- this->peerinfo.identifier);
+ if (priv->read_fail_log == 1) {
+ gf_log (this->name,
+ ((priv->connected == 1) ?
+ GF_LOG_WARNING : GF_LOG_DEBUG),
+ "reading from socket failed. Error (%s)"
+ ", peer (%s)", strerror (errno),
+ this->peerinfo.identifier);
+ }
goto out;
}
@@ -1513,6 +1532,17 @@ __socket_proto_state_machine (rpc_transport_t *this,
priv->incoming.record_state = SP_STATE_READING_FRAG;
priv->incoming.total_bytes_read
+= RPC_FRAGSIZE(priv->incoming.fraghdr);
+ iobuf = iobuf_get2 (this->ctx->iobuf_pool,
+ priv->incoming.total_bytes_read +
+ sizeof (priv->incoming.fraghdr));
+ if (!iobuf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ priv->incoming.iobuf = iobuf;
+ priv->incoming.iobuf_size = 0;
+ priv->incoming.frag.fragcurrent = iobuf_ptr (iobuf);
/* fall through */
case SP_STATE_READING_FRAG:
@@ -1577,7 +1607,7 @@ __socket_proto_state_machine (rpc_transport_t *this,
priv->incoming.iobuf = NULL;
if (*pollin == NULL) {
- gf_log ("", GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_WARNING,
"transport pollin allocation failed");
ret = -1;
goto out;
@@ -1900,7 +1930,7 @@ socket_server_event_handler (int fd, int idx, void *data,
}
pthread_mutex_unlock (&new_priv->lock);
if (ret == -1) {
- gf_log ("", GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_WARNING,
"failed to register the socket with event");
goto unlock;
}
@@ -1945,10 +1975,10 @@ socket_connect (rpc_transport_t *this, int port)
int ret = -1;
int sock = -1;
socket_private_t *priv = NULL;
- struct sockaddr_storage sockaddr = {0, };
socklen_t sockaddr_len = 0;
glusterfs_ctx_t *ctx = NULL;
sa_family_t sa_family = {0, };
+ union gf_sock_union sock_union;
GF_VALIDATE_OR_GOTO ("socket", this, err);
GF_VALIDATE_OR_GOTO ("socket", this->private, err);
@@ -1971,20 +2001,21 @@ socket_connect (rpc_transport_t *this, int port)
if (sock != -1) {
gf_log_callingfn (this->name, GF_LOG_TRACE,
"connect () called on transport already connected");
- ret = 0;
+ errno = EINPROGRESS;
+ ret = -1;
goto err;
}
- ret = socket_client_get_remote_sockaddr (this, SA (&sockaddr),
+ ret = socket_client_get_remote_sockaddr (this, &sock_union.sa,
&sockaddr_len, &sa_family);
if (ret == -1) {
/* logged inside client_get_remote_sockaddr */
goto err;
}
- if (port > 0)
- ((struct sockaddr_in *) (&sockaddr))->sin_port = htons (port);
-
+ if (port > 0) {
+ sock_union.sin.sin_port = htons (port);
+ }
pthread_mutex_lock (&priv->lock);
{
if (priv->sock != -1) {
@@ -1993,7 +2024,8 @@ socket_connect (rpc_transport_t *this, int port)
goto unlock;
}
- memcpy (&this->peerinfo.sockaddr, &sockaddr, sockaddr_len);
+ memcpy (&this->peerinfo.sockaddr, &sock_union.storage,
+ sockaddr_len);
this->peerinfo.sockaddr_len = sockaddr_len;
priv->sock = socket (sa_family, SOCK_STREAM, 0);
@@ -2007,31 +2039,35 @@ socket_connect (rpc_transport_t *this, int port)
/* Cant help if setting socket options fails. We can continue
* working nonetheless.
*/
- if (setsockopt (priv->sock, SOL_SOCKET, SO_RCVBUF,
- &priv->windowsize,
- sizeof (priv->windowsize)) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "setting receive window size failed: %d: %d: "
- "%s", priv->sock, priv->windowsize,
- strerror (errno));
- }
+ if (priv->windowsize != 0) {
+ if (setsockopt (priv->sock, SOL_SOCKET, SO_RCVBUF,
+ &priv->windowsize,
+ sizeof (priv->windowsize)) < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "setting receive window "
+ "size failed: %d: %d: %s",
+ priv->sock, priv->windowsize,
+ strerror (errno));
+ }
- if (setsockopt (priv->sock, SOL_SOCKET, SO_SNDBUF,
- &priv->windowsize,
- sizeof (priv->windowsize)) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "setting send window size failed: %d: %d: "
- "%s", priv->sock, priv->windowsize,
- strerror (errno));
+ if (setsockopt (priv->sock, SOL_SOCKET, SO_SNDBUF,
+ &priv->windowsize,
+ sizeof (priv->windowsize)) < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "setting send window size "
+ "failed: %d: %d: %s",
+ priv->sock, priv->windowsize,
+ strerror (errno));
+ }
}
-
if (priv->nodelay) {
ret = __socket_nodelay (priv->sock);
+
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
- "setsockopt() failed for NODELAY (%s)",
- strerror (errno));
+ "NODELAY on %d failed (%s)",
+ priv->sock, strerror (errno));
}
}
@@ -2074,7 +2110,7 @@ socket_connect (rpc_transport_t *this, int port)
ret = connect (priv->sock, SA (&this->peerinfo.sockaddr),
this->peerinfo.sockaddr_len);
- if (ret == -1 && errno != EINPROGRESS) {
+ if (ret == -1 && ((errno != EINPROGRESS) && (errno != ENOENT))) {
gf_log (this->name, GF_LOG_ERROR,
"connection attempt failed (%s)",
strerror (errno));
@@ -2090,7 +2126,7 @@ socket_connect (rpc_transport_t *this, int port)
priv->idx = event_register (ctx->event_pool, priv->sock,
socket_event_handler, this, 1, 1);
if (priv->idx == -1) {
- gf_log ("", GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_WARNING,
"failed to register the event");
ret = -1;
}
@@ -2110,7 +2146,7 @@ socket_listen (rpc_transport_t *this)
int ret = -1;
int sock = -1;
struct sockaddr_storage sockaddr;
- socklen_t sockaddr_len;
+ socklen_t sockaddr_len = 0;
peer_info_t *myinfo = NULL;
glusterfs_ctx_t *ctx = NULL;
sa_family_t sa_family = {0, };
@@ -2130,7 +2166,7 @@ socket_listen (rpc_transport_t *this)
if (sock != -1) {
gf_log_callingfn (this->name, GF_LOG_DEBUG,
- "alreading listening");
+ "already listening");
return ret;
}
@@ -2163,22 +2199,26 @@ socket_listen (rpc_transport_t *this)
/* Cant help if setting socket options fails. We can continue
* working nonetheless.
*/
- if (setsockopt (priv->sock, SOL_SOCKET, SO_RCVBUF,
- &priv->windowsize,
- sizeof (priv->windowsize)) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "setting receive window size failed: %d: %d: "
- "%s", priv->sock, priv->windowsize,
- strerror (errno));
- }
+ if (priv->windowsize != 0) {
+ if (setsockopt (priv->sock, SOL_SOCKET, SO_RCVBUF,
+ &priv->windowsize,
+ sizeof (priv->windowsize)) < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "setting receive window size "
+ "failed: %d: %d: %s", priv->sock,
+ priv->windowsize,
+ strerror (errno));
+ }
- if (setsockopt (priv->sock, SOL_SOCKET, SO_SNDBUF,
- &priv->windowsize,
- sizeof (priv->windowsize)) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "setting send window size failed: %d: %d: "
- "%s", priv->sock, priv->windowsize,
- strerror (errno));
+ if (setsockopt (priv->sock, SOL_SOCKET, SO_SNDBUF,
+ &priv->windowsize,
+ sizeof (priv->windowsize)) < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "setting send window size failed:"
+ " %d: %d: %s", priv->sock,
+ priv->windowsize,
+ strerror (errno));
+ }
}
if (priv->nodelay) {
@@ -2408,6 +2448,7 @@ socket_getpeeraddr (rpc_transport_t *this, char *peeraddr, int addrlen,
if (peeraddr != NULL) {
ret = socket_getpeername (this, peeraddr, addrlen);
}
+ ret = 0;
out:
return ret;
@@ -2468,10 +2509,11 @@ struct rpc_transport_ops tops = {
int
reconfigure (rpc_transport_t *this, dict_t *options)
{
- socket_private_t *priv = NULL;
- gf_boolean_t tmp_bool = _gf_false;
- char *optstr = NULL;
- int ret = 0;
+ socket_private_t *priv = NULL;
+ gf_boolean_t tmp_bool = _gf_false;
+ char *optstr = NULL;
+ int ret = 0;
+ uint64_t windowsize = 0;
GF_VALIDATE_OR_GOTO ("socket", this, out);
GF_VALIDATE_OR_GOTO ("socket", this->private, out);
@@ -2499,6 +2541,19 @@ reconfigure (rpc_transport_t *this, dict_t *options)
}
else
priv->keepalive = 1;
+
+ optstr = NULL;
+ if (dict_get_str (this->options, "tcp-window-size",
+ &optstr) == 0) {
+ if (gf_string2bytesize (optstr, &windowsize) != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid number format: %s", optstr);
+ goto out;
+ }
+ }
+
+ priv->windowsize = (int)windowsize;
+
ret = 0;
out:
return ret;
@@ -2534,7 +2589,6 @@ socket_init (rpc_transport_t *this)
priv->nodelay = 1;
priv->bio = 0;
priv->windowsize = GF_DEFAULT_SOCKET_WINDOW_SIZE;
-
INIT_LIST_HEAD (&priv->ioq);
/* All the below section needs 'this->options' to be present */
@@ -2579,9 +2633,8 @@ socket_init (rpc_transport_t *this)
}
}
-
optstr = NULL;
- if (dict_get_str (this->options, "transport.window-size",
+ if (dict_get_str (this->options, "tcp-window-size",
&optstr) == 0) {
if (gf_string2bytesize (optstr, &windowsize) != 0) {
gf_log (this->name, GF_LOG_ERROR,
@@ -2590,8 +2643,9 @@ socket_init (rpc_transport_t *this)
}
}
- optstr = NULL;
+ priv->windowsize = (int)windowsize;
+ optstr = NULL;
/* Enable Keep-alive by default. */
priv->keepalive = 1;
priv->keepaliveintvl = 2;
@@ -2627,7 +2681,23 @@ socket_init (rpc_transport_t *this)
priv->backlog = backlog;
}
- priv->windowsize = (int)windowsize;
+ optstr = NULL;
+
+ /* Check if socket read failures are to be logged */
+ priv->read_fail_log = 1;
+ if (dict_get (this->options, "transport.socket.read-fail-log")) {
+ optstr = data_to_str (dict_get (this->options, "transport.socket.read-fail-log"));
+ if (gf_string2boolean (optstr, &tmp_bool) == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "'transport.socket.read-fail-log' takes only "
+ "boolean options; logging socket read fails");
+ }
+ else if (tmp_bool == _gf_false) {
+ priv->read_fail_log = 0;
+ }
+ }
+
+ optstr = NULL;
out:
this->private = priv;
@@ -2701,18 +2771,17 @@ struct volume_options options[] = {
},
{ .key = { "transport.address-family",
"address-family" },
- .value = {"inet", "inet6", "inet/inet6", "inet6/inet",
- "unix", "inet-sdp" },
+ .value = {"inet", "inet6", "unix", "inet-sdp" },
.type = GF_OPTION_TYPE_STR
},
{ .key = {"non-blocking-io"},
.type = GF_OPTION_TYPE_BOOL
},
- { .key = {"transport.window-size"},
+ { .key = {"tcp-window-size"},
.type = GF_OPTION_TYPE_SIZET,
.min = GF_MIN_SOCKET_WINDOW_SIZE,
- .max = GF_MAX_SOCKET_WINDOW_SIZE,
+ .max = GF_MAX_SOCKET_WINDOW_SIZE
},
{ .key = {"transport.socket.nodelay"},
.type = GF_OPTION_TYPE_BOOL
@@ -2732,5 +2801,8 @@ struct volume_options options[] = {
{ .key = {"transport.socket.listen-backlog"},
.type = GF_OPTION_TYPE_INT
},
+ { .key = {"transport.socket.read-fail-log"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
{ .key = {NULL} }
};
diff --git a/rpc/rpc-transport/socket/src/socket.h b/rpc/rpc-transport/socket/src/socket.h
index 4acecab2a..0c897bd2e 100644
--- a/rpc/rpc-transport/socket/src/socket.h
+++ b/rpc/rpc-transport/socket/src/socket.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _SOCKET_H
@@ -41,19 +32,17 @@
#define RPC_MAX_FRAGMENT_SIZE 0x7fffffff
-/* This is the size set through setsockopt for
- * both the TCP receive window size and the
- * send buffer size.
- * Till the time iobuf size becomes configurable, this size is set to include
- * two iobufs + the GlusterFS protocol headers.
+/* The default window size will be 0, indicating not to set
+ * it to any size. Default size of Linux is found to be
+ * performance friendly.
* Linux allows us to over-ride the max values for the system.
* Should we over-ride them? Because if we set a value larger than the default
* setsockopt will fail. Having larger values might be beneficial for
* IB links.
*/
-#define GF_DEFAULT_SOCKET_WINDOW_SIZE (512 * GF_UNIT_KB)
+#define GF_DEFAULT_SOCKET_WINDOW_SIZE (0)
#define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB)
-#define GF_MIN_SOCKET_WINDOW_SIZE (128 * GF_UNIT_KB)
+#define GF_MIN_SOCKET_WINDOW_SIZE (0)
#define GF_USE_DEFAULT_KEEPALIVE (-1)
typedef enum {
@@ -81,6 +70,8 @@ typedef enum {
SP_STATE_READ_CREDBYTES, /* read credential data. */
SP_STATE_READING_VERFBYTES,
SP_STATE_READ_VERFBYTES, /* read verifier data */
+ SP_STATE_READING_PROGHDR,
+ SP_STATE_READ_PROGHDR,
SP_STATE_READING_PROG,
} sp_rpcfrag_vectored_request_state_t;
@@ -112,6 +103,7 @@ struct ioq {
typedef struct {
sp_rpcfrag_request_header_state_t header_state;
sp_rpcfrag_vectored_request_state_t vector_state;
+ int vector_sizer_state;
} sp_rpcfrag_request_state_t;
typedef enum {
@@ -193,6 +185,7 @@ typedef struct {
int keepaliveidle;
int keepaliveintvl;
uint32_t backlog;
+ gf_boolean_t read_fail_log;
} socket_private_t;
diff --git a/rpc/xdr/src/Makefile.am b/rpc/xdr/src/Makefile.am
index 981f319b3..7174815b8 100644
--- a/rpc/xdr/src/Makefile.am
+++ b/rpc/xdr/src/Makefile.am
@@ -9,14 +9,18 @@ libgfxdr_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 \
libgfxdr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la
-libgfxdr_la_SOURCES = xdr-generic.c \
- glusterfs3-xdr.c glusterfs3.c \
- cli1-xdr.c cli1.c \
- glusterd1-xdr.c glusterd1.c \
- portmap-xdr.c portmap.c
+libgfxdr_la_SOURCES = xdr-generic.c rpc-common-xdr.c \
+ glusterfs3-xdr.c \
+ cli1-xdr.c \
+ glusterd1-xdr.c \
+ portmap-xdr.c \
+ nlm4-xdr.c xdr-nfs3.c msg-nfs3.c nsm-xdr.c \
+ nlmcbk-xdr.c
-noinst_HEADERS = xdr-generic.h \
+noinst_HEADERS = xdr-generic.h rpc-common-xdr.h \
glusterfs3-xdr.h glusterfs3.h \
- cli1-xdr.h cli1.h \
- glusterd1-xdr.h glusterd1.h \
- portmap-xdr.h portmap.h
+ cli1-xdr.h \
+ glusterd1-xdr.h \
+ portmap-xdr.h \
+ nlm4-xdr.h xdr-nfs3.h msg-nfs3.h nsm-xdr.h \
+ nlmcbk-xdr.h
diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c
index e0a1e1075..53e180765 100644
--- a/rpc/xdr/src/cli1-xdr.c
+++ b/rpc/xdr/src/cli1-xdr.c
@@ -1,22 +1,30 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
+#include "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
/*
* Please do not edit this file.
@@ -24,11 +32,34 @@
*/
#include "cli1-xdr.h"
-#include "compat.h"
+
+bool_t
+xdr_gf_cli_defrag_type (XDR *xdrs, gf_cli_defrag_type *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_defrag_status_t (XDR *xdrs, gf_defrag_status_t *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
bool_t
xdr_gf1_cluster_type (XDR *xdrs, gf1_cluster_type *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -38,6 +69,19 @@ xdr_gf1_cluster_type (XDR *xdrs, gf1_cluster_type *objp)
bool_t
xdr_gf1_cli_replace_op (XDR *xdrs, gf1_cli_replace_op *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf1_op_commands (XDR *xdrs, gf1_op_commands *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -47,6 +91,8 @@ xdr_gf1_cli_replace_op (XDR *xdrs, gf1_cli_replace_op *objp)
bool_t
xdr_gf_quota_type (XDR *xdrs, gf_quota_type *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -56,6 +102,8 @@ xdr_gf_quota_type (XDR *xdrs, gf_quota_type *objp)
bool_t
xdr_gf1_cli_friends_list (XDR *xdrs, gf1_cli_friends_list *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -65,6 +113,8 @@ xdr_gf1_cli_friends_list (XDR *xdrs, gf1_cli_friends_list *objp)
bool_t
xdr_gf1_cli_get_volume (XDR *xdrs, gf1_cli_get_volume *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -74,6 +124,8 @@ xdr_gf1_cli_get_volume (XDR *xdrs, gf1_cli_get_volume *objp)
bool_t
xdr_gf1_cli_sync_volume (XDR *xdrs, gf1_cli_sync_volume *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -83,6 +135,8 @@ xdr_gf1_cli_sync_volume (XDR *xdrs, gf1_cli_sync_volume *objp)
bool_t
xdr_gf1_cli_op_flags (XDR *xdrs, gf1_cli_op_flags *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -92,6 +146,8 @@ xdr_gf1_cli_op_flags (XDR *xdrs, gf1_cli_op_flags *objp)
bool_t
xdr_gf1_cli_gsync_set (XDR *xdrs, gf1_cli_gsync_set *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -101,6 +157,8 @@ xdr_gf1_cli_gsync_set (XDR *xdrs, gf1_cli_gsync_set *objp)
bool_t
xdr_gf1_cli_stats_op (XDR *xdrs, gf1_cli_stats_op *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -110,15 +168,58 @@ xdr_gf1_cli_stats_op (XDR *xdrs, gf1_cli_stats_op *objp)
bool_t
xdr_gf1_cli_top_op (XDR *xdrs, gf1_cli_top_op *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_cli_status_type (XDR *xdrs, gf_cli_status_type *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_cli_req (XDR *xdrs, gf_cli_req *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
- if (!xdr_enum (xdrs, (enum_t *) objp))
- return FALSE;
- return TRUE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_cli_rsp (XDR *xdrs, gf_cli_rsp *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
+ return TRUE;
}
bool_t
xdr_gf1_cli_probe_req (XDR *xdrs, gf1_cli_probe_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_string (xdrs, &objp->hostname, ~0))
return FALSE;
@@ -131,6 +232,8 @@ bool_t
xdr_gf1_cli_probe_rsp (XDR *xdrs, gf1_cli_probe_rsp *objp)
{
register int32_t *buf;
+ buf = NULL;
+
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
@@ -149,6 +252,8 @@ xdr_gf1_cli_probe_rsp (XDR *xdrs, gf1_cli_probe_rsp *objp)
}
if (!xdr_string (xdrs, &objp->hostname, ~0))
return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
@@ -167,6 +272,8 @@ xdr_gf1_cli_probe_rsp (XDR *xdrs, gf1_cli_probe_rsp *objp)
}
if (!xdr_string (xdrs, &objp->hostname, ~0))
return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
return TRUE;
}
@@ -178,23 +285,31 @@ xdr_gf1_cli_probe_rsp (XDR *xdrs, gf1_cli_probe_rsp *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->hostname, ~0))
return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gf1_cli_deprobe_req (XDR *xdrs, gf1_cli_deprobe_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_string (xdrs, &objp->hostname, ~0))
return FALSE;
if (!xdr_int (xdrs, &objp->port))
return FALSE;
+ if (!xdr_int (xdrs, &objp->flags))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gf1_cli_deprobe_rsp (XDR *xdrs, gf1_cli_deprobe_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -202,12 +317,16 @@ xdr_gf1_cli_deprobe_rsp (XDR *xdrs, gf1_cli_deprobe_rsp *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->hostname, ~0))
return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gf1_cli_peer_list_req (XDR *xdrs, gf1_cli_peer_list_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->flags))
return FALSE;
@@ -219,6 +338,8 @@ xdr_gf1_cli_peer_list_req (XDR *xdrs, gf1_cli_peer_list_req *objp)
bool_t
xdr_gf1_cli_peer_list_rsp (XDR *xdrs, gf1_cli_peer_list_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -230,282 +351,21 @@ xdr_gf1_cli_peer_list_rsp (XDR *xdrs, gf1_cli_peer_list_rsp *objp)
}
bool_t
-xdr_gf1_cli_get_vol_req (XDR *xdrs, gf1_cli_get_vol_req *objp)
-{
-
- if (!xdr_int (xdrs, &objp->flags))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_get_vol_rsp (XDR *xdrs, gf1_cli_get_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->volumes.volumes_val, (u_int *) &objp->volumes.volumes_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_create_vol_req (XDR *xdrs, gf1_cli_create_vol_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_gf1_cluster_type (xdrs, &objp->type))
- return FALSE;
- if (!xdr_int (xdrs, &objp->count))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->bricks.bricks_val, (u_int *) &objp->bricks.bricks_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_create_vol_rsp (XDR *xdrs, gf1_cli_create_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_delete_vol_req (XDR *xdrs, gf1_cli_delete_vol_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_delete_vol_rsp (XDR *xdrs, gf1_cli_delete_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_start_vol_req (XDR *xdrs, gf1_cli_start_vol_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_int (xdrs, &objp->flags))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_start_vol_rsp (XDR *xdrs, gf1_cli_start_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_stop_vol_req (XDR *xdrs, gf1_cli_stop_vol_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_int (xdrs, &objp->flags))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_stop_vol_rsp (XDR *xdrs, gf1_cli_stop_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_rename_vol_req (XDR *xdrs, gf1_cli_rename_vol_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->old_volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->new_volname, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_rename_vol_rsp (XDR *xdrs, gf1_cli_rename_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_defrag_vol_req (XDR *xdrs, gf1_cli_defrag_vol_req *objp)
-{
-
- if (!xdr_int (xdrs, &objp->cmd))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_defrag_vol_rsp (XDR *xdrs, gf1_cli_defrag_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->files))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->size))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->lookedup_files))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf2_cli_defrag_vol_rsp (XDR *xdrs, gf2_cli_defrag_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->files))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->size))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->lookedup_files))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_add_brick_req (XDR *xdrs, gf1_cli_add_brick_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_int (xdrs, &objp->count))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->bricks.bricks_val, (u_int *) &objp->bricks.bricks_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_add_brick_rsp (XDR *xdrs, gf1_cli_add_brick_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_remove_brick_req (XDR *xdrs, gf1_cli_remove_brick_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_int (xdrs, &objp->count))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->bricks.bricks_val, (u_int *) &objp->bricks.bricks_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_remove_brick_rsp (XDR *xdrs, gf1_cli_remove_brick_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_replace_brick_req (XDR *xdrs, gf1_cli_replace_brick_req *objp)
+xdr_gf1_cli_fsm_log_req (XDR *xdrs, gf1_cli_fsm_log_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_gf1_cli_replace_op (xdrs, &objp->op))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->bricks.bricks_val, (u_int *) &objp->bricks.bricks_len, ~0))
+ if (!xdr_string (xdrs, &objp->name, ~0))
return FALSE;
return TRUE;
}
bool_t
-xdr_gf1_cli_replace_brick_rsp (XDR *xdrs, gf1_cli_replace_brick_rsp *objp)
+xdr_gf1_cli_fsm_log_rsp (XDR *xdrs, gf1_cli_fsm_log_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -513,74 +373,44 @@ xdr_gf1_cli_replace_brick_rsp (XDR *xdrs, gf1_cli_replace_brick_rsp *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->op_errstr, ~0))
return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->status, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_reset_vol_req (XDR *xdrs, gf1_cli_reset_vol_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_reset_vol_rsp (XDR *xdrs, gf1_cli_reset_vol_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->fsm_log.fsm_log_val, (u_int *) &objp->fsm_log.fsm_log_len, ~0))
return FALSE;
return TRUE;
}
bool_t
-xdr_gf1_cli_quota_req (XDR *xdrs, gf1_cli_quota_req *objp)
+xdr_gf1_cli_getwd_req (XDR *xdrs, gf1_cli_getwd_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ if (!xdr_int (xdrs, &objp->unused))
return FALSE;
return TRUE;
}
bool_t
-xdr_gf1_cli_quota_rsp (XDR *xdrs, gf1_cli_quota_rsp *objp)
+xdr_gf1_cli_getwd_rsp (XDR *xdrs, gf1_cli_getwd_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->limit_list, ~0))
- return FALSE;
- if (!xdr_gf_quota_type (xdrs, &objp->type))
+ if (!xdr_string (xdrs, &objp->wd, ~0))
return FALSE;
return TRUE;
}
bool_t
-xdr_gf1_cli_set_vol_req (XDR *xdrs, gf1_cli_set_vol_req *objp)
+xdr_gf1_cli_mount_req (XDR *xdrs, gf1_cli_mount_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
- if (!xdr_string (xdrs, &objp->volname, ~0))
+ if (!xdr_string (xdrs, &objp->label, ~0))
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
@@ -588,79 +418,27 @@ xdr_gf1_cli_set_vol_req (XDR *xdrs, gf1_cli_set_vol_req *objp)
}
bool_t
-xdr_gf1_cli_set_vol_rsp (XDR *xdrs, gf1_cli_set_vol_rsp *objp)
+xdr_gf1_cli_mount_rsp (XDR *xdrs, gf1_cli_mount_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_log_filename_req (XDR *xdrs, gf1_cli_log_filename_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->brick, ~0))
- return FALSE;
if (!xdr_string (xdrs, &objp->path, ~0))
return FALSE;
return TRUE;
}
bool_t
-xdr_gf1_cli_log_filename_rsp (XDR *xdrs, gf1_cli_log_filename_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_log_locate_req (XDR *xdrs, gf1_cli_log_locate_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->brick, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_sync_volume_req (XDR *xdrs, gf1_cli_sync_volume_req *objp)
-{
-
- if (!xdr_int (xdrs, &objp->flags))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->hostname, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_log_locate_rsp (XDR *xdrs, gf1_cli_log_locate_rsp *objp)
+xdr_gf1_cli_umount_req (XDR *xdrs, gf1_cli_umount_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
+ if (!xdr_int (xdrs, &objp->lazy))
return FALSE;
if (!xdr_string (xdrs, &objp->path, ~0))
return FALSE;
@@ -668,151 +446,14 @@ xdr_gf1_cli_log_locate_rsp (XDR *xdrs, gf1_cli_log_locate_rsp *objp)
}
bool_t
-xdr_gf1_cli_log_rotate_req (XDR *xdrs, gf1_cli_log_rotate_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->brick, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_log_rotate_rsp (XDR *xdrs, gf1_cli_log_rotate_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_sync_volume_rsp (XDR *xdrs, gf1_cli_sync_volume_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_fsm_log_req (XDR *xdrs, gf1_cli_fsm_log_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->name, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_fsm_log_rsp (XDR *xdrs, gf1_cli_fsm_log_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->fsm_log.fsm_log_val, (u_int *) &objp->fsm_log.fsm_log_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_gsync_set_req (XDR *xdrs, gf1_cli_gsync_set_req *objp)
-{
-
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_gsync_set_rsp (XDR *xdrs, gf1_cli_gsync_set_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- if (!xdr_int (xdrs, &objp->type))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_name, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->subop, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->master, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->slave, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->gsync_prefix, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->glusterd_workdir, ~0))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->status_dict.status_dict_val,
- (u_int *) &objp->status_dict.status_dict_len, ~0))
- return FALSE;
-
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_stats_volume_req (XDR *xdrs, gf1_cli_stats_volume_req *objp)
+xdr_gf1_cli_umount_rsp (XDR *xdrs, gf1_cli_umount_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_gf1_cli_stats_op (xdrs, &objp->op))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict_req.dict_req_val, (u_int *) &objp->dict_req.dict_req_len, ~0))
- return FALSE;
-
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_stats_volume_rsp (XDR *xdrs, gf1_cli_stats_volume_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->stats_info.stats_info_val, (u_int *) &objp->stats_info.stats_info_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_getwd_req (XDR *xdrs, gf1_cli_getwd_req *objp)
-{
- if (!xdr_int (xdrs, &objp->unused))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_getwd_rsp (XDR *xdrs, gf1_cli_getwd_rsp *objp)
-{
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
- if (!xdr_string (xdrs, &objp->wd, ~0))
- return FALSE;
return TRUE;
}
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index 5b6bfd8f1..b30fd740a 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -1,21 +1,31 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
+
+#include "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
+
/*
* Please do not edit this file.
* It was generated using rpcgen.
@@ -32,10 +42,29 @@ extern "C" {
#endif
+enum gf_cli_defrag_type {
+ GF_DEFRAG_CMD_START = 1,
+ GF_DEFRAG_CMD_STOP = 1 + 1,
+ GF_DEFRAG_CMD_STATUS = 1 + 2,
+ GF_DEFRAG_CMD_START_LAYOUT_FIX = 1 + 3,
+ GF_DEFRAG_CMD_START_FORCE = 1 + 4,
+};
+typedef enum gf_cli_defrag_type gf_cli_defrag_type;
+
+enum gf_defrag_status_t {
+ GF_DEFRAG_STATUS_NOT_STARTED = 0,
+ GF_DEFRAG_STATUS_STARTED = 1,
+ GF_DEFRAG_STATUS_STOPPED = 2,
+ GF_DEFRAG_STATUS_COMPLETE = 3,
+ GF_DEFRAG_STATUS_FAILED = 4,
+};
+typedef enum gf_defrag_status_t gf_defrag_status_t;
+
enum gf1_cluster_type {
GF_CLUSTER_TYPE_NONE = 0,
GF_CLUSTER_TYPE_STRIPE = 0 + 1,
GF_CLUSTER_TYPE_REPLICATE = 0 + 2,
+ GF_CLUSTER_TYPE_STRIPE_REPLICATE = 0 + 3,
};
typedef enum gf1_cluster_type gf1_cluster_type;
@@ -50,6 +79,16 @@ enum gf1_cli_replace_op {
};
typedef enum gf1_cli_replace_op gf1_cli_replace_op;
+enum gf1_op_commands {
+ GF_OP_CMD_NONE = 0,
+ GF_OP_CMD_START = 0 + 1,
+ GF_OP_CMD_COMMIT = 0 + 2,
+ GF_OP_CMD_STOP = 0 + 3,
+ GF_OP_CMD_STATUS = 0 + 4,
+ GF_OP_CMD_COMMIT_FORCE = 0 + 5,
+};
+typedef enum gf1_op_commands gf1_op_commands;
+
enum gf_quota_type {
GF_QUOTA_OPTION_TYPE_NONE = 0,
GF_QUOTA_OPTION_TYPE_ENABLE = 0 + 1,
@@ -88,8 +127,8 @@ enum gf1_cli_gsync_set {
GF_GSYNC_OPTION_TYPE_START = 1,
GF_GSYNC_OPTION_TYPE_STOP = 2,
GF_GSYNC_OPTION_TYPE_CONFIG = 3,
- GF_GSYNC_OPTION_TYPE_STATUS = 4,
-
+ GF_GSYNC_OPTION_TYPE_STATUS = 4,
+ GF_GSYNC_OPTION_TYPE_ROTATE = 5,
};
typedef enum gf1_cli_gsync_set gf1_cli_gsync_set;
@@ -98,22 +137,58 @@ enum gf1_cli_stats_op {
GF_CLI_STATS_START = 1,
GF_CLI_STATS_STOP = 2,
GF_CLI_STATS_INFO = 3,
- GF_CLI_STATS_TOP = 4,
+ GF_CLI_STATS_TOP = 4,
};
typedef enum gf1_cli_stats_op gf1_cli_stats_op;
enum gf1_cli_top_op {
- GF_CLI_TOP_NONE = 0,
- GF_CLI_TOP_OPEN = 0 + 1,
- GF_CLI_TOP_READ = 0 + 2,
- GF_CLI_TOP_WRITE = 0 + 3,
- GF_CLI_TOP_OPENDIR = 0 + 4,
- GF_CLI_TOP_READDIR = 0 + 5,
- GF_CLI_TOP_READ_PERF = 0 + 6,
- GF_CLI_TOP_WRITE_PERF = 0 + 7,
+ GF_CLI_TOP_NONE = 0,
+ GF_CLI_TOP_OPEN = 0 + 1,
+ GF_CLI_TOP_READ = 0 + 2,
+ GF_CLI_TOP_WRITE = 0 + 3,
+ GF_CLI_TOP_OPENDIR = 0 + 4,
+ GF_CLI_TOP_READDIR = 0 + 5,
+ GF_CLI_TOP_READ_PERF = 0 + 6,
+ GF_CLI_TOP_WRITE_PERF = 0 + 7,
};
typedef enum gf1_cli_top_op gf1_cli_top_op;
+enum gf_cli_status_type {
+ GF_CLI_STATUS_NONE = 0x0000,
+ GF_CLI_STATUS_MEM = 0x0001,
+ GF_CLI_STATUS_CLIENTS = 0x0002,
+ GF_CLI_STATUS_INODE = 0x0004,
+ GF_CLI_STATUS_FD = 0x0008,
+ GF_CLI_STATUS_CALLPOOL = 0x0010,
+ GF_CLI_STATUS_DETAIL = 0x0020,
+ GF_CLI_STATUS_MASK = 0x00FF,
+ GF_CLI_STATUS_VOL = 0x0100,
+ GF_CLI_STATUS_ALL = 0x0200,
+ GF_CLI_STATUS_BRICK = 0x0400,
+ GF_CLI_STATUS_NFS = 0x0800,
+ GF_CLI_STATUS_SHD = 0x1000,
+};
+typedef enum gf_cli_status_type gf_cli_status_type;
+
+struct gf_cli_req {
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf_cli_req gf_cli_req;
+
+struct gf_cli_rsp {
+ int op_ret;
+ int op_errno;
+ char *op_errstr;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf_cli_rsp gf_cli_rsp;
+
struct gf1_cli_probe_req {
char *hostname;
int port;
@@ -125,12 +200,14 @@ struct gf1_cli_probe_rsp {
int op_errno;
int port;
char *hostname;
+ char *op_errstr;
};
typedef struct gf1_cli_probe_rsp gf1_cli_probe_rsp;
struct gf1_cli_deprobe_req {
char *hostname;
int port;
+ int flags;
};
typedef struct gf1_cli_deprobe_req gf1_cli_deprobe_req;
@@ -138,6 +215,7 @@ struct gf1_cli_deprobe_rsp {
int op_ret;
int op_errno;
char *hostname;
+ char *op_errstr;
};
typedef struct gf1_cli_deprobe_rsp gf1_cli_deprobe_rsp;
@@ -160,291 +238,6 @@ struct gf1_cli_peer_list_rsp {
};
typedef struct gf1_cli_peer_list_rsp gf1_cli_peer_list_rsp;
-struct gf1_cli_get_vol_req {
- int flags;
- struct {
- u_int dict_len;
- char *dict_val;
- } dict;
-};
-typedef struct gf1_cli_get_vol_req gf1_cli_get_vol_req;
-
-struct gf1_cli_get_vol_rsp {
- int op_ret;
- int op_errno;
- struct {
- u_int volumes_len;
- char *volumes_val;
- } volumes;
-};
-typedef struct gf1_cli_get_vol_rsp gf1_cli_get_vol_rsp;
-
-struct gf1_cli_create_vol_req {
- char *volname;
- gf1_cluster_type type;
- int count;
- struct {
- u_int bricks_len;
- char *bricks_val;
- } bricks;
-};
-typedef struct gf1_cli_create_vol_req gf1_cli_create_vol_req;
-
-struct gf1_cli_create_vol_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
-};
-typedef struct gf1_cli_create_vol_rsp gf1_cli_create_vol_rsp;
-
-struct gf1_cli_delete_vol_req {
- char *volname;
-};
-typedef struct gf1_cli_delete_vol_req gf1_cli_delete_vol_req;
-
-struct gf1_cli_delete_vol_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
-};
-typedef struct gf1_cli_delete_vol_rsp gf1_cli_delete_vol_rsp;
-
-struct gf1_cli_start_vol_req {
- char *volname;
- int flags;
-};
-typedef struct gf1_cli_start_vol_req gf1_cli_start_vol_req;
-
-struct gf1_cli_start_vol_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
-};
-typedef struct gf1_cli_start_vol_rsp gf1_cli_start_vol_rsp;
-
-struct gf1_cli_stop_vol_req {
- char *volname;
- int flags;
-};
-typedef struct gf1_cli_stop_vol_req gf1_cli_stop_vol_req;
-
-struct gf1_cli_stop_vol_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
-};
-typedef struct gf1_cli_stop_vol_rsp gf1_cli_stop_vol_rsp;
-
-struct gf1_cli_rename_vol_req {
- char *old_volname;
- char *new_volname;
-};
-typedef struct gf1_cli_rename_vol_req gf1_cli_rename_vol_req;
-
-struct gf1_cli_rename_vol_rsp {
- int op_ret;
- int op_errno;
- char *volname;
-};
-typedef struct gf1_cli_rename_vol_rsp gf1_cli_rename_vol_rsp;
-
-struct gf1_cli_defrag_vol_req {
- int cmd;
- char *volname;
-};
-typedef struct gf1_cli_defrag_vol_req gf1_cli_defrag_vol_req;
-
-struct gf1_cli_defrag_vol_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- u_quad_t files;
- u_quad_t size;
- u_quad_t lookedup_files;
-};
-typedef struct gf1_cli_defrag_vol_rsp gf1_cli_defrag_vol_rsp;
-
-struct gf2_cli_defrag_vol_rsp {
- int op_ret;
- int op_errno;
- char *op_errstr;
- char *volname;
- u_quad_t files;
- u_quad_t size;
- u_quad_t lookedup_files;
-};
-typedef struct gf2_cli_defrag_vol_rsp gf2_cli_defrag_vol_rsp;
-
-struct gf1_cli_add_brick_req {
- char *volname;
- int count;
- struct {
- u_int bricks_len;
- char *bricks_val;
- } bricks;
-};
-typedef struct gf1_cli_add_brick_req gf1_cli_add_brick_req;
-
-struct gf1_cli_add_brick_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
-};
-typedef struct gf1_cli_add_brick_rsp gf1_cli_add_brick_rsp;
-
-struct gf1_cli_remove_brick_req {
- char *volname;
- int count;
- struct {
- u_int bricks_len;
- char *bricks_val;
- } bricks;
-};
-typedef struct gf1_cli_remove_brick_req gf1_cli_remove_brick_req;
-
-struct gf1_cli_remove_brick_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
-};
-typedef struct gf1_cli_remove_brick_rsp gf1_cli_remove_brick_rsp;
-
-struct gf1_cli_replace_brick_req {
- char *volname;
- gf1_cli_replace_op op;
- struct {
- u_int bricks_len;
- char *bricks_val;
- } bricks;
-};
-typedef struct gf1_cli_replace_brick_req gf1_cli_replace_brick_req;
-
-struct gf1_cli_replace_brick_rsp {
- int op_ret;
- int op_errno;
- char *op_errstr;
- char *volname;
- char *status;
-};
-typedef struct gf1_cli_replace_brick_rsp gf1_cli_replace_brick_rsp;
-
-struct gf1_cli_reset_vol_req {
- char *volname;
- struct {
- u_int dict_len;
- char *dict_val;
- } dict;
-};
-typedef struct gf1_cli_reset_vol_req gf1_cli_reset_vol_req;
-
-struct gf1_cli_reset_vol_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
-};
-typedef struct gf1_cli_reset_vol_rsp gf1_cli_reset_vol_rsp;
-
-struct gf1_cli_quota_req {
- char *volname;
- struct {
- u_int dict_len;
- char *dict_val;
- } dict;
-};
-typedef struct gf1_cli_quota_req gf1_cli_quota_req;
-
-struct gf1_cli_quota_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
- char *limit_list;
- gf_quota_type type;
-};
-typedef struct gf1_cli_quota_rsp gf1_cli_quota_rsp;
-
-struct gf1_cli_set_vol_req {
- char *volname;
- struct {
- u_int dict_len;
- char *dict_val;
- } dict;
-};
-typedef struct gf1_cli_set_vol_req gf1_cli_set_vol_req;
-
-struct gf1_cli_set_vol_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
- struct {
- u_int dict_len;
- char *dict_val;
- } dict;
-};
-typedef struct gf1_cli_set_vol_rsp gf1_cli_set_vol_rsp;
-
-struct gf1_cli_log_filename_req {
- char *volname;
- char *brick;
- char *path;
-};
-typedef struct gf1_cli_log_filename_req gf1_cli_log_filename_req;
-
-struct gf1_cli_log_filename_rsp {
- int op_ret;
- int op_errno;
- char *errstr;
-};
-typedef struct gf1_cli_log_filename_rsp gf1_cli_log_filename_rsp;
-
-struct gf1_cli_log_locate_req {
- char *volname;
- char *brick;
-};
-typedef struct gf1_cli_log_locate_req gf1_cli_log_locate_req;
-
-struct gf1_cli_sync_volume_req {
- int flags;
- char *volname;
- char *hostname;
-};
-typedef struct gf1_cli_sync_volume_req gf1_cli_sync_volume_req;
-
-struct gf1_cli_log_locate_rsp {
- int op_ret;
- int op_errno;
- char *path;
-};
-typedef struct gf1_cli_log_locate_rsp gf1_cli_log_locate_rsp;
-
-struct gf1_cli_log_rotate_req {
- char *volname;
- char *brick;
-};
-typedef struct gf1_cli_log_rotate_req gf1_cli_log_rotate_req;
-
-struct gf1_cli_log_rotate_rsp {
- int op_ret;
- int op_errno;
- char *errstr;
-};
-typedef struct gf1_cli_log_rotate_rsp gf1_cli_log_rotate_rsp;
-
-struct gf1_cli_sync_volume_rsp {
- int op_ret;
- int op_errno;
- char *op_errstr;
-};
-typedef struct gf1_cli_sync_volume_rsp gf1_cli_sync_volume_rsp;
-
struct gf1_cli_fsm_log_req {
char *name;
};
@@ -461,131 +254,87 @@ struct gf1_cli_fsm_log_rsp {
};
typedef struct gf1_cli_fsm_log_rsp gf1_cli_fsm_log_rsp;
-struct gf1_cli_gsync_set_req {
- struct {
- u_int dict_len;
- char *dict_val;
- } dict;
+struct gf1_cli_getwd_req {
+ int unused;
};
-typedef struct gf1_cli_gsync_set_req gf1_cli_gsync_set_req;
+typedef struct gf1_cli_getwd_req gf1_cli_getwd_req;
-struct gf1_cli_gsync_set_rsp {
+struct gf1_cli_getwd_rsp {
int op_ret;
int op_errno;
- char *op_errstr;
- int type;
- char *op_name;
- char *subop;
- char *master;
- char *slave;
- char *gsync_prefix;
- char *glusterd_workdir;
- struct {
- u_int status_dict_len;
- char *status_dict_val;
- } status_dict;
+ char *wd;
};
-typedef struct gf1_cli_gsync_set_rsp gf1_cli_gsync_set_rsp;
+typedef struct gf1_cli_getwd_rsp gf1_cli_getwd_rsp;
-struct gf1_cli_stats_volume_req {
- char *volname;
- gf1_cli_stats_op op;
+struct gf1_cli_mount_req {
+ char *label;
struct {
- u_int dict_req_len;
- char* dict_req_val;
- } dict_req;
+ u_int dict_len;
+ char *dict_val;
+ } dict;
};
-typedef struct gf1_cli_stats_volume_req gf1_cli_stats_volume_req;
+typedef struct gf1_cli_mount_req gf1_cli_mount_req;
-struct gf1_cli_stats_volume_rsp {
+struct gf1_cli_mount_rsp {
int op_ret;
int op_errno;
- char *op_errstr;
- struct {
- u_int stats_info_len;
- char *stats_info_val;
- } stats_info;
+ char *path;
};
-typedef struct gf1_cli_stats_volume_rsp gf1_cli_stats_volume_rsp;
+typedef struct gf1_cli_mount_rsp gf1_cli_mount_rsp;
-struct gf1_cli_getwd_req {
- int unused;
+struct gf1_cli_umount_req {
+ int lazy;
+ char *path;
};
-typedef struct gf1_cli_getwd_req gf1_cli_getwd_req;
+typedef struct gf1_cli_umount_req gf1_cli_umount_req;
-struct gf1_cli_getwd_rsp {
+struct gf1_cli_umount_rsp {
int op_ret;
int op_errno;
- char *wd;
};
-typedef struct gf1_cli_getwd_rsp gf1_cli_getwd_rsp;
+typedef struct gf1_cli_umount_rsp gf1_cli_umount_rsp;
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_gf_cli_defrag_type (XDR *, gf_cli_defrag_type*);
+extern bool_t xdr_gf_defrag_status_t (XDR *, gf_defrag_status_t*);
extern bool_t xdr_gf1_cluster_type (XDR *, gf1_cluster_type*);
extern bool_t xdr_gf1_cli_replace_op (XDR *, gf1_cli_replace_op*);
+extern bool_t xdr_gf1_op_commands (XDR *, gf1_op_commands*);
+extern bool_t xdr_gf_quota_type (XDR *, gf_quota_type*);
extern bool_t xdr_gf1_cli_friends_list (XDR *, gf1_cli_friends_list*);
extern bool_t xdr_gf1_cli_get_volume (XDR *, gf1_cli_get_volume*);
extern bool_t xdr_gf1_cli_sync_volume (XDR *, gf1_cli_sync_volume*);
extern bool_t xdr_gf1_cli_op_flags (XDR *, gf1_cli_op_flags*);
extern bool_t xdr_gf1_cli_gsync_set (XDR *, gf1_cli_gsync_set*);
-extern bool_t xdr_gf1_cli_top_op (XDR *, gf1_cli_top_op*);
extern bool_t xdr_gf1_cli_stats_op (XDR *, gf1_cli_stats_op*);
-extern bool_t xdr_gf_quota_type (XDR *, gf_quota_type*);
+extern bool_t xdr_gf1_cli_top_op (XDR *, gf1_cli_top_op*);
+extern bool_t xdr_gf_cli_status_type (XDR *, gf_cli_status_type*);
+extern bool_t xdr_gf_cli_req (XDR *, gf_cli_req*);
+extern bool_t xdr_gf_cli_rsp (XDR *, gf_cli_rsp*);
extern bool_t xdr_gf1_cli_probe_req (XDR *, gf1_cli_probe_req*);
extern bool_t xdr_gf1_cli_probe_rsp (XDR *, gf1_cli_probe_rsp*);
extern bool_t xdr_gf1_cli_deprobe_req (XDR *, gf1_cli_deprobe_req*);
extern bool_t xdr_gf1_cli_deprobe_rsp (XDR *, gf1_cli_deprobe_rsp*);
extern bool_t xdr_gf1_cli_peer_list_req (XDR *, gf1_cli_peer_list_req*);
extern bool_t xdr_gf1_cli_peer_list_rsp (XDR *, gf1_cli_peer_list_rsp*);
-extern bool_t xdr_gf1_cli_get_vol_req (XDR *, gf1_cli_get_vol_req*);
-extern bool_t xdr_gf1_cli_get_vol_rsp (XDR *, gf1_cli_get_vol_rsp*);
-extern bool_t xdr_gf1_cli_create_vol_req (XDR *, gf1_cli_create_vol_req*);
-extern bool_t xdr_gf1_cli_create_vol_rsp (XDR *, gf1_cli_create_vol_rsp*);
-extern bool_t xdr_gf1_cli_delete_vol_req (XDR *, gf1_cli_delete_vol_req*);
-extern bool_t xdr_gf1_cli_delete_vol_rsp (XDR *, gf1_cli_delete_vol_rsp*);
-extern bool_t xdr_gf1_cli_start_vol_req (XDR *, gf1_cli_start_vol_req*);
-extern bool_t xdr_gf1_cli_start_vol_rsp (XDR *, gf1_cli_start_vol_rsp*);
-extern bool_t xdr_gf1_cli_stop_vol_req (XDR *, gf1_cli_stop_vol_req*);
-extern bool_t xdr_gf1_cli_stop_vol_rsp (XDR *, gf1_cli_stop_vol_rsp*);
-extern bool_t xdr_gf1_cli_rename_vol_req (XDR *, gf1_cli_rename_vol_req*);
-extern bool_t xdr_gf1_cli_rename_vol_rsp (XDR *, gf1_cli_rename_vol_rsp*);
-extern bool_t xdr_gf1_cli_defrag_vol_req (XDR *, gf1_cli_defrag_vol_req*);
-extern bool_t xdr_gf1_cli_defrag_vol_rsp (XDR *, gf1_cli_defrag_vol_rsp*);
-extern bool_t xdr_gf2_cli_defrag_vol_rsp (XDR *, gf2_cli_defrag_vol_rsp*);
-extern bool_t xdr_gf1_cli_add_brick_req (XDR *, gf1_cli_add_brick_req*);
-extern bool_t xdr_gf1_cli_add_brick_rsp (XDR *, gf1_cli_add_brick_rsp*);
-extern bool_t xdr_gf1_cli_remove_brick_req (XDR *, gf1_cli_remove_brick_req*);
-extern bool_t xdr_gf1_cli_remove_brick_rsp (XDR *, gf1_cli_remove_brick_rsp*);
-extern bool_t xdr_gf1_cli_replace_brick_req (XDR *, gf1_cli_replace_brick_req*);
-extern bool_t xdr_gf1_cli_replace_brick_rsp (XDR *, gf1_cli_replace_brick_rsp*);
-extern bool_t xdr_gf1_cli_reset_vol_req (XDR *, gf1_cli_reset_vol_req*);
-extern bool_t xdr_gf1_cli_reset_vol_rsp (XDR *, gf1_cli_reset_vol_rsp*);
-extern bool_t xdr_gf1_cli_quota_req (XDR *, gf1_cli_quota_req*);
-extern bool_t xdr_gf1_cli_quota_rsp (XDR *, gf1_cli_quota_rsp*);
-extern bool_t xdr_gf1_cli_set_vol_req (XDR *, gf1_cli_set_vol_req*);
-extern bool_t xdr_gf1_cli_set_vol_rsp (XDR *, gf1_cli_set_vol_rsp*);
-extern bool_t xdr_gf1_cli_log_filename_req (XDR *, gf1_cli_log_filename_req*);
-extern bool_t xdr_gf1_cli_log_filename_rsp (XDR *, gf1_cli_log_filename_rsp*);
-extern bool_t xdr_gf1_cli_log_locate_req (XDR *, gf1_cli_log_locate_req*);
-extern bool_t xdr_gf1_cli_sync_volume_req (XDR *, gf1_cli_sync_volume_req*);
-extern bool_t xdr_gf1_cli_log_locate_rsp (XDR *, gf1_cli_log_locate_rsp*);
-extern bool_t xdr_gf1_cli_log_rotate_req (XDR *, gf1_cli_log_rotate_req*);
-extern bool_t xdr_gf1_cli_log_rotate_rsp (XDR *, gf1_cli_log_rotate_rsp*);
-extern bool_t xdr_gf1_cli_sync_volume_rsp (XDR *, gf1_cli_sync_volume_rsp*);
extern bool_t xdr_gf1_cli_fsm_log_req (XDR *, gf1_cli_fsm_log_req*);
extern bool_t xdr_gf1_cli_fsm_log_rsp (XDR *, gf1_cli_fsm_log_rsp*);
-extern bool_t xdr_gf1_cli_gsync_set_req (XDR *, gf1_cli_gsync_set_req*);
-extern bool_t xdr_gf1_cli_gsync_set_rsp (XDR *, gf1_cli_gsync_set_rsp*);
-extern bool_t xdr_gf1_cli_stats_volume_req (XDR *, gf1_cli_stats_volume_req*);
-extern bool_t xdr_gf1_cli_stats_volume_rsp (XDR *, gf1_cli_stats_volume_rsp*);
extern bool_t xdr_gf1_cli_getwd_req (XDR *, gf1_cli_getwd_req*);
extern bool_t xdr_gf1_cli_getwd_rsp (XDR *, gf1_cli_getwd_rsp*);
+extern bool_t xdr_gf1_cli_mount_req (XDR *, gf1_cli_mount_req*);
+extern bool_t xdr_gf1_cli_mount_rsp (XDR *, gf1_cli_mount_rsp*);
+extern bool_t xdr_gf1_cli_umount_req (XDR *, gf1_cli_umount_req*);
+extern bool_t xdr_gf1_cli_umount_rsp (XDR *, gf1_cli_umount_rsp*);
#else /* K&R C */
+extern bool_t xdr_gf_cli_defrag_type ();
+extern bool_t xdr_gf_defrag_status_t ();
extern bool_t xdr_gf1_cluster_type ();
extern bool_t xdr_gf1_cli_replace_op ();
+extern bool_t xdr_gf1_op_commands ();
+extern bool_t xdr_gf_quota_type ();
extern bool_t xdr_gf1_cli_friends_list ();
extern bool_t xdr_gf1_cli_get_volume ();
extern bool_t xdr_gf1_cli_sync_volume ();
@@ -593,56 +342,23 @@ extern bool_t xdr_gf1_cli_op_flags ();
extern bool_t xdr_gf1_cli_gsync_set ();
extern bool_t xdr_gf1_cli_stats_op ();
extern bool_t xdr_gf1_cli_top_op ();
-extern bool_t xdr_gf_quota_type ();
+extern bool_t xdr_gf_cli_status_type ();
+extern bool_t xdr_gf_cli_req ();
+extern bool_t xdr_gf_cli_rsp ();
extern bool_t xdr_gf1_cli_probe_req ();
extern bool_t xdr_gf1_cli_probe_rsp ();
extern bool_t xdr_gf1_cli_deprobe_req ();
extern bool_t xdr_gf1_cli_deprobe_rsp ();
extern bool_t xdr_gf1_cli_peer_list_req ();
extern bool_t xdr_gf1_cli_peer_list_rsp ();
-extern bool_t xdr_gf1_cli_get_vol_req ();
-extern bool_t xdr_gf1_cli_get_vol_rsp ();
-extern bool_t xdr_gf1_cli_create_vol_req ();
-extern bool_t xdr_gf1_cli_create_vol_rsp ();
-extern bool_t xdr_gf1_cli_delete_vol_req ();
-extern bool_t xdr_gf1_cli_delete_vol_rsp ();
-extern bool_t xdr_gf1_cli_start_vol_req ();
-extern bool_t xdr_gf1_cli_start_vol_rsp ();
-extern bool_t xdr_gf1_cli_stop_vol_req ();
-extern bool_t xdr_gf1_cli_stop_vol_rsp ();
-extern bool_t xdr_gf1_cli_rename_vol_req ();
-extern bool_t xdr_gf1_cli_rename_vol_rsp ();
-extern bool_t xdr_gf1_cli_defrag_vol_req ();
-extern bool_t xdr_gf1_cli_defrag_vol_rsp ();
-extern bool_t xdr_gf2_cli_defrag_vol_rsp ();
-extern bool_t xdr_gf1_cli_add_brick_req ();
-extern bool_t xdr_gf1_cli_add_brick_rsp ();
-extern bool_t xdr_gf1_cli_remove_brick_req ();
-extern bool_t xdr_gf1_cli_remove_brick_rsp ();
-extern bool_t xdr_gf1_cli_replace_brick_req ();
-extern bool_t xdr_gf1_cli_replace_brick_rsp ();
-extern bool_t xdr_gf1_cli_reset_vol_req ();
-extern bool_t xdr_gf1_cli_reset_vol_rsp ();
-extern bool_t xdr_gf1_cli_quota_req ();
-extern bool_t xdr_gf1_cli_quota_rsp ();
-extern bool_t xdr_gf1_cli_set_vol_req ();
-extern bool_t xdr_gf1_cli_set_vol_rsp ();
-extern bool_t xdr_gf1_cli_log_filename_req ();
-extern bool_t xdr_gf1_cli_log_filename_rsp ();
-extern bool_t xdr_gf1_cli_log_locate_req ();
-extern bool_t xdr_gf1_cli_sync_volume_req ();
-extern bool_t xdr_gf1_cli_log_locate_rsp ();
-extern bool_t xdr_gf1_cli_log_rotate_req ();
-extern bool_t xdr_gf1_cli_log_rotate_rsp ();
-extern bool_t xdr_gf1_cli_sync_volume_rsp ();
extern bool_t xdr_gf1_cli_fsm_log_req ();
extern bool_t xdr_gf1_cli_fsm_log_rsp ();
-extern bool_t xdr_gf1_cli_gsync_set_req ();
-extern bool_t xdr_gf1_cli_gsync_set_rsp ();
-extern bool_t xdr_gf1_cli_stats_volume_req ();
-extern bool_t xdr_gf1_cli_stats_volume_rsp ();
extern bool_t xdr_gf1_cli_getwd_req ();
extern bool_t xdr_gf1_cli_getwd_rsp ();
+extern bool_t xdr_gf1_cli_mount_req ();
+extern bool_t xdr_gf1_cli_mount_rsp ();
+extern bool_t xdr_gf1_cli_umount_req ();
+extern bool_t xdr_gf1_cli_umount_rsp ();
#endif /* K&R C */
@@ -650,4 +366,4 @@ extern bool_t xdr_gf1_cli_getwd_rsp ();
}
#endif
-#endif /* !_CLI1-XDR_H_RPCGEN */
+#endif /* !_CLI1_XDR_H_RPCGEN */
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index 154a2c8e3..cb22080cc 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -1,7 +1,24 @@
+ enum gf_cli_defrag_type {
+ GF_DEFRAG_CMD_START = 1,
+ GF_DEFRAG_CMD_STOP,
+ GF_DEFRAG_CMD_STATUS,
+ GF_DEFRAG_CMD_START_LAYOUT_FIX,
+ GF_DEFRAG_CMD_START_FORCE /* used by remove-brick data migration */
+} ;
+
+ enum gf_defrag_status_t {
+ GF_DEFRAG_STATUS_NOT_STARTED,
+ GF_DEFRAG_STATUS_STARTED,
+ GF_DEFRAG_STATUS_STOPPED,
+ GF_DEFRAG_STATUS_COMPLETE,
+ GF_DEFRAG_STATUS_FAILED
+} ;
+
enum gf1_cluster_type {
GF_CLUSTER_TYPE_NONE = 0,
GF_CLUSTER_TYPE_STRIPE,
- GF_CLUSTER_TYPE_REPLICATE
+ GF_CLUSTER_TYPE_REPLICATE,
+ GF_CLUSTER_TYPE_STRIPE_REPLICATE
} ;
enum gf1_cli_replace_op {
@@ -14,6 +31,15 @@
GF_REPLACE_OP_COMMIT_FORCE
} ;
+ enum gf1_op_commands {
+ GF_OP_CMD_NONE = 0,
+ GF_OP_CMD_START,
+ GF_OP_CMD_COMMIT,
+ GF_OP_CMD_STOP,
+ GF_OP_CMD_STATUS,
+ GF_OP_CMD_COMMIT_FORCE
+} ;
+
enum gf_quota_type {
GF_QUOTA_OPTION_TYPE_NONE = 0,
GF_QUOTA_OPTION_TYPE_ENABLE,
@@ -47,7 +73,8 @@ enum gf1_cli_gsync_set {
GF_GSYNC_OPTION_TYPE_START,
GF_GSYNC_OPTION_TYPE_STOP,
GF_GSYNC_OPTION_TYPE_CONFIG,
- GF_GSYNC_OPTION_TYPE_STATUS
+ GF_GSYNC_OPTION_TYPE_STATUS,
+ GF_GSYNC_OPTION_TYPE_ROTATE
};
enum gf1_cli_stats_op {
@@ -69,6 +96,35 @@ enum gf1_cli_top_op {
GF_CLI_TOP_WRITE_PERF
};
+/* The unconventional hex numbers help us perform
+ bit-wise operations which reduces complexity */
+enum gf_cli_status_type {
+ GF_CLI_STATUS_NONE = 0x0000,
+ GF_CLI_STATUS_MEM = 0x0001, /*0000000000001*/
+ GF_CLI_STATUS_CLIENTS = 0x0002, /*0000000000010*/
+ GF_CLI_STATUS_INODE = 0x0004, /*0000000000100*/
+ GF_CLI_STATUS_FD = 0x0008, /*0000000001000*/
+ GF_CLI_STATUS_CALLPOOL = 0x0010, /*0000000010000*/
+ GF_CLI_STATUS_DETAIL = 0x0020, /*0000000100000*/
+ GF_CLI_STATUS_MASK = 0x00FF, /*0000011111111 Used to get the op*/
+ GF_CLI_STATUS_VOL = 0x0100, /*0000100000000*/
+ GF_CLI_STATUS_ALL = 0x0200, /*0001000000000*/
+ GF_CLI_STATUS_BRICK = 0x0400, /*0010000000000*/
+ GF_CLI_STATUS_NFS = 0x0800, /*0100000000000*/
+ GF_CLI_STATUS_SHD = 0x1000 /*1000000000000*/
+};
+
+ struct gf_cli_req {
+ opaque dict<>;
+} ;
+
+ struct gf_cli_rsp {
+ int op_ret;
+ int op_errno;
+ string op_errstr<>;
+ opaque dict<>;
+} ;
+
struct gf1_cli_probe_req {
string hostname<>;
int port;
@@ -79,17 +135,20 @@ enum gf1_cli_top_op {
int op_errno;
int port;
string hostname<>;
+ string op_errstr<>;
} ;
struct gf1_cli_deprobe_req {
string hostname<>;
int port;
+ int flags;
} ;
struct gf1_cli_deprobe_rsp {
int op_ret;
int op_errno;
string hostname<>;
+ string op_errstr<>;
} ;
struct gf1_cli_peer_list_req {
@@ -103,221 +162,6 @@ struct gf1_cli_peer_list_rsp {
opaque friends<>;
} ;
-struct gf1_cli_get_vol_req {
- int flags;
- opaque dict<>;
-} ;
-
-struct gf1_cli_get_vol_rsp {
- int op_ret;
- int op_errno;
- opaque volumes<>;
-} ;
-
- struct gf1_cli_create_vol_req {
- string volname<>;
- gf1_cluster_type type;
- int count;
- opaque bricks<>;
-} ;
-
- struct gf1_cli_create_vol_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
-} ;
-
- struct gf1_cli_delete_vol_req {
- string volname<>;
-} ;
-
- struct gf1_cli_delete_vol_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
-} ;
-
- struct gf1_cli_start_vol_req {
- string volname<>;
- int flags;
-} ;
-
-
- struct gf1_cli_start_vol_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
-} ;
-
- struct gf1_cli_stop_vol_req {
- string volname<>;
- int flags;
-} ;
-
-
- struct gf1_cli_stop_vol_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
-} ;
-
-
- struct gf1_cli_rename_vol_req {
- string old_volname<>;
- string new_volname<>;
-} ;
-
- struct gf1_cli_rename_vol_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
-} ;
-
- struct gf1_cli_defrag_vol_req {
- int cmd;
- string volname<>;
-} ;
-
- struct gf1_cli_defrag_vol_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- unsigned hyper files;
- unsigned hyper size;
- unsigned hyper lookedup_files;
-} ;
-
-
- struct gf2_cli_defrag_vol_rsp {
- int op_ret;
- int op_errno;
- string op_errstr<>;
- string volname<>;
- unsigned hyper files;
- unsigned hyper size;
- unsigned hyper lookedup_files;
-} ;
-
- struct gf1_cli_add_brick_req {
- string volname<>;
- int count;
- opaque bricks<>;
-} ;
-
- struct gf1_cli_add_brick_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
-} ;
-
- struct gf1_cli_remove_brick_req {
- string volname<>;
- int count;
- opaque bricks<>;
-} ;
-
-
- struct gf1_cli_remove_brick_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
-} ;
-
- struct gf1_cli_replace_brick_req {
- string volname<>;
- gf1_cli_replace_op op;
- opaque bricks<>;
-} ;
-
- struct gf1_cli_replace_brick_rsp {
- int op_ret;
- int op_errno;
- string op_errstr<>;
- string volname<>;
- string status<>;
-} ;
-
-struct gf1_cli_reset_vol_req {
- string volname<>;
- opaque dict<>;
-} ;
-
-
- struct gf1_cli_reset_vol_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
-} ;
-
-
-
-struct gf1_cli_set_vol_req {
- string volname<>;
- opaque dict<>;
-} ;
-
-
- struct gf1_cli_set_vol_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
- opaque dict<>;
-} ;
-
-struct gf1_cli_log_filename_req {
- string volname<>;
- string brick<>;
- string path<>;
-};
-
-struct gf1_cli_log_filename_rsp {
- int op_ret;
- int op_errno;
- string errstr<>;
-};
-
-struct gf1_cli_log_locate_req {
- string volname<>;
- string brick<>;
-};
-
-struct gf1_cli_sync_volume_req {
- int flags;
- string volname<>;
- string hostname<>;
-};
-
-struct gf1_cli_log_locate_rsp {
- int op_ret;
- int op_errno;
- string path<>;
-};
-
-struct gf1_cli_log_rotate_req {
- string volname<>;
- string brick<>;
-};
-
-struct gf1_cli_log_rotate_rsp {
- int op_ret;
- int op_errno;
- string errstr<>;
-};
-
-struct gf1_cli_sync_volume_rsp {
- int op_ret;
- int op_errno;
- string op_errstr<>;
-};
-
struct gf1_cli_fsm_log_req {
string name<>;
};
@@ -329,56 +173,33 @@ struct gf1_cli_fsm_log_rsp {
opaque fsm_log<>;
};
-struct gf1_cli_gsync_set_req {
- opaque dict<>;
-};
+struct gf1_cli_getwd_req {
+ int unused;
+} ;
-struct gf1_cli_gsync_set_rsp {
+struct gf1_cli_getwd_rsp {
int op_ret;
int op_errno;
- string op_errstr<>;
- int type;
- string op_name<>;
- string subop<>;
- string master<>;
- string slave<>;
- string gsync_prefix<>;
- string glusterd_workdir<>;
- opaque status_dict<>;
+ string wd<>;
};
-struct gf1_cli_stats_volume_req {
- string volname<>;
- gf1_cli_stats_op op;
+struct gf1_cli_mount_req {
+ string label<>;
+ opaque dict<>;
};
-struct gf1_cli_stats_volume_rsp {
- int op_ret;
- int op_errno;
- string op_errstr<>;
- opaque stats_info<>;
+struct gf1_cli_mount_rsp {
+ int op_ret;
+ int op_errno;
+ string path<>;
};
-struct gf1_cli_quota_req {
- string volname<>;
- opaque dict<>;
-} ;
-
-struct gf1_cli_quota_rsp {
- int op_ret;
- int op_errno;
- string volname<>;
- string op_errstr<>;
- string limit_list<>;
- gf_quota_type type;
+struct gf1_cli_umount_req {
+ int lazy;
+ string path<>;
};
-struct gf1_cli_getwd_req {
- int unused;
-} ;
-
-struct gf1_cli_getwd_rsp {
- int op_ret;
- int op_errno;
- string wd<>;
+struct gf1_cli_umount_rsp {
+ int op_ret;
+ int op_errno;
};
diff --git a/rpc/xdr/src/cli1.c b/rpc/xdr/src/cli1.c
deleted file mode 100644
index e917929b3..000000000
--- a/rpc/xdr/src/cli1.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "cli1.h"
-#include "xdr-generic.h"
-
-ssize_t
-gf_xdr_serialize_cli_probe_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_probe_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_probe_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_probe_req);
-}
-
-ssize_t
-gf_xdr_to_cli_probe_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_probe_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_probe_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_probe_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_deprobe_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_deprobe_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_deprobe_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_deprobe_req);
-}
-
-ssize_t
-gf_xdr_to_cli_deprobe_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_deprobe_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_deprobe_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_deprobe_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_peer_list_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_peer_list_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_peer_list_req);
-}
-
-ssize_t
-gf_xdr_to_cli_peer_list_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_peer_list_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_peer_list_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_get_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_get_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_get_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_get_vol_req);
-}
-
-ssize_t
-gf_xdr_to_cli_get_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_get_vol_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_get_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_get_vol_req);
-}
-ssize_t
-gf_xdr_serialize_cli_create_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_create_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_create_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_create_vol_req);
-}
-
-ssize_t
-gf_xdr_to_cli_create_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_create_vol_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_create_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_create_vol_req);
-}
-
-
-ssize_t
-gf_xdr_serialize_cli_delete_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_delete_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_delete_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_delete_vol_req);
-}
-
-
-ssize_t
-gf_xdr_to_cli_delete_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_delete_vol_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_delete_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_delete_vol_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_start_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_start_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_start_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_start_vol_req);
-}
-
-ssize_t
-gf_xdr_to_cli_start_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_start_vol_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_start_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_start_vol_req);
-}
-
-
-ssize_t
-gf_xdr_serialize_cli_stop_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_stop_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_stop_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_stop_vol_req);
-}
-
-ssize_t
-gf_xdr_to_cli_stop_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_stop_vol_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_stop_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_stop_vol_req);
-}
-
-
-ssize_t
-gf_xdr_serialize_cli_rename_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_rename_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_rename_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_rename_vol_req);
-}
-
-ssize_t
-gf_xdr_to_cli_rename_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_rename_vol_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_rename_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_rename_vol_req);
-}
-
-
-ssize_t
-gf_xdr_serialize_cli_defrag_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_defrag_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_defrag_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_defrag_vol_rsp);
-}
-
-ssize_t
-gf_xdr_serialize_cli_defrag_vol_rsp_v2 (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf2_cli_defrag_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_defrag_vol_rsp_v2 (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf2_cli_defrag_vol_rsp);
-}
-
-ssize_t
-gf_xdr_to_cli_defrag_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_defrag_vol_req);
-}
-
-ssize_t
-gf_xdr_from_cli_defrag_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_defrag_vol_req);
-}
-
-
-
-ssize_t
-gf_xdr_serialize_cli_add_brick_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_add_brick_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_add_brick_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_add_brick_req);
-}
-
-ssize_t
-gf_xdr_to_cli_add_brick_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_add_brick_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_add_brick_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_add_brick_req);
-}
-
-
-ssize_t
-gf_xdr_serialize_cli_remove_brick_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_remove_brick_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_remove_brick_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_remove_brick_req);
-}
-
-
-ssize_t
-gf_xdr_to_cli_remove_brick_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_remove_brick_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_remove_brick_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_remove_brick_req);
-}
-
-
-ssize_t
-gf_xdr_serialize_cli_replace_brick_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_replace_brick_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_replace_brick_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_replace_brick_req);
-}
-
-ssize_t
-gf_xdr_to_cli_replace_brick_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_replace_brick_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_replace_brick_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_replace_brick_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_reset_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_reset_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_reset_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_reset_vol_req);
-}
-
-ssize_t
-gf_xdr_to_cli_reset_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_reset_vol_rsp);
-}
-
-
-ssize_t
-gf_xdr_from_cli_reset_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_reset_vol_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_gsync_set_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_gsync_set_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_gsync_set_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_gsync_set_req);
-}
-
-ssize_t
-gf_xdr_to_cli_gsync_set_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_gsync_set_rsp);
-}
-
-
-ssize_t
-gf_xdr_from_cli_gsync_set_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_gsync_set_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_quota_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_quota_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_quota_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_quota_req);
-}
-
-ssize_t
-gf_xdr_to_cli_quota_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_quota_rsp);
-}
-
-
-ssize_t
-gf_xdr_from_cli_quota_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_quota_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_set_vol_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_set_vol_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_set_vol_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_set_vol_req);
-}
-
-ssize_t
-gf_xdr_to_cli_set_vol_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_set_vol_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_set_vol_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_set_vol_req);
-}
-
-/* log */
-ssize_t
-gf_xdr_serialize_cli_log_filename_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_log_filename_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_log_filename_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_log_filename_req);
-}
-
-ssize_t
-gf_xdr_to_cli_log_filename_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_log_filename_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_log_filename_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_log_filename_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_log_locate_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_log_locate_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_log_locate_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_log_locate_req);
-}
-
-ssize_t
-gf_xdr_to_cli_log_locate_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_log_locate_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_log_locate_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_log_locate_req);
-}
-
-ssize_t
-gf_xdr_serialize_cli_log_rotate_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf1_cli_log_rotate_rsp);
-
-}
-
-ssize_t
-gf_xdr_to_cli_log_rotate_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_log_rotate_req);
-}
-
-ssize_t
-gf_xdr_to_cli_log_rotate_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_log_rotate_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_log_rotate_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf1_cli_log_rotate_req);
-}
-
-ssize_t
-gf_xdr_to_cli_sync_volume_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_sync_volume_req);
-}
-
-ssize_t
-gf_xdr_from_cli_sync_volume_req (struct iovec outmsg, void *args)
-{
- return xdr_serialize_generic (outmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_sync_volume_req);
-}
-
-ssize_t
-gf_xdr_to_cli_sync_volume_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_sync_volume_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_sync_volume_rsp (struct iovec outmsg, void *args)
-{
- return xdr_serialize_generic (outmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_sync_volume_rsp);
-}
-
-ssize_t
-gf_xdr_to_cli_fsm_log_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_fsm_log_req);
-}
-
-ssize_t
-gf_xdr_from_cli_fsm_log_req (struct iovec outmsg, void *args)
-{
- return xdr_serialize_generic (outmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_fsm_log_req);
-}
-
-ssize_t
-gf_xdr_to_cli_fsm_log_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_fsm_log_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_fsm_log_rsp (struct iovec outmsg, void *args)
-{
- return xdr_serialize_generic (outmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_fsm_log_rsp);
-}
-
-ssize_t
-gf_xdr_to_cli_stats_volume_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_stats_volume_req);
-}
-
-ssize_t
-gf_xdr_from_cli_stats_volume_req (struct iovec outmsg, void *args)
-{
- return xdr_serialize_generic (outmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_stats_volume_req);
-}
-
-ssize_t
-gf_xdr_to_cli_stats_volume_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_stats_volume_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_stats_volume_rsp (struct iovec outmsg, void *args)
-{
- return xdr_serialize_generic (outmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_stats_volume_rsp);
-}
-
-ssize_t
-gf_xdr_to_cli_getwd_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_getwd_req);
-}
-
-ssize_t
-gf_xdr_from_cli_getwd_req (struct iovec outmsg, void *args)
-{
- return xdr_serialize_generic (outmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_getwd_req);
-}
-
-ssize_t
-gf_xdr_to_cli_getwd_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_getwd_rsp);
-}
-
-ssize_t
-gf_xdr_from_cli_getwd_rsp (struct iovec outmsg, void *args)
-{
- return xdr_serialize_generic (outmsg, (void *)args,
- (xdrproc_t)xdr_gf1_cli_getwd_rsp);
-}
diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h
deleted file mode 100644
index 32e310aae..000000000
--- a/rpc/xdr/src/cli1.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef _CLI1_H
-#define _CLI1_H
-
-#include <sys/uio.h>
-
-#include "cli1-xdr.h"
-
-enum gf_cli_defrag_type {
- GF_DEFRAG_CMD_START = 1,
- GF_DEFRAG_CMD_STOP,
- GF_DEFRAG_CMD_STATUS,
- GF_DEFRAG_CMD_START_LAYOUT_FIX,
- GF_DEFRAG_CMD_START_MIGRATE_DATA,
-};
-
-ssize_t
-gf_xdr_serialize_cli_probe_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_probe_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_probe_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_probe_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_deprobe_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_deprobe_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_deprobe_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_deprobe_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_peer_list_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_peer_list_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_peer_list_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_peer_list_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_create_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_create_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_create_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_create_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_delete_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_delete_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_delete_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_delete_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_start_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_start_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_start_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_start_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_stop_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_stop_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_stop_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_stop_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_rename_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_rename_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_rename_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_rename_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_defrag_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_defrag_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_defrag_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_to_cli_defrag_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_serialize_cli_defrag_vol_rsp_v2 (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_defrag_vol_rsp_v2 (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_serialize_cli_add_brick_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_add_brick_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_add_brick_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_add_brick_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_remove_brick_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_remove_brick_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_remove_brick_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_remove_brick_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_replace_brick_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_replace_brick_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_replace_brick_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_replace_brick_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_reset_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_reset_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_reset_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_reset_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_gsync_set_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_gsync_set_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_gsync_set_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_gsync_set_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_quota_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_quota_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_quota_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_quota_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_set_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_set_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_set_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_set_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_get_vol_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_get_vol_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_get_vol_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_get_vol_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_log_filename_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_log_filename_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_log_filename_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_log_filename_req (struct iovec outmsg, void *req);
-
-
-ssize_t
-gf_xdr_serialize_cli_log_locate_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_log_locate_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_log_locate_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_log_locate_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_serialize_cli_log_rotate_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gf_xdr_to_cli_log_rotate_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_log_rotate_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_log_rotate_req (struct iovec outmsg, void *req);
-
-ssize_t
-gf_xdr_to_cli_sync_volume_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_sync_volume_req (struct iovec outmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_sync_volume_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_sync_volume_rsp (struct iovec outmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_fsm_log_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_fsm_log_req (struct iovec outmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_fsm_log_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_fsm_log_rsp (struct iovec outmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_stats_volume_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_stats_volume_req (struct iovec outmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_stats_volume_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_stats_volume_rsp (struct iovec outmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_getwd_req (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_getwd_req (struct iovec outmsg, void *args);
-
-ssize_t
-gf_xdr_to_cli_getwd_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gf_xdr_from_cli_getwd_rsp (struct iovec outmsg, void *args);
-#endif /* !_CLI1_H */
diff --git a/rpc/xdr/src/glusterd1-xdr.c b/rpc/xdr/src/glusterd1-xdr.c
index 93cdad767..28ab49b6f 100644
--- a/rpc/xdr/src/glusterd1-xdr.c
+++ b/rpc/xdr/src/glusterd1-xdr.c
@@ -1,33 +1,43 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
+#include "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
+
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "glusterd1-xdr.h"
-#include "compat.h"
bool_t
xdr_glusterd_volume_status (XDR *xdrs, glusterd_volume_status *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
@@ -37,6 +47,8 @@ xdr_glusterd_volume_status (XDR *xdrs, glusterd_volume_status *objp)
bool_t
xdr_gd1_mgmt_probe_req (XDR *xdrs, gd1_mgmt_probe_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -51,6 +63,57 @@ xdr_gd1_mgmt_probe_req (XDR *xdrs, gd1_mgmt_probe_req *objp)
bool_t
xdr_gd1_mgmt_probe_rsp (XDR *xdrs, gd1_mgmt_probe_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
+ sizeof (u_char), (xdrproc_t) xdr_u_char))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->hostname, ~0))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->port))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_LONG(buf, objp->port);
+ IXDR_PUT_LONG(buf, objp->op_ret);
+ IXDR_PUT_LONG(buf, objp->op_errno);
+ }
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
+ sizeof (u_char), (xdrproc_t) xdr_u_char))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->hostname, ~0))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->port))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+
+ } else {
+ objp->port = IXDR_GET_LONG(buf);
+ objp->op_ret = IXDR_GET_LONG(buf);
+ objp->op_errno = IXDR_GET_LONG(buf);
+ }
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
+ return TRUE;
+ }
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -63,12 +126,16 @@ xdr_gd1_mgmt_probe_rsp (XDR *xdrs, gd1_mgmt_probe_rsp *objp)
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gd1_mgmt_friend_req (XDR *xdrs, gd1_mgmt_friend_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -85,6 +152,8 @@ xdr_gd1_mgmt_friend_req (XDR *xdrs, gd1_mgmt_friend_req *objp)
bool_t
xdr_gd1_mgmt_friend_rsp (XDR *xdrs, gd1_mgmt_friend_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -103,6 +172,8 @@ xdr_gd1_mgmt_friend_rsp (XDR *xdrs, gd1_mgmt_friend_rsp *objp)
bool_t
xdr_gd1_mgmt_unfriend_req (XDR *xdrs, gd1_mgmt_unfriend_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -117,6 +188,8 @@ xdr_gd1_mgmt_unfriend_req (XDR *xdrs, gd1_mgmt_unfriend_req *objp)
bool_t
xdr_gd1_mgmt_unfriend_rsp (XDR *xdrs, gd1_mgmt_unfriend_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -135,6 +208,8 @@ xdr_gd1_mgmt_unfriend_rsp (XDR *xdrs, gd1_mgmt_unfriend_rsp *objp)
bool_t
xdr_gd1_mgmt_cluster_lock_req (XDR *xdrs, gd1_mgmt_cluster_lock_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -145,6 +220,8 @@ xdr_gd1_mgmt_cluster_lock_req (XDR *xdrs, gd1_mgmt_cluster_lock_req *objp)
bool_t
xdr_gd1_mgmt_cluster_lock_rsp (XDR *xdrs, gd1_mgmt_cluster_lock_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -159,6 +236,8 @@ xdr_gd1_mgmt_cluster_lock_rsp (XDR *xdrs, gd1_mgmt_cluster_lock_rsp *objp)
bool_t
xdr_gd1_mgmt_cluster_unlock_req (XDR *xdrs, gd1_mgmt_cluster_unlock_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -169,6 +248,8 @@ xdr_gd1_mgmt_cluster_unlock_req (XDR *xdrs, gd1_mgmt_cluster_unlock_req *objp)
bool_t
xdr_gd1_mgmt_cluster_unlock_rsp (XDR *xdrs, gd1_mgmt_cluster_unlock_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -183,6 +264,8 @@ xdr_gd1_mgmt_cluster_unlock_rsp (XDR *xdrs, gd1_mgmt_cluster_unlock_rsp *objp)
bool_t
xdr_gd1_mgmt_stage_op_req (XDR *xdrs, gd1_mgmt_stage_op_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -197,8 +280,9 @@ xdr_gd1_mgmt_stage_op_req (XDR *xdrs, gd1_mgmt_stage_op_req *objp)
bool_t
xdr_gd1_mgmt_stage_op_rsp (XDR *xdrs, gd1_mgmt_stage_op_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
- register int32_t *buf;
if (xdrs->x_op == XDR_ENCODE) {
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
@@ -267,6 +351,8 @@ xdr_gd1_mgmt_stage_op_rsp (XDR *xdrs, gd1_mgmt_stage_op_rsp *objp)
bool_t
xdr_gd1_mgmt_commit_op_req (XDR *xdrs, gd1_mgmt_commit_op_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -282,6 +368,7 @@ bool_t
xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
{
register int32_t *buf;
+ buf = NULL;
if (xdrs->x_op == XDR_ENCODE) {
@@ -351,6 +438,8 @@ xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
bool_t
xdr_gd1_mgmt_friend_update (XDR *xdrs, gd1_mgmt_friend_update *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -365,6 +454,8 @@ xdr_gd1_mgmt_friend_update (XDR *xdrs, gd1_mgmt_friend_update *objp)
bool_t
xdr_gd1_mgmt_friend_update_rsp (XDR *xdrs, gd1_mgmt_friend_update_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -381,6 +472,8 @@ xdr_gd1_mgmt_friend_update_rsp (XDR *xdrs, gd1_mgmt_friend_update_rsp *objp)
bool_t
xdr_gd1_mgmt_brick_op_req (XDR *xdrs, gd1_mgmt_brick_op_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_string (xdrs, &objp->name, ~0))
return FALSE;
@@ -394,6 +487,8 @@ xdr_gd1_mgmt_brick_op_req (XDR *xdrs, gd1_mgmt_brick_op_req *objp)
bool_t
xdr_gd1_mgmt_brick_op_rsp (XDR *xdrs, gd1_mgmt_brick_op_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
diff --git a/rpc/xdr/src/glusterd1-xdr.h b/rpc/xdr/src/glusterd1-xdr.h
index 45f860b86..89de04ebe 100644
--- a/rpc/xdr/src/glusterd1-xdr.h
+++ b/rpc/xdr/src/glusterd1-xdr.h
@@ -1,22 +1,30 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
+#include "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
/*
* Please do not edit this file.
@@ -54,6 +62,7 @@ struct gd1_mgmt_probe_rsp {
int port;
int op_ret;
int op_errno;
+ char *op_errstr;
};
typedef struct gd1_mgmt_probe_rsp gd1_mgmt_probe_rsp;
@@ -252,4 +261,4 @@ extern bool_t xdr_gd1_mgmt_brick_op_rsp ();
}
#endif
-#endif /* !_GLUSTERD1-XDR_H_RPCGEN */
+#endif /* !_GLUSTERD1_XDR_H_RPCGEN */
diff --git a/rpc/xdr/src/glusterd1-xdr.x b/rpc/xdr/src/glusterd1-xdr.x
index c30c71e02..fc1bb58b4 100644
--- a/rpc/xdr/src/glusterd1-xdr.x
+++ b/rpc/xdr/src/glusterd1-xdr.x
@@ -16,6 +16,7 @@
int port;
int op_ret;
int op_errno;
+ string op_errstr<>;
} ;
struct gd1_mgmt_friend_req {
diff --git a/rpc/xdr/src/glusterd1.c b/rpc/xdr/src/glusterd1.c
deleted file mode 100644
index 84cc93d1a..000000000
--- a/rpc/xdr/src/glusterd1.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "glusterd1.h"
-
-
-ssize_t
-gd_xdr_serialize_mgmt_probe_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gd1_mgmt_probe_rsp);
-
-}
-
-ssize_t
-gd_xdr_serialize_mgmt_friend_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gd1_mgmt_friend_rsp);
-
-}
-
-ssize_t
-gd_xdr_serialize_mgmt_cluster_lock_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp);
-
-}
-
-ssize_t
-gd_xdr_serialize_mgmt_cluster_unlock_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp);
-
-}
-
-ssize_t
-gd_xdr_serialize_mgmt_stage_op_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_rsp);
-
-}
-
-ssize_t
-gd_xdr_serialize_mgmt_commit_op_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp);
-
-}
-
-ssize_t
-gd_xdr_serialize_mgmt_friend_update_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp);
-
-}
-/* Decode */
-
-
-ssize_t
-gd_xdr_to_mgmt_probe_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_probe_req);
-}
-
-ssize_t
-gd_xdr_to_mgmt_friend_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_friend_req);
-}
-
-ssize_t
-gd_xdr_to_mgmt_friend_update (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_friend_update);
-}
-
-ssize_t
-gd_xdr_to_mgmt_cluster_lock_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_req);
-}
-
-ssize_t
-gd_xdr_to_mgmt_cluster_unlock_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_req);
-}
-
-ssize_t
-gd_xdr_to_mgmt_stage_op_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_req);
-}
-
-
-ssize_t
-gd_xdr_to_mgmt_commit_op_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_req);
-}
-
-ssize_t
-gd_xdr_to_mgmt_probe_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_probe_rsp);
-}
-
-ssize_t
-gd_xdr_to_mgmt_friend_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_friend_rsp);
-}
-
-ssize_t
-gd_xdr_to_mgmt_cluster_lock_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp);
-}
-
-ssize_t
-gd_xdr_to_mgmt_cluster_unlock_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp);
-}
-
-ssize_t
-gd_xdr_to_mgmt_stage_op_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_rsp);
-}
-
-ssize_t
-gd_xdr_to_mgmt_commit_op_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp);
-}
-
-ssize_t
-gd_xdr_to_mgmt_friend_update_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp);
-}
-
-ssize_t
-gd_xdr_from_mgmt_probe_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gd1_mgmt_probe_req);
-
-}
-
-ssize_t
-gd_xdr_from_mgmt_friend_update (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gd1_mgmt_friend_update);
-
-}
-
-ssize_t
-gd_xdr_from_mgmt_friend_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gd1_mgmt_friend_req);
-
-}
-
-ssize_t
-gd_xdr_from_mgmt_cluster_lock_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_req);
-
-}
-
-ssize_t
-gd_xdr_from_mgmt_cluster_unlock_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_req);
-
-}
-
-ssize_t
-gd_xdr_from_mgmt_stage_op_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_req);
-}
-
-
-ssize_t
-gd_xdr_from_mgmt_commit_op_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_req);
-}
-
-ssize_t
-gd_xdr_to_mgmt_brick_op_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
-}
-
-ssize_t
-gd_xdr_from_mgmt_brick_op_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
-}
-
-ssize_t
-gd_xdr_to_mgmt_brick_op_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
-}
-
-ssize_t
-gd_xdr_serialize_mgmt_brick_op_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
-}
diff --git a/rpc/xdr/src/glusterd1.h b/rpc/xdr/src/glusterd1.h
deleted file mode 100644
index 5c43e5802..000000000
--- a/rpc/xdr/src/glusterd1.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef _GLUSTERD1_H
-#define _GLUSTERD1_H
-
-#include <sys/uio.h>
-
-#include "xdr-generic.h"
-#include "glusterd1-xdr.h"
-
-ssize_t
-gd_xdr_to_mgmt_probe_req (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_to_mgmt_probe_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_serialize_mgmt_probe_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gd_xdr_from_mgmt_probe_req (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_to_mgmt_friend_req (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_to_mgmt_friend_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_serialize_mgmt_friend_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gd_xdr_from_mgmt_friend_req (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_to_mgmt_cluster_lock_req (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_to_mgmt_cluster_lock_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_serialize_mgmt_cluster_lock_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gd_xdr_from_mgmt_cluster_lock_req (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_to_mgmt_cluster_unlock_req (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_to_mgmt_cluster_unlock_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_serialize_mgmt_cluster_unlock_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gd_xdr_from_mgmt_cluster_unlock_req (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_to_mgmt_stage_op_req (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_to_mgmt_stage_op_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_serialize_mgmt_stage_op_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gd_xdr_from_mgmt_stage_op_req (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_to_mgmt_commit_op_req (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_to_mgmt_commit_op_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_serialize_mgmt_commit_op_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gd_xdr_from_mgmt_commit_op_req (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_to_mgmt_friend_update (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_from_mgmt_friend_update (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_serialize_mgmt_friend_update_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-gd_xdr_to_mgmt_friend_update_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_to_mgmt_brick_op_req (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_from_mgmt_brick_op_req (struct iovec outmsg, void *req);
-
-ssize_t
-gd_xdr_to_mgmt_brick_op_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-gd_xdr_serialize_mgmt_brick_op_rsp (struct iovec outmsg, void *rsp);
-
-#endif /* !_MSG_GD_XDR_H */
diff --git a/rpc/xdr/src/glusterfs3-xdr.c b/rpc/xdr/src/glusterfs3-xdr.c
index eb3261f08..9d55f89c2 100644
--- a/rpc/xdr/src/glusterfs3-xdr.c
+++ b/rpc/xdr/src/glusterfs3-xdr.c
@@ -1,22 +1,21 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
/*
* Please do not edit this file.
@@ -24,11 +23,12 @@
*/
#include "glusterfs3-xdr.h"
-#include "compat.h"
bool_t
xdr_gf_statfs (XDR *xdrs, gf_statfs *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_u_quad_t (xdrs, &objp->bsize))
return FALSE;
@@ -58,6 +58,8 @@ xdr_gf_statfs (XDR *xdrs, gf_statfs *objp)
bool_t
xdr_gf_proto_flock (XDR *xdrs, gf_proto_flock *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_u_int (xdrs, &objp->type))
return FALSE;
@@ -69,7 +71,7 @@ xdr_gf_proto_flock (XDR *xdrs, gf_proto_flock *objp)
return FALSE;
if (!xdr_u_int (xdrs, &objp->pid))
return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->owner))
+ if (!xdr_bytes (xdrs, (char **)&objp->lk_owner.lk_owner_val, (u_int *) &objp->lk_owner.lk_owner_len, ~0))
return FALSE;
return TRUE;
}
@@ -78,6 +80,8 @@ bool_t
xdr_gf_iatt (XDR *xdrs, gf_iatt *objp)
{
register int32_t *buf;
+ buf = NULL;
+
if (xdrs->x_op == XDR_ENCODE) {
if (!xdr_opaque (xdrs, objp->ia_gfid, 16))
@@ -136,7 +140,7 @@ xdr_gf_iatt (XDR *xdrs, gf_iatt *objp)
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
if (!xdr_opaque (xdrs, objp->ia_gfid, 16))
- return FALSE;
+ return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->ia_ino))
return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->ia_dev))
@@ -191,7 +195,7 @@ xdr_gf_iatt (XDR *xdrs, gf_iatt *objp)
return TRUE;
}
- if (!xdr_opaque (xdrs, objp->ia_gfid, 16))
+ if (!xdr_opaque (xdrs, objp->ia_gfid, 16))
return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->ia_ino))
return FALSE;
@@ -231,10 +235,12 @@ xdr_gf_iatt (XDR *xdrs, gf_iatt *objp)
bool_t
xdr_gfs3_stat_req (XDR *xdrs, gfs3_stat_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -242,6 +248,8 @@ xdr_gfs3_stat_req (XDR *xdrs, gfs3_stat_req *objp)
bool_t
xdr_gfs3_stat_rsp (XDR *xdrs, gfs3_stat_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -249,18 +257,22 @@ xdr_gfs3_stat_rsp (XDR *xdrs, gfs3_stat_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->stat))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_readlink_req (XDR *xdrs, gfs3_readlink_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
- return FALSE;
+ return FALSE;
if (!xdr_u_int (xdrs, &objp->size))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -268,6 +280,8 @@ xdr_gfs3_readlink_req (XDR *xdrs, gfs3_readlink_req *objp)
bool_t
xdr_gfs3_readlink_rsp (XDR *xdrs, gfs3_readlink_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -277,25 +291,28 @@ xdr_gfs3_readlink_rsp (XDR *xdrs, gfs3_readlink_rsp *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->path, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_mknod_req (XDR *xdrs, gfs3_mknod_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->pargfid, 16))
- return FALSE;
+ return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->dev))
return FALSE;
if (!xdr_u_int (xdrs, &objp->mode))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_u_int (xdrs, &objp->umask))
return FALSE;
if (!xdr_string (xdrs, &objp->bname, ~0))
return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val,
- (u_int *) &objp->dict.dict_len, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -303,6 +320,8 @@ xdr_gfs3_mknod_req (XDR *xdrs, gfs3_mknod_req *objp)
bool_t
xdr_gfs3_mknod_rsp (XDR *xdrs, gfs3_mknod_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -314,23 +333,26 @@ xdr_gfs3_mknod_rsp (XDR *xdrs, gfs3_mknod_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postparent))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_mkdir_req (XDR *xdrs, gfs3_mkdir_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->pargfid, 16))
- return FALSE;
+ return FALSE;
if (!xdr_u_int (xdrs, &objp->mode))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_u_int (xdrs, &objp->umask))
return FALSE;
if (!xdr_string (xdrs, &objp->bname, ~0))
return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val,
- (u_int *) &objp->dict.dict_len, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -338,6 +360,8 @@ xdr_gfs3_mkdir_req (XDR *xdrs, gfs3_mkdir_req *objp)
bool_t
xdr_gfs3_mkdir_rsp (XDR *xdrs, gfs3_mkdir_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -349,25 +373,33 @@ xdr_gfs3_mkdir_rsp (XDR *xdrs, gfs3_mkdir_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postparent))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_unlink_req (XDR *xdrs, gfs3_unlink_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->pargfid, 16))
- return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->bname, ~0))
return FALSE;
+ if (!xdr_u_int (xdrs, &objp->xflags))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_unlink_rsp (XDR *xdrs, gfs3_unlink_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -377,27 +409,33 @@ xdr_gfs3_unlink_rsp (XDR *xdrs, gfs3_unlink_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postparent))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_rmdir_req (XDR *xdrs, gfs3_rmdir_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->pargfid, 16))
- return FALSE;
- if (!xdr_int (xdrs, &objp->flags))
- return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->xflags))
return FALSE;
if (!xdr_string (xdrs, &objp->bname, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_rmdir_rsp (XDR *xdrs, gfs3_rmdir_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -407,23 +445,26 @@ xdr_gfs3_rmdir_rsp (XDR *xdrs, gfs3_rmdir_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postparent))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_symlink_req (XDR *xdrs, gfs3_symlink_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->pargfid, 16))
- return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->bname, ~0))
return FALSE;
+ if (!xdr_u_int (xdrs, &objp->umask))
+ return FALSE;
if (!xdr_string (xdrs, &objp->linkname, ~0))
return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val,
- (u_int *) &objp->dict.dict_len, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -431,6 +472,8 @@ xdr_gfs3_symlink_req (XDR *xdrs, gfs3_symlink_req *objp)
bool_t
xdr_gfs3_symlink_rsp (XDR *xdrs, gfs3_symlink_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -442,31 +485,35 @@ xdr_gfs3_symlink_rsp (XDR *xdrs, gfs3_symlink_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postparent))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_rename_req (XDR *xdrs, gfs3_rename_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->oldgfid, 16))
- return FALSE;
+ return FALSE;
if (!xdr_opaque (xdrs, objp->newgfid, 16))
- return FALSE;
- if (!xdr_string (xdrs, &objp->oldpath, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->oldbname, ~0))
return FALSE;
- if (!xdr_string (xdrs, &objp->newpath, ~0))
- return FALSE;
if (!xdr_string (xdrs, &objp->newbname, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_rename_rsp (XDR *xdrs, gfs3_rename_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -482,29 +529,33 @@ xdr_gfs3_rename_rsp (XDR *xdrs, gfs3_rename_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postnewparent))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_link_req (XDR *xdrs, gfs3_link_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->oldgfid, 16))
- return FALSE;
- if (!xdr_opaque (xdrs, objp->newgfid, 16))
- return FALSE;
- if (!xdr_string (xdrs, &objp->oldpath, ~0))
return FALSE;
- if (!xdr_string (xdrs, &objp->newpath, ~0))
+ if (!xdr_opaque (xdrs, objp->newgfid, 16))
return FALSE;
if (!xdr_string (xdrs, &objp->newbname, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_link_rsp (XDR *xdrs, gfs3_link_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -516,18 +567,22 @@ xdr_gfs3_link_rsp (XDR *xdrs, gfs3_link_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postparent))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_truncate_req (XDR *xdrs, gfs3_truncate_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->offset))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -535,6 +590,8 @@ xdr_gfs3_truncate_req (XDR *xdrs, gfs3_truncate_req *objp)
bool_t
xdr_gfs3_truncate_rsp (XDR *xdrs, gfs3_truncate_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -544,20 +601,22 @@ xdr_gfs3_truncate_rsp (XDR *xdrs, gfs3_truncate_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->poststat))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_open_req (XDR *xdrs, gfs3_open_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_u_int (xdrs, &objp->flags))
return FALSE;
- if (!xdr_u_int (xdrs, &objp->wbflags))
- return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -565,6 +624,8 @@ xdr_gfs3_open_req (XDR *xdrs, gfs3_open_req *objp)
bool_t
xdr_gfs3_open_rsp (XDR *xdrs, gfs3_open_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -572,12 +633,16 @@ xdr_gfs3_open_rsp (XDR *xdrs, gfs3_open_rsp *objp)
return FALSE;
if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_read_req (XDR *xdrs, gfs3_read_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -587,12 +652,18 @@ xdr_gfs3_read_req (XDR *xdrs, gfs3_read_req *objp)
return FALSE;
if (!xdr_u_int (xdrs, &objp->size))
return FALSE;
+ if (!xdr_u_int (xdrs, &objp->flag))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_read_rsp (XDR *xdrs, gfs3_read_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -602,26 +673,26 @@ xdr_gfs3_read_rsp (XDR *xdrs, gfs3_read_rsp *objp)
return FALSE;
if (!xdr_u_int (xdrs, &objp->size))
return FALSE;
-
- return TRUE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
+ return TRUE;
}
bool_t
xdr_gfs3_lookup_req (XDR *xdrs, gfs3_lookup_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_opaque (xdrs, objp->pargfid, 16))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->flags))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_u_int (xdrs, &objp->flags))
return FALSE;
if (!xdr_string (xdrs, &objp->bname, ~0))
return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val,
- (u_int *) &objp->dict.dict_len, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -629,6 +700,8 @@ xdr_gfs3_lookup_req (XDR *xdrs, gfs3_lookup_req *objp)
bool_t
xdr_gfs3_lookup_rsp (XDR *xdrs, gfs3_lookup_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -638,8 +711,7 @@ xdr_gfs3_lookup_rsp (XDR *xdrs, gfs3_lookup_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postparent))
return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val,
- (u_int *) &objp->dict.dict_len, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -647,6 +719,8 @@ xdr_gfs3_lookup_rsp (XDR *xdrs, gfs3_lookup_rsp *objp)
bool_t
xdr_gfs3_write_req (XDR *xdrs, gfs3_write_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -656,12 +730,18 @@ xdr_gfs3_write_req (XDR *xdrs, gfs3_write_req *objp)
return FALSE;
if (!xdr_u_int (xdrs, &objp->size))
return FALSE;
+ if (!xdr_u_int (xdrs, &objp->flag))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_write_rsp (XDR *xdrs, gfs3_write_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -671,16 +751,20 @@ xdr_gfs3_write_rsp (XDR *xdrs, gfs3_write_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->poststat))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_statfs_req (XDR *xdrs, gfs3_statfs_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -688,6 +772,8 @@ xdr_gfs3_statfs_req (XDR *xdrs, gfs3_statfs_req *objp)
bool_t
xdr_gfs3_statfs_rsp (XDR *xdrs, gfs3_statfs_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -695,12 +781,16 @@ xdr_gfs3_statfs_rsp (XDR *xdrs, gfs3_statfs_rsp *objp)
return FALSE;
if (!xdr_gf_statfs (xdrs, &objp->statfs))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_lk_req (XDR *xdrs, gfs3_lk_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -712,12 +802,16 @@ xdr_gfs3_lk_req (XDR *xdrs, gfs3_lk_req *objp)
return FALSE;
if (!xdr_gf_proto_flock (xdrs, &objp->flock))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_lk_rsp (XDR *xdrs, gfs3_lk_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -725,12 +819,16 @@ xdr_gfs3_lk_rsp (XDR *xdrs, gfs3_lk_rsp *objp)
return FALSE;
if (!xdr_gf_proto_flock (xdrs, &objp->flock))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_inodelk_req (XDR *xdrs, gfs3_inodelk_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -740,16 +838,18 @@ xdr_gfs3_inodelk_req (XDR *xdrs, gfs3_inodelk_req *objp)
return FALSE;
if (!xdr_gf_proto_flock (xdrs, &objp->flock))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
- return FALSE;
if (!xdr_string (xdrs, &objp->volume, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_finodelk_req (XDR *xdrs, gfs3_finodelk_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -763,23 +863,31 @@ xdr_gfs3_finodelk_req (XDR *xdrs, gfs3_finodelk_req *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->volume, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_flush_req (XDR *xdrs, gfs3_flush_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fsync_req (XDR *xdrs, gfs3_fsync_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -787,12 +895,16 @@ xdr_gfs3_fsync_req (XDR *xdrs, gfs3_fsync_req *objp)
return FALSE;
if (!xdr_u_int (xdrs, &objp->data))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fsync_rsp (XDR *xdrs, gfs3_fsync_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -802,12 +914,16 @@ xdr_gfs3_fsync_rsp (XDR *xdrs, gfs3_fsync_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->poststat))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_setxattr_req (XDR *xdrs, gfs3_setxattr_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -815,7 +931,7 @@ xdr_gfs3_setxattr_req (XDR *xdrs, gfs3_setxattr_req *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -823,6 +939,8 @@ xdr_gfs3_setxattr_req (XDR *xdrs, gfs3_setxattr_req *objp)
bool_t
xdr_gfs3_fsetxattr_req (XDR *xdrs, gfs3_fsetxattr_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -832,12 +950,16 @@ xdr_gfs3_fsetxattr_req (XDR *xdrs, gfs3_fsetxattr_req *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_xattrop_req (XDR *xdrs, gfs3_xattrop_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -845,7 +967,7 @@ xdr_gfs3_xattrop_req (XDR *xdrs, gfs3_xattrop_req *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -853,6 +975,8 @@ xdr_gfs3_xattrop_req (XDR *xdrs, gfs3_xattrop_req *objp)
bool_t
xdr_gfs3_xattrop_rsp (XDR *xdrs, gfs3_xattrop_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -860,12 +984,16 @@ xdr_gfs3_xattrop_rsp (XDR *xdrs, gfs3_xattrop_rsp *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fxattrop_req (XDR *xdrs, gfs3_fxattrop_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -875,12 +1003,16 @@ xdr_gfs3_fxattrop_req (XDR *xdrs, gfs3_fxattrop_req *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fxattrop_rsp (XDR *xdrs, gfs3_fxattrop_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -888,27 +1020,33 @@ xdr_gfs3_fxattrop_rsp (XDR *xdrs, gfs3_fxattrop_rsp *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_getxattr_req (XDR *xdrs, gfs3_getxattr_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_u_int (xdrs, &objp->namelen))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
- return FALSE;
if (!xdr_string (xdrs, &objp->name, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_getxattr_rsp (XDR *xdrs, gfs3_getxattr_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -916,12 +1054,16 @@ xdr_gfs3_getxattr_rsp (XDR *xdrs, gfs3_getxattr_rsp *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fgetxattr_req (XDR *xdrs, gfs3_fgetxattr_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -931,12 +1073,16 @@ xdr_gfs3_fgetxattr_req (XDR *xdrs, gfs3_fgetxattr_req *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->name, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fgetxattr_rsp (XDR *xdrs, gfs3_fgetxattr_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -944,29 +1090,52 @@ xdr_gfs3_fgetxattr_rsp (XDR *xdrs, gfs3_fgetxattr_rsp *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_removexattr_req (XDR *xdrs, gfs3_removexattr_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_string (xdrs, &objp->name, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gfs3_fremovexattr_req (XDR *xdrs, gfs3_fremovexattr_req *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_opaque (xdrs, objp->gfid, 16))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
if (!xdr_string (xdrs, &objp->name, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_opendir_req (XDR *xdrs, gfs3_opendir_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -974,6 +1143,8 @@ xdr_gfs3_opendir_req (XDR *xdrs, gfs3_opendir_req *objp)
bool_t
xdr_gfs3_opendir_rsp (XDR *xdrs, gfs3_opendir_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -981,12 +1152,16 @@ xdr_gfs3_opendir_rsp (XDR *xdrs, gfs3_opendir_rsp *objp)
return FALSE;
if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fsyncdir_req (XDR *xdrs, gfs3_fsyncdir_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -994,12 +1169,16 @@ xdr_gfs3_fsyncdir_req (XDR *xdrs, gfs3_fsyncdir_req *objp)
return FALSE;
if (!xdr_int (xdrs, &objp->data))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_readdir_req (XDR *xdrs, gfs3_readdir_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -1009,12 +1188,16 @@ xdr_gfs3_readdir_req (XDR *xdrs, gfs3_readdir_req *objp)
return FALSE;
if (!xdr_u_int (xdrs, &objp->size))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_readdirp_req (XDR *xdrs, gfs3_readdirp_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -1024,12 +1207,16 @@ xdr_gfs3_readdirp_req (XDR *xdrs, gfs3_readdirp_req *objp)
return FALSE;
if (!xdr_u_int (xdrs, &objp->size))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gf_setvolume_req (XDR *xdrs, gf_setvolume_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
@@ -1039,6 +1226,8 @@ xdr_gf_setvolume_req (XDR *xdrs, gf_setvolume_req *objp)
bool_t
xdr_gf_setvolume_rsp (XDR *xdrs, gf_setvolume_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -1052,12 +1241,14 @@ xdr_gf_setvolume_rsp (XDR *xdrs, gf_setvolume_rsp *objp)
bool_t
xdr_gfs3_access_req (XDR *xdrs, gfs3_access_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_u_int (xdrs, &objp->mask))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -1065,19 +1256,67 @@ xdr_gfs3_access_req (XDR *xdrs, gfs3_access_req *objp)
bool_t
xdr_gfs3_create_req (XDR *xdrs, gfs3_create_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_opaque (xdrs, objp->pargfid, 16))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->flags))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->umask))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->flags);
+ IXDR_PUT_U_LONG(buf, objp->mode);
+ IXDR_PUT_U_LONG(buf, objp->umask);
+ }
+ if (!xdr_string (xdrs, &objp->bname, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_opaque (xdrs, objp->pargfid, 16))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->flags))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->umask))
+ return FALSE;
+
+ } else {
+ objp->flags = IXDR_GET_U_LONG(buf);
+ objp->mode = IXDR_GET_U_LONG(buf);
+ objp->umask = IXDR_GET_U_LONG(buf);
+ }
+ if (!xdr_string (xdrs, &objp->bname, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
+ return TRUE;
+ }
if (!xdr_opaque (xdrs, objp->pargfid, 16))
- return FALSE;
+ return FALSE;
if (!xdr_u_int (xdrs, &objp->flags))
return FALSE;
if (!xdr_u_int (xdrs, &objp->mode))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_u_int (xdrs, &objp->umask))
return FALSE;
if (!xdr_string (xdrs, &objp->bname, ~0))
return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val,
- (u_int *) &objp->dict.dict_len, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -1085,6 +1324,8 @@ xdr_gfs3_create_req (XDR *xdrs, gfs3_create_req *objp)
bool_t
xdr_gfs3_create_rsp (XDR *xdrs, gfs3_create_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -1098,12 +1339,16 @@ xdr_gfs3_create_rsp (XDR *xdrs, gfs3_create_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->postparent))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_ftruncate_req (XDR *xdrs, gfs3_ftruncate_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -1111,12 +1356,16 @@ xdr_gfs3_ftruncate_req (XDR *xdrs, gfs3_ftruncate_req *objp)
return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->offset))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_ftruncate_rsp (XDR *xdrs, gfs3_ftruncate_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -1126,23 +1375,31 @@ xdr_gfs3_ftruncate_rsp (XDR *xdrs, gfs3_ftruncate_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->poststat))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fstat_req (XDR *xdrs, gfs3_fstat_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fstat_rsp (XDR *xdrs, gfs3_fstat_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -1150,12 +1407,16 @@ xdr_gfs3_fstat_rsp (XDR *xdrs, gfs3_fstat_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->stat))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_entrylk_req (XDR *xdrs, gfs3_entrylk_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -1165,18 +1426,20 @@ xdr_gfs3_entrylk_req (XDR *xdrs, gfs3_entrylk_req *objp)
return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->namelen))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
- return FALSE;
if (!xdr_string (xdrs, &objp->name, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->volume, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fentrylk_req (XDR *xdrs, gfs3_fentrylk_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -1192,13 +1455,16 @@ xdr_gfs3_fentrylk_req (XDR *xdrs, gfs3_fentrylk_req *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->volume, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
-
bool_t
xdr_gfs3_setattr_req (XDR *xdrs, gfs3_setattr_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
@@ -1206,7 +1472,7 @@ xdr_gfs3_setattr_req (XDR *xdrs, gfs3_setattr_req *objp)
return FALSE;
if (!xdr_int (xdrs, &objp->valid))
return FALSE;
- if (!xdr_string (xdrs, &objp->path, ~0))
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
return FALSE;
return TRUE;
}
@@ -1214,6 +1480,8 @@ xdr_gfs3_setattr_req (XDR *xdrs, gfs3_setattr_req *objp)
bool_t
xdr_gfs3_setattr_rsp (XDR *xdrs, gfs3_setattr_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -1223,12 +1491,16 @@ xdr_gfs3_setattr_rsp (XDR *xdrs, gfs3_setattr_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->statpost))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fsetattr_req (XDR *xdrs, gfs3_fsetattr_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
@@ -1236,12 +1508,16 @@ xdr_gfs3_fsetattr_req (XDR *xdrs, gfs3_fsetattr_req *objp)
return FALSE;
if (!xdr_int (xdrs, &objp->valid))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_fsetattr_rsp (XDR *xdrs, gfs3_fsetattr_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -1251,12 +1527,16 @@ xdr_gfs3_fsetattr_rsp (XDR *xdrs, gfs3_fsetattr_rsp *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->statpost))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_rchecksum_req (XDR *xdrs, gfs3_rchecksum_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
@@ -1264,6 +1544,8 @@ xdr_gfs3_rchecksum_req (XDR *xdrs, gfs3_rchecksum_req *objp)
return FALSE;
if (!xdr_u_int (xdrs, &objp->len))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
@@ -1271,6 +1553,7 @@ bool_t
xdr_gfs3_rchecksum_rsp (XDR *xdrs, gfs3_rchecksum_rsp *objp)
{
register int32_t *buf;
+ buf = NULL;
if (xdrs->x_op == XDR_ENCODE) {
@@ -1290,6 +1573,8 @@ xdr_gfs3_rchecksum_rsp (XDR *xdrs, gfs3_rchecksum_rsp *objp)
}
if (!xdr_bytes (xdrs, (char **)&objp->strong_checksum.strong_checksum_val, (u_int *) &objp->strong_checksum.strong_checksum_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
@@ -1308,6 +1593,8 @@ xdr_gfs3_rchecksum_rsp (XDR *xdrs, gfs3_rchecksum_rsp *objp)
}
if (!xdr_bytes (xdrs, (char **)&objp->strong_checksum.strong_checksum_val, (u_int *) &objp->strong_checksum.strong_checksum_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
@@ -1319,23 +1606,31 @@ xdr_gfs3_rchecksum_rsp (XDR *xdrs, gfs3_rchecksum_rsp *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->strong_checksum.strong_checksum_val, (u_int *) &objp->strong_checksum.strong_checksum_len, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gf_getspec_req (XDR *xdrs, gf_getspec_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_u_int (xdrs, &objp->flags))
return FALSE;
if (!xdr_string (xdrs, &objp->key, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gf_getspec_rsp (XDR *xdrs, gf_getspec_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
@@ -1343,12 +1638,16 @@ xdr_gf_getspec_rsp (XDR *xdrs, gf_getspec_rsp *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->spec, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gf_log_req (XDR *xdrs, gf_log_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_bytes (xdrs, (char **)&objp->msg.msg_val, (u_int *) &objp->msg.msg_len, ~0))
return FALSE;
@@ -1358,11 +1657,15 @@ xdr_gf_log_req (XDR *xdrs, gf_log_req *objp)
bool_t
xdr_gf_notify_req (XDR *xdrs, gf_notify_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_u_int (xdrs, &objp->flags))
return FALSE;
if (!xdr_string (xdrs, &objp->buf, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
@@ -1370,6 +1673,8 @@ bool_t
xdr_gf_notify_rsp (XDR *xdrs, gf_notify_rsp *objp)
{
register int32_t *buf;
+ buf = NULL;
+
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
@@ -1388,6 +1693,8 @@ xdr_gf_notify_rsp (XDR *xdrs, gf_notify_rsp *objp)
}
if (!xdr_string (xdrs, &objp->buf, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
@@ -1406,6 +1713,8 @@ xdr_gf_notify_rsp (XDR *xdrs, gf_notify_rsp *objp)
}
if (!xdr_string (xdrs, &objp->buf, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
@@ -1417,46 +1726,62 @@ xdr_gf_notify_rsp (XDR *xdrs, gf_notify_rsp *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->buf, ~0))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_releasedir_req (XDR *xdrs, gfs3_releasedir_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_release_req (XDR *xdrs, gfs3_release_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_opaque (xdrs, objp->gfid, 16))
return FALSE;
if (!xdr_quad_t (xdrs, &objp->fd))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gf_common_rsp (XDR *xdrs, gf_common_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
-
bool_t
xdr_gfs3_dirlist (XDR *xdrs, gfs3_dirlist *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_u_quad_t (xdrs, &objp->d_ino))
return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->d_off))
@@ -1475,22 +1800,30 @@ xdr_gfs3_dirlist (XDR *xdrs, gfs3_dirlist *objp)
bool_t
xdr_gfs3_readdir_rsp (XDR *xdrs, gfs3_readdir_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
if (!xdr_pointer (xdrs, (char **)&objp->reply, sizeof (gfs3_dirlist), (xdrproc_t) xdr_gfs3_dirlist))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
return TRUE;
}
bool_t
xdr_gfs3_dirplist (XDR *xdrs, gfs3_dirplist *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_u_quad_t (xdrs, &objp->d_ino))
return FALSE;
if (!xdr_u_quad_t (xdrs, &objp->d_off))
- return FALSE;
+ return FALSE;
if (!xdr_u_int (xdrs, &objp->d_len))
return FALSE;
if (!xdr_u_int (xdrs, &objp->d_type))
@@ -1499,6 +1832,8 @@ xdr_gfs3_dirplist (XDR *xdrs, gfs3_dirplist *objp)
return FALSE;
if (!xdr_gf_iatt (xdrs, &objp->stat))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (gfs3_dirplist), (xdrproc_t) xdr_gfs3_dirplist))
return FALSE;
return TRUE;
@@ -1507,11 +1842,72 @@ xdr_gfs3_dirplist (XDR *xdrs, gfs3_dirplist *objp)
bool_t
xdr_gfs3_readdirp_rsp (XDR *xdrs, gfs3_readdirp_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
- if (!xdr_pointer (xdrs, (char **)&objp->reply, sizeof (struct gfs3_dirplist), (xdrproc_t) xdr_gfs3_dirplist))
+ if (!xdr_pointer (xdrs, (char **)&objp->reply, sizeof (gfs3_dirplist), (xdrproc_t) xdr_gfs3_dirplist))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_set_lk_ver_rsp (XDR *xdrs, gf_set_lk_ver_rsp *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->lk_ver))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_set_lk_ver_req (XDR *xdrs, gf_set_lk_ver_req *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_string (xdrs, &objp->uid, ~0))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->lk_ver))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_event_notify_req (XDR *xdrs, gf_event_notify_req *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_int (xdrs, &objp->op))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_event_notify_rsp (XDR *xdrs, gf_event_notify_rsp *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
return FALSE;
return TRUE;
}
diff --git a/rpc/xdr/src/glusterfs3-xdr.h b/rpc/xdr/src/glusterfs3-xdr.h
index 4c57bfa40..a68d1a678 100644
--- a/rpc/xdr/src/glusterfs3-xdr.h
+++ b/rpc/xdr/src/glusterfs3-xdr.h
@@ -1,35 +1,32 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
/*
- * Most content of this file is generated using rpcgen. There are very few
- * additions done to this file (changes can be seen by doing
- * 'rpcgen glusterfs3.x' and taking a diff of this file with rpcgen
- * generated file.
+ * Please do not edit this file.
+ * It was generated using rpcgen.
*/
-#ifndef _GLUSTERFS3_H_RPCGEN
-#define _GLUSTERFS3_H_RPCGEN
+#ifndef _GLUSTERFS3_XDR_H_RPCGEN
+#define _GLUSTERFS3_XDR_H_RPCGEN
+
+#include <rpc/rpc.h>
-//#include <rpc/rpc.h>
-#include "xdr-common.h"
#ifdef __cplusplus
extern "C" {
@@ -57,7 +54,10 @@ struct gf_proto_flock {
u_quad_t start;
u_quad_t len;
u_int pid;
- u_quad_t owner;
+ struct {
+ u_int lk_owner_len;
+ char *lk_owner_val;
+ } lk_owner;
};
typedef struct gf_proto_flock gf_proto_flock;
@@ -82,10 +82,12 @@ struct gf_iatt {
};
typedef struct gf_iatt gf_iatt;
-/* Gluster FS Payload structures */
struct gfs3_stat_req {
char gfid[16];
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_stat_req gfs3_stat_req;
@@ -93,13 +95,20 @@ struct gfs3_stat_rsp {
int op_ret;
int op_errno;
struct gf_iatt stat;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_stat_rsp gfs3_stat_rsp;
struct gfs3_readlink_req {
char gfid[16];
u_int size;
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_readlink_req gfs3_readlink_req;
@@ -108,6 +117,10 @@ struct gfs3_readlink_rsp {
int op_errno;
struct gf_iatt buf;
char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_readlink_rsp gfs3_readlink_rsp;
@@ -115,12 +128,12 @@ struct gfs3_mknod_req {
char pargfid[16];
u_quad_t dev;
u_int mode;
- char *path;
+ u_int umask;
char *bname;
struct {
- u_int dict_len;
- char *dict_val;
- } dict;
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_mknod_req gfs3_mknod_req;
@@ -130,18 +143,22 @@ struct gfs3_mknod_rsp {
struct gf_iatt stat;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_mknod_rsp gfs3_mknod_rsp;
struct gfs3_mkdir_req {
char pargfid[16];
u_int mode;
- char *path;
+ u_int umask;
char *bname;
struct {
- u_int dict_len;
- char *dict_val;
- } dict;
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_mkdir_req gfs3_mkdir_req;
@@ -151,13 +168,21 @@ struct gfs3_mkdir_rsp {
struct gf_iatt stat;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_mkdir_rsp gfs3_mkdir_rsp;
struct gfs3_unlink_req {
char pargfid[16];
- char *path;
char *bname;
+ u_int xflags;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_unlink_req gfs3_unlink_req;
@@ -166,14 +191,21 @@ struct gfs3_unlink_rsp {
int op_errno;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_unlink_rsp gfs3_unlink_rsp;
struct gfs3_rmdir_req {
char pargfid[16];
- int flags;
- char *path;
+ int xflags;
char *bname;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_rmdir_req gfs3_rmdir_req;
@@ -182,18 +214,22 @@ struct gfs3_rmdir_rsp {
int op_errno;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_rmdir_rsp gfs3_rmdir_rsp;
struct gfs3_symlink_req {
char pargfid[16];
- char *path;
char *bname;
+ u_int umask;
char *linkname;
struct {
- u_int dict_len;
- char *dict_val;
- } dict;
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_symlink_req gfs3_symlink_req;
@@ -203,16 +239,22 @@ struct gfs3_symlink_rsp {
struct gf_iatt stat;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_symlink_rsp gfs3_symlink_rsp;
struct gfs3_rename_req {
char oldgfid[16];
char newgfid[16];
- char *oldpath;
char *oldbname;
- char *newpath;
char *newbname;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_rename_req gfs3_rename_req;
@@ -224,15 +266,21 @@ struct gfs3_rename_rsp {
struct gf_iatt postoldparent;
struct gf_iatt prenewparent;
struct gf_iatt postnewparent;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_rename_rsp gfs3_rename_rsp;
struct gfs3_link_req {
char oldgfid[16];
char newgfid[16];
- char *oldpath;
- char *newpath;
char *newbname;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_link_req gfs3_link_req;
@@ -242,13 +290,20 @@ struct gfs3_link_rsp {
struct gf_iatt stat;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_link_rsp gfs3_link_rsp;
struct gfs3_truncate_req {
char gfid[16];
u_quad_t offset;
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_truncate_req gfs3_truncate_req;
@@ -257,14 +312,20 @@ struct gfs3_truncate_rsp {
int op_errno;
struct gf_iatt prestat;
struct gf_iatt poststat;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_truncate_rsp gfs3_truncate_rsp;
struct gfs3_open_req {
char gfid[16];
u_int flags;
- u_int wbflags;
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_open_req gfs3_open_req;
@@ -272,6 +333,10 @@ struct gfs3_open_rsp {
int op_ret;
int op_errno;
quad_t fd;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_open_rsp gfs3_open_rsp;
@@ -280,6 +345,11 @@ struct gfs3_read_req {
quad_t fd;
u_quad_t offset;
u_int size;
+ u_int flag;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_read_req gfs3_read_req;
@@ -288,6 +358,10 @@ struct gfs3_read_rsp {
int op_errno;
struct gf_iatt stat;
u_int size;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_read_rsp gfs3_read_rsp;
@@ -295,12 +369,11 @@ struct gfs3_lookup_req {
char gfid[16];
char pargfid[16];
u_int flags;
- char *path;
char *bname;
struct {
- u_int dict_len;
- char *dict_val;
- } dict;
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_lookup_req gfs3_lookup_req;
@@ -310,9 +383,9 @@ struct gfs3_lookup_rsp {
struct gf_iatt stat;
struct gf_iatt postparent;
struct {
- u_int dict_len;
- char *dict_val;
- } dict;
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_lookup_rsp gfs3_lookup_rsp;
@@ -321,6 +394,11 @@ struct gfs3_write_req {
quad_t fd;
u_quad_t offset;
u_int size;
+ u_int flag;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_write_req gfs3_write_req;
@@ -329,12 +407,19 @@ struct gfs3_write_rsp {
int op_errno;
struct gf_iatt prestat;
struct gf_iatt poststat;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_write_rsp gfs3_write_rsp;
struct gfs3_statfs_req {
char gfid[16];
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_statfs_req gfs3_statfs_req;
@@ -342,6 +427,10 @@ struct gfs3_statfs_rsp {
int op_ret;
int op_errno;
struct gf_statfs statfs;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_statfs_rsp gfs3_statfs_rsp;
@@ -351,6 +440,10 @@ struct gfs3_lk_req {
u_int cmd;
u_int type;
struct gf_proto_flock flock;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_lk_req gfs3_lk_req;
@@ -358,6 +451,10 @@ struct gfs3_lk_rsp {
int op_ret;
int op_errno;
struct gf_proto_flock flock;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_lk_rsp gfs3_lk_rsp;
@@ -366,8 +463,11 @@ struct gfs3_inodelk_req {
u_int cmd;
u_int type;
struct gf_proto_flock flock;
- char *path;
char *volume;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_inodelk_req gfs3_inodelk_req;
@@ -378,12 +478,20 @@ struct gfs3_finodelk_req {
u_int type;
struct gf_proto_flock flock;
char *volume;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_finodelk_req gfs3_finodelk_req;
struct gfs3_flush_req {
char gfid[16];
quad_t fd;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_flush_req gfs3_flush_req;
@@ -391,6 +499,10 @@ struct gfs3_fsync_req {
char gfid[16];
quad_t fd;
u_int data;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fsync_req gfs3_fsync_req;
@@ -399,6 +511,10 @@ struct gfs3_fsync_rsp {
int op_errno;
struct gf_iatt prestat;
struct gf_iatt poststat;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fsync_rsp gfs3_fsync_rsp;
@@ -409,7 +525,10 @@ struct gfs3_setxattr_req {
u_int dict_len;
char *dict_val;
} dict;
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_setxattr_req gfs3_setxattr_req;
@@ -421,6 +540,10 @@ struct gfs3_fsetxattr_req {
u_int dict_len;
char *dict_val;
} dict;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fsetxattr_req gfs3_fsetxattr_req;
@@ -431,7 +554,10 @@ struct gfs3_xattrop_req {
u_int dict_len;
char *dict_val;
} dict;
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_xattrop_req gfs3_xattrop_req;
@@ -442,6 +568,10 @@ struct gfs3_xattrop_rsp {
u_int dict_len;
char *dict_val;
} dict;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_xattrop_rsp gfs3_xattrop_rsp;
@@ -453,6 +583,10 @@ struct gfs3_fxattrop_req {
u_int dict_len;
char *dict_val;
} dict;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fxattrop_req gfs3_fxattrop_req;
@@ -463,14 +597,21 @@ struct gfs3_fxattrop_rsp {
u_int dict_len;
char *dict_val;
} dict;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fxattrop_rsp gfs3_fxattrop_rsp;
struct gfs3_getxattr_req {
char gfid[16];
u_int namelen;
- char *path;
char *name;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_getxattr_req gfs3_getxattr_req;
@@ -481,6 +622,10 @@ struct gfs3_getxattr_rsp {
u_int dict_len;
char *dict_val;
} dict;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_getxattr_rsp gfs3_getxattr_rsp;
@@ -489,6 +634,10 @@ struct gfs3_fgetxattr_req {
quad_t fd;
u_int namelen;
char *name;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fgetxattr_req gfs3_fgetxattr_req;
@@ -499,19 +648,40 @@ struct gfs3_fgetxattr_rsp {
u_int dict_len;
char *dict_val;
} dict;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fgetxattr_rsp gfs3_fgetxattr_rsp;
struct gfs3_removexattr_req {
char gfid[16];
- char *path;
char *name;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_removexattr_req gfs3_removexattr_req;
+struct gfs3_fremovexattr_req {
+ char gfid[16];
+ quad_t fd;
+ char *name;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
+};
+typedef struct gfs3_fremovexattr_req gfs3_fremovexattr_req;
+
struct gfs3_opendir_req {
char gfid[16];
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_opendir_req gfs3_opendir_req;
@@ -519,6 +689,10 @@ struct gfs3_opendir_rsp {
int op_ret;
int op_errno;
quad_t fd;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_opendir_rsp gfs3_opendir_rsp;
@@ -526,6 +700,10 @@ struct gfs3_fsyncdir_req {
char gfid[16];
quad_t fd;
int data;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fsyncdir_req gfs3_fsyncdir_req;
@@ -534,6 +712,10 @@ struct gfs3_readdir_req {
quad_t fd;
u_quad_t offset;
u_int size;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_readdir_req gfs3_readdir_req;
@@ -542,6 +724,10 @@ struct gfs3_readdirp_req {
quad_t fd;
u_quad_t offset;
u_int size;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
};
typedef struct gfs3_readdirp_req gfs3_readdirp_req;
@@ -566,7 +752,10 @@ typedef struct gf_setvolume_rsp gf_setvolume_rsp;
struct gfs3_access_req {
char gfid[16];
u_int mask;
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_access_req gfs3_access_req;
@@ -574,12 +763,12 @@ struct gfs3_create_req {
char pargfid[16];
u_int flags;
u_int mode;
- char *path;
+ u_int umask;
char *bname;
struct {
- u_int dict_len;
- char *dict_val;
- } dict;
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_create_req gfs3_create_req;
@@ -590,6 +779,10 @@ struct gfs3_create_rsp {
u_quad_t fd;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_create_rsp gfs3_create_rsp;
@@ -597,6 +790,10 @@ struct gfs3_ftruncate_req {
char gfid[16];
quad_t fd;
u_quad_t offset;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_ftruncate_req gfs3_ftruncate_req;
@@ -605,12 +802,20 @@ struct gfs3_ftruncate_rsp {
int op_errno;
struct gf_iatt prestat;
struct gf_iatt poststat;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_ftruncate_rsp gfs3_ftruncate_rsp;
struct gfs3_fstat_req {
char gfid[16];
quad_t fd;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fstat_req gfs3_fstat_req;
@@ -618,6 +823,10 @@ struct gfs3_fstat_rsp {
int op_ret;
int op_errno;
struct gf_iatt stat;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fstat_rsp gfs3_fstat_rsp;
@@ -626,9 +835,12 @@ struct gfs3_entrylk_req {
u_int cmd;
u_int type;
u_quad_t namelen;
- char *path;
char *name;
char *volume;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_entrylk_req gfs3_entrylk_req;
@@ -640,6 +852,10 @@ struct gfs3_fentrylk_req {
u_quad_t namelen;
char *name;
char *volume;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fentrylk_req gfs3_fentrylk_req;
@@ -647,7 +863,10 @@ struct gfs3_setattr_req {
char gfid[16];
struct gf_iatt stbuf;
int valid;
- char *path;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_setattr_req gfs3_setattr_req;
@@ -656,6 +875,10 @@ struct gfs3_setattr_rsp {
int op_errno;
struct gf_iatt statpre;
struct gf_iatt statpost;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_setattr_rsp gfs3_setattr_rsp;
@@ -663,6 +886,10 @@ struct gfs3_fsetattr_req {
quad_t fd;
struct gf_iatt stbuf;
int valid;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fsetattr_req gfs3_fsetattr_req;
@@ -671,6 +898,10 @@ struct gfs3_fsetattr_rsp {
int op_errno;
struct gf_iatt statpre;
struct gf_iatt statpost;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_fsetattr_rsp gfs3_fsetattr_rsp;
@@ -678,6 +909,10 @@ struct gfs3_rchecksum_req {
quad_t fd;
u_quad_t offset;
u_int len;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_rchecksum_req gfs3_rchecksum_req;
@@ -689,12 +924,20 @@ struct gfs3_rchecksum_rsp {
u_int strong_checksum_len;
char *strong_checksum_val;
} strong_checksum;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_rchecksum_rsp gfs3_rchecksum_rsp;
struct gf_getspec_req {
u_int flags;
char *key;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gf_getspec_req gf_getspec_req;
@@ -702,6 +945,10 @@ struct gf_getspec_rsp {
int op_ret;
int op_errno;
char *spec;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gf_getspec_rsp gf_getspec_rsp;
@@ -716,6 +963,10 @@ typedef struct gf_log_req gf_log_req;
struct gf_notify_req {
u_int flags;
char *buf;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gf_notify_req gf_notify_req;
@@ -724,24 +975,40 @@ struct gf_notify_rsp {
int op_errno;
u_int flags;
char *buf;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gf_notify_rsp gf_notify_rsp;
struct gfs3_releasedir_req {
char gfid[16];
quad_t fd;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_releasedir_req gfs3_releasedir_req;
struct gfs3_release_req {
char gfid[16];
quad_t fd;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_release_req gfs3_release_req;
struct gf_common_rsp {
int op_ret;
int op_errno;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gf_common_rsp gf_common_rsp;
@@ -759,6 +1026,10 @@ struct gfs3_readdir_rsp {
int op_ret;
int op_errno;
struct gfs3_dirlist *reply;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_readdir_rsp gfs3_readdir_rsp;
@@ -769,6 +1040,10 @@ struct gfs3_dirplist {
u_int d_type;
char *name;
struct gf_iatt stat;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
struct gfs3_dirplist *nextentry;
};
typedef struct gfs3_dirplist gfs3_dirplist;
@@ -777,9 +1052,45 @@ struct gfs3_readdirp_rsp {
int op_ret;
int op_errno;
struct gfs3_dirplist *reply;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_readdirp_rsp gfs3_readdirp_rsp;
+struct gf_set_lk_ver_rsp {
+ int op_ret;
+ int op_errno;
+ int lk_ver;
+};
+typedef struct gf_set_lk_ver_rsp gf_set_lk_ver_rsp;
+
+struct gf_set_lk_ver_req {
+ char *uid;
+ int lk_ver;
+};
+typedef struct gf_set_lk_ver_req gf_set_lk_ver_req;
+
+struct gf_event_notify_req {
+ int op;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf_event_notify_req gf_event_notify_req;
+
+struct gf_event_notify_rsp {
+ int op_ret;
+ int op_errno;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf_event_notify_rsp gf_event_notify_rsp;
+
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
@@ -834,6 +1145,7 @@ extern bool_t xdr_gfs3_getxattr_rsp (XDR *, gfs3_getxattr_rsp*);
extern bool_t xdr_gfs3_fgetxattr_req (XDR *, gfs3_fgetxattr_req*);
extern bool_t xdr_gfs3_fgetxattr_rsp (XDR *, gfs3_fgetxattr_rsp*);
extern bool_t xdr_gfs3_removexattr_req (XDR *, gfs3_removexattr_req*);
+extern bool_t xdr_gfs3_fremovexattr_req (XDR *, gfs3_fremovexattr_req*);
extern bool_t xdr_gfs3_opendir_req (XDR *, gfs3_opendir_req*);
extern bool_t xdr_gfs3_opendir_rsp (XDR *, gfs3_opendir_rsp*);
extern bool_t xdr_gfs3_fsyncdir_req (XDR *, gfs3_fsyncdir_req*);
@@ -868,6 +1180,10 @@ extern bool_t xdr_gfs3_dirlist (XDR *, gfs3_dirlist*);
extern bool_t xdr_gfs3_readdir_rsp (XDR *, gfs3_readdir_rsp*);
extern bool_t xdr_gfs3_dirplist (XDR *, gfs3_dirplist*);
extern bool_t xdr_gfs3_readdirp_rsp (XDR *, gfs3_readdirp_rsp*);
+extern bool_t xdr_gf_set_lk_ver_rsp (XDR *, gf_set_lk_ver_rsp*);
+extern bool_t xdr_gf_set_lk_ver_req (XDR *, gf_set_lk_ver_req*);
+extern bool_t xdr_gf_event_notify_req (XDR *, gf_event_notify_req*);
+extern bool_t xdr_gf_event_notify_rsp (XDR *, gf_event_notify_rsp*);
#else /* K&R C */
extern bool_t xdr_gf_statfs ();
@@ -921,6 +1237,7 @@ extern bool_t xdr_gfs3_getxattr_rsp ();
extern bool_t xdr_gfs3_fgetxattr_req ();
extern bool_t xdr_gfs3_fgetxattr_rsp ();
extern bool_t xdr_gfs3_removexattr_req ();
+extern bool_t xdr_gfs3_fremovexattr_req ();
extern bool_t xdr_gfs3_opendir_req ();
extern bool_t xdr_gfs3_opendir_rsp ();
extern bool_t xdr_gfs3_fsyncdir_req ();
@@ -955,6 +1272,10 @@ extern bool_t xdr_gfs3_dirlist ();
extern bool_t xdr_gfs3_readdir_rsp ();
extern bool_t xdr_gfs3_dirplist ();
extern bool_t xdr_gfs3_readdirp_rsp ();
+extern bool_t xdr_gf_set_lk_ver_rsp ();
+extern bool_t xdr_gf_set_lk_ver_req ();
+extern bool_t xdr_gf_event_notify_req ();
+extern bool_t xdr_gf_event_notify_rsp ();
#endif /* K&R C */
@@ -962,4 +1283,4 @@ extern bool_t xdr_gfs3_readdirp_rsp ();
}
#endif
-#endif /* !_GLUSTERFS3_H_RPCGEN */
+#endif /* !_GLUSTERFS3_XDR_H_RPCGEN */
diff --git a/rpc/xdr/src/glusterfs3-xdr.x b/rpc/xdr/src/glusterfs3-xdr.x
index 592f7ed70..ad261423d 100644
--- a/rpc/xdr/src/glusterfs3-xdr.x
+++ b/rpc/xdr/src/glusterfs3-xdr.x
@@ -19,7 +19,7 @@ struct gf_proto_flock {
unsigned hyper start;
unsigned hyper len;
unsigned int pid;
- unsigned hyper owner;
+ opaque lk_owner<>;
} ;
@@ -45,26 +45,27 @@ struct gf_iatt {
struct gfs3_stat_req {
opaque gfid[16];
- string path<>; /* NULL terminated */
-
+ opaque xdata<>; /* Extra data */
};
struct gfs3_stat_rsp {
int op_ret;
int op_errno;
struct gf_iatt stat;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_readlink_req {
opaque gfid[16];
unsigned int size;
- string path<>; /* NULL terminated */
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_readlink_rsp {
int op_ret;
int op_errno;
struct gf_iatt buf;
string path<>; /* NULL terminated */
+ opaque xdata<>; /* Extra data */
} ;
@@ -72,9 +73,9 @@ struct gfs3_readlink_req {
opaque pargfid[16];
unsigned hyper dev;
unsigned int mode;
- string path<>; /* NULL terminated */
+ unsigned int umask;
string bname<>; /* NULL terminated */
- opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_mknod_rsp {
int op_ret;
@@ -82,15 +83,16 @@ struct gfs3_readlink_req {
struct gf_iatt stat;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_mkdir_req {
opaque pargfid[16];
unsigned int mode;
- string path<>; /* NULL terminated */
+ unsigned int umask;
string bname<>; /* NULL terminated */
- opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_mkdir_rsp {
int op_ret;
@@ -98,42 +100,46 @@ struct gfs3_readlink_req {
struct gf_iatt stat;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_unlink_req {
opaque pargfid[16];
- string path<>; /* NULL terminated */
string bname<>; /* NULL terminated */
+ unsigned int xflags;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_unlink_rsp {
int op_ret;
int op_errno;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_rmdir_req {
opaque pargfid[16];
- int flags;
- string path<>;
+ int xflags;
string bname<>; /* NULL terminated */
+ opaque xdata<>; /* Extra data */
};
struct gfs3_rmdir_rsp {
int op_ret;
int op_errno;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_symlink_req {
opaque pargfid[16];
- string path<>;
string bname<>;
+ unsigned int umask;
string linkname<>;
- opaque dict<>;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_symlink_rsp {
int op_ret;
@@ -141,16 +147,16 @@ struct gfs3_readlink_req {
struct gf_iatt stat;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_rename_req {
opaque oldgfid[16];
opaque newgfid[16];
- string oldpath<>;
string oldbname<>; /* NULL terminated */
- string newpath<>;
string newbname<>; /* NULL terminated */
+ opaque xdata<>; /* Extra data */
};
struct gfs3_rename_rsp {
int op_ret;
@@ -160,15 +166,15 @@ struct gfs3_readlink_req {
struct gf_iatt postoldparent;
struct gf_iatt prenewparent;
struct gf_iatt postnewparent;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_link_req {
opaque oldgfid[16];
opaque newgfid[16];
- string oldpath<>;
- string newpath<>;
string newbname<>;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_link_rsp {
int op_ret;
@@ -176,31 +182,33 @@ struct gfs3_readlink_req {
struct gf_iatt stat;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_truncate_req {
opaque gfid[16];
unsigned hyper offset;
- string path<>;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_truncate_rsp {
int op_ret;
int op_errno;
struct gf_iatt prestat;
struct gf_iatt poststat;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_open_req {
opaque gfid[16];
unsigned int flags;
- unsigned int wbflags;
- string path<>;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_open_rsp {
int op_ret;
int op_errno;
hyper fd;
+ opaque xdata<>; /* Extra data */
};
@@ -209,28 +217,30 @@ struct gfs3_readlink_req {
hyper fd;
unsigned hyper offset;
unsigned int size;
+ unsigned int flag;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_read_rsp {
int op_ret;
int op_errno;
struct gf_iatt stat;
unsigned int size;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_lookup_req {
opaque gfid[16];
opaque pargfid[16];
unsigned int flags;
- string path<>;
string bname<>;
- opaque dict<>;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_lookup_rsp {
int op_ret;
int op_errno;
struct gf_iatt stat;
struct gf_iatt postparent;
- opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
@@ -240,23 +250,27 @@ struct gfs3_lookup_req {
hyper fd;
unsigned hyper offset;
unsigned int size;
+ unsigned int flag;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_write_rsp {
int op_ret;
int op_errno;
struct gf_iatt prestat;
struct gf_iatt poststat;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_statfs_req {
opaque gfid[16];
- string path<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_statfs_rsp {
int op_ret;
int op_errno;
struct gf_statfs statfs;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_lk_req {
@@ -265,11 +279,13 @@ struct gfs3_lookup_req {
unsigned int cmd;
unsigned int type;
struct gf_proto_flock flock;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_lk_rsp {
int op_ret;
int op_errno;
struct gf_proto_flock flock;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_inodelk_req {
@@ -277,8 +293,8 @@ struct gfs3_lookup_req {
unsigned int cmd;
unsigned int type;
struct gf_proto_flock flock;
- string path<>;
string volume<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_finodelk_req {
@@ -288,12 +304,14 @@ struct gfs3_finodelk_req {
unsigned int type;
struct gf_proto_flock flock;
string volume<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_flush_req {
opaque gfid[16];
hyper fd;
+ opaque xdata<>; /* Extra data */
} ;
@@ -301,12 +319,14 @@ struct gfs3_finodelk_req {
opaque gfid[16];
hyper fd;
unsigned int data;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_fsync_rsp {
int op_ret;
int op_errno;
struct gf_iatt prestat;
struct gf_iatt poststat;
+ opaque xdata<>; /* Extra data */
} ;
@@ -314,7 +334,7 @@ struct gfs3_finodelk_req {
opaque gfid[16];
unsigned int flags;
opaque dict<>;
- string path<>;
+ opaque xdata<>; /* Extra data */
} ;
@@ -324,6 +344,7 @@ struct gfs3_finodelk_req {
hyper fd;
unsigned int flags;
opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
@@ -332,13 +353,14 @@ struct gfs3_finodelk_req {
opaque gfid[16];
unsigned int flags;
opaque dict<>;
- string path<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_xattrop_rsp {
int op_ret;
int op_errno;
opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
@@ -347,25 +369,28 @@ struct gfs3_finodelk_req {
hyper fd;
unsigned int flags;
opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_fxattrop_rsp {
int op_ret;
int op_errno;
opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_getxattr_req {
opaque gfid[16];
unsigned int namelen;
- string path<>;
string name<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_getxattr_rsp {
int op_ret;
int op_errno;
opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
@@ -374,30 +399,40 @@ struct gfs3_finodelk_req {
hyper fd;
unsigned int namelen;
string name<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_fgetxattr_rsp {
int op_ret;
int op_errno;
opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_removexattr_req {
opaque gfid[16];
- string path<>;
string name<>;
+ opaque xdata<>; /* Extra data */
+} ;
+
+ struct gfs3_fremovexattr_req {
+ opaque gfid[16];
+ hyper fd;
+ string name<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_opendir_req {
opaque gfid[16];
- string path<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_opendir_rsp {
int op_ret;
int op_errno;
hyper fd;
+ opaque xdata<>; /* Extra data */
} ;
@@ -405,6 +440,7 @@ struct gfs3_finodelk_req {
opaque gfid[16];
hyper fd;
int data;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_readdir_req {
@@ -412,6 +448,7 @@ struct gfs3_finodelk_req {
hyper fd;
unsigned hyper offset;
unsigned int size;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_readdirp_req {
@@ -419,6 +456,7 @@ struct gfs3_finodelk_req {
hyper fd;
unsigned hyper offset;
unsigned int size;
+ opaque dict<>;
} ;
@@ -434,7 +472,7 @@ struct gfs3_finodelk_req {
struct gfs3_access_req {
opaque gfid[16];
unsigned int mask;
- string path<>;
+ opaque xdata<>; /* Extra data */
} ;
@@ -442,9 +480,9 @@ struct gfs3_create_req {
opaque pargfid[16];
unsigned int flags;
unsigned int mode;
- string path<>;
+ unsigned int umask;
string bname<>;
- opaque dict<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_create_rsp {
int op_ret;
@@ -453,6 +491,7 @@ struct gfs3_create_rsp {
unsigned hyper fd;
struct gf_iatt preparent;
struct gf_iatt postparent;
+ opaque xdata<>; /* Extra data */
} ;
@@ -461,23 +500,27 @@ struct gfs3_ftruncate_req {
opaque gfid[16];
hyper fd;
unsigned hyper offset;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_ftruncate_rsp {
int op_ret;
int op_errno;
struct gf_iatt prestat;
struct gf_iatt poststat;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_fstat_req {
opaque gfid[16];
hyper fd;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_fstat_rsp {
int op_ret;
int op_errno;
struct gf_iatt stat;
+ opaque xdata<>; /* Extra data */
} ;
@@ -487,9 +530,9 @@ struct gfs3_fstat_req {
unsigned int cmd;
unsigned int type;
unsigned hyper namelen;
- string path<>;
string name<>;
string volume<>;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_fentrylk_req {
@@ -500,6 +543,7 @@ struct gfs3_fstat_req {
unsigned hyper namelen;
string name<>;
string volume<>;
+ opaque xdata<>; /* Extra data */
};
@@ -507,48 +551,55 @@ struct gfs3_fstat_req {
opaque gfid[16];
struct gf_iatt stbuf;
int valid;
- string path<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_setattr_rsp {
int op_ret;
int op_errno;
struct gf_iatt statpre;
struct gf_iatt statpost;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_fsetattr_req {
hyper fd;
struct gf_iatt stbuf;
int valid;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_fsetattr_rsp {
int op_ret;
int op_errno;
struct gf_iatt statpre;
struct gf_iatt statpost;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_rchecksum_req {
hyper fd;
unsigned hyper offset;
unsigned int len;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_rchecksum_rsp {
int op_ret;
int op_errno;
unsigned int weak_checksum;
opaque strong_checksum<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gf_getspec_req {
unsigned int flags;
string key<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gf_getspec_rsp {
int op_ret;
int op_errno;
string spec<>;
+ opaque xdata<>; /* Extra data */
} ;
@@ -559,27 +610,32 @@ struct gfs3_fstat_req {
struct gf_notify_req {
unsigned int flags;
string buf<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gf_notify_rsp {
int op_ret;
int op_errno;
unsigned int flags;
string buf<>;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_releasedir_req {
opaque gfid[16];
hyper fd;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_release_req {
opaque gfid[16];
hyper fd;
+ opaque xdata<>; /* Extra data */
} ;
struct gf_common_rsp {
int op_ret;
int op_errno;
+ opaque xdata<>; /* Extra data */
} ;
struct gfs3_dirlist {
@@ -596,6 +652,7 @@ struct gfs3_readdir_rsp {
int op_ret;
int op_errno;
struct gfs3_dirlist *reply;
+ opaque xdata<>; /* Extra data */
};
struct gfs3_dirplist {
@@ -605,6 +662,7 @@ struct gfs3_dirplist {
unsigned int d_type;
string name<>;
struct gf_iatt stat;
+ opaque dict<>;
struct gfs3_dirplist *nextentry;
};
@@ -612,5 +670,27 @@ struct gfs3_readdirp_rsp {
int op_ret;
int op_errno;
struct gfs3_dirplist *reply;
+ opaque xdata<>; /* Extra data */
+};
+
+struct gf_set_lk_ver_rsp {
+ int op_ret;
+ int op_errno;
+ int lk_ver;
};
+struct gf_set_lk_ver_req {
+ string uid<>;
+ int lk_ver;
+};
+
+struct gf_event_notify_req {
+ int op;
+ opaque dict<>;
+};
+
+struct gf_event_notify_rsp {
+ int op_ret;
+ int op_errno;
+ opaque dict<>;
+};
diff --git a/rpc/xdr/src/glusterfs3.c b/rpc/xdr/src/glusterfs3.c
deleted file mode 100644
index 5e02fda50..000000000
--- a/rpc/xdr/src/glusterfs3.c
+++ /dev/null
@@ -1,1137 +0,0 @@
-/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "glusterfs3.h"
-#include "xdr-generic.h"
-
-
-/* Encode */
-
-ssize_t
-xdr_serialize_getspec_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf_getspec_rsp);
-
-}
-
-ssize_t
-xdr_serialize_lookup_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_lookup_rsp);
-
-}
-
-ssize_t
-xdr_serialize_common_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf_common_rsp);
-
-}
-
-ssize_t
-xdr_serialize_setvolume_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf_setvolume_rsp);
-
-}
-ssize_t
-xdr_serialize_statfs_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_statfs_rsp);
-
-}
-ssize_t
-xdr_serialize_stat_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_stat_rsp);
-
-}
-ssize_t
-xdr_serialize_fstat_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fstat_rsp);
-
-}
-ssize_t
-xdr_serialize_open_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_open_rsp);
-
-}
-ssize_t
-xdr_serialize_read_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_read_rsp);
-
-}
-ssize_t
-xdr_serialize_write_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_write_rsp);
-
-}
-ssize_t
-xdr_serialize_rename_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_rename_rsp);
-
-}
-ssize_t
-xdr_serialize_fsync_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fsync_rsp);
-
-}
-ssize_t
-xdr_serialize_rmdir_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_rmdir_rsp);
-}
-ssize_t
-xdr_serialize_unlink_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_unlink_rsp);
-}
-ssize_t
-xdr_serialize_writev_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_write_rsp);
-}
-ssize_t
-xdr_serialize_readv_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_read_rsp);
-}
-ssize_t
-xdr_serialize_readdir_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_readdir_rsp);
-}
-ssize_t
-xdr_serialize_readdirp_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_readdirp_rsp);
-}
-ssize_t
-xdr_serialize_rchecksum_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_rchecksum_rsp);
-}
-ssize_t
-xdr_serialize_setattr_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_setattr_rsp);
-}
-ssize_t
-xdr_serialize_fsetattr_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fsetattr_rsp);
-}
-
-ssize_t
-xdr_serialize_readlink_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_readlink_rsp);
-
-}
-ssize_t
-xdr_serialize_symlink_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_symlink_rsp);
-
-}
-ssize_t
-xdr_serialize_create_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_create_rsp);
-
-}
-ssize_t
-xdr_serialize_link_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_link_rsp);
-
-}
-ssize_t
-xdr_serialize_mkdir_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_mkdir_rsp);
-
-}
-ssize_t
-xdr_serialize_mknod_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_mknod_rsp);
-
-}
-ssize_t
-xdr_serialize_getxattr_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_getxattr_rsp);
-
-}
-ssize_t
-xdr_serialize_fgetxattr_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
-
-}
-ssize_t
-xdr_serialize_xattrop_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_xattrop_rsp);
-
-}
-ssize_t
-xdr_serialize_fxattrop_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fxattrop_rsp);
-}
-
-ssize_t
-xdr_serialize_truncate_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_truncate_rsp);
-}
-
-ssize_t
-xdr_serialize_lk_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_lk_rsp);
-}
-
-ssize_t
-xdr_serialize_opendir_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_opendir_rsp);
-}
-
-ssize_t
-xdr_serialize_ftruncate_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_serialize_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_ftruncate_rsp);
-}
-
-
-ssize_t
-xdr_to_lookup_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_lookup_req);
-}
-
-ssize_t
-xdr_to_getspec_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf_getspec_req);
-
-}
-
-ssize_t
-xdr_to_setvolume_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gf_setvolume_req);
-
-}
-
-ssize_t
-xdr_to_statfs_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_statfs_req);
-
-}
-
-ssize_t
-xdr_to_fsync_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_fsync_req);
-
-}
-
-ssize_t
-xdr_to_flush_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_flush_req);
-
-}
-
-ssize_t
-xdr_to_xattrop_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_xattrop_req);
-
-}
-
-ssize_t
-xdr_to_fxattrop_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_fxattrop_req);
-
-}
-
-ssize_t
-xdr_to_getxattr_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_getxattr_req);
-
-}
-ssize_t
-xdr_to_fgetxattr_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_fgetxattr_req);
-
-}
-ssize_t
-xdr_to_open_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_open_req);
-
-}
-ssize_t
-xdr_to_create_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_create_req);
-
-}
-ssize_t
-xdr_to_symlink_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_symlink_req);
-}
-ssize_t
-xdr_to_link_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_link_req);
-}
-ssize_t
-xdr_to_readlink_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_readlink_req);
-}
-ssize_t
-xdr_to_rename_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_rename_req);
-}
-ssize_t
-xdr_to_mkdir_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_mkdir_req);
-}
-ssize_t
-xdr_to_mknod_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_mknod_req);
-}
-ssize_t
-xdr_to_readv_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_read_req);
-}
-ssize_t
-xdr_to_writev_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_write_req);
-}
-
-ssize_t
-xdr_to_readdir_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_readdir_req);
-}
-
-ssize_t
-xdr_to_opendir_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_opendir_req);
-}
-
-ssize_t
-xdr_to_rmdir_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_rmdir_req);
-}
-
-ssize_t
-xdr_to_fsetxattr_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_fsetxattr_req);
-}
-ssize_t
-xdr_to_setattr_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_setattr_req);
-}
-ssize_t
-xdr_to_fsetattr_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_fsetattr_req);
-}
-
-ssize_t
-xdr_to_finodelk_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_finodelk_req);
-}
-
-ssize_t
-xdr_to_inodelk_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_inodelk_req);
-}
-
-ssize_t
-xdr_to_ftruncate_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_ftruncate_req);
-}
-
-ssize_t
-xdr_to_fsyncdir_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_fsyncdir_req);
-}
-
-ssize_t
-xdr_to_fstat_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_fstat_req);
-}
-ssize_t
-xdr_to_rchecksum_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_rchecksum_req);
-}
-ssize_t
-xdr_to_removexattr_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_removexattr_req);
-}
-ssize_t
-xdr_to_setxattr_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_setxattr_req);
-}
-
-ssize_t
-xdr_to_fentrylk_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_fentrylk_req);
-}
-
-ssize_t
-xdr_to_entrylk_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_entrylk_req);
-}
-
-ssize_t
-xdr_to_lk_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_lk_req);
-}
-
-ssize_t
-xdr_to_stat_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_stat_req);
-}
-
-ssize_t
-xdr_to_release_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_release_req);
-}
-
-ssize_t
-xdr_to_readdirp_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_readdirp_req);
-}
-ssize_t
-xdr_to_truncate_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_truncate_req);
-}
-ssize_t
-xdr_to_access_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_access_req);
-}
-ssize_t
-xdr_to_unlink_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_gfs3_unlink_req);
-}
-
-ssize_t
-xdr_from_lookup_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_lookup_req);
-
-}
-
-ssize_t
-xdr_from_stat_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_stat_req);
-
-}
-
-ssize_t
-xdr_from_fstat_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_fstat_req);
-
-}
-
-ssize_t
-xdr_from_mkdir_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_mkdir_req);
-
-}
-
-ssize_t
-xdr_from_mknod_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_mknod_req);
-
-}
-
-ssize_t
-xdr_from_symlink_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_symlink_req);
-
-}
-
-ssize_t
-xdr_from_readlink_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_readlink_req);
-
-}
-
-ssize_t
-xdr_from_rename_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_rename_req);
-
-}
-
-ssize_t
-xdr_from_link_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_link_req);
-
-}
-
-ssize_t
-xdr_from_create_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_create_req);
-
-}
-
-ssize_t
-xdr_from_open_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_open_req);
-
-}
-
-ssize_t
-xdr_from_opendir_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_opendir_req);
-
-}
-
-ssize_t
-xdr_from_readdir_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_readdir_req);
-
-}
-
-ssize_t
-xdr_from_readdirp_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_readdirp_req);
-
-}
-
-ssize_t
-xdr_from_fsyncdir_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_fsyncdir_req);
-
-}
-ssize_t
-xdr_from_releasedir_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_releasedir_req);
-
-}
-ssize_t
-xdr_from_release_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_release_req);
-
-}
-ssize_t
-xdr_from_lk_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_lk_req);
-
-}
-ssize_t
-xdr_from_entrylk_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_entrylk_req);
-
-}
-ssize_t
-xdr_from_fentrylk_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_fentrylk_req);
-
-}
-ssize_t
-xdr_from_inodelk_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_inodelk_req);
-
-}
-ssize_t
-xdr_from_finodelk_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_finodelk_req);
-
-}
-ssize_t
-xdr_from_setxattr_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_setxattr_req);
-
-}
-ssize_t
-xdr_from_fsetxattr_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_fsetxattr_req);
-
-}
-ssize_t
-xdr_from_getxattr_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_getxattr_req);
-
-}
-ssize_t
-xdr_from_fgetxattr_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_fgetxattr_req);
-
-}
-ssize_t
-xdr_from_removexattr_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_removexattr_req);
-
-}
-ssize_t
-xdr_from_xattrop_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_xattrop_req);
-
-}
-ssize_t
-xdr_from_fxattrop_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_fxattrop_req);
-
-}
-ssize_t
-xdr_from_access_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_access_req);
-
-}
-ssize_t
-xdr_from_setattr_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_setattr_req);
-
-}
-ssize_t
-xdr_from_truncate_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_truncate_req);
-
-}
-ssize_t
-xdr_from_ftruncate_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_ftruncate_req);
-
-}
-ssize_t
-xdr_from_fsetattr_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_fsetattr_req);
-
-}
-ssize_t
-xdr_from_readv_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_read_req);
-
-}
-ssize_t
-xdr_from_writev_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_write_req);
-
-}
-ssize_t
-xdr_from_fsync_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_fsync_req);
-
-}
-ssize_t
-xdr_from_flush_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_flush_req);
-
-}
-ssize_t
-xdr_from_statfs_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_statfs_req);
-
-}
-ssize_t
-xdr_from_rchecksum_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_rchecksum_req);
-
-}
-ssize_t
-xdr_from_getspec_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf_getspec_req);
-
-}
-ssize_t
-xdr_from_setvolume_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gf_setvolume_req);
-
-}
-ssize_t
-xdr_from_rmdir_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_rmdir_req);
-
-}
-ssize_t
-xdr_from_unlink_req (struct iovec outmsg, void *req)
-{
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_unlink_req);
-
-}
-
-/* Client decode */
-
-ssize_t
-xdr_to_lookup_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_lookup_rsp);
-
-}
-
-ssize_t
-xdr_to_stat_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_stat_rsp);
-
-}
-
-ssize_t
-xdr_to_fstat_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fstat_rsp);
-
-}
-
-ssize_t
-xdr_to_mkdir_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_mkdir_rsp);
-
-}
-
-ssize_t
-xdr_to_mknod_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_mknod_rsp);
-
-}
-
-ssize_t
-xdr_to_symlink_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_symlink_rsp);
-
-}
-
-ssize_t
-xdr_to_readlink_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_readlink_rsp);
-
-}
-
-ssize_t
-xdr_to_rename_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_rename_rsp);
-
-}
-
-ssize_t
-xdr_to_link_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_link_rsp);
-
-}
-
-ssize_t
-xdr_to_create_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_create_rsp);
-
-}
-
-ssize_t
-xdr_to_open_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_open_rsp);
-
-}
-
-ssize_t
-xdr_to_opendir_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_opendir_rsp);
-
-}
-
-ssize_t
-xdr_to_readdir_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_readdir_rsp);
-
-}
-
-ssize_t
-xdr_to_readdirp_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_readdirp_rsp);
-
-}
-ssize_t
-xdr_to_lk_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_lk_rsp);
-
-}
-ssize_t
-xdr_to_getxattr_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_getxattr_rsp);
-
-}
-ssize_t
-xdr_to_fgetxattr_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
-
-}
-ssize_t
-xdr_to_xattrop_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_xattrop_rsp);
-
-}
-ssize_t
-xdr_to_fxattrop_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fxattrop_rsp);
-
-}
-ssize_t
-xdr_to_setattr_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_setattr_rsp);
-
-}
-ssize_t
-xdr_to_truncate_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_truncate_rsp);
-
-}
-ssize_t
-xdr_to_ftruncate_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_ftruncate_rsp);
-
-}
-ssize_t
-xdr_to_fsetattr_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fsetattr_rsp);
-
-}
-ssize_t
-xdr_to_readv_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_read_rsp);
-
-}
-ssize_t
-xdr_to_writev_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_write_rsp);
-
-}
-ssize_t
-xdr_to_fsync_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_fsync_rsp);
-
-}
-ssize_t
-xdr_to_statfs_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_statfs_rsp);
-
-}
-ssize_t
-xdr_to_rchecksum_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_rchecksum_rsp);
-
-}
-ssize_t
-xdr_to_getspec_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf_getspec_rsp);
-
-}
-ssize_t
-xdr_to_setvolume_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf_setvolume_rsp);
-
-}
-ssize_t
-xdr_to_rmdir_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_rmdir_rsp);
-
-}
-ssize_t
-xdr_to_unlink_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gfs3_unlink_rsp);
-
-}
-ssize_t
-xdr_to_common_rsp (struct iovec outmsg, void *rsp)
-{
- return xdr_to_generic (outmsg, (void *)rsp,
- (xdrproc_t)xdr_gf_common_rsp);
-
-}
-
-ssize_t
-xdr_to_mgmt_probe_query_req (struct iovec outmsg, void *req)
-{
-
- return xdr_serialize_generic (outmsg, (void *)req,
- (xdrproc_t)xdr_gfs3_setattr_req);
-}
diff --git a/rpc/xdr/src/glusterfs3.h b/rpc/xdr/src/glusterfs3.h
index ecee1fea4..488c70d85 100644
--- a/rpc/xdr/src/glusterfs3.h
+++ b/rpc/xdr/src/glusterfs3.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -23,6 +14,7 @@
#include <sys/uio.h>
+#include "xdr-generic.h"
#include "glusterfs3-xdr.h"
#include "iatt.h"
@@ -53,6 +45,8 @@
#define GF_O_LARGEFILE 0100000
+#define GF_O_FMODE_EXEC 040
+
#define XLATE_BIT(from, to, bit) do { \
if (from & bit) \
to = to | GF_##bit; \
@@ -111,6 +105,7 @@ gf_flags_from_flags (uint32_t flags)
XLATE_BIT (flags, gf_flags, O_CLOEXEC);
#endif
XLATE_BIT (flags, gf_flags, O_LARGEFILE);
+ XLATE_BIT (flags, gf_flags, O_FMODE_EXEC);
return gf_flags;
}
@@ -141,6 +136,7 @@ gf_flags_to_flags (uint32_t gf_flags)
UNXLATE_BIT (gf_flags, flags, O_CLOEXEC);
#endif
UNXLATE_BIT (gf_flags, flags, O_LARGEFILE);
+ UNXLATE_BIT (gf_flags, flags, O_FMODE_EXEC);
return flags;
}
@@ -196,7 +192,11 @@ gf_proto_flock_to_flock (struct gf_proto_flock *gf_proto_flock, struct gf_flock
gf_flock->l_start = gf_proto_flock->start;
gf_flock->l_len = gf_proto_flock->len;
gf_flock->l_pid = gf_proto_flock->pid;
- gf_flock->l_owner = gf_proto_flock->owner;
+ gf_flock->l_owner.len = gf_proto_flock->lk_owner.lk_owner_len;
+ if (gf_flock->l_owner.len &&
+ (gf_flock->l_owner.len < GF_MAX_LOCK_OWNER_LEN))
+ memcpy (gf_flock->l_owner.data, gf_proto_flock->lk_owner.lk_owner_val,
+ gf_flock->l_owner.len);
}
@@ -211,7 +211,9 @@ gf_proto_flock_from_flock (struct gf_proto_flock *gf_proto_flock, struct gf_floc
gf_proto_flock->start = (gf_flock->l_start);
gf_proto_flock->len = (gf_flock->l_len);
gf_proto_flock->pid = (gf_flock->l_pid);
- gf_proto_flock->owner = (gf_flock->l_owner);
+ gf_proto_flock->lk_owner.lk_owner_len = gf_flock->l_owner.len;
+ if (gf_flock->l_owner.len)
+ gf_proto_flock->lk_owner.lk_owner_val = gf_flock->l_owner.data;
}
static inline void
@@ -266,486 +268,4 @@ gf_stat_from_iatt (struct gf_iatt *gf_stat, struct iatt *iatt)
gf_stat->ia_ctime_nsec = iatt->ia_ctime_nsec ;
}
-/* FOPS */
-ssize_t
-xdr_serialize_lookup_rsp (struct iovec outmsg, void *resp);
-
-ssize_t
-xdr_serialize_getspec_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_common_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_setvolume_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_open_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_create_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_mknod_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_mkdir_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_symlink_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_link_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_rename_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_writev_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_readv_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_readdir_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_readdirp_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_opendir_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_setattr_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_fsetattr_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_truncate_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_ftruncate_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_statfs_rsp (struct iovec outmsg, void *rsp);
-
-
-ssize_t
-xdr_serialize_lk_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_xattrop_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_fxattrop_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_getxattr_rsp (struct iovec outmsg, void *rsp);
-
-
-ssize_t
-xdr_serialize_fgetxattr_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_unlink_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_rmdir_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_rchecksum_rsp (struct iovec outmsg, void *rsp);
-
-
-ssize_t
-xdr_serialize_fstat_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_fsync_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_readlink_rsp (struct iovec outmsg, void *rsp);
-
-ssize_t
-xdr_serialize_stat_rsp (struct iovec outmsg, void *rsp);
-
-
-ssize_t
-xdr_to_lookup_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_getspec_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_setvolume_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_statfs_req (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_stat_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_getattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fstat_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_setattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fsetattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_readv_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_writev_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fsetattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_readlink_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_create_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_open_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_release_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_xattrop_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fxattrop_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_setxattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fsetxattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_flush_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_unlink_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fsync_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_ftruncate_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_truncate_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_getxattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fgetxattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_removexattr_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_entrylk_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fentrylk_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_inodelk_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_finodelk_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_lk_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_access_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_opendir_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_readdirp_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_readdir_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fsyncdir_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_mknod_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_mkdir_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_symlink_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_rmdir_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_rchecksum_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_rename_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_link_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_from_lookup_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_getspec_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_stat_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_access_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_truncate_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_ftruncate_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_readlink_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_writev_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_readv_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_flush_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_fstat_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_fsync_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_open_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_unlink_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_rmdir_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_fsyncdir_req (struct iovec outmsg, void *args);
-
-
-ssize_t
-xdr_from_fsetxattr_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_setxattr_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_getxattr_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_fgetxattr_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_statfs_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_opendir_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_lk_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_inodelk_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_finodelk_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_entrylk_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_fentrylk_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_removexattr_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_xattrop_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_fxattrop_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_rchecksum_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_readdir_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_readdirp_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_setattr_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_fsetattr_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_symlink_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_rename_req (struct iovec outmsg, void *args);
-
-
-ssize_t
-xdr_from_link_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_rename_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_create_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_mkdir_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_mknod_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_releasedir_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_release_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_setvolume_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_to_setvolume_rsp (struct iovec inmsg, void *args);
-
-
-
-ssize_t
-xdr_to_statfs_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_stat_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fstat_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_rename_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_readlink_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_link_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_access_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_truncate_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_ftruncate_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_unlink_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_rmdir_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_open_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_create_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_mkdir_rsp (struct iovec inmsg, void *args);
-
-
-ssize_t
-xdr_to_mknod_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_setattr_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fsetattr_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_common_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_getxattr_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fxattrop_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_xattrop_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_symlink_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_fgetxattr_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_rchecksum_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_lk_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_readdirp_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_readdir_rsp (struct iovec inmsg, void *args);
-ssize_t
-xdr_to_opendir_rsp (struct iovec inmsg, void *args);
-ssize_t
-xdr_to_lookup_rsp (struct iovec inmsg, void *args);
-ssize_t
-xdr_to_readv_rsp (struct iovec inmsg, void *args);
-ssize_t
-xdr_to_getspec_rsp (struct iovec inmsg, void *args);
-
#endif /* !_GLUSTERFS3_H */
diff --git a/rpc/xdr/src/mount3udp.x b/rpc/xdr/src/mount3udp.x
new file mode 100644
index 000000000..90b5b741a
--- /dev/null
+++ b/rpc/xdr/src/mount3udp.x
@@ -0,0 +1,34 @@
+/*
+ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/* This is used by rpcgen to auto generate the rpc stubs.
+ * mount3udp_svc.c is heavily modified though
+ */
+
+const MNTUDPPATHLEN = 1024;
+
+typedef string mntudpdirpath<MNTPATHLEN>;
+
+program MOUNTUDP_PROGRAM {
+ version MOUNTUDP_V3 {
+ void MOUNTUDPPROC3_NULL(void) = 0;
+ mountres3 MOUNTUDPPROC3_MNT (mntudpdirpath) = 1;
+ mountstat3 MOUNTUDPPROC3_UMNT (mntudpdirpath) = 3;
+ } = 3;
+} = 100005;
diff --git a/xlators/nfs/lib/src/msg-nfs3.c b/rpc/xdr/src/msg-nfs3.c
index e6e722051..8078f23f0 100644
--- a/xlators/nfs/lib/src/msg-nfs3.c
+++ b/rpc/xdr/src/msg-nfs3.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -29,6 +29,7 @@
#include "xdr-nfs3.h"
#include "msg-nfs3.h"
+#include "xdr-generic.h"
#include "xdr-common.h"
@@ -56,90 +57,12 @@ xdr_to_mountpath (struct iovec outpath, struct iovec inmsg)
goto ret;
}
- ret = nfs_xdr_decoded_length (xdr);
+ ret = xdr_decoded_length (xdr);
ret:
return ret;
}
-
-ssize_t
-nfs_xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc)
-{
- ssize_t ret = -1;
- XDR xdr;
-
- if ((!outmsg.iov_base) || (!res) || (!proc))
- return -1;
-
- xdrmem_create (&xdr, outmsg.iov_base, (unsigned int)outmsg.iov_len,
- XDR_ENCODE);
-
- if (!proc (&xdr, res)) {
- ret = -1;
- goto ret;
- }
-
- ret = nfs_xdr_encoded_length (xdr);
-
-ret:
- return ret;
-}
-
-
-ssize_t
-nfs_xdr_to_generic (struct iovec inmsg, void *args, xdrproc_t proc)
-{
- XDR xdr;
- ssize_t ret = -1;
-
- if ((!inmsg.iov_base) || (!args) || (!proc))
- return -1;
-
- xdrmem_create (&xdr, inmsg.iov_base, (unsigned int)inmsg.iov_len,
- XDR_DECODE);
-
- if (!proc (&xdr, args)) {
- ret = -1;
- goto ret;
- }
-
- ret = nfs_xdr_decoded_length (xdr);
-ret:
- return ret;
-}
-
-
-ssize_t
-nfs_xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc,
- struct iovec *pendingpayload)
-{
- XDR xdr;
- ssize_t ret = -1;
-
- if ((!inmsg.iov_base) || (!args) || (!proc))
- return -1;
-
- xdrmem_create (&xdr, inmsg.iov_base, (unsigned int)inmsg.iov_len,
- XDR_DECODE);
-
- if (!proc (&xdr, args)) {
- ret = -1;
- goto ret;
- }
-
- ret = nfs_xdr_decoded_length (xdr);
-
- if (pendingpayload) {
- pendingpayload->iov_base = nfs_xdr_decoded_remaining_addr (xdr);
- pendingpayload->iov_len = nfs_xdr_decoded_remaining_len (xdr);
- }
-
-ret:
- return ret;
-}
-
-
/* Translate the mountres3 structure in res into XDR format into memory
* referenced by outmsg.iov_base.
* Returns the number of bytes used in encoding into XDR format.
@@ -147,7 +70,7 @@ ret:
ssize_t
xdr_serialize_mountres3 (struct iovec outmsg, mountres3 *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_mountres3);
}
@@ -155,14 +78,14 @@ xdr_serialize_mountres3 (struct iovec outmsg, mountres3 *res)
ssize_t
xdr_serialize_mountbody (struct iovec outmsg, mountbody *mb)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)mb,
+ return xdr_serialize_generic (outmsg, (void *)mb,
(xdrproc_t)xdr_mountbody);
}
ssize_t
xdr_serialize_mountlist (struct iovec outmsg, mountlist *ml)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)ml,
+ return xdr_serialize_generic (outmsg, (void *)ml,
(xdrproc_t)xdr_mountlist);
}
@@ -170,7 +93,7 @@ xdr_serialize_mountlist (struct iovec outmsg, mountlist *ml)
ssize_t
xdr_serialize_mountstat3 (struct iovec outmsg, mountstat3 *m)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)m,
+ return xdr_serialize_generic (outmsg, (void *)m,
(xdrproc_t)xdr_mountstat3);
}
@@ -178,7 +101,7 @@ xdr_serialize_mountstat3 (struct iovec outmsg, mountstat3 *m)
ssize_t
xdr_to_getattr3args (struct iovec inmsg, getattr3args *ga)
{
- return nfs_xdr_to_generic (inmsg, (void *)ga,
+ return xdr_to_generic (inmsg, (void *)ga,
(xdrproc_t)xdr_getattr3args);
}
@@ -186,7 +109,7 @@ xdr_to_getattr3args (struct iovec inmsg, getattr3args *ga)
ssize_t
xdr_serialize_getattr3res (struct iovec outmsg, getattr3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_getattr3res);
}
@@ -194,7 +117,7 @@ xdr_serialize_getattr3res (struct iovec outmsg, getattr3res *res)
ssize_t
xdr_serialize_setattr3res (struct iovec outmsg, setattr3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_setattr3res);
}
@@ -202,7 +125,7 @@ xdr_serialize_setattr3res (struct iovec outmsg, setattr3res *res)
ssize_t
xdr_to_setattr3args (struct iovec inmsg, setattr3args *sa)
{
- return nfs_xdr_to_generic (inmsg, (void *)sa,
+ return xdr_to_generic (inmsg, (void *)sa,
(xdrproc_t)xdr_setattr3args);
}
@@ -210,7 +133,7 @@ xdr_to_setattr3args (struct iovec inmsg, setattr3args *sa)
ssize_t
xdr_serialize_lookup3res (struct iovec outmsg, lookup3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_lookup3res);
}
@@ -218,7 +141,7 @@ xdr_serialize_lookup3res (struct iovec outmsg, lookup3res *res)
ssize_t
xdr_to_lookup3args (struct iovec inmsg, lookup3args *la)
{
- return nfs_xdr_to_generic (inmsg, (void *)la,
+ return xdr_to_generic (inmsg, (void *)la,
(xdrproc_t)xdr_lookup3args);
}
@@ -226,7 +149,7 @@ xdr_to_lookup3args (struct iovec inmsg, lookup3args *la)
ssize_t
xdr_to_access3args (struct iovec inmsg, access3args *ac)
{
- return nfs_xdr_to_generic (inmsg,(void *)ac,
+ return xdr_to_generic (inmsg,(void *)ac,
(xdrproc_t)xdr_access3args);
}
@@ -234,7 +157,7 @@ xdr_to_access3args (struct iovec inmsg, access3args *ac)
ssize_t
xdr_serialize_access3res (struct iovec outmsg, access3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_access3res);
}
@@ -242,7 +165,7 @@ xdr_serialize_access3res (struct iovec outmsg, access3res *res)
ssize_t
xdr_to_readlink3args (struct iovec inmsg, readlink3args *ra)
{
- return nfs_xdr_to_generic (inmsg, (void *)ra,
+ return xdr_to_generic (inmsg, (void *)ra,
(xdrproc_t)xdr_readlink3args);
}
@@ -250,7 +173,7 @@ xdr_to_readlink3args (struct iovec inmsg, readlink3args *ra)
ssize_t
xdr_serialize_readlink3res (struct iovec outmsg, readlink3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_readlink3res);
}
@@ -258,21 +181,21 @@ xdr_serialize_readlink3res (struct iovec outmsg, readlink3res *res)
ssize_t
xdr_to_read3args (struct iovec inmsg, read3args *ra)
{
- return nfs_xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_read3args);
+ return xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_read3args);
}
ssize_t
xdr_serialize_read3res (struct iovec outmsg, read3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_read3res);
}
ssize_t
xdr_serialize_read3res_nocopy (struct iovec outmsg, read3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_read3res_nocopy);
}
@@ -280,7 +203,7 @@ xdr_serialize_read3res_nocopy (struct iovec outmsg, read3res *res)
ssize_t
xdr_to_write3args (struct iovec inmsg, write3args *wa)
{
- return nfs_xdr_to_generic (inmsg, (void *)wa,(xdrproc_t)xdr_write3args);
+ return xdr_to_generic (inmsg, (void *)wa,(xdrproc_t)xdr_write3args);
}
@@ -288,7 +211,7 @@ ssize_t
xdr_to_write3args_nocopy (struct iovec inmsg, write3args *wa,
struct iovec *payload)
{
- return nfs_xdr_to_generic_payload (inmsg, (void *)wa,
+ return xdr_to_generic_payload (inmsg, (void *)wa,
(xdrproc_t)xdr_write3args, payload);
}
@@ -296,7 +219,7 @@ xdr_to_write3args_nocopy (struct iovec inmsg, write3args *wa,
ssize_t
xdr_serialize_write3res (struct iovec outmsg, write3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_write3res);
}
@@ -304,7 +227,7 @@ xdr_serialize_write3res (struct iovec outmsg, write3res *res)
ssize_t
xdr_to_create3args (struct iovec inmsg, create3args *ca)
{
- return nfs_xdr_to_generic (inmsg, (void *)ca,
+ return xdr_to_generic (inmsg, (void *)ca,
(xdrproc_t)xdr_create3args);
}
@@ -312,7 +235,7 @@ xdr_to_create3args (struct iovec inmsg, create3args *ca)
ssize_t
xdr_serialize_create3res (struct iovec outmsg, create3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_create3res);
}
@@ -320,7 +243,7 @@ xdr_serialize_create3res (struct iovec outmsg, create3res *res)
ssize_t
xdr_serialize_mkdir3res (struct iovec outmsg, mkdir3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_mkdir3res);
}
@@ -328,7 +251,7 @@ xdr_serialize_mkdir3res (struct iovec outmsg, mkdir3res *res)
ssize_t
xdr_to_mkdir3args (struct iovec inmsg, mkdir3args *ma)
{
- return nfs_xdr_to_generic (inmsg, (void *)ma,
+ return xdr_to_generic (inmsg, (void *)ma,
(xdrproc_t)xdr_mkdir3args);
}
@@ -336,7 +259,7 @@ xdr_to_mkdir3args (struct iovec inmsg, mkdir3args *ma)
ssize_t
xdr_to_symlink3args (struct iovec inmsg, symlink3args *sa)
{
- return nfs_xdr_to_generic (inmsg, (void *)sa,
+ return xdr_to_generic (inmsg, (void *)sa,
(xdrproc_t)xdr_symlink3args);
}
@@ -344,7 +267,7 @@ xdr_to_symlink3args (struct iovec inmsg, symlink3args *sa)
ssize_t
xdr_serialize_symlink3res (struct iovec outmsg, symlink3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_symlink3res);
}
@@ -352,7 +275,7 @@ xdr_serialize_symlink3res (struct iovec outmsg, symlink3res *res)
ssize_t
xdr_to_mknod3args (struct iovec inmsg, mknod3args *ma)
{
- return nfs_xdr_to_generic (inmsg, (void *)ma,
+ return xdr_to_generic (inmsg, (void *)ma,
(xdrproc_t)xdr_mknod3args);
}
@@ -360,7 +283,7 @@ xdr_to_mknod3args (struct iovec inmsg, mknod3args *ma)
ssize_t
xdr_serialize_mknod3res (struct iovec outmsg, mknod3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_mknod3res);
}
@@ -368,7 +291,7 @@ xdr_serialize_mknod3res (struct iovec outmsg, mknod3res *res)
ssize_t
xdr_to_remove3args (struct iovec inmsg, remove3args *ra)
{
- return nfs_xdr_to_generic (inmsg, (void *)ra,
+ return xdr_to_generic (inmsg, (void *)ra,
(xdrproc_t)xdr_remove3args);
}
@@ -376,7 +299,7 @@ xdr_to_remove3args (struct iovec inmsg, remove3args *ra)
ssize_t
xdr_serialize_remove3res (struct iovec outmsg, remove3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_remove3res);
}
@@ -384,7 +307,7 @@ xdr_serialize_remove3res (struct iovec outmsg, remove3res *res)
ssize_t
xdr_to_rmdir3args (struct iovec inmsg, rmdir3args *ra)
{
- return nfs_xdr_to_generic (inmsg, (void *)ra,
+ return xdr_to_generic (inmsg, (void *)ra,
(xdrproc_t)xdr_rmdir3args);
}
@@ -392,7 +315,7 @@ xdr_to_rmdir3args (struct iovec inmsg, rmdir3args *ra)
ssize_t
xdr_serialize_rmdir3res (struct iovec outmsg, rmdir3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_rmdir3res);
}
@@ -400,7 +323,7 @@ xdr_serialize_rmdir3res (struct iovec outmsg, rmdir3res *res)
ssize_t
xdr_serialize_rename3res (struct iovec outmsg, rename3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_rename3res);
}
@@ -408,7 +331,7 @@ xdr_serialize_rename3res (struct iovec outmsg, rename3res *res)
ssize_t
xdr_to_rename3args (struct iovec inmsg, rename3args *ra)
{
- return nfs_xdr_to_generic (inmsg, (void *)ra,
+ return xdr_to_generic (inmsg, (void *)ra,
(xdrproc_t)xdr_rename3args);
}
@@ -416,7 +339,7 @@ xdr_to_rename3args (struct iovec inmsg, rename3args *ra)
ssize_t
xdr_serialize_link3res (struct iovec outmsg, link3res *li)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)li,
+ return xdr_serialize_generic (outmsg, (void *)li,
(xdrproc_t)xdr_link3res);
}
@@ -424,14 +347,14 @@ xdr_serialize_link3res (struct iovec outmsg, link3res *li)
ssize_t
xdr_to_link3args (struct iovec inmsg, link3args *la)
{
- return nfs_xdr_to_generic (inmsg, (void *)la, (xdrproc_t)xdr_link3args);
+ return xdr_to_generic (inmsg, (void *)la, (xdrproc_t)xdr_link3args);
}
ssize_t
xdr_to_readdir3args (struct iovec inmsg, readdir3args *rd)
{
- return nfs_xdr_to_generic (inmsg, (void *)rd,
+ return xdr_to_generic (inmsg, (void *)rd,
(xdrproc_t)xdr_readdir3args);
}
@@ -439,7 +362,7 @@ xdr_to_readdir3args (struct iovec inmsg, readdir3args *rd)
ssize_t
xdr_serialize_readdir3res (struct iovec outmsg, readdir3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_readdir3res);
}
@@ -447,7 +370,7 @@ xdr_serialize_readdir3res (struct iovec outmsg, readdir3res *res)
ssize_t
xdr_to_readdirp3args (struct iovec inmsg, readdirp3args *rp)
{
- return nfs_xdr_to_generic (inmsg, (void *)rp,
+ return xdr_to_generic (inmsg, (void *)rp,
(xdrproc_t)xdr_readdirp3args);
}
@@ -455,7 +378,7 @@ xdr_to_readdirp3args (struct iovec inmsg, readdirp3args *rp)
ssize_t
xdr_serialize_readdirp3res (struct iovec outmsg, readdirp3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_readdirp3res);
}
@@ -463,7 +386,7 @@ xdr_serialize_readdirp3res (struct iovec outmsg, readdirp3res *res)
ssize_t
xdr_to_fsstat3args (struct iovec inmsg, fsstat3args *fa)
{
- return nfs_xdr_to_generic (inmsg, (void *)fa,
+ return xdr_to_generic (inmsg, (void *)fa,
(xdrproc_t)xdr_fsstat3args);
}
@@ -471,14 +394,14 @@ xdr_to_fsstat3args (struct iovec inmsg, fsstat3args *fa)
ssize_t
xdr_serialize_fsstat3res (struct iovec outmsg, fsstat3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_fsstat3res);
}
ssize_t
xdr_to_fsinfo3args (struct iovec inmsg, fsinfo3args *fi)
{
- return nfs_xdr_to_generic (inmsg, (void *)fi,
+ return xdr_to_generic (inmsg, (void *)fi,
(xdrproc_t)xdr_fsinfo3args);
}
@@ -486,7 +409,7 @@ xdr_to_fsinfo3args (struct iovec inmsg, fsinfo3args *fi)
ssize_t
xdr_serialize_fsinfo3res (struct iovec outmsg, fsinfo3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_fsinfo3res);
}
@@ -494,14 +417,14 @@ xdr_serialize_fsinfo3res (struct iovec outmsg, fsinfo3res *res)
ssize_t
xdr_to_pathconf3args (struct iovec inmsg, pathconf3args *pc)
{
- return nfs_xdr_to_generic (inmsg, (void *)pc,
+ return xdr_to_generic (inmsg, (void *)pc,
(xdrproc_t)xdr_pathconf3args);}
ssize_t
xdr_serialize_pathconf3res (struct iovec outmsg, pathconf3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_pathconf3res);
}
@@ -509,7 +432,7 @@ xdr_serialize_pathconf3res (struct iovec outmsg, pathconf3res *res)
ssize_t
xdr_to_commit3args (struct iovec inmsg, commit3args *ca)
{
- return nfs_xdr_to_generic (inmsg, (void *)ca,
+ return xdr_to_generic (inmsg, (void *)ca,
(xdrproc_t)xdr_commit3args);
}
@@ -517,7 +440,7 @@ xdr_to_commit3args (struct iovec inmsg, commit3args *ca)
ssize_t
xdr_serialize_commit3res (struct iovec outmsg, commit3res *res)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ return xdr_serialize_generic (outmsg, (void *)res,
(xdrproc_t)xdr_commit3res);
}
@@ -537,7 +460,7 @@ xdr_serialize_exports (struct iovec outmsg, exports *elist)
if (!xdr_exports (&xdr, elist))
goto ret;
- ret = nfs_xdr_decoded_length (xdr);
+ ret = xdr_decoded_length (xdr);
ret:
return ret;
@@ -547,8 +470,83 @@ ret:
ssize_t
xdr_serialize_nfsstat3 (struct iovec outmsg, nfsstat3 *s)
{
- return nfs_xdr_serialize_generic (outmsg, (void *)s,
+ return xdr_serialize_generic (outmsg, (void *)s,
(xdrproc_t)xdr_nfsstat3);
}
+ssize_t
+xdr_to_nlm4_testargs (struct iovec inmsg, nlm4_testargs *args)
+{
+ return xdr_to_generic (inmsg, (void*)args,
+ (xdrproc_t)xdr_nlm4_testargs);
+}
+
+ssize_t
+xdr_serialize_nlm4_testres (struct iovec outmsg, nlm4_testres *res)
+{
+ return xdr_serialize_generic (outmsg, (void*)res,
+ (xdrproc_t)xdr_nlm4_testres);
+}
+
+ssize_t
+xdr_to_nlm4_lockargs (struct iovec inmsg, nlm4_lockargs *args)
+{
+ return xdr_to_generic (inmsg, (void*)args,
+ (xdrproc_t)xdr_nlm4_lockargs);
+}
+ssize_t
+xdr_serialize_nlm4_res (struct iovec outmsg, nlm4_res *res)
+{
+ return xdr_serialize_generic (outmsg, (void*)res,
+ (xdrproc_t)xdr_nlm4_res);
+}
+
+ssize_t
+xdr_to_nlm4_cancelargs (struct iovec inmsg, nlm4_cancargs *args)
+{
+ return xdr_to_generic (inmsg, (void*)args,
+ (xdrproc_t)xdr_nlm4_cancargs);
+}
+
+ssize_t
+xdr_to_nlm4_unlockargs (struct iovec inmsg, nlm4_unlockargs *args)
+{
+ return xdr_to_generic (inmsg, (void*)args,
+ (xdrproc_t)xdr_nlm4_unlockargs);
+}
+
+ssize_t
+xdr_to_nlm4_shareargs (struct iovec inmsg, nlm4_shareargs *args)
+{
+ return xdr_to_generic (inmsg, (void*)args,
+ (xdrproc_t)xdr_nlm4_shareargs);
+}
+
+ssize_t
+xdr_serialize_nlm4_shareres (struct iovec outmsg, nlm4_shareres *res)
+{
+ return xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_nlm4_shareres);
+}
+
+ssize_t
+xdr_serialize_nlm4_testargs (struct iovec outmsg, nlm4_testargs *args)
+{
+ return xdr_serialize_generic (outmsg, (void*)args,
+ (xdrproc_t)xdr_nlm4_testargs);
+}
+
+ssize_t
+xdr_to_nlm4_res (struct iovec inmsg, nlm4_res *args)
+{
+ return xdr_to_generic (inmsg, (void*)args,
+ (xdrproc_t)xdr_nlm4_res);
+}
+
+ssize_t
+xdr_to_nlm4_freeallargs (struct iovec inmsg, nlm4_freeallargs *args)
+{
+ return xdr_to_generic (inmsg, (void*)args,
+ (xdrproc_t)xdr_nlm4_freeallargs);
+}
diff --git a/xlators/nfs/lib/src/msg-nfs3.h b/rpc/xdr/src/msg-nfs3.h
index f0d57c646..701df300a 100644
--- a/xlators/nfs/lib/src/msg-nfs3.h
+++ b/rpc/xdr/src/msg-nfs3.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -26,7 +26,7 @@
#endif
#include "xdr-nfs3.h"
-
+#include "nlm4-xdr.h"
#include <sys/types.h>
#include <sys/uio.h>
@@ -183,4 +183,38 @@ xdr_serialize_mountstat3 (struct iovec outmsg, mountstat3 *m);
extern ssize_t
xdr_serialize_nfsstat3 (struct iovec outmsg, nfsstat3 *s);
+
+extern ssize_t
+xdr_to_nlm4_testargs (struct iovec inmsg, nlm4_testargs *args);
+
+extern ssize_t
+xdr_serialize_nlm4_testres (struct iovec outmsg, nlm4_testres *res);
+
+extern ssize_t
+xdr_to_nlm4_lockargs (struct iovec inmsg, nlm4_lockargs *args);
+
+extern ssize_t
+xdr_serialize_nlm4_res (struct iovec outmsg, nlm4_res *res);
+
+extern ssize_t
+xdr_to_nlm4_cancelargs (struct iovec inmsg, nlm4_cancargs *args);
+
+extern ssize_t
+xdr_to_nlm4_unlockargs (struct iovec inmsg, nlm4_unlockargs *args);
+
+extern ssize_t
+xdr_to_nlm4_shareargs (struct iovec inmsg, nlm4_shareargs *args);
+
+extern ssize_t
+xdr_serialize_nlm4_shareres (struct iovec outmsg, nlm4_shareres *res);
+
+extern ssize_t
+xdr_serialize_nlm4_testargs (struct iovec outmsg, nlm4_testargs *args);
+
+extern ssize_t
+xdr_to_nlm4_res (struct iovec inmsg, nlm4_res *args);
+
+extern ssize_t
+xdr_to_nlm4_freeallargs (struct iovec inmsg, nlm4_freeallargs *args);
+
#endif
diff --git a/rpc/xdr/src/nlm4-xdr.c b/rpc/xdr/src/nlm4-xdr.c
new file mode 100644
index 000000000..4cf6a51e8
--- /dev/null
+++ b/rpc/xdr/src/nlm4-xdr.c
@@ -0,0 +1,254 @@
+/*
+ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "nlm4-xdr.h"
+
+bool_t
+xdr_netobj (XDR *xdrs, netobj *objp)
+{
+ if (!xdr_bytes (xdrs, (char **)&objp->n_bytes, (u_int *) &objp->n_len, MAXNETOBJ_SZ))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fsh_mode (XDR *xdrs, fsh_mode *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fsh_access (XDR *xdrs, fsh_access *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_stats (XDR *xdrs, nlm4_stats *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_stat (XDR *xdrs, nlm4_stat *objp)
+{
+ if (!xdr_nlm4_stats (xdrs, &objp->stat))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_holder (XDR *xdrs, nlm4_holder *objp)
+{
+ if (!xdr_bool (xdrs, &objp->exclusive))
+ return FALSE;
+ if (!xdr_uint32_t (xdrs, &objp->svid))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->oh))
+ return FALSE;
+ if (!xdr_uint64_t (xdrs, &objp->l_offset))
+ return FALSE;
+ if (!xdr_uint64_t (xdrs, &objp->l_len))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_lock (XDR *xdrs, nlm4_lock *objp)
+{
+ if (!xdr_string (xdrs, &objp->caller_name, MAXNAMELEN))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->fh))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->oh))
+ return FALSE;
+ if (!xdr_uint32_t (xdrs, &objp->svid))
+ return FALSE;
+ if (!xdr_uint64_t (xdrs, &objp->l_offset))
+ return FALSE;
+ if (!xdr_uint64_t (xdrs, &objp->l_len))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_share (XDR *xdrs, nlm4_share *objp)
+{
+ if (!xdr_string (xdrs, &objp->caller_name, MAXNAMELEN))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->fh))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->oh))
+ return FALSE;
+ if (!xdr_fsh_mode (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_fsh_access (xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_testrply (XDR *xdrs, nlm4_testrply *objp)
+{
+ if (!xdr_nlm4_stats (xdrs, &objp->stat))
+ return FALSE;
+ switch (objp->stat) {
+ case nlm4_denied:
+ if (!xdr_nlm4_holder (xdrs, &objp->nlm4_testrply_u.holder))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_testres (XDR *xdrs, nlm4_testres *objp)
+{
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_nlm4_testrply (xdrs, &objp->stat))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_testargs (XDR *xdrs, nlm4_testargs *objp)
+{
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->exclusive))
+ return FALSE;
+ if (!xdr_nlm4_lock (xdrs, &objp->alock))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_res (XDR *xdrs, nlm4_res *objp)
+{
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_nlm4_stat (xdrs, &objp->stat))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_lockargs (XDR *xdrs, nlm4_lockargs *objp)
+{
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->block))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->exclusive))
+ return FALSE;
+ if (!xdr_nlm4_lock (xdrs, &objp->alock))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->reclaim))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->state))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_cancargs (XDR *xdrs, nlm4_cancargs *objp)
+{
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->block))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->exclusive))
+ return FALSE;
+ if (!xdr_nlm4_lock (xdrs, &objp->alock))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_unlockargs (XDR *xdrs, nlm4_unlockargs *objp)
+{
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_nlm4_lock (xdrs, &objp->alock))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_shareargs (XDR *xdrs, nlm4_shareargs *objp)
+{
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_nlm4_share (xdrs, &objp->share))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->reclaim))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_shareres (XDR *xdrs, nlm4_shareres *objp)
+{
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_nlm4_stats (xdrs, &objp->stat))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->sequence))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nlm4_freeallargs (XDR *xdrs, nlm4_freeallargs *objp)
+{
+ if (!xdr_string (xdrs, &objp->name, LM_MAXSTRLEN))
+ return FALSE;
+ if (!xdr_uint32_t (xdrs, &objp->state))
+ return FALSE;
+ return TRUE;
+}
+
+
+/*
+bool_t
+xdr_nlm_sm_status (XDR *xdrs, nlm_sm_status *objp)
+{
+ if (!xdr_string (xdrs, &objp->mon_name, LM_MAXSTRLEN))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->state))
+ return FALSE;
+ if (!xdr_opaque (xdrs, objp->priv, 16))
+ return FALSE;
+ return TRUE;
+}
+*/
diff --git a/rpc/xdr/src/nlm4-xdr.h b/rpc/xdr/src/nlm4-xdr.h
new file mode 100644
index 000000000..3799f6b1d
--- /dev/null
+++ b/rpc/xdr/src/nlm4-xdr.h
@@ -0,0 +1,267 @@
+/*
+ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _NLM_H_RPCGEN
+#define _NLM_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+#if defined(__NetBSD__)
+#define xdr_u_quad_t xdr_u_int64_t
+#define xdr_quad_t xdr_int64_t
+#define xdr_uint32_t xdr_u_int32_t
+#define xdr_uint64_t xdr_u_int64_t
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAXNETOBJ_SZ 1024
+#define LM_MAXSTRLEN 1024
+#define MAXNAMELEN 1025
+
+#if defined(__NetBSD__)
+#define xdr_u_quad_t xdr_u_int64_t
+#define xdr_quad_t xdr_int64_t
+#define xdr_uint32_t xdr_u_int32_t
+#define xdr_uint64_t xdr_u_int64_t
+#endif
+
+/*
+ * The following enums are actually bit encoded for efficient
+ * boolean algebra.... DON'T change them.....
+ */
+
+enum fsh_mode {
+ fsm_DN = 0,
+ fsm_DR = 1,
+ fsm_DW = 2,
+ fsm_DRW = 3,
+};
+typedef enum fsh_mode fsh_mode;
+
+enum fsh_access {
+ fsa_NONE = 0,
+ fsa_R = 1,
+ fsa_W = 2,
+ fsa_RW = 3,
+};
+typedef enum fsh_access fsh_access;
+/* definitions for NLM version 4 */
+
+enum nlm4_stats {
+ nlm4_granted = 0,
+ nlm4_denied = 1,
+ nlm4_denied_nolock = 2,
+ nlm4_blocked = 3,
+ nlm4_denied_grace_period = 4,
+ nlm4_deadlck = 5,
+ nlm4_rofs = 6,
+ nlm4_stale_fh = 7,
+ nlm4_fbig = 8,
+ nlm4_failed = 9,
+};
+typedef enum nlm4_stats nlm4_stats;
+
+struct nlm4_stat {
+ nlm4_stats stat;
+};
+typedef struct nlm4_stat nlm4_stat;
+
+struct nlm4_holder {
+ bool_t exclusive;
+ u_int32_t svid;
+ netobj oh;
+ u_int64_t l_offset;
+ u_int64_t l_len;
+};
+typedef struct nlm4_holder nlm4_holder;
+
+struct nlm4_lock {
+ char *caller_name;
+ netobj fh;
+ netobj oh;
+ u_int32_t svid;
+ u_int64_t l_offset;
+ u_int64_t l_len;
+};
+typedef struct nlm4_lock nlm4_lock;
+
+struct nlm4_share {
+ char *caller_name;
+ netobj fh;
+ netobj oh;
+ fsh_mode mode;
+ fsh_access access;
+};
+typedef struct nlm4_share nlm4_share;
+
+struct nlm4_testrply {
+ nlm4_stats stat;
+ union {
+ struct nlm4_holder holder;
+ } nlm4_testrply_u;
+};
+typedef struct nlm4_testrply nlm4_testrply;
+
+struct nlm4_testres {
+ netobj cookie;
+ nlm4_testrply stat;
+};
+typedef struct nlm4_testres nlm4_testres;
+
+struct nlm4_testargs {
+ netobj cookie;
+ bool_t exclusive;
+ struct nlm4_lock alock;
+};
+typedef struct nlm4_testargs nlm4_testargs;
+
+struct nlm4_res {
+ netobj cookie;
+ nlm4_stat stat;
+};
+typedef struct nlm4_res nlm4_res;
+
+struct nlm4_lockargs {
+ netobj cookie;
+ bool_t block;
+ bool_t exclusive;
+ struct nlm4_lock alock;
+ bool_t reclaim;
+ int state;
+};
+typedef struct nlm4_lockargs nlm4_lockargs;
+
+struct nlm4_cancargs {
+ netobj cookie;
+ bool_t block;
+ bool_t exclusive;
+ struct nlm4_lock alock;
+};
+typedef struct nlm4_cancargs nlm4_cancargs;
+
+struct nlm4_unlockargs {
+ netobj cookie;
+ struct nlm4_lock alock;
+};
+typedef struct nlm4_unlockargs nlm4_unlockargs;
+
+struct nlm4_shareargs {
+ netobj cookie;
+ nlm4_share share;
+ bool_t reclaim;
+};
+typedef struct nlm4_shareargs nlm4_shareargs;
+
+struct nlm4_shareres {
+ netobj cookie;
+ nlm4_stats stat;
+ int sequence;
+};
+typedef struct nlm4_shareres nlm4_shareres;
+
+struct nlm4_freeallargs {
+ char *name;
+ u_int32_t state;
+};
+typedef struct nlm4_freeallargs nlm4_freeallargs;
+
+
+#define NLM4_NULL 0
+#define NLM4_TEST 1
+#define NLM4_LOCK 2
+#define NLM4_CANCEL 3
+#define NLM4_UNLOCK 4
+#define NLM4_GRANTED 5
+#define NLM4_TEST_MSG 6
+#define NLM4_LOCK_MSG 7
+#define NLM4_CANCEL_MSG 8
+#define NLM4_UNLOCK_MSG 9
+#define NLM4_GRANTED_MSG 10
+#define NLM4_TEST_RES 11
+#define NLM4_LOCK_RES 12
+#define NLM4_CANCEL_RES 13
+#define NLM4_UNLOCK_RES 14
+#define NLM4_GRANTED_RES 15
+#define NLM4_SM_NOTIFY 16
+#define NLM4_SEVENTEEN 17
+#define NLM4_EIGHTEEN 18
+#define NLM4_NINETEEN 19
+#define NLM4_SHARE 20
+#define NLM4_UNSHARE 21
+#define NLM4_NM_LOCK 22
+#define NLM4_FREE_ALL 23
+#define NLM4_PROC_COUNT 24
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_netobj (XDR *, netobj*);
+extern bool_t xdr_fsh_mode (XDR *, fsh_mode*);
+extern bool_t xdr_fsh_access (XDR *, fsh_access*);
+extern bool_t xdr_nlm4_stats (XDR *, nlm4_stats*);
+extern bool_t xdr_nlm4_stat (XDR *, nlm4_stat*);
+extern bool_t xdr_nlm4_holder (XDR *, nlm4_holder*);
+extern bool_t xdr_nlm4_lock (XDR *, nlm4_lock*);
+extern bool_t xdr_nlm4_share (XDR *, nlm4_share*);
+extern bool_t xdr_nlm4_testrply (XDR *, nlm4_testrply*);
+extern bool_t xdr_nlm4_testres (XDR *, nlm4_testres*);
+extern bool_t xdr_nlm4_testargs (XDR *, nlm4_testargs*);
+extern bool_t xdr_nlm4_res (XDR *, nlm4_res*);
+extern bool_t xdr_nlm4_lockargs (XDR *, nlm4_lockargs*);
+extern bool_t xdr_nlm4_cancargs (XDR *, nlm4_cancargs*);
+extern bool_t xdr_nlm4_unlockargs (XDR *, nlm4_unlockargs*);
+extern bool_t xdr_nlm4_shareargs (XDR *, nlm4_shareargs*);
+extern bool_t xdr_nlm4_shareres (XDR *, nlm4_shareres*);
+extern bool_t xdr_nlm4_freeallargs (XDR *, nlm4_freeallargs*);
+
+#else /* K&R C */
+extern bool_t xdr_netobj ();
+extern bool_t xdr_fsh_mode ();
+extern bool_t xdr_fsh_access ();
+extern bool_t xdr_nlm4_stats ();
+extern bool_t xdr_nlm4_stat ();
+extern bool_t xdr_nlm4_holder ();
+extern bool_t xdr_nlm4_lock ();
+extern bool_t xdr_nlm4_share ();
+extern bool_t xdr_nlm4_testrply ();
+extern bool_t xdr_nlm4_testres ();
+extern bool_t xdr_nlm4_testargs ();
+extern bool_t xdr_nlm4_res ();
+extern bool_t xdr_nlm4_lockargs ();
+extern bool_t xdr_nlm4_cancargs ();
+extern bool_t xdr_nlm4_unlockargs ();
+extern bool_t xdr_nlm4_shareargs ();
+extern bool_t xdr_nlm4_shareres ();
+extern bool_t xdr_nlm4_freeallargs ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_NLM_H_RPCGEN */
diff --git a/rpc/xdr/src/nlm4.x b/rpc/xdr/src/nlm4.x
new file mode 100644
index 000000000..a6de6f32b
--- /dev/null
+++ b/rpc/xdr/src/nlm4.x
@@ -0,0 +1,163 @@
+/*
+ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/* .x file defined as according to the RFC */
+
+const MAXNETOBJ_SZ = 1024;
+const LM_MAXSTRLEN = 1024;
+const MAXNAMELEN = 1025;
+
+typedef opaque netobj<MAXNETOBJ_SZ>;
+
+#ifdef RPC_HDR
+%/*
+% * The following enums are actually bit encoded for efficient
+% * boolean algebra.... DON'T change them.....
+% */
+#endif
+enum fsh_mode {
+ fsm_DN = 0, /* deny none */
+ fsm_DR = 1, /* deny read */
+ fsm_DW = 2, /* deny write */
+ fsm_DRW = 3 /* deny read/write */
+};
+
+enum fsh_access {
+ fsa_NONE = 0, /* for completeness */
+ fsa_R = 1, /* read only */
+ fsa_W = 2, /* write only */
+ fsa_RW = 3 /* read/write */
+};
+
+#ifdef RPC_HDR
+%/* definitions for NLM version 4 */
+#endif
+enum nlm4_stats {
+ nlm4_granted = 0,
+ nlm4_denied = 1,
+ nlm4_denied_nolock = 2,
+ nlm4_blocked = 3,
+ nlm4_denied_grace_period = 4,
+ nlm4_deadlck = 5,
+ nlm4_rofs = 6,
+ nlm4_stale_fh = 7,
+ nlm4_fbig = 8,
+ nlm4_failed = 9
+};
+
+struct nlm4_stat {
+ nlm4_stats stat;
+};
+
+struct nlm4_holder {
+ bool exclusive;
+ u_int32_t svid;
+ netobj oh;
+ u_int64_t l_offset;
+ u_int64_t l_len;
+};
+
+struct nlm4_lock {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh;
+ netobj oh;
+ u_int32_t svid;
+ u_int64_t l_offset;
+ u_int64_t l_len;
+};
+
+struct nlm4_share {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh;
+ netobj oh;
+ fsh_mode mode;
+ fsh_access access;
+};
+
+union nlm4_testrply switch (nlm4_stats stat) {
+ case nlm_denied:
+ struct nlm4_holder holder;
+ default:
+ void;
+};
+
+struct nlm4_testres {
+ netobj cookie;
+ nlm4_testrply stat;
+};
+
+struct nlm4_testargs {
+ netobj cookie;
+ bool exclusive;
+ struct nlm4_lock alock;
+};
+
+struct nlm4_res {
+ netobj cookie;
+ nlm4_stat stat;
+};
+
+struct nlm4_lockargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm4_lock alock;
+ bool reclaim; /* used for recovering locks */
+ int state; /* specify local status monitor state */
+};
+
+struct nlm4_cancargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm4_lock alock;
+};
+
+struct nlm4_unlockargs {
+ netobj cookie;
+ struct nlm4_lock alock;
+};
+
+struct nlm4_shareargs {
+ netobj cookie;
+ nlm4_share share;
+ bool reclaim;
+};
+
+struct nlm4_shareres {
+ netobj cookie;
+ nlm4_stats stat;
+ int sequence;
+};
+
+struct nlm4_freeallargs {
+ string name<LM_MAXSTRLEN>; /* client hostname */
+ uint32 state; /* unused */
+};
+
+/*
+ * argument for the procedure called by rpc.statd when a monitored host
+ * status change.
+ * XXX assumes LM_MAXSTRLEN == SM_MAXSTRLEN
+ */
+struct nlm_sm_status {
+ string mon_name<LM_MAXSTRLEN>; /* name of host */
+ int state; /* new state */
+ opaque priv[16]; /* private data */
+};
diff --git a/rpc/xdr/src/nlmcbk-xdr.c b/rpc/xdr/src/nlmcbk-xdr.c
new file mode 100644
index 000000000..26446ab1b
--- /dev/null
+++ b/rpc/xdr/src/nlmcbk-xdr.c
@@ -0,0 +1,37 @@
+/*
+ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "nlmcbk-xdr.h"
+
+bool_t
+xdr_nlm_sm_status (XDR *xdrs, nlm_sm_status *objp)
+{
+ if (!xdr_string (xdrs, &objp->mon_name, LM_MAXSTRLEN))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->state))
+ return FALSE;
+ if (!xdr_opaque (xdrs, objp->priv, 16))
+ return FALSE;
+ return TRUE;
+}
diff --git a/rpc/xdr/src/nlmcbk-xdr.h b/rpc/xdr/src/nlmcbk-xdr.h
new file mode 100644
index 000000000..4d6d670ab
--- /dev/null
+++ b/rpc/xdr/src/nlmcbk-xdr.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _NLMCBK_H_RPCGEN
+#define _NLMCBK_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LM_MAXSTRLEN 1024
+
+struct nlm_sm_status {
+ char *mon_name;
+ int state;
+ char priv[16];
+};
+typedef struct nlm_sm_status nlm_sm_status;
+
+#define NLMCBK_PROGRAM 100021
+#define NLMCBK_V1 1
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define NLMCBK_SM_NOTIFY 16
+extern void * nlmcbk_sm_notify_0(struct nlm_sm_status *, CLIENT *);
+extern void * nlmcbk_sm_notify_0_svc(struct nlm_sm_status *, struct svc_req *);
+extern int nlmcbk_program_0_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define NLMCBK_SM_NOTIFY 16
+extern void * nlmcbk_sm_notify_0();
+extern void * nlmcbk_sm_notify_0_svc();
+extern int nlmcbk_program_0_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_nlm_sm_status (XDR *, nlm_sm_status*);
+
+#else /* K&R C */
+extern bool_t xdr_nlm_sm_status ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_NLMCBK_H_RPCGEN */
diff --git a/rpc/xdr/src/nlmcbk.x b/rpc/xdr/src/nlmcbk.x
new file mode 100644
index 000000000..49901047e
--- /dev/null
+++ b/rpc/xdr/src/nlmcbk.x
@@ -0,0 +1,33 @@
+/*
+ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+const LM_MAXSTRLEN = 1024;
+
+struct nlm_sm_status {
+ string mon_name<LM_MAXSTRLEN>; /* name of host */
+ int state; /* new state */
+ opaque priv[16]; /* private data */
+};
+
+program NLMCBK_PROGRAM {
+ version NLMCBK_V0 {
+ void NLMCBK_SM_NOTIFY(struct nlm_sm_status) = 1;
+ } = 0;
+} = 1238477;
+
diff --git a/rpc/xdr/src/nsm-xdr.c b/rpc/xdr/src/nsm-xdr.c
new file mode 100644
index 000000000..8c41b4365
--- /dev/null
+++ b/rpc/xdr/src/nsm-xdr.c
@@ -0,0 +1,105 @@
+/*
+ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "nsm-xdr.h"
+
+bool_t
+xdr_sm_name (XDR *xdrs, sm_name *objp)
+{
+ if (!xdr_string (xdrs, &objp->mon_name, SM_MAXSTRLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_res (XDR *xdrs, res *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_sm_stat_res (XDR *xdrs, sm_stat_res *objp)
+{
+ if (!xdr_res (xdrs, &objp->res_stat))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->state))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_sm_stat (XDR *xdrs, sm_stat *objp)
+{
+ if (!xdr_int (xdrs, &objp->state))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_my_id (XDR *xdrs, my_id *objp)
+{
+ if (!xdr_string (xdrs, &objp->my_name, SM_MAXSTRLEN))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->my_prog))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->my_vers))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->my_proc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mon_id (XDR *xdrs, mon_id *objp)
+{
+ if (!xdr_string (xdrs, &objp->mon_name, SM_MAXSTRLEN))
+ return FALSE;
+ if (!xdr_my_id (xdrs, &objp->my_id))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mon (XDR *xdrs, mon *objp)
+{
+ if (!xdr_mon_id (xdrs, &objp->mon_id))
+ return FALSE;
+ if (!xdr_opaque (xdrs, objp->priv, 16))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nsm_callback_status (XDR *xdrs, nsm_callback_status *objp)
+{
+ if (!xdr_string (xdrs, &objp->mon_name, SM_MAXSTRLEN))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->state))
+ return FALSE;
+ if (!xdr_opaque (xdrs, objp->priv, 16))
+ return FALSE;
+ return TRUE;
+}
diff --git a/rpc/xdr/src/nsm-xdr.h b/rpc/xdr/src/nsm-xdr.h
new file mode 100644
index 000000000..9de642c15
--- /dev/null
+++ b/rpc/xdr/src/nsm-xdr.h
@@ -0,0 +1,95 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _NSM_H_RPCGEN
+#define _NSM_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SM_MAXSTRLEN 1024
+
+struct sm_name {
+ char *mon_name;
+};
+typedef struct sm_name sm_name;
+
+enum res {
+ STAT_SUCC = 0,
+ STAT_FAIL = 1,
+};
+typedef enum res res;
+
+struct sm_stat_res {
+ res res_stat;
+ int state;
+};
+typedef struct sm_stat_res sm_stat_res;
+
+struct sm_stat {
+ int state;
+};
+typedef struct sm_stat sm_stat;
+
+struct my_id {
+ char *my_name;
+ int my_prog;
+ int my_vers;
+ int my_proc;
+};
+typedef struct my_id my_id;
+
+struct mon_id {
+ char *mon_name;
+ struct my_id my_id;
+};
+typedef struct mon_id mon_id;
+
+struct mon {
+ struct mon_id mon_id;
+ char priv[16];
+};
+typedef struct mon mon;
+
+struct nsm_callback_status {
+ char *mon_name;
+ int state;
+ char priv[16];
+};
+typedef struct nsm_callback_status nsm_callback_status;
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_sm_name (XDR *, sm_name*);
+extern bool_t xdr_res (XDR *, res*);
+extern bool_t xdr_sm_stat_res (XDR *, sm_stat_res*);
+extern bool_t xdr_sm_stat (XDR *, sm_stat*);
+extern bool_t xdr_my_id (XDR *, my_id*);
+extern bool_t xdr_mon_id (XDR *, mon_id*);
+extern bool_t xdr_mon (XDR *, mon*);
+extern bool_t xdr_nsm_callback_status (XDR *, nsm_callback_status*);
+
+#else /* K&R C */
+extern bool_t xdr_sm_name ();
+extern bool_t xdr_res ();
+extern bool_t xdr_sm_stat_res ();
+extern bool_t xdr_sm_stat ();
+extern bool_t xdr_my_id ();
+extern bool_t xdr_mon_id ();
+extern bool_t xdr_mon ();
+extern bool_t xdr_nsm_callback_status ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_NSM_H_RPCGEN */
diff --git a/rpc/xdr/src/nsm.x b/rpc/xdr/src/nsm.x
new file mode 100644
index 000000000..8f97b1aaa
--- /dev/null
+++ b/rpc/xdr/src/nsm.x
@@ -0,0 +1,47 @@
+/*
+ * This defines the maximum length of the string
+ * identifying the caller.
+ */
+const SM_MAXSTRLEN = 1024;
+
+struct sm_name {
+ string mon_name<SM_MAXSTRLEN>;
+};
+
+enum res {
+ STAT_SUCC = 0, /* NSM agrees to monitor. */
+ STAT_FAIL = 1 /* NSM cannot monitor. */
+};
+
+struct sm_stat_res {
+ res res_stat;
+ int state;
+};
+
+struct sm_stat {
+ int state; /* state number of NSM */
+};
+
+struct my_id {
+ string my_name<SM_MAXSTRLEN>; /* hostname */
+ int my_prog; /* RPC program number */
+ int my_vers; /* program version number */
+ int my_proc; /* procedure number */
+};
+
+struct mon_id {
+ string mon_name<SM_MAXSTRLEN>; /* name of the host to be monitored */
+ struct my_id my_id;
+};
+
+struct mon {
+ struct mon_id mon_id;
+ opaque priv[16]; /* private information */
+};
+
+struct nsm_callback_status {
+ string mon_name<SM_MAXSTRLEN>;
+ int state;
+ opaque priv[16]; /* for private information */
+};
+
diff --git a/rpc/xdr/src/portmap-xdr.c b/rpc/xdr/src/portmap-xdr.c
index 45803dcc1..4766122e6 100644
--- a/rpc/xdr/src/portmap-xdr.c
+++ b/rpc/xdr/src/portmap-xdr.c
@@ -1,22 +1,21 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
/*
* Please do not edit this file.
@@ -24,11 +23,13 @@
*/
#include "portmap-xdr.h"
-#include "compat.h"
bool_t
xdr_pmap_port_by_brick_req (XDR *xdrs, pmap_port_by_brick_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_string (xdrs, &objp->brick, ~0))
return FALSE;
return TRUE;
@@ -38,6 +39,7 @@ bool_t
xdr_pmap_port_by_brick_rsp (XDR *xdrs, pmap_port_by_brick_rsp *objp)
{
register int32_t *buf;
+ buf = NULL;
if (xdrs->x_op == XDR_ENCODE) {
@@ -92,6 +94,9 @@ xdr_pmap_port_by_brick_rsp (XDR *xdrs, pmap_port_by_brick_rsp *objp)
bool_t
xdr_pmap_brick_by_port_req (XDR *xdrs, pmap_brick_by_port_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_int (xdrs, &objp->port))
return FALSE;
return TRUE;
@@ -101,6 +106,7 @@ bool_t
xdr_pmap_brick_by_port_rsp (XDR *xdrs, pmap_brick_by_port_rsp *objp)
{
register int32_t *buf;
+ buf = NULL;
if (xdrs->x_op == XDR_ENCODE) {
@@ -155,6 +161,9 @@ xdr_pmap_brick_by_port_rsp (XDR *xdrs, pmap_brick_by_port_rsp *objp)
bool_t
xdr_pmap_signup_req (XDR *xdrs, pmap_signup_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_string (xdrs, &objp->brick, ~0))
return FALSE;
if (!xdr_int (xdrs, &objp->port))
@@ -165,6 +174,9 @@ xdr_pmap_signup_req (XDR *xdrs, pmap_signup_req *objp)
bool_t
xdr_pmap_signup_rsp (XDR *xdrs, pmap_signup_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
@@ -175,6 +187,9 @@ xdr_pmap_signup_rsp (XDR *xdrs, pmap_signup_rsp *objp)
bool_t
xdr_pmap_signin_req (XDR *xdrs, pmap_signin_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_string (xdrs, &objp->brick, ~0))
return FALSE;
if (!xdr_int (xdrs, &objp->port))
@@ -185,6 +200,9 @@ xdr_pmap_signin_req (XDR *xdrs, pmap_signin_req *objp)
bool_t
xdr_pmap_signin_rsp (XDR *xdrs, pmap_signin_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
@@ -195,6 +213,9 @@ xdr_pmap_signin_rsp (XDR *xdrs, pmap_signin_rsp *objp)
bool_t
xdr_pmap_signout_req (XDR *xdrs, pmap_signout_req *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_string (xdrs, &objp->brick, ~0))
return FALSE;
if (!xdr_int (xdrs, &objp->port))
@@ -205,6 +226,9 @@ xdr_pmap_signout_req (XDR *xdrs, pmap_signout_req *objp)
bool_t
xdr_pmap_signout_rsp (XDR *xdrs, pmap_signout_rsp *objp)
{
+ register int32_t *buf;
+ buf = NULL;
+
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
diff --git a/rpc/xdr/src/portmap-xdr.h b/rpc/xdr/src/portmap-xdr.h
index edc2ccf24..8e4ff4f45 100644
--- a/rpc/xdr/src/portmap-xdr.h
+++ b/rpc/xdr/src/portmap-xdr.h
@@ -1,33 +1,31 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
-#ifndef _PORTMAP_H_RPCGEN
-#define _PORTMAP_H_RPCGEN
+#ifndef _PORTMAP_XDR_H_RPCGEN
+#define _PORTMAP_XDR_H_RPCGEN
#include <rpc/rpc.h>
-#include <rpc/types.h>
#ifdef __cplusplus
@@ -129,4 +127,4 @@ extern bool_t xdr_pmap_signout_rsp ();
}
#endif
-#endif /* !_PORTMAP_H_RPCGEN */
+#endif /* !_PORTMAP_XDR_H_RPCGEN */
diff --git a/rpc/xdr/src/portmap.c b/rpc/xdr/src/portmap.c
deleted file mode 100644
index fd29bf9a1..000000000
--- a/rpc/xdr/src/portmap.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "portmap.h"
-
-
-ssize_t
-xdr_to_pmap_port_by_brick_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_port_by_brick_req);
-}
-
-
-ssize_t
-xdr_to_pmap_port_by_brick_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_port_by_brick_rsp);
-}
-
-
-ssize_t
-xdr_from_pmap_port_by_brick_req (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_port_by_brick_req);
-}
-
-
-ssize_t
-xdr_from_pmap_port_by_brick_rsp (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_port_by_brick_rsp);
-}
-
-
-
-ssize_t
-xdr_to_pmap_brick_by_port_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_brick_by_port_req);
-}
-
-
-ssize_t
-xdr_to_pmap_brick_by_port_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_brick_by_port_rsp);
-}
-
-
-ssize_t
-xdr_from_pmap_brick_by_port_req (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_brick_by_port_req);
-}
-
-
-ssize_t
-xdr_from_pmap_brick_by_port_rsp (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_brick_by_port_rsp);
-}
-
-
-
-
-ssize_t
-xdr_to_pmap_signup_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signup_req);
-}
-
-
-ssize_t
-xdr_to_pmap_signup_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signup_rsp);
-}
-
-
-ssize_t
-xdr_from_pmap_signup_req (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signup_req);
-}
-
-
-ssize_t
-xdr_from_pmap_signup_rsp (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signup_rsp);
-}
-
-
-
-
-ssize_t
-xdr_to_pmap_signin_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signin_req);
-}
-
-
-ssize_t
-xdr_to_pmap_signin_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signin_rsp);
-}
-
-
-ssize_t
-xdr_from_pmap_signin_req (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signin_req);
-}
-
-
-ssize_t
-xdr_from_pmap_signin_rsp (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signin_rsp);
-}
-
-
-
-
-ssize_t
-xdr_to_pmap_signout_req (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signout_req);
-}
-
-
-ssize_t
-xdr_to_pmap_signout_rsp (struct iovec inmsg, void *args)
-{
- return xdr_to_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signout_rsp);
-}
-
-
-ssize_t
-xdr_from_pmap_signout_req (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signout_req);
-}
-
-
-ssize_t
-xdr_from_pmap_signout_rsp (struct iovec inmsg, void *args)
-{
- return xdr_serialize_generic (inmsg, (void *)args,
- (xdrproc_t)xdr_pmap_signout_rsp);
-}
-
diff --git a/rpc/xdr/src/portmap.h b/rpc/xdr/src/portmap.h
deleted file mode 100644
index 397a63938..000000000
--- a/rpc/xdr/src/portmap.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef _PORTMAP_H
-#define _PORTMAP_H
-
-#include <sys/uio.h>
-
-#include "xdr-generic.h"
-#include "portmap-xdr.h"
-
-
-ssize_t
-xdr_to_pmap_port_by_brick_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_pmap_port_by_brick_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_from_pmap_port_by_brick_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_pmap_port_by_brick_rsp (struct iovec outmsg, void *args);
-
-
-ssize_t
-xdr_to_pmap_brick_by_port_req (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_to_pmap_brick_by_port_rsp (struct iovec inmsg, void *args);
-
-ssize_t
-xdr_from_pmap_brick_by_port_req (struct iovec outmsg, void *args);
-
-ssize_t
-xdr_from_pmap_brick_by_port_rsp (struct iovec outmsg, void *args);
-
-
-ssize_t
-xdr_from_pmap_signup_req (struct iovec msg, void *args);
-
-ssize_t
-xdr_from_pmap_signup_rsp (struct iovec msg, void *args);
-
-ssize_t
-xdr_to_pmap_signup_req (struct iovec msg, void *args);
-
-ssize_t
-xdr_to_pmap_signup_rsp (struct iovec msg, void *args);
-
-
-ssize_t
-xdr_from_pmap_signin_req (struct iovec msg, void *args);
-
-ssize_t
-xdr_from_pmap_signin_rsp (struct iovec msg, void *args);
-
-ssize_t
-xdr_to_pmap_signin_req (struct iovec msg, void *args);
-
-ssize_t
-xdr_to_pmap_signin_rsp (struct iovec msg, void *args);
-
-
-ssize_t
-xdr_from_pmap_signout_req (struct iovec msg, void *args);
-
-ssize_t
-xdr_from_pmap_signout_rsp (struct iovec msg, void *args);
-
-ssize_t
-xdr_to_pmap_signout_req (struct iovec msg, void *args);
-
-ssize_t
-xdr_to_pmap_signout_rsp (struct iovec msg, void *args);
-
-
-#endif /* !_PORTMAP_H */
diff --git a/rpc/xdr/src/rpc-common-xdr.c b/rpc/xdr/src/rpc-common-xdr.c
new file mode 100644
index 000000000..6cb48a923
--- /dev/null
+++ b/rpc/xdr/src/rpc-common-xdr.c
@@ -0,0 +1,223 @@
+/*
+ Copyright (c) 2007-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 "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "rpc-common-xdr.h"
+
+bool_t
+xdr_auth_glusterfs_parms_v2 (XDR *xdrs, auth_glusterfs_parms_v2 *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->pid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_LONG(buf, objp->pid);
+ IXDR_PUT_U_LONG(buf, objp->uid);
+ IXDR_PUT_U_LONG(buf, objp->gid);
+ }
+ if (!xdr_array (xdrs, (char **)&objp->groups.groups_val, (u_int *) &objp->groups.groups_len, ~0,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->lk_owner.lk_owner_val, (u_int *) &objp->lk_owner.lk_owner_len, ~0))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->pid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+
+ } else {
+ objp->pid = IXDR_GET_LONG(buf);
+ objp->uid = IXDR_GET_U_LONG(buf);
+ objp->gid = IXDR_GET_U_LONG(buf);
+ }
+ if (!xdr_array (xdrs, (char **)&objp->groups.groups_val, (u_int *) &objp->groups.groups_len, ~0,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->lk_owner.lk_owner_val, (u_int *) &objp->lk_owner.lk_owner_len, ~0))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (!xdr_int (xdrs, &objp->pid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **)&objp->groups.groups_val, (u_int *) &objp->groups.groups_len, ~0,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->lk_owner.lk_owner_val, (u_int *) &objp->lk_owner.lk_owner_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_auth_glusterfs_parms (XDR *xdrs, auth_glusterfs_parms *objp)
+{
+ register int32_t *buf;
+ int i;
+ buf = NULL;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_u_quad_t (xdrs, &objp->lk_owner))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, (4 + 16 )* BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->pid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->ngrps))
+ return FALSE;
+ if (!xdr_vector (xdrs, (char *)objp->groups, 16,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return FALSE;
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->pid);
+ IXDR_PUT_U_LONG(buf, objp->uid);
+ IXDR_PUT_U_LONG(buf, objp->gid);
+ IXDR_PUT_U_LONG(buf, objp->ngrps);
+ {
+ register u_int *genp;
+
+ for (i = 0, genp = objp->groups;
+ i < 16; ++i) {
+ IXDR_PUT_U_LONG(buf, *genp++);
+ }
+ }
+ }
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_u_quad_t (xdrs, &objp->lk_owner))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, (4 + 16 )* BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->pid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->ngrps))
+ return FALSE;
+ if (!xdr_vector (xdrs, (char *)objp->groups, 16,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return FALSE;
+ } else {
+ objp->pid = IXDR_GET_U_LONG(buf);
+ objp->uid = IXDR_GET_U_LONG(buf);
+ objp->gid = IXDR_GET_U_LONG(buf);
+ objp->ngrps = IXDR_GET_U_LONG(buf);
+ {
+ register u_int *genp;
+
+ for (i = 0, genp = objp->groups;
+ i < 16; ++i) {
+ *genp++ = IXDR_GET_U_LONG(buf);
+ }
+ }
+ }
+ return TRUE;
+ }
+
+ if (!xdr_u_quad_t (xdrs, &objp->lk_owner))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->pid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->ngrps))
+ return FALSE;
+ if (!xdr_vector (xdrs, (char *)objp->groups, 16,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_dump_req (XDR *xdrs, gf_dump_req *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_u_quad_t (xdrs, &objp->gfs_id))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_prog_detail (XDR *xdrs, gf_prog_detail *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_string (xdrs, &objp->progname, ~0))
+ return FALSE;
+ if (!xdr_u_quad_t (xdrs, &objp->prognum))
+ return FALSE;
+ if (!xdr_u_quad_t (xdrs, &objp->progver))
+ return FALSE;
+ if (!xdr_pointer (xdrs, (char **)&objp->next, sizeof (gf_prog_detail), (xdrproc_t) xdr_gf_prog_detail))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_dump_rsp (XDR *xdrs, gf_dump_rsp *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_u_quad_t (xdrs, &objp->gfs_id))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_pointer (xdrs, (char **)&objp->prog, sizeof (gf_prog_detail), (xdrproc_t) xdr_gf_prog_detail))
+ return FALSE;
+ return TRUE;
+}
diff --git a/rpc/xdr/src/rpc-common-xdr.h b/rpc/xdr/src/rpc-common-xdr.h
new file mode 100644
index 000000000..c43eab315
--- /dev/null
+++ b/rpc/xdr/src/rpc-common-xdr.h
@@ -0,0 +1,104 @@
+/*
+ Copyright (c) 2007-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 "xdr-common.h"
+#include "compat.h"
+
+#if defined(__GNUC__)
+#if __GNUC__ >= 4
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#endif
+
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _RPC_COMMON_XDR_H_RPCGEN
+#define _RPC_COMMON_XDR_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct auth_glusterfs_parms_v2 {
+ int pid;
+ u_int uid;
+ u_int gid;
+ struct {
+ u_int groups_len;
+ u_int *groups_val;
+ } groups;
+ struct {
+ u_int lk_owner_len;
+ char *lk_owner_val;
+ } lk_owner;
+};
+typedef struct auth_glusterfs_parms_v2 auth_glusterfs_parms_v2;
+
+struct auth_glusterfs_parms {
+ u_quad_t lk_owner;
+ u_int pid;
+ u_int uid;
+ u_int gid;
+ u_int ngrps;
+ u_int groups[16];
+};
+typedef struct auth_glusterfs_parms auth_glusterfs_parms;
+
+struct gf_dump_req {
+ u_quad_t gfs_id;
+};
+typedef struct gf_dump_req gf_dump_req;
+
+struct gf_prog_detail {
+ char *progname;
+ u_quad_t prognum;
+ u_quad_t progver;
+ struct gf_prog_detail *next;
+};
+typedef struct gf_prog_detail gf_prog_detail;
+
+struct gf_dump_rsp {
+ u_quad_t gfs_id;
+ int op_ret;
+ int op_errno;
+ struct gf_prog_detail *prog;
+};
+typedef struct gf_dump_rsp gf_dump_rsp;
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_auth_glusterfs_parms_v2 (XDR *, auth_glusterfs_parms_v2*);
+extern bool_t xdr_auth_glusterfs_parms (XDR *, auth_glusterfs_parms*);
+extern bool_t xdr_gf_dump_req (XDR *, gf_dump_req*);
+extern bool_t xdr_gf_prog_detail (XDR *, gf_prog_detail*);
+extern bool_t xdr_gf_dump_rsp (XDR *, gf_dump_rsp*);
+
+#else /* K&R C */
+extern bool_t xdr_auth_glusterfs_parms_v2 ();
+extern bool_t xdr_auth_glusterfs_parms ();
+extern bool_t xdr_gf_dump_req ();
+extern bool_t xdr_gf_prog_detail ();
+extern bool_t xdr_gf_dump_rsp ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_RPC_COMMON_XDR_H_RPCGEN */
diff --git a/rpc/xdr/src/rpc-common-xdr.x b/rpc/xdr/src/rpc-common-xdr.x
new file mode 100644
index 000000000..ca28f38b5
--- /dev/null
+++ b/rpc/xdr/src/rpc-common-xdr.x
@@ -0,0 +1,39 @@
+/* This file has definition of few XDR structures which are
+ * not captured in any section specific file */
+
+struct auth_glusterfs_parms_v2 {
+ int pid;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int groups<>;
+ opaque lk_owner<>;
+};
+
+struct auth_glusterfs_parms {
+ unsigned hyper lk_owner;
+ unsigned int pid;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int ngrps;
+ unsigned groups[16];
+};
+
+struct gf_dump_req {
+ unsigned hyper gfs_id;
+};
+
+
+struct gf_prog_detail {
+ string progname<>;
+ unsigned hyper prognum;
+ unsigned hyper progver;
+ struct gf_prog_detail *next;
+};
+
+
+struct gf_dump_rsp {
+ unsigned hyper gfs_id;
+ int op_ret;
+ int op_errno;
+ struct gf_prog_detail *prog;
+};
diff --git a/rpc/xdr/src/xdr-generic.c b/rpc/xdr/src/xdr-generic.c
index f7e09482b..d815d18d4 100644
--- a/rpc/xdr/src/xdr-generic.c
+++ b/rpc/xdr/src/xdr-generic.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -96,3 +87,39 @@ xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc,
ret:
return ret;
}
+
+ssize_t
+xdr_length_round_up (size_t len, size_t bufsize)
+{
+ int roundup = 0;
+
+ roundup = len % XDR_BYTES_PER_UNIT;
+ if (roundup > 0)
+ roundup = XDR_BYTES_PER_UNIT - roundup;
+
+ if ((roundup > 0) && ((roundup + len) <= bufsize))
+ len += roundup;
+
+ return len;
+}
+
+int
+xdr_bytes_round_up (struct iovec *vec, size_t bufsize)
+{
+ vec->iov_len = xdr_length_round_up (vec->iov_len, bufsize);
+ return 0;
+}
+
+
+void
+xdr_vector_round_up (struct iovec *vec, int vcount, uint32_t count)
+{
+ uint32_t round_count = 0;
+
+ round_count = xdr_length_round_up (count, 1048576);
+ round_count -= count;
+ if (round_count == 0)
+ return;
+
+ vec[vcount-1].iov_len += round_count;
+}
diff --git a/rpc/xdr/src/xdr-generic.h b/rpc/xdr/src/xdr-generic.h
index 9b8019637..391a3386a 100644
--- a/rpc/xdr/src/xdr-generic.h
+++ b/rpc/xdr/src/xdr-generic.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -26,11 +17,14 @@
#include <rpc/types.h>
#include <rpc/xdr.h>
+#include "compat.h"
+
#define xdr_decoded_remaining_addr(xdr) ((&xdr)->x_private)
#define xdr_decoded_remaining_len(xdr) ((&xdr)->x_handy)
#define xdr_encoded_length(xdr) (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base))
#define xdr_decoded_length(xdr) (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base))
+#define XDR_BYTES_PER_UNIT 4
ssize_t
xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc);
@@ -42,4 +36,14 @@ ssize_t
xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc,
struct iovec *pendingpayload);
+
+extern int
+xdr_bytes_round_up (struct iovec *vec, size_t bufsize);
+
+extern ssize_t
+xdr_length_round_up (size_t len, size_t bufsize);
+
+void
+xdr_vector_round_up (struct iovec *vec, int vcount, uint32_t count);
+
#endif /* !_XDR_GENERIC_H */
diff --git a/xlators/nfs/lib/src/xdr-nfs3.c b/rpc/xdr/src/xdr-nfs3.c
index febc6a695..35fca59ff 100644
--- a/xlators/nfs/lib/src/xdr-nfs3.c
+++ b/rpc/xdr/src/xdr-nfs3.c
@@ -1,29 +1,31 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#include "xdr-nfs3.h"
#include "mem-pool.h"
+#include "xdr-common.h"
#if GF_DARWIN_HOST_OS
#define xdr_u_quad_t xdr_u_int64_t
#define xdr_quad_t xdr_int64_t
#define xdr_uint32_t xdr_u_int32_t
+#define xdr_uint64_t xdr_u_int64_t
#endif
bool_t
diff --git a/xlators/nfs/lib/src/xdr-nfs3.h b/rpc/xdr/src/xdr-nfs3.h
index 0530876a8..9e5ccd186 100644
--- a/xlators/nfs/lib/src/xdr-nfs3.h
+++ b/rpc/xdr/src/xdr-nfs3.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/alu/src/alu-mem-types.h b/scheduler/alu/src/alu-mem-types.h
index 4821ad7e6..92702f286 100644
--- a/scheduler/alu/src/alu-mem-types.h
+++ b/scheduler/alu/src/alu-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/alu/src/alu.c b/scheduler/alu/src/alu.c
index fc021932d..58bef60ae 100644
--- a/scheduler/alu/src/alu.c
+++ b/scheduler/alu/src/alu.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/alu/src/alu.h b/scheduler/alu/src/alu.h
index 6af1a13ad..c716ad8e5 100644
--- a/scheduler/alu/src/alu.h
+++ b/scheduler/alu/src/alu.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/nufa/src/nufa-mem-types.h b/scheduler/nufa/src/nufa-mem-types.h
index 909478cde..945dafa7c 100644
--- a/scheduler/nufa/src/nufa-mem-types.h
+++ b/scheduler/nufa/src/nufa-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/nufa/src/nufa.c b/scheduler/nufa/src/nufa.c
index 66394fce7..1bf477bdc 100644
--- a/scheduler/nufa/src/nufa.c
+++ b/scheduler/nufa/src/nufa.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/random/src/random-mem-types.h b/scheduler/random/src/random-mem-types.h
index 83fa1776d..ff30d9244 100644
--- a/scheduler/random/src/random-mem-types.h
+++ b/scheduler/random/src/random-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/random/src/random.c b/scheduler/random/src/random.c
index 93f5a363f..03a284b66 100644
--- a/scheduler/random/src/random.c
+++ b/scheduler/random/src/random.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/random/src/random.h b/scheduler/random/src/random.h
index 01861bf19..154b1bdfb 100644
--- a/scheduler/random/src/random.h
+++ b/scheduler/random/src/random.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/rr/src/rr-mem-types.h b/scheduler/rr/src/rr-mem-types.h
index 16d3e5fdd..cb05323cd 100644
--- a/scheduler/rr/src/rr-mem-types.h
+++ b/scheduler/rr/src/rr-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/rr/src/rr-options.c b/scheduler/rr/src/rr-options.c
index 23e6eeca0..505b1713e 100644
--- a/scheduler/rr/src/rr-options.c
+++ b/scheduler/rr/src/rr-options.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/rr/src/rr-options.h b/scheduler/rr/src/rr-options.h
index 60875f8f3..1b0a1ef3d 100644
--- a/scheduler/rr/src/rr-options.h
+++ b/scheduler/rr/src/rr-options.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/rr/src/rr.c b/scheduler/rr/src/rr.c
index 54a983173..e7b556e67 100644
--- a/scheduler/rr/src/rr.c
+++ b/scheduler/rr/src/rr.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/rr/src/rr.h b/scheduler/rr/src/rr.h
index 37d333565..3bd95929b 100644
--- a/scheduler/rr/src/rr.h
+++ b/scheduler/rr/src/rr.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/switch/src/switch-mem-types.h b/scheduler/switch/src/switch-mem-types.h
index 4d7f3eef7..7039b035d 100644
--- a/scheduler/switch/src/switch-mem-types.h
+++ b/scheduler/switch/src/switch-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/scheduler/switch/src/switch.c b/scheduler/switch/src/switch.c
index a8410bb19..1362e5cc9 100644
--- a/scheduler/switch/src/switch.c
+++ b/scheduler/switch/src/switch.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/smoke.sh b/smoke.sh
new file mode 100755
index 000000000..a87908d79
--- /dev/null
+++ b/smoke.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+set -e;
+
+M=/mnt;
+P=/build;
+H=$(hostname);
+T=600;
+V=patchy;
+
+
+function cleanup()
+{
+ killall -15 glusterfs glusterfsd glusterd glusterd 2>&1 || true;
+ killall -9 glusterfs glusterfsd glusterd glusterd 2>&1 || true;
+ umount -l $M 2>&1 || true;
+ rm -rf /var/lib/glusterd /etc/glusterd $P/export;
+}
+
+function start_fs()
+{
+ mkdir -p $P/export;
+ chmod 0755 $P/export;
+
+ glusterd;
+ gluster --mode=script volume create $V replica 2 $H:$P/export/export{1,2,3,4};
+ gluster volume start $V;
+ glusterfs -s $H --volfile-id $V $M;
+# mount -t glusterfs $H:/$V $M;
+}
+
+
+function run_tests()
+{
+ cd $M;
+
+ (sleep 1; dbench -s -t 60 10 >/dev/null) &
+
+ (sleep 1; /opt/qa/tools/posix_compliance.sh) &
+
+ wait %2
+ wait %3
+
+ rm -rf clients;
+
+ cd -;
+}
+
+
+function watchdog ()
+{
+ # insurance against hangs during the test
+
+ sleep $1;
+
+ echo "Kicking in watchdog after $1 secs";
+
+ cleanup;
+}
+
+
+function finish ()
+{
+ cleanup;
+ kill %1;
+}
+
+function main ()
+{
+ cleanup;
+
+ watchdog $T &
+
+ trap finish EXIT;
+
+ set -x;
+
+ start_fs;
+
+ run_tests;
+}
+
+main "$@";
diff --git a/swift/1.4.8/README b/swift/1.4.8/README
new file mode 100644
index 000000000..0ea91535e
--- /dev/null
+++ b/swift/1.4.8/README
@@ -0,0 +1,22 @@
+Gluster Unified File and Object Storage allows files and directories created
+via gluster-native/nfs mount to be accessed as containers and objects. It is
+a plugin for OpenStack Swift project.
+
+Install
+* Clone the swift repo from git://github.com/openstack/swift.git
+* Apply the swift.diff present in glusterfs.git/swift/1.4.8 to the swift repo.
+* Create a directory named "plugins" under swift.git/swift directory.
+* Copy the contents of glusterfs.git/swift/1.4.8/plugins/ under swift.git/swift/
+ except the conf directory.
+* Copy the contents of glusterfs.git/swift/1.4.5/plugins/conf under /etc/swift/.
+* Run python setup.py install
+
+Once this is done, you can access the GlusterFS volumes as Swift accounts.
+Add the Volume names with the user-name and its corresponding password to the
+/etc/swift/proxy-server.conf (follow the syntax used in the sample conf file).
+
+Command to start the servers
+ swift-init main start
+
+Command to stop the servers
+ swift-init main stop
diff --git a/swift/1.4.8/gluster-swift-plugin.spec b/swift/1.4.8/gluster-swift-plugin.spec
new file mode 100644
index 000000000..746f75c5f
--- /dev/null
+++ b/swift/1.4.8/gluster-swift-plugin.spec
@@ -0,0 +1,60 @@
+############################################################################################################
+# Command to build rpms.#
+# $ rpmbuild -ta %{name}-%{version}-%{release}.tar.gz #
+############################################################################################################
+# Setting up the environment. #
+# * Create a directory %{name}-%{version} under $HOME/rpmbuild/SOURCES #
+# * Copy the contents of plugins directory into $HOME/rpmbuild/SOURCES/%{name}-%{version} #
+# * tar zcvf %{name}-%{version}-%{release}.tar.gz $HOME/rpmbuild/SOURCES/%{name}-%{version} %{name}.spec #
+# For more information refer #
+# http://fedoraproject.org/wiki/How_to_create_an_RPM_package #
+############################################################################################################
+
+%define _confdir /etc/swift
+%define _swiftdir /usr/lib/python2.6/site-packages/swift
+%define _ufo_version 1.0
+%define _ufo_release 3
+
+Summary : GlusterFS Unified File and Object Storage.
+Name : gluster-swift-plugin
+Version : %{_ufo_version}
+Release : %{_ufo_release}
+Group : Application/File
+Vendor : Red Hat Inc.
+Source0 : %{name}-%{version}-%{release}.tar.gz
+Packager : gluster-users@gluster.org
+License : Apache
+BuildArch: noarch
+Requires : memcached
+Requires : openssl
+Requires : python
+Requires : gluster-swift
+
+%description
+Gluster Unified File and Object Storage unifies NAS and object storage
+technology. This provides a system for data storage that enables users to access
+the same data as an object and as a file, simplifying management and controlling
+storage costs.
+
+%prep
+%setup -q
+
+%install
+rm -rf %{buildroot}
+
+mkdir -p %{buildroot}/%{_swiftdir}/plugins
+mkdir -p %{buildroot}/%{_confdir}/
+
+cp constraints.py %{buildroot}/%{_swiftdir}/plugins
+cp DiskDir.py %{buildroot}/%{_swiftdir}/plugins
+cp DiskFile.py %{buildroot}/%{_swiftdir}/plugins
+cp Glusterfs.py %{buildroot}/%{_swiftdir}/plugins
+cp __init__.py %{buildroot}/%{_swiftdir}/plugins
+cp utils.py %{buildroot}/%{_swiftdir}/plugins
+
+cp -r conf/* %{buildroot}/%{_confdir}/
+
+%files
+%defattr(-,root,root)
+%{_swiftdir}/plugins
+%{_confdir}/
diff --git a/swift/1.4.8/gluster-swift.spec b/swift/1.4.8/gluster-swift.spec
new file mode 100644
index 000000000..640b944e8
--- /dev/null
+++ b/swift/1.4.8/gluster-swift.spec
@@ -0,0 +1,396 @@
+%if ! (0%{?fedora} > 12 || 0%{?rhel} > 5)
+%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")}
+%endif
+
+Name: gluster-swift
+Version: 1.4.8
+Release: 3%{?dist}
+Summary: OpenStack Object Storage (swift)
+
+Group: Development/Languages
+License: ASL 2.0
+URL: http://launchpad.net/swift
+Source0: http://launchpad.net/swift/essex/%{version}/+download/swift-%{version}.tar.gz
+Source1: %{name}-functions
+Source2: %{name}-account.init
+Source4: %{name}-container.init
+Source5: %{name}-object.init
+Source6: %{name}-proxy.init
+Patch0: openstack-swift-newdeps.patch
+Patch1: openstack-swift-docmod.patch
+Patch2: openstack-swift-nonet.patch
+Patch3: gluster.patch
+
+BuildRoot: %{_tmppath}/swift-%{version}-%{release}-root-%(%{__id_u} -n)
+
+BuildArch: noarch
+BuildRequires: dos2unix
+BuildRequires: python-devel
+BuildRequires: python-setuptools
+BuildRequires: python-netifaces
+BuildRequires: python-paste-deploy
+Requires: python-configobj
+Requires: python-eventlet >= 0.9.8
+Requires: python-greenlet >= 0.3.1
+Requires: python-paste-deploy
+Requires: python-simplejson
+Requires: python-webob1.0
+Requires: pyxattr
+Requires: python-setuptools
+Requires: python-netifaces
+Requires: python-netifaces
+
+Conflicts: openstack-swift
+
+Requires(post): chkconfig
+Requires(postun): initscripts
+Requires(preun): chkconfig
+Requires(pre): shadow-utils
+Obsoletes: openstack-swift-auth <= 1.4.0
+
+%description
+OpenStack Object Storage (swift) aggregates commodity servers to work together
+in clusters for reliable, redundant, and large-scale storage of static objects.
+Objects are written to multiple hardware devices in the data center, with the
+OpenStack software responsible for ensuring data replication and integrity
+across the cluster. Storage clusters can scale horizontally by adding new nodes,
+which are automatically configured. Should a node fail, OpenStack works to
+replicate its content from other active nodes. Because OpenStack uses software
+logic to ensure data replication and distribution across different devices,
+inexpensive commodity hard drives and servers can be used in lieu of more
+expensive equipment.
+
+%package account
+Summary: A swift account server
+Group: Applications/System
+
+Requires: %{name} = %{version}-%{release}
+
+%description account
+OpenStack Object Storage (swift) aggregates commodity servers to work together
+in clusters for reliable, redundant, and large-scale storage of static objects.
+
+This package contains the %{name} account server.
+
+%package container
+Summary: A swift container server
+Group: Applications/System
+
+Requires: %{name} = %{version}-%{release}
+
+%description container
+OpenStack Object Storage (swift) aggregates commodity servers to work together
+in clusters for reliable, redundant, and large-scale storage of static objects.
+
+This package contains the %{name} container server.
+
+%package object
+Summary: A swift object server
+Group: Applications/System
+
+Requires: %{name} = %{version}-%{release}
+Requires: rsync >= 3.0
+
+%description object
+OpenStack Object Storage (swift) aggregates commodity servers to work together
+in clusters for reliable, redundant, and large-scale storage of static objects.
+
+This package contains the %{name} object server.
+
+%package proxy
+Summary: A swift proxy server
+Group: Applications/System
+
+Requires: %{name} = %{version}-%{release}
+
+%description proxy
+OpenStack Object Storage (swift) aggregates commodity servers to work together
+in clusters for reliable, redundant, and large-scale storage of static objects.
+
+This package contains the %{name} proxy server.
+
+%package doc
+Summary: Documentation for %{name}
+Group: Documentation
+#%if 0%{?rhel} >= 6
+#BuildRequires: python-sphinx10 >= 1.0
+#%endif
+%if 0%{?fedora} >= 14
+BuildRequires: python-sphinx >= 1.0
+%endif
+# Required for generating docs
+BuildRequires: python-eventlet
+BuildRequires: python-simplejson
+BuildRequires: python-webob1.0
+BuildRequires: pyxattr
+
+%description doc
+OpenStack Object Storage (swift) aggregates commodity servers to work together
+in clusters for reliable, redundant, and large-scale storage of static objects.
+
+This package contains documentation files for %{name}.
+
+%prep
+%setup -q -n swift-%{version}
+%patch0 -p1 -b .newdeps
+%patch1 -p1 -b .docmod
+%patch2 -p1 -b .nonet
+%patch3 -p1 -b .gluster
+# Fix wrong-file-end-of-line-encoding warning
+dos2unix LICENSE
+
+%build
+%{__python} setup.py build
+# Fails unless we create the build directory
+mkdir -p doc/build
+# Build docs
+%if 0%{?fedora} >= 14
+%{__python} setup.py build_sphinx
+%endif
+#%if 0%{?rhel} >= 6
+#export PYTHONPATH="$( pwd ):$PYTHONPATH"
+#SPHINX_DEBUG=1 sphinx-1.0-build -b html doc/source doc/build/html
+#SPHINX_DEBUG=1 sphinx-1.0-build -b man doc/source doc/build/man
+#%endif
+# Fix hidden-file-or-dir warning
+#rm doc/build/html/.buildinfo
+
+%install
+rm -rf %{buildroot}
+%{__python} setup.py install -O1 --skip-build --root %{buildroot}
+# Init helper functions
+install -p -D -m 644 %{SOURCE1} %{buildroot}%{_datarootdir}/%{name}/functions
+# Init scripts
+install -p -D -m 755 %{SOURCE2} %{buildroot}%{_initrddir}/%{name}-account
+install -p -D -m 755 %{SOURCE4} %{buildroot}%{_initrddir}/%{name}-container
+install -p -D -m 755 %{SOURCE5} %{buildroot}%{_initrddir}/%{name}-object
+install -p -D -m 755 %{SOURCE6} %{buildroot}%{_initrddir}/%{name}-proxy
+# Remove tests
+rm -fr %{buildroot}/%{python_sitelib}/test
+# Misc other
+install -d -m 755 %{buildroot}%{_sysconfdir}/swift
+install -d -m 755 %{buildroot}%{_sysconfdir}/swift/account-server
+install -d -m 755 %{buildroot}%{_sysconfdir}/swift/container-server
+install -d -m 755 %{buildroot}%{_sysconfdir}/swift/object-server
+install -d -m 755 %{buildroot}%{_sysconfdir}/swift/proxy-server
+# Install pid directory
+install -d -m 755 %{buildroot}%{_localstatedir}/run/swift
+install -d -m 755 %{buildroot}%{_localstatedir}/run/swift/account-server
+install -d -m 755 %{buildroot}%{_localstatedir}/run/swift/container-server
+install -d -m 755 %{buildroot}%{_localstatedir}/run/swift/object-server
+install -d -m 755 %{buildroot}%{_localstatedir}/run/swift/proxy-server
+
+%clean
+rm -rf %{buildroot}
+
+%pre
+getent group swift >/dev/null || groupadd -r swift -g 160
+getent passwd swift >/dev/null || \
+useradd -r -g swift -u 160 -d %{_sharedstatedir}/swift -s /sbin/nologin \
+-c "OpenStack Swift Daemons" swift
+exit 0
+
+%post account
+/sbin/chkconfig --add %{name}-account
+
+%preun account
+if [ $1 = 0 ] ; then
+ /sbin/service %{name}-account stop >/dev/null 2>&1
+ /sbin/chkconfig --del %{name}-account
+fi
+
+%postun account
+if [ "$1" -ge "1" ] ; then
+ /sbin/service %{name}-account condrestart >/dev/null 2>&1 || :
+fi
+
+%post container
+/sbin/chkconfig --add %{name}-container
+
+%preun container
+if [ $1 = 0 ] ; then
+ /sbin/service %{name}-container stop >/dev/null 2>&1
+ /sbin/chkconfig --del %{name}-container
+fi
+
+%postun container
+if [ "$1" -ge "1" ] ; then
+ /sbin/service %{name}-container condrestart >/dev/null 2>&1 || :
+fi
+
+%post object
+/sbin/chkconfig --add %{name}-object
+
+%preun object
+if [ $1 = 0 ] ; then
+ /sbin/service %{name}-object stop >/dev/null 2>&1
+ /sbin/chkconfig --del %{name}-object
+fi
+
+%postun object
+if [ "$1" -ge "1" ] ; then
+ /sbin/service %{name}-object condrestart >/dev/null 2>&1 || :
+fi
+
+%post proxy
+/sbin/chkconfig --add %{name}-proxy
+
+%preun proxy
+if [ $1 = 0 ] ; then
+ /sbin/service %{name}-proxy stop >/dev/null 2>&1
+ /sbin/chkconfig --del %{name}-proxy
+fi
+
+%postun proxy
+if [ "$1" -ge "1" ] ; then
+ /sbin/service %{name}-proxy condrestart >/dev/null 2>&1 || :
+fi
+
+%files
+%defattr(-,root,root,-)
+%doc AUTHORS LICENSE README
+%doc etc/dispersion.conf-sample etc/drive-audit.conf-sample etc/object-expirer.conf-sample
+%doc etc/swift.conf-sample
+%dir %{_datarootdir}/%{name}/functions
+%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift
+%dir %{_sysconfdir}/swift
+%dir %{python_sitelib}/swift
+%{_bindir}/swift
+%{_bindir}/swift-account-audit
+%{_bindir}/swift-bench
+%{_bindir}/swift-drive-audit
+%{_bindir}/swift-get-nodes
+%{_bindir}/swift-init
+%{_bindir}/swift-ring-builder
+%{_bindir}/swift-dispersion-populate
+%{_bindir}/swift-dispersion-report
+%{_bindir}/swift-recon*
+%{_bindir}/swift-object-expirer
+%{_bindir}/swift-oldies
+%{_bindir}/swift-orphans
+%{_bindir}/swift-form-signature
+%{_bindir}/swift-temp-url
+%{python_sitelib}/swift/*.py*
+%{python_sitelib}/swift/common
+%{python_sitelib}/swift-%{version}-*.egg-info
+
+%files account
+%defattr(-,root,root,-)
+%doc etc/account-server.conf-sample
+%dir %{_initrddir}/%{name}-account
+%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift/account-server
+%dir %{_sysconfdir}/swift/account-server
+%{_bindir}/swift-account-auditor
+%{_bindir}/swift-account-reaper
+%{_bindir}/swift-account-replicator
+%{_bindir}/swift-account-server
+%{python_sitelib}/swift/account
+
+
+%files container
+%defattr(-,root,root,-)
+%doc etc/container-server.conf-sample
+%dir %{_initrddir}/%{name}-container
+%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift/container-server
+%dir %{_sysconfdir}/swift/container-server
+%{_bindir}/swift-container-auditor
+%{_bindir}/swift-container-server
+%{_bindir}/swift-container-replicator
+%{_bindir}/swift-container-updater
+%{_bindir}/swift-container-sync
+%{python_sitelib}/swift/container
+
+%files object
+%defattr(-,root,root,-)
+%doc etc/object-server.conf-sample etc/rsyncd.conf-sample
+%dir %{_initrddir}/%{name}-object
+%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift/object-server
+%dir %{_sysconfdir}/swift/object-server
+%{_bindir}/swift-object-auditor
+%{_bindir}/swift-object-info
+%{_bindir}/swift-object-replicator
+%{_bindir}/swift-object-server
+%{_bindir}/swift-object-updater
+%{python_sitelib}/swift/obj
+
+%files proxy
+%defattr(-,root,root,-)
+%doc etc/proxy-server.conf-sample
+%dir %{_initrddir}/%{name}-proxy
+%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift/proxy-server
+%dir %{_sysconfdir}/swift/proxy-server
+%{_bindir}/swift-proxy-server
+%{python_sitelib}/swift/proxy
+
+%files doc
+%defattr(-,root,root,-)
+%doc LICENSE
+#%doc doc/build/html
+
+%changelog
+* Thu Apr 26 2012 Anthony Towns <atowns@redhat.com> 1.4.8-2
+- Apply gluster patches
+- Rename to gluster-swift
+
+* Thu Mar 22 2012 Alan Pevec <apevec@redhat.com> 1.4.8-1
+- Update to 1.4.8
+
+* Fri Mar 09 2012 Alan Pevec <apevec@redhat.com> 1.4.7-1
+- Update to 1.4.7
+
+* Mon Feb 13 2012 Alan Pevec <apevec@redhat.com> 1.4.6-1
+- Update to 1.4.6
+
+* Thu Jan 12 2012 Alan Pevec <apevec@redhat.com> 1.4.4-2
+- add back /var/run/swift for el6
+
+* Wed Jan 04 2012 Alan Pevec <apevec@redhat.com> 1.4.4-1
+- Use updated parallel install versions of epel packages (pbrady)
+- Ensure the docs aren't built with the system glance module (pbrady)
+- Ensure we don't access the net when building docs (pbrady)
+- Update to 1.4.4
+
+* Wed Nov 23 2011 David Nalley <david@gnsa.us> -1.4.3-2
+* fixed some missing requires
+
+* Sat Nov 05 2011 David Nalley <david@gnsa.us> - 1.4.3-1
+- Update to 1.4.3
+- fix init script add, registration, deletion BZ 685155
+- fixing BR to facilitate epel6 building
+
+* Tue Aug 23 2011 David Nalley <david@gnsa.us> - 1.4.0-2
+- adding uid:gid for bz 732693
+
+* Wed Jun 22 2011 David Nalley <david@gnsa.us> - 1.4.1-1
+- Update to 1.4.0
+- change the name of swift binary from st to swift
+
+* Sat Jun 04 2011 David Nalley <david@gnsa.us> - 1.4.0-1
+- Update to 1.4.0
+
+* Fri May 20 2011 David Nalley <david@gnsa.us> - 1.3.0-1
+- Update to 1.3.0
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Sun Dec 05 2010 Silas Sewell <silas@sewell.ch> - 1.1.0-1
+- Update to 1.1.0
+
+* Sun Aug 08 2010 Silas Sewell <silas@sewell.ch> - 1.0.2-5
+- Update for new Python macro guidelines
+- Use dos2unix instead of sed
+- Make gecos field more descriptive
+
+* Wed Jul 28 2010 Silas Sewell <silas@sewell.ch> - 1.0.2-4
+- Rename to openstack-swift
+
+* Wed Jul 28 2010 Silas Sewell <silas@sewell.ch> - 1.0.2-3
+- Fix return value in swift-functions
+
+* Tue Jul 27 2010 Silas Sewell <silas@sewell.ch> - 1.0.2-2
+- Add swift user
+- Update init scripts
+
+* Sun Jul 18 2010 Silas Sewell <silas@sewell.ch> - 1.0.2-1
+- Initial build
diff --git a/swift/1.4.8/plugins/DiskDir.py b/swift/1.4.8/plugins/DiskDir.py
new file mode 100644
index 000000000..28671be3c
--- /dev/null
+++ b/swift/1.4.8/plugins/DiskDir.py
@@ -0,0 +1,484 @@
+# Copyright (c) 2011 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+
+from swift.plugins.utils import clean_metadata, dir_empty, rmdirs, mkdirs, \
+ validate_account, validate_container, check_valid_account, is_marker, \
+ get_container_details, get_account_details, create_container_metadata, \
+ create_account_metadata, DEFAULT_GID, DEFAULT_UID, get_account_details, \
+ validate_object, create_object_metadata, read_metadata, write_metadata
+
+from swift.common.constraints import CONTAINER_LISTING_LIMIT, \
+ check_mount
+
+from swift.plugins.utils import X_CONTENT_TYPE, X_CONTENT_LENGTH, X_TIMESTAMP,\
+ X_PUT_TIMESTAMP, X_TYPE, X_ETAG, X_OBJECTS_COUNT, X_BYTES_USED, \
+ X_CONTAINER_COUNT, CONTAINER
+
+from swift import plugins
+def strip_obj_storage_path(path, string='/mnt/gluster-object'):
+ """
+ strip /mnt/gluster-object
+ """
+ return path.replace(string, '').strip('/')
+
+DATADIR = 'containers'
+
+
+class DiskCommon(object):
+ def is_deleted(self):
+ return not os.path.exists(self.datadir)
+
+ def filter_prefix(self, objects, prefix):
+ """
+ Accept sorted list.
+ """
+ found = 0
+ filtered_objs = []
+ for object_name in objects:
+ if object_name.startswith(prefix):
+ filtered_objs.append(object_name)
+ found = 1
+ else:
+ if found:
+ break
+ return filtered_objs
+
+ def filter_delimiter(self, objects, delimiter, prefix):
+ """
+ Accept sorted list.
+ Objects should start with prefix.
+ """
+ filtered_objs=[]
+ for object_name in objects:
+ tmp_obj = object_name.replace(prefix, '', 1)
+ sufix = tmp_obj.split(delimiter, 1)
+ new_obj = prefix + sufix[0]
+ if new_obj and new_obj not in filtered_objs:
+ filtered_objs.append(new_obj)
+
+ return filtered_objs
+
+ def filter_marker(self, objects, marker):
+ """
+ TODO: We can traverse in reverse order to optimize.
+ Accept sorted list.
+ """
+ filtered_objs=[]
+ found = 0
+ if objects[-1] < marker:
+ return filtered_objs
+ for object_name in objects:
+ if object_name > marker:
+ filtered_objs.append(object_name)
+
+ return filtered_objs
+
+ def filter_end_marker(self, objects, end_marker):
+ """
+ Accept sorted list.
+ """
+ filtered_objs=[]
+ for object_name in objects:
+ if object_name < end_marker:
+ filtered_objs.append(object_name)
+ else:
+ break
+
+ return filtered_objs
+
+ def filter_limit(self, objects, limit):
+ filtered_objs=[]
+ for i in range(0, limit):
+ filtered_objs.append(objects[i])
+
+ return filtered_objs
+
+ def update_account(self, metadata):
+ acc_path = self.datadir
+ write_metadata(acc_path, metadata)
+ self.metadata = metadata
+
+class DiskDir(DiskCommon):
+ """
+ Manage object files on disk.
+
+ :param path: path to devices on the node
+ :param device: device name
+ :param partition: partition on the device the object lives in
+ :param account: account name for the object
+ :param container: container name for the object
+ :param obj: object name for the object
+ :param keep_data_fp: if True, don't close the fp, otherwise close it
+ :param disk_chunk_Size: size of chunks on file reads
+ """
+
+ def __init__(self, path, device, partition, account, container, logger,
+ uid=DEFAULT_UID, gid=DEFAULT_GID, fs_object=None):
+ self.root = path
+ device = account
+ if container:
+ self.name = container
+ else:
+ self.name = None
+ if self.name:
+ self.datadir = os.path.join(path, account, self.name)
+ else:
+ self.datadir = os.path.join(path, device)
+ self.account = account
+ self.device_path = os.path.join(path, device)
+ if not check_mount(path, device):
+ check_valid_account(account, fs_object)
+ self.logger = logger
+ self.metadata = {}
+ self.uid = int(uid)
+ self.gid = int(gid)
+ # Create a dummy db_file in /etc/swift
+ self.db_file = '/etc/swift/db_file.db'
+ if not os.path.exists(self.db_file):
+ file(self.db_file, 'w+')
+ self.dir_exists = os.path.exists(self.datadir)
+ if self.dir_exists:
+ try:
+ self.metadata = read_metadata(self.datadir)
+ except EOFError:
+ create_container_metadata(self.datadir)
+ else:
+ return
+ if container:
+ if not self.metadata:
+ create_container_metadata(self.datadir)
+ self.metadata = read_metadata(self.datadir)
+ else:
+ if not validate_container(self.metadata):
+ create_container_metadata(self.datadir)
+ self.metadata = read_metadata(self.datadir)
+ else:
+ if not self.metadata:
+ create_account_metadata(self.datadir)
+ self.metadata = read_metadata(self.datadir)
+ else:
+ if not validate_account(self.metadata):
+ create_account_metadata(self.datadir)
+ self.metadata = read_metadata(self.datadir)
+
+ def empty(self):
+ return dir_empty(self.datadir)
+
+ def delete(self):
+ if self.empty():
+ #For delete account.
+ if os.path.ismount(self.datadir):
+ clean_metadata(self.datadir)
+ else:
+ rmdirs(self.datadir)
+ self.dir_exists = False
+
+
+ def put_metadata(self, metadata):
+ """
+ Write metadata to directory/container.
+ """
+ write_metadata(self.datadir, metadata)
+ self.metadata = metadata
+
+ def put(self, metadata):
+ """
+ Create and write metatdata to directory/container.
+ :param metadata: Metadata to write.
+ """
+ if not self.dir_exists:
+ mkdirs(self.datadir)
+
+ os.chown(self.datadir, self.uid, self.gid)
+ write_metadata(self.datadir, metadata)
+ self.metadata = metadata
+ self.dir_exists = True
+
+ def put_obj(self, content_length, timestamp):
+ self.metadata[X_OBJECTS_COUNT] = int(self.metadata[X_OBJECTS_COUNT]) + 1
+ self.metadata[X_PUT_TIMESTAMP] = timestamp
+ self.metadata[X_BYTES_USED] = int(self.metadata[X_BYTES_USED]) + int(content_length)
+ #TODO: define update_metadata instad of writing whole metadata again.
+ self.put_metadata(self.metadata)
+
+ def delete_obj(self, content_length):
+ self.metadata[X_OBJECTS_COUNT] = int(self.metadata[X_OBJECTS_COUNT]) - 1
+ self.metadata[X_BYTES_USED] = int(self.metadata[X_BYTES_USED]) - int(content_length)
+ self.put_metadata(self.metadata)
+
+ def put_container(self, container, put_timestamp, del_timestamp, object_count, bytes_used):
+ """
+ For account server.
+ """
+ self.metadata[X_OBJECTS_COUNT] = 0
+ self.metadata[X_BYTES_USED] = 0
+ self.metadata[X_CONTAINER_COUNT] = int(self.metadata[X_CONTAINER_COUNT]) + 1
+ self.metadata[X_PUT_TIMESTAMP] = 1
+ self.put_metadata(self.metadata)
+
+ def delete_container(self, object_count, bytes_used):
+ """
+ For account server.
+ """
+ self.metadata[X_OBJECTS_COUNT] = 0
+ self.metadata[X_BYTES_USED] = 0
+ self.metadata[X_CONTAINER_COUNT] = int(self.metadata[X_CONTAINER_COUNT]) - 1
+ self.put_metadata(self.metadata)
+
+ def unlink(self):
+ """
+ Remove directory/container if empty.
+ """
+ if dir_empty(self.datadir):
+ rmdirs(self.datadir)
+
+ def list_objects_iter(self, limit, marker, end_marker,
+ prefix, delimiter, path):
+ """
+ Returns tuple of name, created_at, size, content_type, etag.
+ """
+ if path:
+ prefix = path = path.rstrip('/') + '/'
+ delimiter = '/'
+ if delimiter and not prefix:
+ prefix = ''
+
+ objects = []
+ object_count = 0
+ bytes_used = 0
+ container_list = []
+
+ objects, object_count, bytes_used = get_container_details(self.datadir)
+
+ if int(self.metadata[X_OBJECTS_COUNT]) != object_count or \
+ int(self.metadata[X_BYTES_USED]) != bytes_used:
+ self.metadata[X_OBJECTS_COUNT] = object_count
+ self.metadata[X_BYTES_USED] = bytes_used
+ self.update_container(self.metadata)
+
+ if objects:
+ objects.sort()
+
+ if objects and prefix:
+ objects = self.filter_prefix(objects, prefix)
+
+ if objects and delimiter:
+ objects = self.filter_delimiter(objects, delimiter, prefix)
+
+ if objects and marker:
+ objects = self.filter_marker(objects, marker)
+
+ if objects and end_marker:
+ objects = self.filter_end_marker(objects, end_marker)
+
+ if objects and limit:
+ if len(objects) > limit:
+ objects = self.filter_limit(objects, limit)
+
+ if objects:
+ for obj in objects:
+ list_item = []
+ list_item.append(obj)
+ metadata = read_metadata(self.datadir + '/' + obj)
+ if not metadata or not validate_object(metadata):
+ metadata = create_object_metadata(self.datadir + '/' + obj)
+ if metadata:
+ list_item.append(metadata[X_TIMESTAMP])
+ list_item.append(int(metadata[X_CONTENT_LENGTH]))
+ list_item.append(metadata[X_CONTENT_TYPE])
+ list_item.append(metadata[X_ETAG])
+ container_list.append(list_item)
+
+ return container_list
+
+ def update_container(self, metadata):
+ cont_path = self.datadir
+ write_metadata(cont_path, metadata)
+ self.metadata = metadata
+
+ def update_object_count(self):
+ objects = []
+ object_count = 0
+ bytes_used = 0
+ objects, object_count, bytes_used = get_container_details(self.datadir)
+
+
+ if int(self.metadata[X_OBJECTS_COUNT]) != object_count or \
+ int(self.metadata[X_BYTES_USED]) != bytes_used:
+ self.metadata[X_OBJECTS_COUNT] = object_count
+ self.metadata[X_BYTES_USED] = bytes_used
+ self.update_container(self.metadata)
+
+ def update_container_count(self):
+ containers = []
+ container_count = 0
+
+ containers, container_count = get_account_details(self.datadir)
+
+ if int(self.metadata[X_CONTAINER_COUNT]) != container_count:
+ self.metadata[X_CONTAINER_COUNT] = container_count
+ self.update_account(self.metadata)
+
+ def get_info(self, include_metadata=False):
+ """
+ Get global data for the container.
+ :returns: dict with keys: account, container, created_at,
+ put_timestamp, delete_timestamp, object_count, bytes_used,
+ reported_put_timestamp, reported_delete_timestamp,
+ reported_object_count, reported_bytes_used, hash, id,
+ x_container_sync_point1, and x_container_sync_point2.
+ If include_metadata is set, metadata is included as a key
+ pointing to a dict of tuples of the metadata
+ """
+ # TODO: delete_timestamp, reported_put_timestamp
+ # reported_delete_timestamp, reported_object_count,
+ # reported_bytes_used, created_at
+
+ metadata = {}
+ if os.path.exists(self.datadir):
+ metadata = read_metadata(self.datadir)
+
+ data = {'account' : self.account, 'container' : self.name,
+ 'object_count' : metadata.get(X_OBJECTS_COUNT, '0'),
+ 'bytes_used' : metadata.get(X_BYTES_USED, '0'),
+ 'hash': '', 'id' : '', 'created_at' : '1',
+ 'put_timestamp' : metadata.get(X_PUT_TIMESTAMP, '0'),
+ 'delete_timestamp' : '1',
+ 'reported_put_timestamp' : '1', 'reported_delete_timestamp' : '1',
+ 'reported_object_count' : '1', 'reported_bytes_used' : '1'}
+ if include_metadata:
+ data['metadata'] = metadata
+ return data
+
+ def put_object(self, name, timestamp, size, content_type,
+ etag, deleted=0):
+ # TODO: Implement the specifics of this func.
+ pass
+
+ def initialize(self, timestamp):
+ pass
+
+ def update_put_timestamp(self, timestamp):
+ """
+ Create the container if it doesn't exist and update the timestamp
+ """
+ if not os.path.exists(self.datadir):
+ self.put(self.metadata)
+
+ def delete_object(self, name, timestamp):
+ # TODO: Implement the delete object
+ pass
+
+ def delete_db(self, timestamp):
+ """
+ Delete the container
+ """
+ self.unlink()
+
+ def update_metadata(self, metadata):
+ self.metadata.update(metadata)
+ write_metadata(self.datadir, self.metadata)
+
+
+class DiskAccount(DiskDir):
+ def __init__(self, root, account, fs_object = None):
+ self.root = root
+ self.account = account
+ self.datadir = os.path.join(self.root, self.account)
+ if not check_mount(root, account):
+ check_valid_account(account, fs_object)
+ self.metadata = read_metadata(self.datadir)
+ if not self.metadata or not validate_account(self.metadata):
+ self.metadata = create_account_metadata(self.datadir)
+
+ def list_containers_iter(self, limit, marker, end_marker,
+ prefix, delimiter):
+ """
+ Return tuple of name, object_count, bytes_used, 0(is_subdir).
+ Used by account server.
+ """
+ if delimiter and not prefix:
+ prefix = ''
+ containers = []
+ container_count = 0
+ account_list = []
+
+ containers, container_count = get_account_details(self.datadir)
+
+ if int(self.metadata[X_CONTAINER_COUNT]) != container_count:
+ self.metadata[X_CONTAINER_COUNT] = container_count
+ self.update_account(self.metadata)
+
+ if containers:
+ containers.sort()
+
+ if containers and prefix:
+ containers = self.filter_prefix(containers, prefix)
+
+ if containers and delimiter:
+ containers = self.filter_delimiter(containers, delimiter, prefix)
+
+ if containers and marker:
+ containers = self.filter_marker(containers, marker)
+
+ if containers and end_marker:
+ containers = self.filter_end_marker(containers, end_marker)
+
+ if containers and limit:
+ if len(containers) > limit:
+ containers = self.filter_limit(containers, limit)
+
+ if containers:
+ for cont in containers:
+ list_item = []
+ metadata = None
+ list_item.append(cont)
+ metadata = read_metadata(self.datadir + '/' + cont)
+ if not metadata or not validate_container(metadata):
+ metadata = create_container_metadata(self.datadir + '/' + cont)
+
+ if metadata:
+ list_item.append(metadata[X_OBJECTS_COUNT])
+ list_item.append(metadata[X_BYTES_USED])
+ list_item.append(0)
+ account_list.append(list_item)
+
+ return account_list
+
+ def get_info(self, include_metadata=False):
+ """
+ Get global data for the account.
+ :returns: dict with keys: account, created_at, put_timestamp,
+ delete_timestamp, container_count, object_count,
+ bytes_used, hash, id
+ """
+ metadata = {}
+ if (os.path.exists(self.datadir)):
+ metadata = read_metadata(self.datadir)
+ if not metadata:
+ metadata = create_account_metadata(self.datadir)
+
+ data = {'account' : self.account, 'created_at' : '1',
+ 'put_timestamp' : '1', 'delete_timestamp' : '1',
+ 'container_count' : metadata.get(X_CONTAINER_COUNT, 0),
+ 'object_count' : metadata.get(X_OBJECTS_COUNT, 0),
+ 'bytes_used' : metadata.get(X_BYTES_USED, 0),
+ 'hash' : '', 'id' : ''}
+
+ if include_metadata:
+ data['metadata'] = metadata
+ return data
diff --git a/swift/1.4.8/plugins/DiskFile.py b/swift/1.4.8/plugins/DiskFile.py
new file mode 100644
index 000000000..6f77eaaa5
--- /dev/null
+++ b/swift/1.4.8/plugins/DiskFile.py
@@ -0,0 +1,316 @@
+# Copyright (c) 2011 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from eventlet import tpool
+from tempfile import mkstemp
+from contextlib import contextmanager
+from swift.common.utils import normalize_timestamp, renamer
+from swift.plugins.utils import mkdirs, rmdirs, validate_object, \
+ check_valid_account, create_object_metadata, do_open, \
+ do_close, do_unlink, do_chown, do_stat, do_listdir, read_metadata,\
+ write_metadata
+from swift.common.constraints import check_mount
+from swift.plugins.utils import X_CONTENT_TYPE, X_CONTENT_LENGTH, X_TIMESTAMP,\
+ X_PUT_TIMESTAMP, X_TYPE, X_ETAG, X_OBJECTS_COUNT, X_BYTES_USED, \
+ X_OBJECT_TYPE, FILE, DIR, MARKER_DIR, OBJECT, \
+ DIR_TYPE, FILE_TYPE, DEFAULT_UID, DEFAULT_GID
+
+import logging
+from swift.obj.server import DiskFile
+
+
+DATADIR = 'objects'
+ASYNCDIR = 'async_pending'
+KEEP_CACHE_SIZE = (5 * 1024 * 1024)
+# keep these lower-case
+DISALLOWED_HEADERS = set('content-length content-type deleted etag'.split())
+
+
+class Gluster_DiskFile(DiskFile):
+ """
+ Manage object files on disk.
+
+ :param path: path to devices on the node/mount path for UFO.
+ :param device: device name/account_name for UFO.
+ :param partition: partition on the device the object lives in
+ :param account: account name for the object
+ :param container: container name for the object
+ :param obj: object name for the object
+ :param keep_data_fp: if True, don't close the fp, otherwise close it
+ :param disk_chunk_Size: size of chunks on file reads
+ """
+
+ def __init__(self, path, device, partition, account, container, obj,
+ logger, keep_data_fp=False, disk_chunk_size=65536,
+ uid=DEFAULT_UID, gid=DEFAULT_GID, fs_object = None):
+ self.disk_chunk_size = disk_chunk_size
+ device = account
+ #Don't support obj_name ending/begining with '/', like /a, a/, /a/b/ etc
+ obj = obj.strip('/')
+ if '/' in obj:
+ self.obj_path, self.obj = obj.rsplit('/', 1)
+ else:
+ self.obj_path = ''
+ self.obj = obj
+
+ if self.obj_path:
+ self.name = '/'.join((container, self.obj_path))
+ else:
+ self.name = container
+ #Absolute path for obj directory.
+ self.datadir = os.path.join(path, device, self.name)
+
+ self.device_path = os.path.join(path, device)
+ if not check_mount(path, device):
+ check_valid_account(account, fs_object)
+
+ self.container_path = os.path.join(path, device, container)
+ self.tmpdir = os.path.join(path, device, 'tmp')
+ self.logger = logger
+ self.metadata = {}
+ self.meta_file = None
+ self.data_file = None
+ self.fp = None
+ self.iter_etag = None
+ self.started_at_0 = False
+ self.read_to_eof = False
+ self.quarantined_dir = None
+ self.keep_cache = False
+ self.is_dir = False
+ self.is_valid = True
+ self.uid = int(uid)
+ self.gid = int(gid)
+ if not os.path.exists(self.datadir + '/' + self.obj):
+ return
+
+ self.data_file = os.path.join(self.datadir, self.obj)
+ self.metadata = read_metadata(self.datadir + '/' + self.obj)
+ if not self.metadata:
+ create_object_metadata(self.datadir + '/' + self.obj)
+ self.metadata = read_metadata(self.datadir + '/' + self.obj)
+
+ if not validate_object(self.metadata):
+ create_object_metadata(self.datadir + '/' + self.obj)
+ self.metadata = read_metadata(self.datadir + '/' +
+ self.obj)
+
+ self.filter_metadata()
+
+ if os.path.isdir(self.datadir + '/' + self.obj):
+ self.is_dir = True
+ else:
+ self.fp = do_open(self.data_file, 'rb')
+ if not keep_data_fp:
+ self.close(verify_file=False)
+
+ def close(self, verify_file=True):
+ """
+ Close the file. Will handle quarantining file if necessary.
+
+ :param verify_file: Defaults to True. If false, will not check
+ file to see if it needs quarantining.
+ """
+ #Marker directory
+ if self.is_dir:
+ return
+ if self.fp:
+ do_close(self.fp)
+ self.fp = None
+
+ def is_deleted(self):
+ """
+ Check if the file is deleted.
+
+ :returns: True if the file doesn't exist or has been flagged as
+ deleted.
+ """
+ return not self.data_file
+
+ def create_dir_object(self, dir_path):
+ #TODO: if object already exists???
+ if os.path.exists(dir_path) and not os.path.isdir(dir_path):
+ self.logger.error("Deleting file %s", dir_path)
+ do_unlink(dir_path)
+ #If dir aleady exist just override metadata.
+ mkdirs(dir_path)
+ do_chown(dir_path, self.uid, self.gid)
+ create_object_metadata(dir_path)
+ return True
+
+
+
+ def put_metadata(self, metadata):
+ obj_path = self.datadir + '/' + self.obj
+ write_metadata(obj_path, metadata)
+ self.metadata = metadata
+
+
+ def put(self, fd, tmppath, metadata, extension=''):
+ """
+ Finalize writing the file on disk, and renames it from the temp file to
+ the real location. This should be called after the data has been
+ written to the temp file.
+
+ :params fd: file descriptor of the temp file
+ :param tmppath: path to the temporary file being used
+ :param metadata: dictionary of metadata to be written
+ :param extention: extension to be used when making the file
+ """
+ #Marker dir.
+ if extension == '.ts':
+ return True
+ if extension == '.meta':
+ self.put_metadata(metadata)
+ return True
+ else:
+ extension = ''
+ if metadata[X_OBJECT_TYPE] == MARKER_DIR:
+ self.create_dir_object(os.path.join(self.datadir, self.obj))
+ self.put_metadata(metadata)
+ self.data_file = self.datadir + '/' + self.obj
+ return True
+ #Check if directory already exists.
+ if self.is_dir:
+ self.logger.error('Directory already exists %s/%s' % \
+ (self.datadir , self.obj))
+ return False
+ #metadata['name'] = self.name
+ timestamp = normalize_timestamp(metadata[X_TIMESTAMP])
+ write_metadata(tmppath, metadata)
+ if X_CONTENT_LENGTH in metadata:
+ self.drop_cache(fd, 0, int(metadata[X_CONTENT_LENGTH]))
+ tpool.execute(os.fsync, fd)
+ if self.obj_path:
+ dir_objs = self.obj_path.split('/')
+ tmp_path = ''
+ if len(dir_objs):
+ for dir_name in dir_objs:
+ if tmp_path:
+ tmp_path = tmp_path + '/' + dir_name
+ else:
+ tmp_path = dir_name
+ if not self.create_dir_object(os.path.join(self.container_path,
+ tmp_path)):
+ self.logger.error("Failed in subdir %s",\
+ os.path.join(self.container_path,tmp_path))
+ return False
+
+ renamer(tmppath, os.path.join(self.datadir,
+ self.obj + extension))
+ do_chown(os.path.join(self.datadir, self.obj + extension), \
+ self.uid, self.gid)
+ self.metadata = metadata
+ #self.logger.error("Meta %s", self.metadata)
+ self.data_file = self.datadir + '/' + self.obj + extension
+ return True
+
+
+ def unlinkold(self, timestamp):
+ """
+ Remove any older versions of the object file. Any file that has an
+ older timestamp than timestamp will be deleted.
+
+ :param timestamp: timestamp to compare with each file
+ """
+ if self.metadata and self.metadata['X-Timestamp'] != timestamp:
+ self.unlink()
+
+ def unlink(self):
+ """
+ Remove the file.
+ """
+ #Marker dir.
+ if self.is_dir:
+ rmdirs(os.path.join(self.datadir, self.obj))
+ if not os.path.isdir(os.path.join(self.datadir, self.obj)):
+ self.metadata = {}
+ self.data_file = None
+ else:
+ logging.error('Unable to delete dir %s' % os.path.join(self.datadir, self.obj))
+ return
+
+ for fname in do_listdir(self.datadir):
+ if fname == self.obj:
+ try:
+ do_unlink(os.path.join(self.datadir, fname))
+ except OSError, err:
+ if err.errno != errno.ENOENT:
+ raise
+
+ #Remove entire path for object.
+ #remove_dir_path(self.obj_path, self.container_path)
+
+ self.metadata = {}
+ self.data_file = None
+
+ def get_data_file_size(self):
+ """
+ Returns the os.path.getsize for the file. Raises an exception if this
+ file does not match the Content-Length stored in the metadata. Or if
+ self.data_file does not exist.
+
+ :returns: file size as an int
+ :raises DiskFileError: on file size mismatch.
+ :raises DiskFileNotExist: on file not existing (including deleted)
+ """
+ #Marker directory.
+ if self.is_dir:
+ return 0
+ try:
+ file_size = 0
+ if self.data_file:
+ file_size = os.path.getsize(self.data_file)
+ if X_CONTENT_LENGTH in self.metadata:
+ metadata_size = int(self.metadata[X_CONTENT_LENGTH])
+ if file_size != metadata_size:
+ self.metadata[X_CONTENT_LENGTH] = file_size
+ self.update_object(self.metadata)
+
+ return file_size
+ except OSError, err:
+ if err.errno != errno.ENOENT:
+ raise
+ raise DiskFileNotExist('Data File does not exist.')
+
+ def update_object(self, metadata):
+ obj_path = self.datadir + '/' + self.obj
+ write_metadata(obj_path, metadata)
+ self.metadata = metadata
+
+ def filter_metadata(self):
+ if X_TYPE in self.metadata:
+ self.metadata.pop(X_TYPE)
+ if X_OBJECT_TYPE in self.metadata:
+ self.metadata.pop(X_OBJECT_TYPE)
+
+ @contextmanager
+ def mkstemp(self):
+ """Contextmanager to make a temporary file."""
+
+ if not os.path.exists(self.tmpdir):
+ mkdirs(self.tmpdir)
+ fd, tmppath = mkstemp(dir=self.tmpdir)
+ try:
+ yield fd, tmppath
+ finally:
+ try:
+ os.close(fd)
+ except OSError:
+ pass
+ try:
+ os.unlink(tmppath)
+ except OSError:
+ pass
diff --git a/swift/1.4.8/plugins/Glusterfs.py b/swift/1.4.8/plugins/Glusterfs.py
new file mode 100644
index 000000000..5e191e1bd
--- /dev/null
+++ b/swift/1.4.8/plugins/Glusterfs.py
@@ -0,0 +1,131 @@
+# Copyright (c) 2011 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+import os, fcntl, time
+from ConfigParser import ConfigParser
+from swift.common.utils import TRUE_VALUES
+from hashlib import md5
+from swift.plugins.utils import mkdirs
+
+class Glusterfs(object):
+ def __init__(self):
+ self.name = 'glusterfs'
+ self.fs_conf = ConfigParser()
+ self.fs_conf.read(os.path.join('/etc/swift', 'fs.conf'))
+ self.mount_path = self.fs_conf.get('DEFAULT', 'mount_path', '/mnt/gluster-object')
+ self.auth_account = self.fs_conf.get('DEFAULT', 'auth_account', 'auth')
+ self.mount_ip = self.fs_conf.get('DEFAULT', 'mount_ip', 'localhost')
+ self.remote_cluster = self.fs_conf.get('DEFAULT', 'remote_cluster', False) in TRUE_VALUES
+ self.object_only = self.fs_conf.get('DEFAULT', 'object_only', "no") in TRUE_VALUES
+
+ def busy_wait(self, mount_path):
+ # Iterate for definite number of time over a given
+ # interval for successful mount
+ for i in range(0, 5):
+ if os.path.ismount(os.path.join(mount_path)):
+ return True
+ time.sleep(2)
+ return False
+
+ def mount(self, account):
+ mount_path = os.path.join(self.mount_path, account)
+ export = self.get_export_from_account_id(account)
+
+ pid_dir = "/var/lib/glusterd/vols/%s/run/" %export
+ pid_file = os.path.join(pid_dir, 'swift.pid');
+
+ if not os.path.exists(pid_dir):
+ mkdirs(pid_dir)
+
+ fd = os.open(pid_file, os.O_CREAT|os.O_RDWR)
+ with os.fdopen(fd, 'r+b') as f:
+ try:
+ fcntl.lockf(f, fcntl.LOCK_EX|fcntl.LOCK_NB)
+ except:
+ ex = sys.exc_info()[1]
+ if isinstance(ex, IOError) and ex.errno in (EACCES, EAGAIN):
+ # This means that some other process is mounting the
+ # filesystem, so wait for the mount process to complete
+ return self.busy_wait(mount_path)
+
+ mnt_cmd = 'mount -t glusterfs %s:%s %s' % (self.mount_ip, export, \
+ mount_path)
+ if os.system(mnt_cmd) or not self.busy_wait(mount_path):
+ raise Exception('Mount failed %s: %s' % (self.name, mnt_cmd))
+ return False
+ return True
+
+ def unmount(self, mount_path):
+ umnt_cmd = 'umount %s 2>> /dev/null' % mount_path
+ if os.system(umnt_cmd):
+ logging.error('Unable to unmount %s %s' % (mount_path, self.name))
+
+ def get_export_list_local(self):
+ export_list = []
+ cmnd = 'gluster volume info'
+
+ if os.system(cmnd + ' >> /dev/null'):
+ raise Exception('Getting volume failed %s', self.name)
+ return export_list
+
+ fp = os.popen(cmnd)
+ while True:
+ item = fp.readline()
+ if not item:
+ break
+ item = item.strip('\n').strip(' ')
+ if item.lower().startswith('volume name:'):
+ export_list.append(item.split(':')[1].strip(' '))
+
+ return export_list
+
+
+ def get_export_list_remote(self):
+ export_list = []
+ cmnd = 'ssh %s gluster volume info' % self.mount_ip
+
+ if os.system(cmnd + ' >> /dev/null'):
+ raise Exception('Getting volume info failed %s, make sure to have \
+ passwordless ssh on %s', self.name, self.mount_ip)
+ return export_list
+
+ fp = os.popen(cmnd)
+ while True:
+ item = fp.readline()
+ if not item:
+ break
+ item = item.strip('\n').strip(' ')
+ if item.lower().startswith('volume name:'):
+ export_list.append(item.split(':')[1].strip(' '))
+
+ return export_list
+
+ def get_export_list(self):
+ if self.remote_cluster:
+ return self.get_export_list_remote()
+ else:
+ return self.get_export_list_local()
+
+ def get_export_from_account_id(self, account):
+ if not account:
+ print 'account is none, returning'
+ raise AttributeError
+
+ for export in self.get_export_list():
+ if account == 'AUTH_' + export:
+ return export
+
+ raise Exception('No export found %s %s' % (account, self.name))
+ return None
diff --git a/swift/1.4.8/plugins/__init__.py b/swift/1.4.8/plugins/__init__.py
new file mode 100644
index 000000000..3d98c960c
--- /dev/null
+++ b/swift/1.4.8/plugins/__init__.py
@@ -0,0 +1,16 @@
+# Copyright (c) 2011 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from Glusterfs import Glusterfs
diff --git a/swift/1.4.8/plugins/conf/account-server/1.conf b/swift/1.4.8/plugins/conf/account-server/1.conf
new file mode 100644
index 000000000..54cbf6540
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/account-server/1.conf
@@ -0,0 +1,22 @@
+[DEFAULT]
+devices = /srv/1/node
+mount_check = false
+bind_port = 6012
+user = root
+log_facility = LOG_LOCAL2
+
+[pipeline:main]
+pipeline = gluster account-server
+
+[app:account-server]
+use = egg:swift#account
+
+[filter:gluster]
+use = egg:swift#gluster
+
+[account-replicator]
+vm_test_mode = yes
+
+[account-auditor]
+
+[account-reaper]
diff --git a/swift/1.4.8/plugins/conf/account.builder b/swift/1.4.8/plugins/conf/account.builder
new file mode 100644
index 000000000..2943b9cfb
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/account.builder
Binary files differ
diff --git a/swift/1.4.8/plugins/conf/account.ring.gz b/swift/1.4.8/plugins/conf/account.ring.gz
new file mode 100644
index 000000000..e1a5e6ae2
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/account.ring.gz
Binary files differ
diff --git a/swift/1.4.8/plugins/conf/container-server/1.conf b/swift/1.4.8/plugins/conf/container-server/1.conf
new file mode 100644
index 000000000..9e776838f
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/container-server/1.conf
@@ -0,0 +1,24 @@
+[DEFAULT]
+devices = /srv/1/node
+mount_check = false
+bind_port = 6011
+user = root
+log_facility = LOG_LOCAL2
+
+[pipeline:main]
+pipeline = gluster container-server
+
+[app:container-server]
+use = egg:swift#container
+
+[filter:gluster]
+use = egg:swift#gluster
+
+[container-replicator]
+vm_test_mode = yes
+
+[container-updater]
+
+[container-auditor]
+
+[container-sync]
diff --git a/swift/1.4.8/plugins/conf/container.builder b/swift/1.4.8/plugins/conf/container.builder
new file mode 100644
index 000000000..6031d79df
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/container.builder
Binary files differ
diff --git a/swift/1.4.8/plugins/conf/container.ring.gz b/swift/1.4.8/plugins/conf/container.ring.gz
new file mode 100644
index 000000000..fdbcb18b2
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/container.ring.gz
Binary files differ
diff --git a/swift/1.4.8/plugins/conf/db_file.db b/swift/1.4.8/plugins/conf/db_file.db
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/db_file.db
diff --git a/swift/1.4.8/plugins/conf/fs.conf b/swift/1.4.8/plugins/conf/fs.conf
new file mode 100644
index 000000000..b6ec5121f
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/fs.conf
@@ -0,0 +1,9 @@
+[DEFAULT]
+mount_path = /mnt/gluster-object
+auth_account = auth
+#ip of the fs server.
+mount_ip = localhost
+#fs server need not be local, remote server can also be used,
+#set remote_cluster=yes for using remote server.
+remote_cluster = no
+object_only = no \ No newline at end of file
diff --git a/swift/1.4.8/plugins/conf/object-server/1.conf b/swift/1.4.8/plugins/conf/object-server/1.conf
new file mode 100644
index 000000000..f191cefcf
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/object-server/1.conf
@@ -0,0 +1,22 @@
+[DEFAULT]
+devices = /srv/1/node
+mount_check = false
+bind_port = 6010
+user = root
+log_facility = LOG_LOCAL2
+
+[pipeline:main]
+pipeline = gluster object-server
+
+[app:object-server]
+use = egg:swift#object
+
+[filter:gluster]
+use = egg:swift#gluster
+
+[object-replicator]
+vm_test_mode = yes
+
+[object-updater]
+
+[object-auditor]
diff --git a/swift/1.4.8/plugins/conf/object.builder b/swift/1.4.8/plugins/conf/object.builder
new file mode 100644
index 000000000..ce4535059
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/object.builder
Binary files differ
diff --git a/swift/1.4.8/plugins/conf/object.ring.gz b/swift/1.4.8/plugins/conf/object.ring.gz
new file mode 100644
index 000000000..73e88d589
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/object.ring.gz
Binary files differ
diff --git a/swift/1.4.8/plugins/conf/proxy-server.conf b/swift/1.4.8/plugins/conf/proxy-server.conf
new file mode 100644
index 000000000..1fcde8e0d
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/proxy-server.conf
@@ -0,0 +1,21 @@
+[DEFAULT]
+bind_port = 8080
+user = root
+log_facility = LOG_LOCAL1
+
+[pipeline:main]
+pipeline = healthcheck cache tempauth proxy-server
+
+[app:proxy-server]
+use = egg:swift#proxy
+allow_account_management = true
+account_autocreate = true
+
+[filter:tempauth]
+use = egg:swift#tempauth
+
+[filter:healthcheck]
+use = egg:swift#healthcheck
+
+[filter:cache]
+use = egg:swift#memcache
diff --git a/swift/1.4.8/plugins/conf/swift.conf b/swift/1.4.8/plugins/conf/swift.conf
new file mode 100644
index 000000000..f9864e352
--- /dev/null
+++ b/swift/1.4.8/plugins/conf/swift.conf
@@ -0,0 +1,7 @@
+[DEFAULT]
+Enable_plugin = yes
+
+[swift-hash]
+# random unique string that can never change (DO NOT LOSE)
+swift_hash_path_suffix = gluster
+
diff --git a/swift/1.4.8/plugins/constraints.py b/swift/1.4.8/plugins/constraints.py
new file mode 100644
index 000000000..6be853629
--- /dev/null
+++ b/swift/1.4.8/plugins/constraints.py
@@ -0,0 +1,97 @@
+# Copyright (c) 2011 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import logging
+from swift.common.constraints import check_utf8, check_metadata
+
+from webob.exc import HTTPBadRequest, HTTPLengthRequired, \
+ HTTPRequestEntityTooLarge
+
+
+#: Max file size allowed for objects
+MAX_FILE_SIZE = 0xffffffffffffffff
+#: Max length of the name of a key for metadata
+MAX_META_NAME_LENGTH = 128
+#: Max length of the value of a key for metadata
+MAX_META_VALUE_LENGTH = 256
+#: Max number of metadata items
+MAX_META_COUNT = 90
+#: Max overall size of metadata
+MAX_META_OVERALL_SIZE = 4096
+#: Max object name length
+MAX_OBJECT_NAME_LENGTH = 255
+#: Max object list length of a get request for a container
+CONTAINER_LISTING_LIMIT = 10000
+#: Max container list length of a get request for an account
+ACCOUNT_LISTING_LIMIT = 10000
+MAX_ACCOUNT_NAME_LENGTH = 255
+MAX_CONTAINER_NAME_LENGTH = 255
+
+def validate_obj_name(obj):
+ if len(obj) > MAX_OBJECT_NAME_LENGTH:
+ logging.error('Object name too long %s' % obj)
+ return False
+ if obj == '.' or obj == '..':
+ logging.error('Object name cannot be . or .. %s' % obj)
+ return False
+
+ return True
+
+def check_object_creation(req, object_name):
+ """
+ Check to ensure that everything is alright about an object to be created.
+
+ :param req: HTTP request object
+ :param object_name: name of object to be created
+ :raises HTTPRequestEntityTooLarge: the object is too large
+ :raises HTTPLengthRequered: missing content-length header and not
+ a chunked request
+ :raises HTTPBadRequest: missing or bad content-type header, or
+ bad metadata
+ """
+ if req.content_length and req.content_length > MAX_FILE_SIZE:
+ return HTTPRequestEntityTooLarge(body='Your request is too large.',
+ request=req, content_type='text/plain')
+ if req.content_length is None and \
+ req.headers.get('transfer-encoding') != 'chunked':
+ return HTTPLengthRequired(request=req)
+ if 'X-Copy-From' in req.headers and req.content_length:
+ return HTTPBadRequest(body='Copy requests require a zero byte body',
+ request=req, content_type='text/plain')
+ for obj in object_name.split('/'):
+ if not validate_obj_name(obj):
+ return HTTPBadRequest(body='Invalid object name %s' %
+ (obj), request=req,
+ content_type='text/plain')
+ if 'Content-Type' not in req.headers:
+ return HTTPBadRequest(request=req, content_type='text/plain',
+ body='No content type')
+ if not check_utf8(req.headers['Content-Type']):
+ return HTTPBadRequest(request=req, body='Invalid Content-Type',
+ content_type='text/plain')
+ if 'x-object-manifest' in req.headers:
+ value = req.headers['x-object-manifest']
+ container = prefix = None
+ try:
+ container, prefix = value.split('/', 1)
+ except ValueError:
+ pass
+ if not container or not prefix or '?' in value or '&' in value or \
+ prefix[0] == '/':
+ return HTTPBadRequest(request=req,
+ body='X-Object-Manifest must in the format container/prefix')
+ return check_metadata(req, 'object')
+
diff --git a/swift/1.4.8/plugins/utils.py b/swift/1.4.8/plugins/utils.py
new file mode 100644
index 000000000..d8fc7a436
--- /dev/null
+++ b/swift/1.4.8/plugins/utils.py
@@ -0,0 +1,679 @@
+# Copyright (c) 2011 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+import os
+import errno
+from hashlib import md5
+from swift.common.utils import normalize_timestamp
+from xattr import setxattr, removexattr, getxattr, removexattr
+import cPickle as pickle
+
+X_CONTENT_TYPE = 'Content-Type'
+X_CONTENT_LENGTH = 'Content-Length'
+X_TIMESTAMP = 'X-Timestamp'
+X_PUT_TIMESTAMP = 'X-PUT-Timestamp'
+X_TYPE = 'X-Type'
+X_ETAG = 'ETag'
+X_OBJECTS_COUNT = 'X-Object-Count'
+X_BYTES_USED = 'X-Bytes-Used'
+X_CONTAINER_COUNT = 'X-Container-Count'
+X_OBJECT_TYPE = 'X-Object-Type'
+DIR_TYPE = 'application/directory'
+ACCOUNT = 'Account'
+MOUNT_PATH = '/mnt/gluster-object'
+METADATA_KEY = 'user.swift.metadata'
+CONTAINER = 'container'
+DIR = 'dir'
+MARKER_DIR = 'marker_dir'
+FILE = 'file'
+DIR_TYPE = 'application/directory'
+FILE_TYPE = 'application/octet-stream'
+OBJECT = 'Object'
+OBJECT_TYPE = 'application/octet-stream'
+DEFAULT_UID = -1
+DEFAULT_GID = -1
+PICKLE_PROTOCOL = 2
+CHUNK_SIZE = 65536
+
+
+def mkdirs(path):
+ """
+ Ensures the path is a directory or makes it if not. Errors if the path
+ exists but is a file or on permissions failure.
+
+ :param path: path to create
+ """
+ if not os.path.isdir(path):
+ try:
+ do_makedirs(path)
+ except OSError, err:
+ #TODO: check, isdir will fail if mounted and volume stopped.
+ #if err.errno != errno.EEXIST or not os.path.isdir(path)
+ if err.errno != errno.EEXIST:
+ raise
+
+def rmdirs(path):
+ if os.path.isdir(path) and dir_empty(path):
+ do_rmdir(path)
+ else:
+ logging.error("rmdirs failed dir may not be empty or not valid dir")
+ return False
+
+def strip_obj_storage_path(path, string='/mnt/gluster-object'):
+ """
+ strip /mnt/gluster-object
+ """
+ return path.replace(string, '').strip('/')
+
+def do_mkdir(path):
+ try:
+ os.mkdir(path)
+ except Exception, err:
+ logging.exception("Mkdir failed on %s err: %s", path, str(err))
+ if err.errno != errno.EEXIST:
+ raise
+ return True
+
+def do_makedirs(path):
+ try:
+ os.makedirs(path)
+ except Exception, err:
+ logging.exception("Makedirs failed on %s err: %s", path, str(err))
+ if err.errno != errno.EEXIST:
+ raise
+ return True
+
+
+def do_listdir(path):
+ try:
+ buf = os.listdir(path)
+ except Exception, err:
+ logging.exception("Listdir failed on %s err: %s", path, str(err))
+ raise
+ return buf
+
+def do_chown(path, uid, gid):
+ try:
+ os.chown(path, uid, gid)
+ except Exception, err:
+ logging.exception("Chown failed on %s err: %s", path, str(err))
+ raise
+ return True
+
+def do_stat(path):
+ try:
+ #Check for fd.
+ if isinstance(path, int):
+ buf = os.fstat(path)
+ else:
+ buf = os.stat(path)
+ except Exception, err:
+ logging.exception("Stat failed on %s err: %s", path, str(err))
+ raise
+
+ return buf
+
+def do_open(path, mode):
+ try:
+ fd = open(path, mode)
+ except Exception, err:
+ logging.exception("Open failed on %s err: %s", path, str(err))
+ raise
+ return fd
+
+def do_close(fd):
+ #fd could be file or int type.
+ try:
+ if isinstance(fd, int):
+ os.close(fd)
+ else:
+ fd.close()
+ except Exception, err:
+ logging.exception("Close failed on %s err: %s", fd, str(err))
+ raise
+ return True
+
+def do_unlink(path, log = True):
+ try:
+ os.unlink(path)
+ except Exception, err:
+ if log:
+ logging.exception("Unlink failed on %s err: %s", path, str(err))
+ if err.errno != errno.ENOENT:
+ raise
+ return True
+
+def do_rmdir(path):
+ try:
+ os.rmdir(path)
+ except Exception, err:
+ logging.exception("Rmdir failed on %s err: %s", path, str(err))
+ if err.errno != errno.ENOENT:
+ raise
+ return True
+
+def do_rename(old_path, new_path):
+ try:
+ os.rename(old_path, new_path)
+ except Exception, err:
+ logging.exception("Rename failed on %s to %s err: %s", old_path, new_path, \
+ str(err))
+ raise
+ return True
+
+def do_setxattr(path, key, value):
+ fd = None
+ if not os.path.isdir(path):
+ fd = do_open(path, 'rb')
+ else:
+ fd = path
+ if fd or os.path.isdir(path):
+ try:
+ setxattr(fd, key, value)
+ except Exception, err:
+ logging.exception("setxattr failed on %s key %s err: %s", path, key, str(err))
+ raise
+ finally:
+ if fd and not os.path.isdir(path):
+ do_close(fd)
+ else:
+ logging.error("Open failed path %s", path)
+ return False
+ return True
+
+
+
+def do_getxattr(path, key, log = True):
+ fd = None
+ if not os.path.isdir(path):
+ fd = do_open(path, 'rb')
+ else:
+ fd = path
+ if fd or os.path.isdir(path):
+ try:
+ value = getxattr(fd, key)
+ except Exception, err:
+ if log:
+ logging.exception("getxattr failed on %s key %s err: %s", path, key, str(err))
+ raise
+ finally:
+ if fd and not os.path.isdir(path):
+ do_close(fd)
+ else:
+ logging.error("Open failed path %s", path)
+ return False
+ return value
+
+def do_removexattr(path, key):
+ fd = None
+ if not os.path.isdir(path):
+ fd = do_open(path, 'rb')
+ else:
+ fd = path
+ if fd or os.path.isdir(path):
+ try:
+ removexattr(fd, key)
+ except Exception, err:
+ logging.exception("removexattr failed on %s key %s err: %s", path, key, str(err))
+ raise
+ finally:
+ if fd and not os.path.isdir(path):
+ do_close(fd)
+ else:
+ logging.error("Open failed path %s", path)
+ return False
+ return True
+
+def read_metadata(path):
+ """
+ Helper function to read the pickled metadata from a File/Directory .
+
+ :param path: File/Directory to read metadata from.
+
+ :returns: dictionary of metadata
+ """
+ metadata = ''
+ key = 0
+ while True:
+ try:
+ metadata += do_getxattr(path, '%s%s' % (METADATA_KEY, (key or '')),
+ log = False)
+ except Exception:
+ break
+ key += 1
+ if metadata:
+ return pickle.loads(metadata)
+ else:
+ return {}
+
+
+def write_metadata(path, metadata):
+ """
+ Helper function to write pickled metadata for a File/Directory.
+
+ :param path: File/Directory path to write the metadata
+ :param metadata: metadata to write
+ """
+ metastr = pickle.dumps(metadata, PICKLE_PROTOCOL)
+ key = 0
+ while metastr:
+ do_setxattr(path, '%s%s' % (METADATA_KEY, key or ''), metastr[:254])
+ metastr = metastr[254:]
+ key += 1
+
+def clean_metadata(path):
+ key = 0
+ while True:
+ value = do_getxattr(path, '%s%s' % (METADATA_KEY, (key or '')))
+ do_removexattr(path, '%s%s' % (METADATA_KEY, (key or '')))
+ key += 1
+
+
+def dir_empty(path):
+ """
+ Return true if directory/container is empty.
+ :param path: Directory path.
+ :returns: True/False.
+ """
+ if os.path.isdir(path):
+ try:
+ files = do_listdir(path)
+ except Exception, err:
+ logging.exception("listdir failed on %s err: %s", path, str(err))
+ raise
+ if not files:
+ return True
+ else:
+ return False
+ else:
+ if not os.path.exists(path):
+ return True
+
+
+def get_device_from_account(account):
+ if account.startswith(RESELLER_PREFIX):
+ device = account.replace(RESELLER_PREFIX, '', 1)
+ return device
+
+def check_user_xattr(path):
+ if not os.path.exists(path):
+ return False
+ do_setxattr(path, 'user.test.key1', 'value1')
+ try:
+ removexattr(path, 'user.test.key1')
+ except Exception, err:
+ logging.exception("removexattr failed on %s err: %s", path, str(err))
+ #Remove xattr may fail in case of concurrent remove.
+ return True
+
+
+def _check_valid_account(account, fs_object):
+ mount_path = getattr(fs_object, 'mount_path', MOUNT_PATH)
+
+ if os.path.ismount(os.path.join(mount_path, account)):
+ return True
+
+ if not check_account_exists(fs_object.get_export_from_account_id(account), fs_object):
+ logging.error('Account not present %s', account)
+ return False
+
+ if not os.path.isdir(os.path.join(mount_path, account)):
+ mkdirs(os.path.join(mount_path, account))
+
+ if fs_object:
+ if not fs_object.mount(account):
+ return False
+
+ return True
+
+def check_valid_account(account, fs_object):
+ return _check_valid_account(account, fs_object)
+
+def validate_container(metadata):
+ if not metadata:
+ logging.error('No metadata')
+ return False
+
+ if X_TYPE not in metadata.keys() or \
+ X_TIMESTAMP not in metadata.keys() or \
+ X_PUT_TIMESTAMP not in metadata.keys() or \
+ X_OBJECTS_COUNT not in metadata.keys() or \
+ X_BYTES_USED not in metadata.keys():
+ #logging.error('Container error %s' % metadata)
+ return False
+
+ if metadata[X_TYPE] == CONTAINER:
+ return True
+
+ logging.error('Container error %s' % metadata)
+ return False
+
+def validate_account(metadata):
+ if not metadata:
+ logging.error('No metadata')
+ return False
+
+ if X_TYPE not in metadata.keys() or \
+ X_TIMESTAMP not in metadata.keys() or \
+ X_PUT_TIMESTAMP not in metadata.keys() or \
+ X_OBJECTS_COUNT not in metadata.keys() or \
+ X_BYTES_USED not in metadata.keys() or \
+ X_CONTAINER_COUNT not in metadata.keys():
+ #logging.error('Account error %s' % metadata)
+ return False
+
+ if metadata[X_TYPE] == ACCOUNT:
+ return True
+
+ logging.error('Account error %s' % metadata)
+ return False
+
+def validate_object(metadata):
+ if not metadata:
+ logging.error('No metadata')
+ return False
+
+ if X_TIMESTAMP not in metadata.keys() or \
+ X_CONTENT_TYPE not in metadata.keys() or \
+ X_ETAG not in metadata.keys() or \
+ X_CONTENT_LENGTH not in metadata.keys() or \
+ X_TYPE not in metadata.keys() or \
+ X_OBJECT_TYPE not in metadata.keys():
+ #logging.error('Object error %s' % metadata)
+ return False
+
+ if metadata[X_TYPE] == OBJECT:
+ return True
+
+ logging.error('Object error %s' % metadata)
+ return False
+
+def is_marker(metadata):
+ if not metadata:
+ logging.error('No metadata')
+ return False
+
+ if X_OBJECT_TYPE not in metadata.keys():
+ logging.error('X_OBJECT_TYPE missing %s' % metadata)
+ return False
+
+ if metadata[X_OBJECT_TYPE] == MARKER_DIR:
+ return True
+ else:
+ return False
+
+def _update_list(path, const_path, src_list, reg_file=True, object_count=0,
+ bytes_used=0, obj_list=[]):
+ obj_path = strip_obj_storage_path(path, const_path)
+
+ for i in src_list:
+ if obj_path:
+ obj_list.append(os.path.join(obj_path, i))
+ else:
+ obj_list.append(i)
+
+ object_count += 1
+
+ if reg_file:
+ bytes_used += os.path.getsize(path + '/' + i)
+
+ return object_count, bytes_used
+
+def update_list(path, const_path, dirs=[], files=[], object_count=0,
+ bytes_used=0, obj_list=[]):
+ object_count, bytes_used = _update_list (path, const_path, files, True,
+ object_count, bytes_used,
+ obj_list)
+ object_count, bytes_used = _update_list (path, const_path, dirs, False,
+ object_count, bytes_used,
+ obj_list)
+ return object_count, bytes_used
+
+def get_container_details_from_fs(cont_path, const_path,
+ memcache=None):
+ """
+ get container details by traversing the filesystem
+ """
+ bytes_used = 0
+ object_count = 0
+ obj_list=[]
+ dir_list = []
+
+ if os.path.isdir(cont_path):
+ for (path, dirs, files) in os.walk(cont_path):
+ object_count, bytes_used = update_list(path, const_path, dirs, files,
+ object_count, bytes_used,
+ obj_list)
+
+ dir_list.append(path + ':' + str(do_stat(path).st_mtime))
+
+ if memcache:
+ memcache.set(strip_obj_storage_path(cont_path), obj_list)
+ memcache.set(strip_obj_storage_path(cont_path) + '-dir_list',
+ ','.join(dir_list))
+ memcache.set(strip_obj_storage_path(cont_path) + '-cont_meta',
+ [object_count, bytes_used])
+
+ return obj_list, object_count, bytes_used
+
+def get_container_details_from_memcache(cont_path, const_path,
+ memcache):
+ """
+ get container details stored in memcache
+ """
+
+ bytes_used = 0
+ object_count = 0
+ obj_list=[]
+
+ dir_contents = memcache.get(strip_obj_storage_path(cont_path) + '-dir_list')
+ if not dir_contents:
+ return get_container_details_from_fs(cont_path, const_path,
+ memcache=memcache)
+
+ for i in dir_contents.split(','):
+ path, mtime = i.split(':')
+ if mtime != str(do_stat(path).st_mtime):
+ return get_container_details_from_fs(cont_path, const_path,
+ memcache=memcache)
+
+ obj_list = memcache.get(strip_obj_storage_path(cont_path))
+
+ object_count, bytes_used = memcache.get(strip_obj_storage_path(cont_path) + '-cont_meta')
+
+ return obj_list, object_count, bytes_used
+
+def get_container_details(cont_path, memcache=None):
+ """
+ Return object_list, object_count and bytes_used.
+ """
+ if memcache:
+ object_list, object_count, bytes_used = get_container_details_from_memcache(cont_path, cont_path,
+ memcache=memcache)
+ else:
+ object_list, object_count, bytes_used = get_container_details_from_fs(cont_path, cont_path)
+
+ return object_list, object_count, bytes_used
+
+def get_account_details_from_fs(acc_path, memcache=None):
+ container_list = []
+ container_count = 0
+
+ if os.path.isdir(acc_path):
+ for name in do_listdir(acc_path):
+ if not os.path.isdir(acc_path + '/' + name) or \
+ name.lower() == 'tmp' or name.lower() == 'async_pending':
+ continue
+ container_count += 1
+ container_list.append(name)
+
+ if memcache:
+ memcache.set(strip_obj_storage_path(acc_path) + '_container_list', container_list)
+ memcache.set(strip_obj_storage_path(acc_path)+'_mtime', str(do_stat(acc_path).st_mtime))
+ memcache.set(strip_obj_storage_path(acc_path)+'_container_count', container_count)
+
+ return container_list, container_count
+
+def get_account_details_from_memcache(acc_path, memcache=None):
+ if memcache:
+ mtime = memcache.get(strip_obj_storage_path(acc_path)+'_mtime')
+ if not mtime or mtime != str(do_stat(acc_path).st_mtime):
+ return get_account_details_from_fs(acc_path, memcache)
+ container_list = memcache.get(strip_obj_storage_path(acc_path) + '_container_list')
+ container_count = memcache.get(strip_obj_storage_path(acc_path)+'_container_count')
+ return container_list, container_count
+
+
+def get_account_details(acc_path, memcache=None):
+ """
+ Return container_list and container_count.
+ """
+ if memcache:
+ return get_account_details_from_memcache(acc_path, memcache)
+ else:
+ return get_account_details_from_fs(acc_path, memcache)
+
+
+
+def get_etag(path):
+ etag = None
+ if os.path.exists(path):
+ etag = md5()
+ if not os.path.isdir(path):
+ fp = open(path, 'rb')
+ if fp:
+ while True:
+ chunk = fp.read(CHUNK_SIZE)
+ if chunk:
+ etag.update(chunk)
+ else:
+ break
+ fp.close()
+
+ etag = etag.hexdigest()
+
+ return etag
+
+
+def get_object_metadata(obj_path):
+ """
+ Return metadata of object.
+ """
+ metadata = {}
+ if os.path.exists(obj_path):
+ if not os.path.isdir(obj_path):
+ metadata = {
+ X_TIMESTAMP: normalize_timestamp(os.path.getctime(obj_path)),
+ X_CONTENT_TYPE: FILE_TYPE,
+ X_ETAG: get_etag(obj_path),
+ X_CONTENT_LENGTH: os.path.getsize(obj_path),
+ X_TYPE: OBJECT,
+ X_OBJECT_TYPE: FILE,
+ }
+ else:
+ metadata = {
+ X_TIMESTAMP: normalize_timestamp(os.path.getctime(obj_path)),
+ X_CONTENT_TYPE: DIR_TYPE,
+ X_ETAG: get_etag(obj_path),
+ X_CONTENT_LENGTH: 0,
+ X_TYPE: OBJECT,
+ X_OBJECT_TYPE: DIR,
+ }
+
+ return metadata
+
+def get_container_metadata(cont_path, memcache=None):
+ objects = []
+ object_count = 0
+ bytes_used = 0
+ objects, object_count, bytes_used = get_container_details(cont_path,
+ memcache=memcache)
+ metadata = {X_TYPE: CONTAINER,
+ X_TIMESTAMP: normalize_timestamp(os.path.getctime(cont_path)),
+ X_PUT_TIMESTAMP: normalize_timestamp(os.path.getmtime(cont_path)),
+ X_OBJECTS_COUNT: object_count,
+ X_BYTES_USED: bytes_used}
+ return metadata
+
+def get_account_metadata(acc_path, memcache=None):
+ containers = []
+ container_count = 0
+ containers, container_count = get_account_details(acc_path, memcache)
+ metadata = {X_TYPE: ACCOUNT,
+ X_TIMESTAMP: normalize_timestamp(os.path.getctime(acc_path)),
+ X_PUT_TIMESTAMP: normalize_timestamp(os.path.getmtime(acc_path)),
+ X_OBJECTS_COUNT: 0,
+ X_BYTES_USED: 0,
+ X_CONTAINER_COUNT: container_count}
+ return metadata
+
+def restore_object(obj_path, metadata):
+ meta = read_metadata(obj_path)
+ if meta:
+ meta.update(metadata)
+ write_metadata(obj_path, meta)
+ else:
+ write_metadata(obj_path, metadata)
+
+def restore_container(cont_path, metadata):
+ meta = read_metadata(cont_path)
+ if meta:
+ meta.update(metadata)
+ write_metadata(cont_path, meta)
+ else:
+ write_metadata(cont_path, metadata)
+
+def restore_account(acc_path, metadata):
+ meta = read_metadata(acc_path)
+ if meta:
+ meta.update(metadata)
+ write_metadata(acc_path, meta)
+ else:
+ write_metadata(acc_path, metadata)
+
+def create_object_metadata(obj_path):
+ meta = get_object_metadata(obj_path)
+ restore_object(obj_path, meta)
+ return meta
+
+def create_container_metadata(cont_path, memcache=None):
+ meta = get_container_metadata(cont_path, memcache)
+ restore_container(cont_path, meta)
+ return meta
+
+def create_account_metadata(acc_path, memcache=None):
+ meta = get_account_metadata(acc_path, memcache)
+ restore_account(acc_path, meta)
+ return meta
+
+
+def check_account_exists(account, fs_object):
+ if account not in get_account_list(fs_object):
+ logging.error('Account not exists %s' % account)
+ return False
+ else:
+ return True
+
+def get_account_list(fs_object):
+ account_list = []
+ if fs_object:
+ account_list = fs_object.get_export_list()
+ return account_list
+
+
+def get_account_id(account):
+ return RESELLER_PREFIX + md5(account + HASH_PATH_SUFFIX).hexdigest()
+
diff --git a/swift/1.4.8/swift.diff b/swift/1.4.8/swift.diff
new file mode 100644
index 000000000..8ed5070e1
--- /dev/null
+++ b/swift/1.4.8/swift.diff
@@ -0,0 +1,797 @@
+diff --git a/setup.py b/setup.py
+index d195d34..b5b5ca2 100644
+--- a/setup.py
++++ b/setup.py
+@@ -1,5 +1,6 @@
+ #!/usr/bin/python
+ # Copyright (c) 2010-2012 OpenStack, LLC.
++# Copyright (c) 2011 Red Hat, Inc.
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+@@ -94,6 +95,7 @@ setup(
+ 'tempurl=swift.common.middleware.tempurl:filter_factory',
+ 'formpost=swift.common.middleware.formpost:filter_factory',
+ 'name_check=swift.common.middleware.name_check:filter_factory',
++ 'gluster=swift.common.middleware.gluster:filter_factory',
+ ],
+ },
+ )
+diff --git a/swift/account/server.py b/swift/account/server.py
+index 800b3c0..cb17970 100644
+--- a/swift/account/server.py
++++ b/swift/account/server.py
+@@ -1,4 +1,5 @@
+ # Copyright (c) 2010-2012 OpenStack, LLC.
++# Copyright (c) 2011 Red Hat, Inc.
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+@@ -31,7 +32,7 @@ import simplejson
+
+ from swift.common.db import AccountBroker
+ from swift.common.utils import get_logger, get_param, hash_path, \
+- normalize_timestamp, split_path, storage_directory
++ normalize_timestamp, split_path, storage_directory, plugin_enabled
+ from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \
+ check_mount, check_float, check_utf8
+ from swift.common.db_replicator import ReplicatorRpc
+@@ -39,6 +40,8 @@ from swift.common.db_replicator import ReplicatorRpc
+
+ DATADIR = 'accounts'
+
++if plugin_enabled():
++ from swift.plugins.DiskDir import DiskAccount
+
+ class AccountController(object):
+ """WSGI controller for the account server."""
+@@ -52,8 +55,12 @@ class AccountController(object):
+ self.mount_check, logger=self.logger)
+ self.auto_create_account_prefix = \
+ conf.get('auto_create_account_prefix') or '.'
++ self.fs_object = None
+
+ def _get_account_broker(self, drive, part, account):
++ if self.fs_object:
++ return DiskAccount(self.root, account, self.fs_object);
++
+ hsh = hash_path(account)
+ db_dir = storage_directory(DATADIR, part, hsh)
+ db_path = os.path.join(self.root, drive, db_dir, hsh + '.db')
+@@ -121,9 +128,15 @@ class AccountController(object):
+ if broker.is_deleted():
+ return HTTPConflict(request=req)
+ metadata = {}
+- metadata.update((key, (value, timestamp))
+- for key, value in req.headers.iteritems()
+- if key.lower().startswith('x-account-meta-'))
++ if not self.fs_object:
++ metadata.update((key, (value, timestamp))
++ for key, value in req.headers.iteritems()
++ if key.lower().startswith('x-account-meta-'))
++ else:
++ metadata.update((key, value)
++ for key, value in req.headers.iteritems()
++ if key.lower().startswith('x-account-meta-'))
++
+ if metadata:
+ broker.update_metadata(metadata)
+ if created:
+@@ -153,6 +166,9 @@ class AccountController(object):
+ broker.stale_reads_ok = True
+ if broker.is_deleted():
+ return HTTPNotFound(request=req)
++ if self.fs_object and not self.fs_object.object_only:
++ broker.list_containers_iter(None, None,None,
++ None, None)
+ info = broker.get_info()
+ headers = {
+ 'X-Account-Container-Count': info['container_count'],
+@@ -164,9 +180,16 @@ class AccountController(object):
+ container_ts = broker.get_container_timestamp(container)
+ if container_ts is not None:
+ headers['X-Container-Timestamp'] = container_ts
+- headers.update((key, value)
+- for key, (value, timestamp) in broker.metadata.iteritems()
+- if value != '')
++ if not self.fs_object:
++ headers.update((key, value)
++ for key, (value, timestamp) in broker.metadata.iteritems()
++ if value != '')
++ else:
++ headers.update((key, value)
++ for key, value in broker.metadata.iteritems()
++ if value != '')
++
++
+ return HTTPNoContent(request=req, headers=headers)
+
+ def GET(self, req):
+@@ -190,9 +213,15 @@ class AccountController(object):
+ 'X-Account-Bytes-Used': info['bytes_used'],
+ 'X-Timestamp': info['created_at'],
+ 'X-PUT-Timestamp': info['put_timestamp']}
+- resp_headers.update((key, value)
+- for key, (value, timestamp) in broker.metadata.iteritems()
+- if value != '')
++ if not self.fs_object:
++ resp_headers.update((key, value)
++ for key, (value, timestamp) in broker.metadata.iteritems()
++ if value != '')
++ else:
++ resp_headers.update((key, value)
++ for key, value in broker.metadata.iteritems()
++ if value != '')
++
+ try:
+ prefix = get_param(req, 'prefix')
+ delimiter = get_param(req, 'delimiter')
+@@ -224,6 +253,7 @@ class AccountController(object):
+ content_type='text/plain', request=req)
+ account_list = broker.list_containers_iter(limit, marker, end_marker,
+ prefix, delimiter)
++
+ if out_content_type == 'application/json':
+ json_pattern = ['"name":%s', '"count":%s', '"bytes":%s']
+ json_pattern = '{' + ','.join(json_pattern) + '}'
+@@ -298,15 +328,29 @@ class AccountController(object):
+ return HTTPNotFound(request=req)
+ timestamp = normalize_timestamp(req.headers['x-timestamp'])
+ metadata = {}
+- metadata.update((key, (value, timestamp))
+- for key, value in req.headers.iteritems()
+- if key.lower().startswith('x-account-meta-'))
++ if not self.fs_object:
++ metadata.update((key, (value, timestamp))
++ for key, value in req.headers.iteritems()
++ if key.lower().startswith('x-account-meta-'))
++ else:
++ metadata.update((key, value)
++ for key, value in req.headers.iteritems()
++ if key.lower().startswith('x-account-meta-'))
+ if metadata:
+ broker.update_metadata(metadata)
+ return HTTPNoContent(request=req)
+
++ def plugin(self, env):
++ if env.get('Gluster_enabled', False):
++ self.fs_object = env.get('fs_object')
++ self.root = env.get('root')
++ self.mount_check = False
++ else:
++ self.fs_object = None
++
+ def __call__(self, env, start_response):
+ start_time = time.time()
++ self.plugin(env)
+ req = Request(env)
+ self.logger.txn_id = req.headers.get('x-trans-id', None)
+ if not check_utf8(req.path_info):
+diff --git a/swift/common/middleware/gluster.py b/swift/common/middleware/gluster.py
+new file mode 100644
+index 0000000..341285d
+--- /dev/null
++++ b/swift/common/middleware/gluster.py
+@@ -0,0 +1,55 @@
++# Copyright (c) 2011 Red Hat, Inc.
++#
++# Licensed under the Apache License, Version 2.0 (the "License");
++# you may not use this file except in compliance with the License.
++# You may obtain a copy of the License at
++#
++# http://www.apache.org/licenses/LICENSE-2.0
++#
++# Unless required by applicable law or agreed to in writing, software
++# distributed under the License is distributed on an "AS IS" BASIS,
++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++# implied.
++# See the License for the specific language governing permissions and
++# limitations under the License.
++
++from swift.common.utils import get_logger, plugin_enabled
++from swift import plugins
++from ConfigParser import ConfigParser
++
++class Gluster_plugin(object):
++ """
++ Update the environment with keys that reflect Gluster_plugin enabled
++ """
++
++ def __init__(self, app, conf):
++ self.app = app
++ self.conf = conf
++ self.fs_name = 'Glusterfs'
++ self.logger = get_logger(conf, log_route='gluster')
++
++ def __call__(self, env, start_response):
++ if not plugin_enabled():
++ return self.app(env, start_response)
++ env['Gluster_enabled'] =True
++ fs_object = getattr(plugins, self.fs_name, False)
++ if not fs_object:
++ raise Exception('%s plugin not found', self.fs_name)
++
++ env['fs_object'] = fs_object()
++ fs_conf = ConfigParser()
++ if fs_conf.read('/etc/swift/fs.conf'):
++ try:
++ env['root'] = fs_conf.get ('DEFAULT', 'mount_path')
++ except NoSectionError, NoOptionError:
++ self.logger.exception(_('ERROR mount_path not present'))
++ return self.app(env, start_response)
++
++def filter_factory(global_conf, **local_conf):
++ """Returns a WSGI filter app for use with paste.deploy."""
++ conf = global_conf.copy()
++ conf.update(local_conf)
++
++ def gluster_filter(app):
++ return Gluster_plugin(app, conf)
++ return gluster_filter
+diff --git a/swift/common/utils.py b/swift/common/utils.py
+index 47edce8..03701ce 100644
+--- a/swift/common/utils.py
++++ b/swift/common/utils.py
+@@ -1,4 +1,5 @@
+ # Copyright (c) 2010-2012 OpenStack, LLC.
++# Copyright (c) 2011 Red Hat, Inc.
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+@@ -1138,3 +1139,11 @@ def streq_const_time(s1, s2):
+ for (a, b) in zip(s1, s2):
+ result |= ord(a) ^ ord(b)
+ return result == 0
++
++def plugin_enabled():
++ swift_conf = ConfigParser()
++ swift_conf.read(os.path.join('/etc/swift', 'swift.conf'))
++ try:
++ return swift_conf.get('DEFAULT', 'Enable_plugin', 'no') in TRUE_VALUES
++ except NoOptionError, NoSectionError:
++ return False
+diff --git a/swift/container/server.py b/swift/container/server.py
+index 8a18cfd..93943a3 100644
+--- a/swift/container/server.py
++++ b/swift/container/server.py
+@@ -1,4 +1,5 @@
+ # Copyright (c) 2010-2012 OpenStack, LLC.
++# Copyright (c) 2011 Red Hat, Inc.
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+@@ -31,7 +32,8 @@ from webob.exc import HTTPAccepted, HTTPBadRequest, HTTPConflict, \
+
+ from swift.common.db import ContainerBroker
+ from swift.common.utils import get_logger, get_param, hash_path, \
+- normalize_timestamp, storage_directory, split_path, validate_sync_to
++ normalize_timestamp, storage_directory, split_path, validate_sync_to, \
++ plugin_enabled
+ from swift.common.constraints import CONTAINER_LISTING_LIMIT, \
+ check_mount, check_float, check_utf8
+ from swift.common.bufferedhttp import http_connect
+@@ -40,6 +42,9 @@ from swift.common.db_replicator import ReplicatorRpc
+
+ DATADIR = 'containers'
+
++if plugin_enabled():
++ from swift.plugins.DiskDir import DiskDir
++
+
+ class ContainerController(object):
+ """WSGI Controller for the container server."""
+@@ -62,6 +67,7 @@ class ContainerController(object):
+ ContainerBroker, self.mount_check, logger=self.logger)
+ self.auto_create_account_prefix = \
+ conf.get('auto_create_account_prefix') or '.'
++ self.fs_object = None
+
+ def _get_container_broker(self, drive, part, account, container):
+ """
+@@ -73,6 +79,11 @@ class ContainerController(object):
+ :param container: container name
+ :returns: ContainerBroker object
+ """
++ if self.fs_object:
++ return DiskDir(self.root, drive, part, account,
++ container, self.logger,
++ fs_object = self.fs_object)
++
+ hsh = hash_path(account, container)
+ db_dir = storage_directory(DATADIR, part, hsh)
+ db_path = os.path.join(self.root, drive, db_dir, hsh + '.db')
+@@ -211,10 +222,18 @@ class ContainerController(object):
+ if broker.is_deleted():
+ return HTTPConflict(request=req)
+ metadata = {}
+- metadata.update((key, (value, timestamp))
+- for key, value in req.headers.iteritems()
+- if key.lower() in self.save_headers or
+- key.lower().startswith('x-container-meta-'))
++ #Note: check the structure of req.headers
++ if not self.fs_object:
++ metadata.update((key, (value, timestamp))
++ for key, value in req.headers.iteritems()
++ if key.lower() in self.save_headers or
++ key.lower().startswith('x-container-meta-'))
++ else:
++ metadata.update((key, value)
++ for key, value in req.headers.iteritems()
++ if key.lower() in self.save_headers or
++ key.lower().startswith('x-container-meta-'))
++
+ if metadata:
+ if 'X-Container-Sync-To' in metadata:
+ if 'X-Container-Sync-To' not in broker.metadata or \
+@@ -222,6 +241,7 @@ class ContainerController(object):
+ broker.metadata['X-Container-Sync-To'][0]:
+ broker.set_x_container_sync_points(-1, -1)
+ broker.update_metadata(metadata)
++
+ resp = self.account_update(req, account, container, broker)
+ if resp:
+ return resp
+@@ -245,6 +265,11 @@ class ContainerController(object):
+ broker.stale_reads_ok = True
+ if broker.is_deleted():
+ return HTTPNotFound(request=req)
++
++ if self.fs_object and not self.fs_object.object_only:
++ broker.list_objects_iter(None, None, None, None,
++ None, None)
++
+ info = broker.get_info()
+ headers = {
+ 'X-Container-Object-Count': info['object_count'],
+@@ -252,10 +277,17 @@ class ContainerController(object):
+ 'X-Timestamp': info['created_at'],
+ 'X-PUT-Timestamp': info['put_timestamp'],
+ }
+- headers.update((key, value)
+- for key, (value, timestamp) in broker.metadata.iteritems()
+- if value != '' and (key.lower() in self.save_headers or
+- key.lower().startswith('x-container-meta-')))
++ if not self.fs_object:
++ headers.update((key, value)
++ for key, (value, timestamp) in broker.metadata.iteritems()
++ if value != '' and (key.lower() in self.save_headers or
++ key.lower().startswith('x-container-meta-')))
++ else:
++ headers.update((key, value)
++ for key, value in broker.metadata.iteritems()
++ if value != '' and (key.lower() in self.save_headers or
++ key.lower().startswith('x-container-meta-')))
++
+ return HTTPNoContent(request=req, headers=headers)
+
+ def GET(self, req):
+@@ -268,6 +300,7 @@ class ContainerController(object):
+ request=req)
+ if self.mount_check and not check_mount(self.root, drive):
+ return Response(status='507 %s is not mounted' % drive)
++
+ broker = self._get_container_broker(drive, part, account, container)
+ broker.pending_timeout = 0.1
+ broker.stale_reads_ok = True
+@@ -280,10 +313,17 @@ class ContainerController(object):
+ 'X-Timestamp': info['created_at'],
+ 'X-PUT-Timestamp': info['put_timestamp'],
+ }
+- resp_headers.update((key, value)
+- for key, (value, timestamp) in broker.metadata.iteritems()
+- if value != '' and (key.lower() in self.save_headers or
+- key.lower().startswith('x-container-meta-')))
++ if not self.fs_object:
++ resp_headers.update((key, value)
++ for key, (value, timestamp) in broker.metadata.iteritems()
++ if value != '' and (key.lower() in self.save_headers or
++ key.lower().startswith('x-container-meta-')))
++ else:
++ resp_headers.update((key, value)
++ for key, value in broker.metadata.iteritems()
++ if value != '' and (key.lower() in self.save_headers or
++ key.lower().startswith('x-container-meta-')))
++
+ try:
+ path = get_param(req, 'path')
+ prefix = get_param(req, 'prefix')
+@@ -414,10 +454,17 @@ class ContainerController(object):
+ return HTTPNotFound(request=req)
+ timestamp = normalize_timestamp(req.headers['x-timestamp'])
+ metadata = {}
+- metadata.update((key, (value, timestamp))
+- for key, value in req.headers.iteritems()
+- if key.lower() in self.save_headers or
+- key.lower().startswith('x-container-meta-'))
++ if not self.fs_object:
++ metadata.update((key, (value, timestamp))
++ for key, value in req.headers.iteritems()
++ if key.lower() in self.save_headers or
++ key.lower().startswith('x-container-meta-'))
++ else:
++ metadata.update((key, value)
++ for key, value in req.headers.iteritems()
++ if key.lower() in self.save_headers or
++ key.lower().startswith('x-container-meta-'))
++
+ if metadata:
+ if 'X-Container-Sync-To' in metadata:
+ if 'X-Container-Sync-To' not in broker.metadata or \
+@@ -427,8 +474,19 @@ class ContainerController(object):
+ broker.update_metadata(metadata)
+ return HTTPNoContent(request=req)
+
++ def plugin(self, env):
++ if env.get('Gluster_enabled', False):
++ self.fs_object = env.get('fs_object')
++ if not self.fs_object:
++ raise NoneTypeError
++ self.root = env.get('root')
++ self.mount_check = False
++ else:
++ self.fs_object = None
++
+ def __call__(self, env, start_response):
+ start_time = time.time()
++ self.plugin(env)
+ req = Request(env)
+ self.logger.txn_id = req.headers.get('x-trans-id', None)
+ if not check_utf8(req.path_info):
+diff --git a/swift/obj/server.py b/swift/obj/server.py
+index 9cca16b..a45daff 100644
+--- a/swift/obj/server.py
++++ b/swift/obj/server.py
+@@ -1,4 +1,5 @@
+ # Copyright (c) 2010-2012 OpenStack, LLC.
++# Copyright (c) 2011 Red Hat, Inc.
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+@@ -26,6 +27,7 @@ from hashlib import md5
+ from tempfile import mkstemp
+ from urllib import unquote
+ from contextlib import contextmanager
++from ConfigParser import ConfigParser
+
+ from webob import Request, Response, UTC
+ from webob.exc import HTTPAccepted, HTTPBadRequest, HTTPCreated, \
+@@ -37,16 +39,23 @@ from eventlet import sleep, Timeout, tpool
+
+ from swift.common.utils import mkdirs, normalize_timestamp, \
+ storage_directory, hash_path, renamer, fallocate, \
+- split_path, drop_buffer_cache, get_logger, write_pickle
++ split_path, drop_buffer_cache, get_logger, write_pickle, \
++ plugin_enabled
+ from swift.common.bufferedhttp import http_connect
+-from swift.common.constraints import check_object_creation, check_mount, \
+- check_float, check_utf8
++if plugin_enabled():
++ from swift.plugins.constraints import check_object_creation
++ from swift.plugins.utils import X_TYPE, X_OBJECT_TYPE, FILE, DIR, MARKER_DIR, \
++ OBJECT, DIR_TYPE, FILE_TYPE
++else:
++ from swift.common.constraints import check_object_creation
++
++from swift.common.constraints import check_mount, check_float, check_utf8
++
+ from swift.common.exceptions import ConnectionTimeout, DiskFileError, \
+ DiskFileNotExist
+ from swift.obj.replicator import tpooled_get_hashes, invalidate_hash, \
+ quarantine_renamer
+
+-
+ DATADIR = 'objects'
+ ASYNCDIR = 'async_pending'
+ PICKLE_PROTOCOL = 2
+@@ -339,6 +348,9 @@ class DiskFile(object):
+ raise
+ raise DiskFileNotExist('Data File does not exist.')
+
++if plugin_enabled():
++ from swift.plugins.DiskFile import Gluster_DiskFile
++
+
+ class ObjectController(object):
+ """Implements the WSGI application for the Swift Object Server."""
+@@ -377,6 +389,17 @@ class ObjectController(object):
+ 'expiring_objects'
+ self.expiring_objects_container_divisor = \
+ int(conf.get('expiring_objects_container_divisor') or 86400)
++ self.fs_object = None
++
++ def get_DiskFile_obj(self, path, device, partition, account, container, obj,
++ logger, keep_data_fp=False, disk_chunk_size=65536):
++ if self.fs_object:
++ return Gluster_DiskFile(path, device, partition, account, container,
++ obj, logger, keep_data_fp,
++ disk_chunk_size, fs_object = self.fs_object);
++ else:
++ return DiskFile(path, device, partition, account, container,
++ obj, logger, keep_data_fp, disk_chunk_size)
+
+ def async_update(self, op, account, container, obj, host, partition,
+ contdevice, headers_out, objdevice):
+@@ -493,7 +516,7 @@ class ObjectController(object):
+ content_type='text/plain')
+ if self.mount_check and not check_mount(self.devices, device):
+ return Response(status='507 %s is not mounted' % device)
+- file = DiskFile(self.devices, device, partition, account, container,
++ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
+ obj, self.logger, disk_chunk_size=self.disk_chunk_size)
+
+ if 'X-Delete-At' in file.metadata and \
+@@ -548,7 +571,7 @@ class ObjectController(object):
+ if new_delete_at and new_delete_at < time.time():
+ return HTTPBadRequest(body='X-Delete-At in past', request=request,
+ content_type='text/plain')
+- file = DiskFile(self.devices, device, partition, account, container,
++ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
+ obj, self.logger, disk_chunk_size=self.disk_chunk_size)
+ orig_timestamp = file.metadata.get('X-Timestamp')
+ upload_expiration = time.time() + self.max_upload_time
+@@ -580,12 +603,29 @@ class ObjectController(object):
+ if 'etag' in request.headers and \
+ request.headers['etag'].lower() != etag:
+ return HTTPUnprocessableEntity(request=request)
+- metadata = {
+- 'X-Timestamp': request.headers['x-timestamp'],
+- 'Content-Type': request.headers['content-type'],
+- 'ETag': etag,
+- 'Content-Length': str(os.fstat(fd).st_size),
+- }
++ content_type = request.headers['content-type']
++ if self.fs_object and not content_type:
++ content_type = FILE_TYPE
++ if not self.fs_object:
++ metadata = {
++ 'X-Timestamp': request.headers['x-timestamp'],
++ 'Content-Type': request.headers['content-type'],
++ 'ETag': etag,
++ 'Content-Length': str(os.fstat(fd).st_size),
++ }
++ else:
++ metadata = {
++ 'X-Timestamp': request.headers['x-timestamp'],
++ 'Content-Type': request.headers['content-type'],
++ 'ETag': etag,
++ 'Content-Length': str(os.fstat(fd).st_size),
++ X_TYPE: OBJECT,
++ X_OBJECT_TYPE: FILE,
++ }
++
++ if self.fs_object and \
++ request.headers['content-type'].lower() == DIR_TYPE:
++ metadata.update({X_OBJECT_TYPE: MARKER_DIR})
+ metadata.update(val for val in request.headers.iteritems()
+ if val[0].lower().startswith('x-object-meta-') and
+ len(val[0]) > 14)
+@@ -612,7 +652,7 @@ class ObjectController(object):
+ 'x-timestamp': file.metadata['X-Timestamp'],
+ 'x-etag': file.metadata['ETag'],
+ 'x-trans-id': request.headers.get('x-trans-id', '-')},
+- device)
++ (self.fs_object and account) or device)
+ resp = HTTPCreated(request=request, etag=etag)
+ return resp
+
+@@ -626,9 +666,9 @@ class ObjectController(object):
+ content_type='text/plain')
+ if self.mount_check and not check_mount(self.devices, device):
+ return Response(status='507 %s is not mounted' % device)
+- file = DiskFile(self.devices, device, partition, account, container,
+- obj, self.logger, keep_data_fp=True,
+- disk_chunk_size=self.disk_chunk_size)
++ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
++ obj, self.logger, keep_data_fp=True,
++ disk_chunk_size=self.disk_chunk_size)
+ if file.is_deleted() or ('X-Delete-At' in file.metadata and
+ int(file.metadata['X-Delete-At']) <= time.time()):
+ if request.headers.get('if-match') == '*':
+@@ -702,7 +742,7 @@ class ObjectController(object):
+ return resp
+ if self.mount_check and not check_mount(self.devices, device):
+ return Response(status='507 %s is not mounted' % device)
+- file = DiskFile(self.devices, device, partition, account, container,
++ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
+ obj, self.logger, disk_chunk_size=self.disk_chunk_size)
+ if file.is_deleted() or ('X-Delete-At' in file.metadata and
+ int(file.metadata['X-Delete-At']) <= time.time()):
+@@ -744,7 +784,7 @@ class ObjectController(object):
+ if self.mount_check and not check_mount(self.devices, device):
+ return Response(status='507 %s is not mounted' % device)
+ response_class = HTTPNoContent
+- file = DiskFile(self.devices, device, partition, account, container,
++ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
+ obj, self.logger, disk_chunk_size=self.disk_chunk_size)
+ if 'x-if-delete-at' in request.headers and \
+ int(request.headers['x-if-delete-at']) != \
+@@ -797,9 +837,18 @@ class ObjectController(object):
+ raise hashes
+ return Response(body=pickle.dumps(hashes))
+
++ def plugin(self, env):
++ if env.get('Gluster_enabled', False):
++ self.fs_object = env.get('fs_object')
++ self.devices = env.get('root')
++ self.mount_check = False
++ else:
++ self.fs_object = None
++
+ def __call__(self, env, start_response):
+ """WSGI Application entry point for the Swift Object Server."""
+ start_time = time.time()
++ self.plugin(env)
+ req = Request(env)
+ self.logger.txn_id = req.headers.get('x-trans-id', None)
+ if not check_utf8(req.path_info):
+diff --git a/swift/proxy/server.py b/swift/proxy/server.py
+index 17613b8..d277d28 100644
+--- a/swift/proxy/server.py
++++ b/swift/proxy/server.py
+@@ -1,4 +1,5 @@
+ # Copyright (c) 2010-2012 OpenStack, LLC.
++# Copyright (c) 2011 Red Hat, Inc.
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+@@ -53,11 +54,20 @@ from webob import Request, Response
+
+ from swift.common.ring import Ring
+ from swift.common.utils import cache_from_env, ContextPool, get_logger, \
+- get_remote_client, normalize_timestamp, split_path, TRUE_VALUES
++ get_remote_client, normalize_timestamp, split_path, TRUE_VALUES, \
++ plugin_enabled
+ from swift.common.bufferedhttp import http_connect
+-from swift.common.constraints import check_metadata, check_object_creation, \
+- check_utf8, CONTAINER_LISTING_LIMIT, MAX_ACCOUNT_NAME_LENGTH, \
+- MAX_CONTAINER_NAME_LENGTH, MAX_FILE_SIZE
++
++if plugin_enabled():
++ from swift.plugins.constraints import check_object_creation, \
++ MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, MAX_FILE_SIZE
++else:
++ from swift.common.constraints import check_object_creation, \
++ MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, MAX_FILE_SIZE
++
++from swift.common.constraints import check_metadata, check_utf8, \
++ CONTAINER_LISTING_LIMIT
++
+ from swift.common.exceptions import ChunkReadTimeout, \
+ ChunkWriteTimeout, ConnectionTimeout
+
+diff --git a/test/__init__.py b/test/__init__.py
+index ef2ce31..363a051 100644
+--- a/test/__init__.py
++++ b/test/__init__.py
+@@ -6,8 +6,16 @@ import sys
+ import os
+ from ConfigParser import MissingSectionHeaderError
+ from StringIO import StringIO
+-
+ from swift.common.utils import readconf
++from swift.common.utils import plugin_enabled
++if plugin_enabled():
++ from swift.plugins.constraints import MAX_OBJECT_NAME_LENGTH, \
++ MAX_CONTAINER_NAME_LENGTH, MAX_ACCOUNT_NAME_LENGTH, \
++ MAX_FILE_SIZE
++else:
++ from swift.common.constraints import MAX_OBJECT_NAME_LENGTH, \
++ MAX_CONTAINER_NAME_LENGTH, MAX_ACCOUNT_NAME_LENGTH, \
++ MAX_FILE_SIZE
+
+ setattr(__builtin__, '_', lambda x: x)
+
+diff --git a/test/functional/tests.py b/test/functional/tests.py
+index b25b4fd..8d12f58 100644
+--- a/test/functional/tests.py
++++ b/test/functional/tests.py
+@@ -31,6 +31,16 @@ import urllib
+ from test import get_config
+ from swift import Account, AuthenticationFailed, Connection, Container, \
+ File, ResponseError
++from test import plugin_enabled
++if plugin_enabled():
++ from test import MAX_OBJECT_NAME_LENGTH, \
++ MAX_CONTAINER_NAME_LENGTH, MAX_ACCOUNT_NAME_LENGTH, \
++ MAX_FILE_SIZE
++else:
++ from test import MAX_OBJECT_NAME_LENGTH, \
++ MAX_CONTAINER_NAME_LENGTH, MAX_ACCOUNT_NAME_LENGTH, \
++ MAX_FILE_SIZE
++
+
+ config = get_config()
+
+@@ -361,7 +371,7 @@ class TestContainer(Base):
+ set_up = False
+
+ def testContainerNameLimit(self):
+- limit = 256
++ limit = MAX_CONTAINER_NAME_LENGTH
+
+ for l in (limit-100, limit-10, limit-1, limit,
+ limit+1, limit+10, limit+100):
+@@ -949,7 +959,7 @@ class TestFile(Base):
+ self.assert_status(404)
+
+ def testNameLimit(self):
+- limit = 1024
++ limit = MAX_OBJECT_NAME_LENGTH
+
+ for l in (1, 10, limit/2, limit-1, limit, limit+1, limit*2):
+ file = self.env.container.file('a'*l)
+@@ -1093,7 +1103,7 @@ class TestFile(Base):
+ self.assert_(file.read(hdrs={'Range': r}) == data[0:1000])
+
+ def testFileSizeLimit(self):
+- limit = 5*2**30 + 2
++ limit = MAX_FILE_SIZE
+ tsecs = 3
+
+ for i in (limit-100, limit-10, limit-1, limit, limit+1, limit+10,
+diff --git a/test/unit/obj/test_server.py b/test/unit/obj/test_server.py
+index 075700e..5b6f32d 100644
+--- a/test/unit/obj/test_server.py
++++ b/test/unit/obj/test_server.py
+@@ -1355,7 +1355,7 @@ class TestObjectController(unittest.TestCase):
+
+ def test_max_object_name_length(self):
+ timestamp = normalize_timestamp(time())
+- req = Request.blank('/sda1/p/a/c/' + ('1' * 1024),
++ req = Request.blank('/sda1/p/a/c/' + ('1' * MAX_OBJECT_NAME_LENGTH),
+ environ={'REQUEST_METHOD': 'PUT'},
+ headers={'X-Timestamp': timestamp,
+ 'Content-Length': '4',
+diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py
+index 364370e..c17fe59 100644
+--- a/test/unit/proxy/test_server.py
++++ b/test/unit/proxy/test_server.py
+@@ -21,7 +21,6 @@ import os
+ import sys
+ import unittest
+ from nose import SkipTest
+-from ConfigParser import ConfigParser
+ from contextlib import contextmanager
+ from cStringIO import StringIO
+ from gzip import GzipFile
+@@ -44,8 +43,18 @@ from swift.account import server as account_server
+ from swift.container import server as container_server
+ from swift.obj import server as object_server
+ from swift.common import ring
+-from swift.common.constraints import MAX_META_NAME_LENGTH, \
+- MAX_META_VALUE_LENGTH, MAX_META_COUNT, MAX_META_OVERALL_SIZE, MAX_FILE_SIZE
++from swift.common.utils import plugin_enabled
++if plugin_enabled():
++ from swift.plugins.constraints import MAX_META_NAME_LENGTH, \
++ MAX_META_VALUE_LENGTH, MAX_META_COUNT, MAX_META_OVERALL_SIZE, \
++ MAX_FILE_SIZE, MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, \
++ MAX_OBJECT_NAME_LENGTH
++else:
++ from swift.plugins.constraints import MAX_META_NAME_LENGTH, \
++ MAX_META_VALUE_LENGTH, MAX_META_COUNT, MAX_META_OVERALL_SIZE, \
++ MAX_FILE_SIZE, MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, \
++ MAX_OBJECT_NAME_LENGTH
++
+ from swift.common.utils import mkdirs, normalize_timestamp, NullLogger
+ from swift.common.wsgi import monkey_patch_mimetools
+
+@@ -3207,7 +3216,8 @@ class TestContainerController(unittest.TestCase):
+ def test_PUT_max_container_name_length(self):
+ with save_globals():
+ controller = proxy_server.ContainerController(self.app, 'account',
+- '1' * 256)
++ '1' *
++ MAX_CONTAINER_NAME_LENGTH,)
+ self.assert_status_map(controller.PUT,
+ (200, 200, 200, 201, 201, 201), 201,
+ missing_container=True)
+@@ -3813,7 +3823,8 @@ class TestAccountController(unittest.TestCase):
+ def test_PUT_max_account_name_length(self):
+ with save_globals():
+ self.app.allow_account_management = True
+- controller = proxy_server.AccountController(self.app, '1' * 256)
++ controller = proxy_server.AccountController(self.app, '1' *
++ MAX_ACCOUNT_NAME_LENGTH)
+ self.assert_status_map(controller.PUT, (201, 201, 201), 201)
+ controller = proxy_server.AccountController(self.app, '2' * 257)
+ self.assert_status_map(controller.PUT, (201, 201, 201), 400)
diff --git a/tests/bugs/bug-874272.t b/tests/bugs/bug-874272.t
new file mode 100755
index 000000000..01793a368
--- /dev/null
+++ b/tests/bugs/bug-874272.t
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume info;
+
+function volinfo_field()
+{
+ local vol=$1;
+ local field=$2;
+
+ $CLI volume info $vol | grep "^$field: " | sed 's/.*: //';
+}
+
+TEST $CLI volume create $V0 $H0:$B0/brick1;
+EXPECT 'Created' volinfo_field $V0 'Status';
+
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Wait for volume to register with rpc.mountd
+sleep 5;
+
+#mount on a random dir
+TEST MOUNTDIR="/tmp/$RANDOM"
+TEST mkdir $MOUNTDIR
+TEST mount -t nfs -o vers=3,nolock,soft,intr $H0:/$V0 $MOUNTDIR;
+flag=0
+
+TEST touch $MOUNTDIR/testfile
+
+TEST GEOREPDIR="/tmp/$RANDOM"
+TEST mkdir $GEOREPDIR
+
+TEST $CLI volume geo-replication $V0 file:///$GEOREPDIR start
+
+for i in {1..500}; do cat /etc/passwd >> $MOUNTDIR/testfile; if [ $? -ne 0 ]; then flag=1; break; fi; done
+TEST [ $flag -eq 0 ]
+TEST rm -rf $GEOREPDIR
+
+TEST umount $MOUNTDIR
+TEST rm -rf $MOUNTDIR
+
+cleanup;
diff --git a/tests/bugs/bug-887098-gmount-crash.t b/tests/bugs/bug-887098-gmount-crash.t
new file mode 100644
index 000000000..54e52d4dc
--- /dev/null
+++ b/tests/bugs/bug-887098-gmount-crash.t
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+cleanup;
+
+## Start and create a volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume info;
+
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2,3,4};
+
+## Verify volume is is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+
+function pidgrep()
+{
+ ps ax | grep "$1" | awk '{print $1}' | head -1
+}
+
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+TEST glusterfs -s $H0 --volfile-id=$V0 --acl $M0
+MOUNT_PID=`ps ax |grep "glusterfs -s $H0 --volfile-id=$V0 --acl $M0" | awk '{print $1}' | head -1`
+
+for i in {1..25};
+do
+ mkdir $M0/tmp_$i && cat /etc/hosts > $M0/tmp_$i/file
+ cp -RPp $M0/tmp_$i $M0/newtmp_$i && cat /etc/hosts > $M0/newtmp_$i/newfile
+done
+
+EXPECT "$MOUNT_PID" pidgrep $MOUNT_PID
+TEST rm -rf $M0/*
+umount $M0
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+
+cleanup;
diff --git a/tests/bugs/bug-918437-sh-mtime.t b/tests/bugs/bug-918437-sh-mtime.t
new file mode 100644
index 000000000..080956f51
--- /dev/null
+++ b/tests/bugs/bug-918437-sh-mtime.t
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+function get_mtime {
+ local f=$1
+ stat $f | grep Modify | awk '{print $2 $3}' | cut -f1 -d'.'
+}
+cleanup;
+
+## Tests if mtime is correct after self-heal.
+TEST glusterd
+TEST pidof glusterd
+TEST mkdir -p $B0/gfs0/brick0{1,2}
+TEST $CLI volume create $V0 replica 2 transport tcp $H0:$B0/gfs0/brick01 $H0:$B0/gfs0/brick02
+TEST $CLI volume set $V0 nfs.disable on
+TEST $CLI volume set $V0 performance.stat-prefetch off
+TEST $CLI volume set $V0 cluster.background-self-heal-count 0
+TEST $CLI volume set $V0 cluster.self-heal-daemon off
+TEST $CLI volume start $V0
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --direct-io-mode=enable
+# file 'a' is healed from brick02 to brick01 where as file 'b' is healed from
+# brick01 to brick02
+
+TEST cp -p /etc/passwd $M0/a
+TEST cp -p /etc/passwd $M0/b
+
+#Store mtimes before self-heals
+TEST modify_atstamp=$(get_mtime $B0/gfs0/brick02/a)
+TEST modify_btstamp=$(get_mtime $B0/gfs0/brick02/b)
+
+TEST $CLI volume stop $V0
+TEST gf_rm_file_and_gfid_link $B0/gfs0/brick01 a
+TEST gf_rm_file_and_gfid_link $B0/gfs0/brick02 b
+
+TEST $CLI volume start $V0 force
+EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0
+EXPECT_WITHIN 20 "1" afr_child_up_status $V0 1
+
+find $M0 | xargs stat 1>/dev/null
+
+TEST modify_atstamp1=$(get_mtime $B0/gfs0/brick01/a)
+TEST modify_atstamp2=$(get_mtime $B0/gfs0/brick02/a)
+EXPECT $modify_atstamp echo $modify_atstamp1
+EXPECT $modify_atstamp echo $modify_atstamp2
+
+TEST modify_btstamp1=$(get_mtime $B0/gfs0/brick01/b)
+TEST modify_btstamp2=$(get_mtime $B0/gfs0/brick02/b)
+EXPECT $modify_btstamp echo $modify_btstamp1
+EXPECT $modify_btstamp echo $modify_btstamp2
+cleanup;
diff --git a/xlators/Makefile.am b/xlators/Makefile.am
index 4c94f5e44..b1643d26c 100644
--- a/xlators/Makefile.am
+++ b/xlators/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = cluster storage protocol performance debug features encryption mount nfs mgmt
+SUBDIRS = cluster storage protocol performance debug features encryption mount nfs mgmt system
CLEANFILES =
diff --git a/xlators/cluster/afr/src/Makefile.am b/xlators/cluster/afr/src/Makefile.am
index e192b599b..95db5dd96 100644
--- a/xlators/cluster/afr/src/Makefile.am
+++ b/xlators/cluster/afr/src/Makefile.am
@@ -1,7 +1,11 @@
xlator_LTLIBRARIES = afr.la pump.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
-afr_common_source = afr-dir-read.c afr-dir-write.c afr-inode-read.c afr-inode-write.c afr-open.c afr-transaction.c afr-self-heal-data.c afr-self-heal-common.c afr-self-heal-metadata.c afr-self-heal-entry.c afr-self-heal-algorithm.c afr-lk-common.c $(top_builddir)/xlators/lib/src/libxlator.c
+afr_common_source = afr-dir-read.c afr-dir-write.c afr-inode-read.c \
+ afr-inode-write.c afr-open.c afr-transaction.c afr-self-heal-data.c \
+ afr-self-heal-common.c afr-self-heal-metadata.c afr-self-heal-entry.c \
+ afr-self-heal-algorithm.c afr-lk-common.c afr-self-heald.c \
+ $(top_builddir)/xlators/lib/src/libxlator.c
afr_la_LDFLAGS = -module -avoidversion
afr_la_SOURCES = $(afr_common_source) afr.c
@@ -11,11 +15,15 @@ pump_la_LDFLAGS = -module -avoidversion
pump_la_SOURCES = $(afr_common_source) pump.c
pump_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = afr.h afr-transaction.h afr-inode-write.h afr-inode-read.h afr-dir-read.h afr-dir-write.h afr-self-heal.h afr-self-heal-common.h afr-self-heal-algorithm.h pump.h afr-mem-types.h afr-common.c $(top_builddir)/xlators/lib/src/libxlator.h
+noinst_HEADERS = afr.h afr-transaction.h afr-inode-write.h afr-inode-read.h \
+ afr-dir-read.h afr-dir-write.h afr-self-heal.h afr-self-heal-common.h \
+ afr-self-heal-algorithm.h pump.h afr-mem-types.h afr-common.c \
+ afr-self-heald.h $(top_builddir)/xlators/lib/src/libxlator.h \
+ $(top_builddir)/glusterfsd/src/glusterfsd.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
- -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/contrib/md5 -shared -nostartfiles $(GF_CFLAGS) \
- -I$(top_srcdir)/xlators/lib/src
+ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/xlators/lib/src \
+ -I$(top_srcdir)/rpc/rpc-lib/src -shared -nostartfiles $(GF_CFLAGS)
CLEANFILES =
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index c8b1ea960..cefbaa8ec 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <libgen.h>
@@ -44,6 +35,7 @@
#include "compat.h"
#include "byte-order.h"
#include "statedump.h"
+#include "inode.h"
#include "fd.h"
@@ -54,218 +46,687 @@
#include "afr-transaction.h"
#include "afr-self-heal.h"
#include "afr-self-heal-common.h"
+#include "afr-self-heald.h"
#include "pump.h"
#define AFR_ICTX_OPENDIR_DONE_MASK 0x0000000200000000ULL
#define AFR_ICTX_SPLIT_BRAIN_MASK 0x0000000100000000ULL
#define AFR_ICTX_READ_CHILD_MASK 0x00000000FFFFFFFFULL
+int
+afr_lookup_done_success_action (call_frame_t *frame, xlator_t *this,
+ gf_boolean_t fail_conflict);
+void
+afr_children_copy (int32_t *dst, int32_t *src, unsigned int child_count)
+{
+ int i = 0;
+
+ for (i = 0; i < child_count; i++)
+ dst[i] = src[i];
+}
+
+void
+afr_xattr_req_prepare (xlator_t *this, dict_t *xattr_req, const char *path)
+{
+ int i = 0;
+ afr_private_t *priv = NULL;
+ int ret = 0;
+
+ priv = this->private;
+
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_set_uint64 (xattr_req, priv->pending_key[i],
+ 3 * sizeof(int32_t));
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Unable to set dict value for %s",
+ path, priv->pending_key[i]);
+ /* 3 = data+metadata+entry */
+ }
+ ret = dict_set_int32 (xattr_req, GF_GFIDLESS_LOOKUP, 1);
+ if (ret) {
+ gf_log (this->name, GF_LOG_DEBUG, "%s: failed to set gfidless "
+ "lookup", path);
+ }
+}
+
+int
+afr_lookup_xattr_req_prepare (afr_local_t *local, xlator_t *this,
+ dict_t *xattr_req, loc_t *loc, void **gfid_req)
+{
+ int ret = -ENOMEM;
+
+ GF_ASSERT (gfid_req);
+
+ *gfid_req = NULL;
+ local->xattr_req = dict_new ();
+ if (!local->xattr_req)
+ goto out;
+ if (xattr_req)
+ dict_copy (xattr_req, local->xattr_req);
+
+ afr_xattr_req_prepare (this, local->xattr_req, loc->path);
+ ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_INODELK_COUNT, 0);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Unable to set dict value for %s",
+ loc->path, GLUSTERFS_INODELK_COUNT);
+ }
+ ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_ENTRYLK_COUNT, 0);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Unable to set dict value for %s",
+ loc->path, GLUSTERFS_ENTRYLK_COUNT);
+ }
+
+ ret = dict_set_uint32 (local->xattr_req, GLUSTERFS_PARENT_ENTRYLK, 0);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Unable to set dict value for %s",
+ loc->path, GLUSTERFS_PARENT_ENTRYLK);
+ }
+
+ ret = dict_get_ptr (local->xattr_req, "gfid-req", gfid_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: failed to get the gfid from dict", loc->path);
+ *gfid_req = NULL;
+ } else {
+ if (loc->parent != NULL)
+ dict_del (local->xattr_req, "gfid-req");
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+void
+afr_lookup_save_gfid (uuid_t dst, void* new, const loc_t *loc)
+{
+ inode_t *inode = NULL;
+
+ inode = loc->inode;
+ if (inode && !uuid_is_null (inode->gfid))
+ uuid_copy (dst, inode->gfid);
+ else if (!uuid_is_null (loc->gfid))
+ uuid_copy (dst, loc->gfid);
+ else if (new && !uuid_is_null (new))
+ uuid_copy (dst, new);
+}
+
+int
+afr_errno_count (int32_t *children, int *child_errno,
+ unsigned int child_count, int32_t op_errno)
+{
+ int i = 0;
+ int errno_count = 0;
+ int child = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (children) {
+ child = children[i];
+ if (child == -1)
+ break;
+ } else {
+ child = i;
+ }
+ if (child_errno[child] == op_errno)
+ errno_count++;
+ }
+ return errno_count;
+}
+
int32_t
afr_set_dict_gfid (dict_t *dict, uuid_t gfid)
{
- int ret = 0;
+ int ret = 0;
+ uuid_t *pgfid = NULL;
GF_ASSERT (gfid);
- ret = dict_set_static_bin (dict, "gfid-req", gfid, 16);
+ pgfid = GF_CALLOC (1, sizeof (uuid_t), gf_common_mt_char);
+ if (!pgfid) {
+ ret = -1;
+ goto out;
+ }
+
+ uuid_copy (*pgfid, gfid);
+
+ ret = dict_set_dynptr (dict, "gfid-req", pgfid, sizeof (uuid_t));
if (ret)
- gf_log (THIS->name, GF_LOG_DEBUG, "gfid set failed");
+ gf_log (THIS->name, GF_LOG_ERROR, "gfid set failed");
+
+out:
+ if (ret && pgfid)
+ GF_FREE (pgfid);
return ret;
}
-uint64_t
-afr_is_split_brain (xlator_t *this, inode_t *inode)
+afr_inode_ctx_t*
+afr_inode_ctx_get_from_addr (uint64_t addr, int32_t child_count)
{
- int ret = 0;
+ int ret = -1;
+ afr_inode_ctx_t *ctx = NULL;
+ size_t size = 0;
+
+ GF_ASSERT (child_count > 0);
+
+ if (!addr) {
+ ctx = GF_CALLOC (1, sizeof (*ctx),
+ gf_afr_mt_inode_ctx_t);
+ if (!ctx)
+ goto out;
+ size = sizeof (*ctx->fresh_children);
+ ctx->fresh_children = GF_CALLOC (child_count, size,
+ gf_afr_mt_int32_t);
+ if (!ctx->fresh_children)
+ goto out;
+ } else {
+ ctx = (afr_inode_ctx_t*) (long) addr;
+ }
+ ret = 0;
+out:
+ if (ret && ctx) {
+ if (ctx->fresh_children)
+ GF_FREE (ctx->fresh_children);
+ GF_FREE (ctx);
+ ctx = NULL;
+ }
+ return ctx;
+}
- uint64_t ctx = 0;
- uint64_t split_brain = 0;
+void
+afr_inode_get_ctx (xlator_t *this, inode_t *inode, afr_inode_params_t *params)
+{
+ GF_ASSERT (inode);
+ GF_ASSERT (params);
- VALIDATE_OR_GOTO (inode, out);
+ int ret = 0;
+ afr_inode_ctx_t *ctx = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+ uint64_t ctx_addr = 0;
+ int32_t read_child = -1;
+ int32_t *fresh_children = NULL;
+ priv = this->private;
LOCK (&inode->lock);
{
- ret = __inode_ctx_get (inode, this, &ctx);
-
+ ret = __inode_ctx_get (inode, this, &ctx_addr);
if (ret < 0)
goto unlock;
-
- split_brain = ctx & AFR_ICTX_SPLIT_BRAIN_MASK;
+ ctx = afr_inode_ctx_get_from_addr (ctx_addr, priv->child_count);
+ if (!ctx)
+ goto unlock;
+ switch (params->op) {
+ case AFR_INODE_GET_READ_CTX:
+ fresh_children = params->u.read_ctx.children;
+ read_child = (int32_t)(ctx->masks &
+ AFR_ICTX_READ_CHILD_MASK);
+ params->u.read_ctx.read_child = read_child;
+ if (!fresh_children)
+ goto unlock;
+ for (i = 0; i < priv->child_count; i++)
+ fresh_children[i] = ctx->fresh_children[i];
+ break;
+ case AFR_INODE_GET_OPENDIR_DONE:
+ params->u.value = _gf_false;
+ if (ctx->masks & AFR_ICTX_OPENDIR_DONE_MASK)
+ params->u.value = _gf_true;
+ break;
+ case AFR_INODE_GET_SPLIT_BRAIN:
+ params->u.value = _gf_false;
+ if (ctx->masks & AFR_ICTX_SPLIT_BRAIN_MASK)
+ params->u.value = _gf_true;
+ ;
+ break;
+ default:
+ GF_ASSERT (0);
+ break;
+ }
}
unlock:
UNLOCK (&inode->lock);
+}
-out:
- return split_brain;
+gf_boolean_t
+afr_is_split_brain (xlator_t *this, inode_t *inode)
+{
+ afr_inode_params_t params = {0};
+
+ params.op = AFR_INODE_GET_SPLIT_BRAIN;
+ afr_inode_get_ctx (this, inode, &params);
+ return params.u.value;
+}
+
+gf_boolean_t
+afr_is_opendir_done (xlator_t *this, inode_t *inode)
+{
+ afr_inode_params_t params = {0};
+
+ params.op = AFR_INODE_GET_OPENDIR_DONE;
+ afr_inode_get_ctx (this, inode, &params);
+ return params.u.value;
}
+int32_t
+afr_inode_get_read_ctx (xlator_t *this, inode_t *inode, int32_t *fresh_children)
+{
+ afr_inode_params_t params = {0};
+
+ params.op = AFR_INODE_GET_READ_CTX;
+ params.u.read_ctx.children = fresh_children;
+ afr_inode_get_ctx (this, inode, &params);
+ return params.u.read_ctx.read_child;
+}
+
void
-afr_set_split_brain (xlator_t *this, inode_t *inode, gf_boolean_t set)
+afr_inode_ctx_set_read_child (afr_inode_ctx_t *ctx, int32_t read_child)
{
- uint64_t ctx = 0;
- int ret = 0;
+ uint64_t remaining_mask = 0;
+ uint64_t mask = 0;
- VALIDATE_OR_GOTO (inode, out);
+ remaining_mask = (~AFR_ICTX_READ_CHILD_MASK & ctx->masks);
+ mask = (AFR_ICTX_READ_CHILD_MASK & read_child);
+ ctx->masks = remaining_mask | mask;
+}
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get (inode, this, &ctx);
+void
+afr_inode_ctx_set_read_ctx (afr_inode_ctx_t *ctx, int32_t read_child,
+ int32_t *fresh_children, int32_t child_count)
+{
+ int i = 0;
- if (ret < 0) {
- ctx = 0;
- }
+ afr_inode_ctx_set_read_child (ctx, read_child);
+ for (i = 0; i < child_count; i++) {
+ if (fresh_children)
+ ctx->fresh_children[i] = fresh_children[i];
+ else
+ ctx->fresh_children[i] = -1;
+ }
+}
- if (set) {
- ctx = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx)
- | (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_SPLIT_BRAIN_MASK);
- } else {
- ctx = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx);
- }
+void
+afr_inode_ctx_rm_stale_children (afr_inode_ctx_t *ctx, int32_t *stale_children,
+ int32_t child_count)
+{
+ int i = 0;
+ int32_t read_child = -1;
- ret = __inode_ctx_put (inode, this, ctx);
- if (ret) {
- gf_log_callingfn (this->name, GF_LOG_INFO,
- "failed to set the inode ctx (%s)",
- uuid_utoa (inode->gfid));
- }
+ GF_ASSERT (stale_children);
+ for (i = 0; i < child_count; i++) {
+ if (stale_children[i] == -1)
+ break;
+ afr_children_rm_child (ctx->fresh_children,
+ stale_children[i], child_count);
}
- UNLOCK (&inode->lock);
-out:
- return;
+ read_child = (int32_t)(ctx->masks & AFR_ICTX_READ_CHILD_MASK);
+ if (!afr_is_child_present (ctx->fresh_children, child_count,
+ read_child))
+ afr_inode_ctx_set_read_child (ctx, ctx->fresh_children[0]);
}
+void
+afr_inode_ctx_set_opendir_done (afr_inode_ctx_t *ctx)
+{
+ uint64_t remaining_mask = 0;
+ uint64_t mask = 0;
-uint64_t
-afr_is_opendir_done (xlator_t *this, inode_t *inode)
+ remaining_mask = (~AFR_ICTX_OPENDIR_DONE_MASK & ctx->masks);
+ mask = (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_OPENDIR_DONE_MASK);
+ ctx->masks = remaining_mask | mask;
+}
+
+void
+afr_inode_ctx_set_splitbrain (afr_inode_ctx_t *ctx, gf_boolean_t set)
{
- int ret = 0;
- uint64_t ctx = 0;
- uint64_t opendir_done = 0;
+ uint64_t remaining_mask = 0;
+ uint64_t mask = 0;
+
+ if (set) {
+ remaining_mask = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx->masks);
+ mask = (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_SPLIT_BRAIN_MASK);
+ ctx->masks = remaining_mask | mask;
+ } else {
+ ctx->masks = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx->masks);
+ }
+}
- VALIDATE_OR_GOTO (inode, out);
+void
+afr_inode_set_ctx (xlator_t *this, inode_t *inode, afr_inode_params_t *params)
+{
+ GF_ASSERT (inode);
+ GF_ASSERT (params);
+
+ int ret = 0;
+ afr_inode_ctx_t *ctx = NULL;
+ afr_private_t *priv = NULL;
+ uint64_t ctx_addr = 0;
+ gf_boolean_t set = _gf_false;
+ int32_t read_child = -1;
+ int32_t *fresh_children = NULL;
+ int32_t *stale_children = NULL;
+ priv = this->private;
LOCK (&inode->lock);
{
- ret = __inode_ctx_get (inode, this, &ctx);
-
+ ret = __inode_ctx_get (inode, this, &ctx_addr);
if (ret < 0)
+ ctx_addr = 0;
+ ctx = afr_inode_ctx_get_from_addr (ctx_addr, priv->child_count);
+ if (!ctx)
goto unlock;
-
- opendir_done = ctx & AFR_ICTX_OPENDIR_DONE_MASK;
+ switch (params->op) {
+ case AFR_INODE_SET_READ_CTX:
+ read_child = params->u.read_ctx.read_child;
+ fresh_children = params->u.read_ctx.children;
+ afr_inode_ctx_set_read_ctx (ctx, read_child,
+ fresh_children,
+ priv->child_count);
+ break;
+ case AFR_INODE_RM_STALE_CHILDREN:
+ stale_children = params->u.read_ctx.children;
+ afr_inode_ctx_rm_stale_children (ctx,
+ stale_children,
+ priv->child_count);
+ break;
+ case AFR_INODE_SET_OPENDIR_DONE:
+ afr_inode_ctx_set_opendir_done (ctx);
+ break;
+ case AFR_INODE_SET_SPLIT_BRAIN:
+ set = params->u.value;
+ afr_inode_ctx_set_splitbrain (ctx, set);
+ break;
+ default:
+ GF_ASSERT (0);
+ break;
+ }
+ ret = __inode_ctx_put (inode, this, (uint64_t)ctx);
+ if (ret) {
+ gf_log_callingfn (this->name, GF_LOG_ERROR, "failed to "
+ "set the inode ctx (%s)",
+ uuid_utoa (inode->gfid));
+ }
}
unlock:
UNLOCK (&inode->lock);
-
-out:
- return opendir_done;
}
+void
+afr_set_split_brain (xlator_t *this, inode_t *inode, gf_boolean_t set)
+{
+ afr_inode_params_t params = {0};
+
+ params.op = AFR_INODE_SET_SPLIT_BRAIN;
+ params.u.value = set;
+ afr_inode_set_ctx (this, inode, &params);
+}
void
afr_set_opendir_done (xlator_t *this, inode_t *inode)
{
- uint64_t ctx = 0;
- int ret = 0;
+ afr_inode_params_t params = {0};
- VALIDATE_OR_GOTO (inode, out);
+ params.op = AFR_INODE_SET_OPENDIR_DONE;
+ afr_inode_set_ctx (this, inode, &params);
+}
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get (inode, this, &ctx);
+void
+afr_inode_set_read_ctx (xlator_t *this, inode_t *inode, int32_t read_child,
+ int32_t *fresh_children)
+{
+ afr_inode_params_t params = {0};
+ afr_private_t *priv = NULL;
- if (ret < 0) {
- ctx = 0;
- }
+ priv = this->private;
+ GF_ASSERT (read_child >= 0);
+ GF_ASSERT (fresh_children);
+ GF_ASSERT (afr_is_child_present (fresh_children, priv->child_count,
+ read_child));
+
+ params.op = AFR_INODE_SET_READ_CTX;
+ params.u.read_ctx.read_child = read_child;
+ params.u.read_ctx.children = fresh_children;
+ afr_inode_set_ctx (this, inode, &params);
+}
- ctx = (~AFR_ICTX_OPENDIR_DONE_MASK & ctx)
- | (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_OPENDIR_DONE_MASK);
+void
+afr_inode_rm_stale_children (xlator_t *this, inode_t *inode,
+ int32_t *stale_children)
+{
+ afr_inode_params_t params = {0};
- ret = __inode_ctx_put (inode, this, ctx);
- if (ret) {
- gf_log_callingfn (this->name, GF_LOG_INFO,
- "failed to set the inode ctx (%s)",
- uuid_utoa (inode->gfid));
- }
+ GF_ASSERT (stale_children);
+
+ params.op = AFR_INODE_RM_STALE_CHILDREN;
+ params.u.read_ctx.children = stale_children;
+ afr_inode_set_ctx (this, inode, &params);
+}
+
+gf_boolean_t
+afr_is_source_child (int32_t *sources, int32_t child_count, int32_t child)
+{
+ gf_boolean_t source_xattrs = _gf_false;
+
+ GF_ASSERT (child < child_count);
+
+ if ((child >= 0) && (child < child_count) &&
+ sources[child]) {
+ source_xattrs = _gf_true;
}
- UNLOCK (&inode->lock);
-out:
- return;
+ return source_xattrs;
}
+gf_boolean_t
+afr_is_child_present (int32_t *success_children, int32_t child_count,
+ int32_t child)
+{
+ gf_boolean_t success_child = _gf_false;
+ int i = 0;
+
+ GF_ASSERT (child < child_count);
-uint64_t
-afr_read_child (xlator_t *this, inode_t *inode)
+ for (i = 0; i < child_count; i++) {
+ if (success_children[i] == -1)
+ break;
+ if (child == success_children[i]) {
+ success_child = _gf_true;
+ break;
+ }
+ }
+ return success_child;
+}
+
+gf_boolean_t
+afr_is_read_child (int32_t *success_children, int32_t *sources,
+ int32_t child_count, int32_t child)
{
- int ret = 0;
+ gf_boolean_t success_child = _gf_false;
+ gf_boolean_t source = _gf_false;
- uint64_t ctx = 0;
- uint64_t read_child = 0;
+ GF_ASSERT (success_children);
+ GF_ASSERT (child_count > 0);
- VALIDATE_OR_GOTO (inode, out);
+ success_child = afr_is_child_present (success_children, child_count,
+ child);
+ if (!success_child)
+ goto out;
+ if (NULL == sources) {
+ source = _gf_true;
+ goto out;
+ }
+ source = afr_is_source_child (sources, child_count, child);
+out:
+ return (success_child && source);
+}
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get (inode, this, &ctx);
+/* If sources is NULL the xattrs are assumed to be of source for all
+ * success_children.
+ */
+int
+afr_select_read_child_from_policy (int32_t *success_children, int32_t child_count,
+ int32_t prev_read_child,
+ int32_t config_read_child, int32_t *sources)
+{
+ int32_t read_child = -1;
+ int i = 0;
- if (ret < 0)
- goto unlock;
+ GF_ASSERT (success_children);
+
+ read_child = prev_read_child;
+ if (afr_is_read_child (success_children, sources, child_count,
+ read_child))
+ goto out;
+
+ read_child = config_read_child;
+ if (afr_is_read_child (success_children, sources, child_count,
+ read_child))
+ goto out;
- read_child = ctx & AFR_ICTX_READ_CHILD_MASK;
+ for (i = 0; i < child_count; i++) {
+ read_child = success_children[i];
+ if (read_child < 0)
+ break;
+ if (afr_is_read_child (success_children, sources, child_count,
+ read_child))
+ goto out;
}
-unlock:
- UNLOCK (&inode->lock);
+ read_child = -1;
out:
return read_child;
}
-
+/* This function should be used when all the success_children are sources
+ */
void
-afr_set_read_child (xlator_t *this, inode_t *inode, int32_t read_child)
+afr_set_read_ctx_from_policy (xlator_t *this, inode_t *inode,
+ int32_t *fresh_children, int32_t prev_read_child,
+ int32_t config_read_child)
{
- uint64_t ctx = 0;
- int ret = 0;
+ int read_child = -1;
+ afr_private_t *priv = NULL;
- VALIDATE_OR_GOTO (inode, out);
+ priv = this->private;
+ read_child = afr_select_read_child_from_policy (fresh_children,
+ priv->child_count,
+ prev_read_child,
+ config_read_child,
+ NULL);
+ if (read_child >= 0)
+ afr_inode_set_read_ctx (this, inode, read_child,
+ fresh_children);
+}
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get (inode, this, &ctx);
+/* afr_next_call_child ()
+ * This is a common function used by all the read-type fops
+ * This function should not be called with the inode's read_children array.
+ * The fop's handler should make a copy of the inode's read_children,
+ * preferred read_child into the local vars, because while this function is
+ * in execution there is a chance for inode's read_ctx to change.
+ */
+int32_t
+afr_next_call_child (int32_t *fresh_children, unsigned char *child_up,
+ size_t child_count, int32_t *last_index,
+ int32_t read_child)
+{
+ int next_index = 0;
+ int32_t next_call_child = -1;
- if (ret < 0) {
- ctx = 0;
- }
+ GF_ASSERT (last_index);
- ctx = (~AFR_ICTX_READ_CHILD_MASK & ctx)
- | (AFR_ICTX_READ_CHILD_MASK & read_child);
+ next_index = *last_index;
+retry:
+ next_index++;
+ if ((next_index >= child_count) ||
+ (fresh_children[next_index] == -1))
+ goto out;
+ if ((fresh_children[next_index] == read_child) ||
+ (!child_up[fresh_children[next_index]]))
+ goto retry;
+ *last_index = next_index;
+ next_call_child = fresh_children[next_index];
+out:
+ return next_call_child;
+}
- ret = __inode_ctx_put (inode, this, ctx);
- if (ret) {
- gf_log_callingfn (this->name, GF_LOG_INFO,
- "failed to set the inode ctx (%s)",
- uuid_utoa (inode->gfid));
- }
+ /* This function should not be called with the inode's read_children array.
+ * The fop's handler should make a copy of the inode's read_children,
+ * preferred read_child into the local vars, because while this function is
+ * in execution there is a chance for inode's read_ctx to change.
+ */
+int32_t
+afr_get_call_child (xlator_t *this, unsigned char *child_up, int32_t read_child,
+ int32_t *fresh_children,
+ int32_t *call_child, int32_t *last_index)
+{
+ int ret = 0;
+ afr_private_t *priv = NULL;
+ int i = 0;
+
+ GF_ASSERT (child_up);
+ GF_ASSERT (call_child);
+ GF_ASSERT (last_index);
+ GF_ASSERT (fresh_children);
+
+ if (read_child < 0) {
+ ret = -EIO;
+ goto out;
}
- UNLOCK (&inode->lock);
+ priv = this->private;
+ *call_child = -1;
+ *last_index = -1;
+
+ if (child_up[read_child]) {
+ *call_child = read_child;
+ } else {
+ for (i = 0; i < priv->child_count; i++) {
+ if (fresh_children[i] == -1)
+ break;
+ if (child_up[fresh_children[i]]) {
+ *call_child = fresh_children[i];
+ ret = 0;
+ break;
+ }
+ }
+
+ if (*call_child == -1) {
+ ret = -ENOTCONN;
+ goto out;
+ }
+ *last_index = i;
+ }
out:
- return;
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d, call_child: %d, "
+ "last_index: %d", ret, *call_child, *last_index);
+ return ret;
}
+void
+afr_reset_xattr (dict_t **xattr, unsigned int child_count)
+{
+ unsigned int i = 0;
-/**
- * afr_local_cleanup - cleanup everything in frame->local
- */
+ if (!xattr)
+ goto out;
+ for (i = 0; i < child_count; i++) {
+ if (xattr[i]) {
+ dict_unref (xattr[i]);
+ xattr[i] = NULL;
+ }
+ }
+out:
+ return;
+}
void
afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)
{
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
- int i = 0;
-
sh = &local->self_heal;
priv = this->private;
@@ -273,32 +734,22 @@ afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)
if (sh->buf)
GF_FREE (sh->buf);
+ if (sh->parentbufs)
+ GF_FREE (sh->parentbufs);
+
+ if (sh->inode)
+ inode_unref (sh->inode);
+
if (sh->xattr) {
- for (i = 0; i < priv->child_count; i++) {
- if (sh->xattr[i]) {
- dict_unref (sh->xattr[i]);
- sh->xattr[i] = NULL;
- }
- }
+ afr_reset_xattr (sh->xattr, priv->child_count);
GF_FREE (sh->xattr);
}
if (sh->child_errno)
GF_FREE (sh->child_errno);
- if (sh->pending_matrix) {
- for (i = 0; i < priv->child_count; i++) {
- GF_FREE (sh->pending_matrix[i]);
- }
- GF_FREE (sh->pending_matrix);
- }
-
- if (sh->delta_matrix) {
- for (i = 0; i < priv->child_count; i++) {
- GF_FREE (sh->delta_matrix[i]);
- }
- GF_FREE (sh->delta_matrix);
- }
+ afr_matrix_cleanup (sh->pending_matrix, priv->child_count);
+ afr_matrix_cleanup (sh->delta_matrix, priv->child_count);
if (sh->sources)
GF_FREE (sh->sources);
@@ -309,7 +760,7 @@ afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)
if (sh->locked_nodes)
GF_FREE (sh->locked_nodes);
- if (sh->healing_fd && !sh->healing_fd_opened) {
+ if (sh->healing_fd) {
fd_unref (sh->healing_fd);
sh->healing_fd = NULL;
}
@@ -317,24 +768,36 @@ afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)
if (sh->linkname)
GF_FREE ((char *)sh->linkname);
+ if (sh->success_children)
+ GF_FREE (sh->success_children);
+
+ if (sh->fresh_children)
+ GF_FREE (sh->fresh_children);
+
+ if (sh->fresh_parent_dirs)
+ GF_FREE (sh->fresh_parent_dirs);
+
loc_wipe (&sh->parent_loc);
+ loc_wipe (&sh->lookup_loc);
+
+ if (sh->checksum)
+ GF_FREE (sh->checksum);
+
+ if (sh->write_needed)
+ GF_FREE (sh->write_needed);
+ if (sh->healing_fd)
+ fd_unref (sh->healing_fd);
}
void
afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)
{
- int i = 0;
afr_private_t * priv = NULL;
priv = this->private;
- for (i = 0; i < priv->child_count; i++) {
- if (local->pending && local->pending[i])
- GF_FREE (local->pending[i]);
- }
-
- GF_FREE (local->pending);
+ afr_matrix_cleanup (local->pending, priv->child_count);
if (local->internal_lock.locked_nodes)
GF_FREE (local->internal_lock.locked_nodes);
@@ -349,8 +812,9 @@ afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)
GF_FREE (local->internal_lock.lower_locked_nodes);
+ GF_FREE (local->transaction.pre_op);
GF_FREE (local->transaction.child_errno);
- GF_FREE (local->child_errno);
+ GF_FREE (local->transaction.eager_lock);
GF_FREE (local->transaction.basename);
GF_FREE (local->transaction.new_basename);
@@ -363,7 +827,6 @@ afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)
void
afr_local_cleanup (afr_local_t *local, xlator_t *this)
{
- int i = 0;
afr_private_t * priv = NULL;
if (!local)
@@ -384,16 +847,25 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
if (local->xattr_req)
dict_unref (local->xattr_req);
- GF_FREE (local->child_up);
+ if (local->dict)
+ dict_unref (local->dict);
+
+ if (local->child_up)
+ GF_FREE (local->child_up);
+
+ if (local->child_errno)
+ GF_FREE (local->child_errno);
+
+ if (local->fresh_children)
+ GF_FREE (local->fresh_children);
+
+ if (local->fd_open_on)
+ GF_FREE (local->fd_open_on);
{ /* lookup */
if (local->cont.lookup.xattrs) {
- for (i = 0; i < priv->child_count; i++) {
- if (local->cont.lookup.xattrs[i]) {
- dict_unref (local->cont.lookup.xattrs[i]);
- local->cont.lookup.xattrs[i] = NULL;
- }
- }
+ afr_reset_xattr (local->cont.lookup.xattrs,
+ priv->child_count);
GF_FREE (local->cont.lookup.xattrs);
local->cont.lookup.xattrs = NULL;
}
@@ -405,6 +877,18 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
if (local->cont.lookup.inode) {
inode_unref (local->cont.lookup.inode);
}
+
+ if (local->cont.lookup.postparents)
+ GF_FREE (local->cont.lookup.postparents);
+
+ if (local->cont.lookup.bufs)
+ GF_FREE (local->cont.lookup.bufs);
+
+ if (local->cont.lookup.success_children)
+ GF_FREE (local->cont.lookup.success_children);
+
+ if (local->cont.lookup.sources)
+ GF_FREE (local->cont.lookup.sources);
}
{ /* getxattr */
@@ -448,10 +932,22 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
dict_unref (local->cont.setxattr.dict);
}
+ { /* fsetxattr */
+ if (local->cont.fsetxattr.dict)
+ dict_unref (local->cont.fsetxattr.dict);
+ }
+
{ /* removexattr */
GF_FREE (local->cont.removexattr.name);
}
-
+ { /* xattrop */
+ if (local->cont.xattrop.xattr)
+ dict_unref (local->cont.xattrop.xattr);
+ }
+ { /* fxattrop */
+ if (local->cont.fxattrop.xattr)
+ dict_unref (local->cont.fxattrop.xattr);
+ }
{ /* symlink */
GF_FREE (local->cont.symlink.linkpath);
}
@@ -460,6 +956,17 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
if (local->cont.opendir.checksum)
GF_FREE (local->cont.opendir.checksum);
}
+
+ { /* readdirp */
+ if (local->cont.readdir.dict)
+ dict_unref (local->cont.readdir.dict);
+ }
+
+ if (local->xdata_req)
+ dict_unref (local->xdata_req);
+
+ if (local->xdata_rsp)
+ dict_unref (local->xdata_rsp);
}
@@ -480,106 +987,140 @@ afr_frame_return (call_frame_t *frame)
return call_count;
}
-
-/**
- * up_children_count - return the number of children that are up
- */
-
int
-afr_up_children_count (int child_count, unsigned char *child_up)
+afr_set_elem_count_get (unsigned char *elems, int child_count)
{
int i = 0;
int ret = 0;
for (i = 0; i < child_count; i++)
- if (child_up[i])
+ if (elems[i])
ret++;
return ret;
}
+/**
+ * up_children_count - return the number of children that are up
+ */
-ino64_t
-afr_itransform (ino64_t ino, int child_count, int child_index)
+unsigned int
+afr_up_children_count (unsigned char *child_up, unsigned int child_count)
{
- ino64_t scaled_ino = -1;
-
- if (ino == ((uint64_t) -1)) {
- scaled_ino = ((uint64_t) -1);
- goto out;
- }
-
- scaled_ino = (ino * child_count) + child_index;
+ return afr_set_elem_count_get (child_up, child_count);
+}
-out:
- return scaled_ino;
+unsigned int
+afr_locked_children_count (unsigned char *children, unsigned int child_count)
+{
+ return afr_set_elem_count_get (children, child_count);
}
+unsigned int
+afr_pre_op_done_children_count (unsigned char *pre_op,
+ unsigned int child_count)
+{
+ return afr_set_elem_count_get (pre_op, child_count);
+}
-int
-afr_deitransform_orig (ino64_t ino, int child_count)
+gf_boolean_t
+afr_is_fresh_lookup (loc_t *loc, xlator_t *this)
{
- int index = -1;
+ uint64_t ctx = 0;
+ int32_t ret = 0;
- index = ino % child_count;
+ GF_ASSERT (loc);
+ GF_ASSERT (this);
+ GF_ASSERT (loc->inode);
- return index;
+ ret = inode_ctx_get (loc->inode, this, &ctx);
+ if (0 == ret)
+ return _gf_false;
+ return _gf_true;
}
-
-int
-afr_deitransform (ino64_t ino, int child_count)
+void
+afr_update_loc_gfids (loc_t *loc, struct iatt *buf, struct iatt *postparent)
{
- return 0;
-}
+ GF_ASSERT (loc);
+ GF_ASSERT (buf);
+ uuid_copy (loc->gfid, buf->ia_gfid);
+ if (postparent)
+ uuid_copy (loc->pargfid, postparent->ia_gfid);
+}
int
-afr_self_heal_lookup_unwind (call_frame_t *frame, xlator_t *this)
+afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)
{
- afr_local_t *local = NULL;
-
- local = frame->local;
+ struct iatt *buf = NULL;
+ struct iatt *postparent = NULL;
+ dict_t **xattr = NULL;
+ int32_t *success_children = NULL;
+ int32_t *sources = NULL;
+ afr_private_t *priv = NULL;
+ int32_t read_child = -1;
+ int ret = 0;
+ int i = 0;
- if (local->govinda_gOvinda && local->cont.lookup.inode) {
- afr_set_split_brain (this, local->cont.lookup.inode, _gf_true);
- }
+ GF_ASSERT (local);
- AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->cont.lookup.inode,
- &local->cont.lookup.buf,
- local->cont.lookup.xattr,
- &local->cont.lookup.postparent);
+ buf = &local->cont.lookup.buf;
+ postparent = &local->cont.lookup.postparent;
+ xattr = &local->cont.lookup.xattr;
+ priv = this->private;
- return 0;
+ read_child = afr_inode_get_read_ctx (this, local->cont.lookup.inode,
+ local->fresh_children);
+ if (read_child < 0) {
+ ret = -1;
+ goto out;
+ }
+ success_children = local->cont.lookup.success_children;
+ sources = local->cont.lookup.sources;
+ memset (sources, 0, sizeof (*sources) * priv->child_count);
+ afr_children_intersection_get (local->fresh_children, success_children,
+ sources, priv->child_count);
+ if (!sources[read_child]) {
+ read_child = -1;
+ for (i = 0; i < priv->child_count; i++) {
+ if (sources[i]) {
+ read_child = i;
+ break;
+ }
+ }
+ }
+ if (read_child < 0) {
+ ret = -1;
+ goto out;
+ }
+ gf_log (this->name, GF_LOG_DEBUG, "Building lookup response from %d",
+ read_child);
+ if (!*xattr)
+ *xattr = dict_ref (local->cont.lookup.xattrs[read_child]);
+ *buf = local->cont.lookup.bufs[read_child];
+ *postparent = local->cont.lookup.postparents[read_child];
+
+ if (IA_INVAL == local->cont.lookup.inode->ia_type) {
+ /* fix for RT #602 */
+ local->cont.lookup.inode->ia_type = buf->ia_type;
+ }
+out:
+ return ret;
}
-
static void
-afr_lookup_collect_xattr (afr_local_t *local, xlator_t *this,
- int child_index, dict_t *xattr)
+afr_lookup_update_lk_counts (afr_local_t *local, xlator_t *this,
+ int child_index, dict_t *xattr)
{
uint32_t inodelk_count = 0;
uint32_t entrylk_count = 0;
- int ret = 0;
+ int ret = -1;
+ uint32_t parent_entrylk = 0;
- if (afr_sh_has_metadata_pending (xattr, child_index, this)) {
- local->self_heal.need_metadata_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_DEBUG,
- "metadata self-heal is pending for %s.",
- local->loc.path);
- }
-
- if (afr_sh_has_entry_pending (xattr, child_index, this)) {
- local->self_heal.need_entry_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_INFO,
- "entry self-heal is pending for %s.", local->loc.path);
- }
-
- if (afr_sh_has_data_pending (xattr, child_index, this)) {
- local->self_heal.need_data_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_INFO,
- "data self-heal is pending for %s.", local->loc.path);
- }
+ GF_ASSERT (local);
+ GF_ASSERT (this);
+ GF_ASSERT (xattr);
+ GF_ASSERT (child_index >= 0);
ret = dict_get_uint32 (xattr, GLUSTERFS_INODELK_COUNT,
&inodelk_count);
@@ -590,42 +1131,63 @@ afr_lookup_collect_xattr (afr_local_t *local, xlator_t *this,
&entrylk_count);
if (ret == 0)
local->entrylk_count += entrylk_count;
+ ret = dict_get_uint32 (xattr, GLUSTERFS_PARENT_ENTRYLK,
+ &parent_entrylk);
+ if (!ret)
+ local->cont.lookup.parent_entrylk += parent_entrylk;
}
-
static void
-afr_lookup_self_heal_check (xlator_t *this, afr_local_t *local,
- struct iatt *buf, struct iatt *lookup_buf)
+afr_lookup_set_self_heal_params_by_xattr (afr_local_t *local, xlator_t *this,
+ dict_t *xattr)
{
- if (FILETYPE_DIFFERS (buf, lookup_buf)) {
- /* mismatching filetypes with same name
- */
+ GF_ASSERT (local);
+ GF_ASSERT (this);
+ GF_ASSERT (xattr);
- gf_log (this->name, GF_LOG_INFO,
- "filetype differs for %s ", local->loc.path);
+ if (afr_sh_has_metadata_pending (xattr, this)) {
+ local->self_heal.do_metadata_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_DEBUG,
+ "metadata self-heal is pending for %s.",
+ local->loc.path);
+ }
- local->govinda_gOvinda = 1;
+ if (afr_sh_has_entry_pending (xattr, this)) {
+ local->self_heal.do_entry_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_DEBUG,
+ "entry self-heal is pending for %s.", local->loc.path);
}
+ if (afr_sh_has_data_pending (xattr, this)) {
+ local->self_heal.do_data_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_DEBUG,
+ "data self-heal is pending for %s.", local->loc.path);
+ }
+}
+
+static void
+afr_detect_self_heal_by_iatt (afr_local_t *local, xlator_t *this,
+ struct iatt *buf, struct iatt *lookup_buf)
+{
if (PERMISSION_DIFFERS (buf, lookup_buf)) {
/* mismatching permissions */
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_DEBUG,
"permissions differ for %s ", local->loc.path);
- local->self_heal.need_metadata_self_heal = _gf_true;
+ local->self_heal.do_metadata_self_heal = _gf_true;
}
if (OWNERSHIP_DIFFERS (buf, lookup_buf)) {
/* mismatching permissions */
- local->self_heal.need_metadata_self_heal = _gf_true;
- gf_log (this->name, GF_LOG_INFO,
+ local->self_heal.do_metadata_self_heal = _gf_true;
+ gf_log (this->name, GF_LOG_DEBUG,
"ownership differs for %s ", local->loc.path);
}
if (SIZE_DIFFERS (buf, lookup_buf)
&& IA_ISREG (buf->ia_type)) {
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_DEBUG,
"size differs for %s ", local->loc.path);
- local->self_heal.need_data_self_heal = _gf_true;
+ local->self_heal.do_data_self_heal = _gf_true;
}
if (uuid_compare (buf->ia_gfid, lookup_buf->ia_gfid)) {
@@ -635,437 +1197,1024 @@ afr_lookup_self_heal_check (xlator_t *this, afr_local_t *local,
}
}
-
static void
-afr_lookup_done (call_frame_t *frame, xlator_t *this, struct iatt *lookup_buf)
+afr_detect_self_heal_by_lookup_status (afr_local_t *local, xlator_t *this,
+ gf_boolean_t split_brain)
{
- int unwind = 1;
- int source = -1;
- int up_count = 0;
- char sh_type_str[256] = {0,};
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- local->cont.lookup.postparent.ia_ino = local->cont.lookup.parent_ino;
+ GF_ASSERT (local);
+ GF_ASSERT (this);
- if (local->cont.lookup.ino) {
- local->cont.lookup.buf.ia_ino = local->cont.lookup.ino;
+ if ((local->success_count > 0) && (local->enoent_count > 0)) {
+ local->self_heal.do_metadata_self_heal = _gf_true;
+ local->self_heal.do_data_self_heal = _gf_true;
+ local->self_heal.do_entry_self_heal = _gf_true;
+ local->self_heal.do_gfid_self_heal = _gf_true;
+ local->self_heal.do_missing_entry_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_DEBUG,
+ "entries are missing in lookup of %s.",
+ local->loc.path);
+ //If all self-heals are needed no need to check for other rules
+ goto out;
}
- if (local->op_ret == 0) {
- /* KLUDGE: assuming DHT will not itransform in
- revalidate */
- if (local->cont.lookup.inode->ino) {
- local->cont.lookup.buf.ia_ino =
- local->cont.lookup.inode->ino;
- }
- }
- up_count = afr_up_children_count (priv->child_count, priv->child_up);
- if (up_count == 1) {
+ if ((local->success_count > 0) && split_brain &&
+ IA_ISREG (local->cont.lookup.inode->ia_type)) {
+ local->self_heal.do_data_self_heal = _gf_true;
+ local->self_heal.do_metadata_self_heal = _gf_true;
gf_log (this->name, GF_LOG_DEBUG,
- "Only 1 child up - do not attempt to detect self heal");
-
- goto unwind;
+ "split brain detected during lookup of %s.",
+ local->loc.path);
}
- if (local->success_count && local->enoent_count) {
- local->self_heal.need_metadata_self_heal = _gf_true;
- local->self_heal.need_data_self_heal = _gf_true;
- local->self_heal.need_entry_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_INFO,
- "entries are missing in lookup of %s.",
- local->loc.path);
+out:
+ return;
+}
+
+gf_boolean_t
+afr_can_self_heal_proceed (afr_self_heal_t *sh, afr_private_t *priv)
+{
+ GF_ASSERT (sh);
+ GF_ASSERT (priv);
+
+ return (sh->do_gfid_self_heal
+ || sh->do_missing_entry_self_heal
+ || (afr_data_self_heal_enabled (priv->data_self_heal) &&
+ sh->do_data_self_heal)
+ || (priv->metadata_self_heal && sh->do_metadata_self_heal)
+ || (priv->entry_self_heal && sh->do_entry_self_heal));
+}
+
+afr_transaction_type
+afr_transaction_type_get (ia_type_t ia_type)
+{
+ afr_transaction_type type = AFR_METADATA_TRANSACTION;
+
+ GF_ASSERT (ia_type != IA_INVAL);
+
+ if (IA_ISDIR (ia_type)) {
+ type = AFR_ENTRY_TRANSACTION;
+ } else if (IA_ISREG (ia_type)) {
+ type = AFR_DATA_TRANSACTION;
}
+ return type;
+}
- if (local->success_count) {
- /* check for split-brain case in previous lookup */
- if (afr_is_split_brain (this, local->cont.lookup.inode)) {
- local->self_heal.need_data_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_WARNING,
- "split brain detected during lookup of %s.",
- local->loc.path);
- }
+int
+afr_lookup_select_read_child (afr_local_t *local, xlator_t *this,
+ int32_t *read_child)
+{
+ ia_type_t ia_type = IA_INVAL;
+ int32_t source = -1;
+ int ret = -1;
+ dict_t **xattrs = NULL;
+ int32_t *success_children = NULL;
+ afr_transaction_type type = AFR_METADATA_TRANSACTION;
+
+ GF_ASSERT (local);
+ GF_ASSERT (this);
+ GF_ASSERT (local->success_count > 0);
+
+ success_children = local->cont.lookup.success_children;
+ /*We can take the success_children[0] only because we already
+ *handle the conflicting children other wise, we could select the
+ *read_child based on wrong file type
+ */
+ ia_type = local->cont.lookup.bufs[success_children[0]].ia_type;
+ type = afr_transaction_type_get (ia_type);
+ xattrs = local->cont.lookup.xattrs;
+ source = afr_lookup_select_read_child_by_txn_type (this, local, xattrs,
+ type);
+ if (source < 0) {
+ gf_log (this->name, GF_LOG_DEBUG, "failed to select source "
+ "for %s", local->loc.path);
+ goto out;
}
- if ((local->self_heal.need_metadata_self_heal
- || local->self_heal.need_data_self_heal
- || local->self_heal.need_entry_self_heal)
- && ((!local->cont.lookup.is_revalidate)
- || (local->op_ret != -1))) {
+ gf_log (this->name, GF_LOG_DEBUG, "Source selected as %d for %s",
+ source, local->loc.path);
+ *read_child = source;
+ ret = 0;
+out:
+ return ret;
+}
- if (local->inodelk_count || local->entrylk_count) {
+static inline gf_boolean_t
+afr_is_transaction_running (afr_local_t *local)
+{
+ GF_ASSERT (local->fop == GF_FOP_LOOKUP);
+ return ((local->inodelk_count > 0) || (local->entrylk_count > 0));
+}
+
+void
+afr_launch_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode,
+ gf_boolean_t background, ia_type_t ia_type, char *reason,
+ void (*gfid_sh_success_cbk) (call_frame_t *sh_frame,
+ xlator_t *this),
+ int (*unwind) (call_frame_t *frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ int32_t sh_failed))
+{
+ afr_local_t *local = NULL;
+ char sh_type_str[256] = {0,};
+ char *bg = "";
- /* Someone else is doing self-heal on this file.
- So just make a best effort to set the read-subvolume
- and return */
+ GF_ASSERT (frame);
+ GF_ASSERT (this);
+ GF_ASSERT (inode);
+ GF_ASSERT (ia_type != IA_INVAL);
- if (IA_ISREG (local->cont.lookup.inode->ia_type)) {
- source = afr_self_heal_get_source (this, local, local->cont.lookup.xattrs);
+ local = frame->local;
+ local->self_heal.background = background;
+ local->self_heal.type = ia_type;
+ local->self_heal.unwind = unwind;
+ local->self_heal.gfid_sh_success_cbk = gfid_sh_success_cbk;
+
+ afr_self_heal_type_str_get (&local->self_heal,
+ sh_type_str,
+ sizeof (sh_type_str));
+
+ if (background)
+ bg = "background";
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s %s self-heal triggered. path: %s, reason: %s", bg,
+ sh_type_str, local->loc.path, reason);
+
+ afr_self_heal (frame, this, inode);
+}
- if (source >= 0) {
- afr_set_read_child (this,
- local->cont.lookup.inode,
- source);
- }
- }
- goto unwind;
- }
+unsigned int
+afr_gfid_missing_count (const char *xlator_name, int32_t *success_children,
+ struct iatt *bufs, unsigned int child_count,
+ const char *path)
+{
+ unsigned int gfid_miss_count = 0;
+ int i = 0;
+ struct iatt *child1 = NULL;
- if (!local->cont.lookup.inode->ia_type) {
- /* fix for RT #602 */
- local->cont.lookup.inode->ia_type =
- lookup_buf->ia_type;
+ for (i = 0; i < child_count; i++) {
+ if (success_children[i] == -1)
+ break;
+ child1 = &bufs[success_children[i]];
+ if (uuid_is_null (child1->ia_gfid)) {
+ gf_log (xlator_name, GF_LOG_DEBUG, "%s: gfid is null"
+ " on subvolume %d", path, success_children[i]);
+ gfid_miss_count++;
}
+ }
- local->self_heal.background = _gf_true;
- local->self_heal.type = local->cont.lookup.buf.ia_type;
- local->self_heal.unwind = afr_self_heal_lookup_unwind;
+ return gfid_miss_count;
+}
- unwind = 0;
+static int
+afr_lookup_gfid_missing_count (afr_local_t *local, xlator_t *this)
+{
+ int32_t *success_children = NULL;
+ afr_private_t *priv = NULL;
+ struct iatt *bufs = NULL;
+ int miss_count = 0;
- afr_self_heal_type_str_get(&local->self_heal,
- sh_type_str,
- sizeof(sh_type_str));
+ priv = this->private;
+ bufs = local->cont.lookup.bufs;
+ success_children = local->cont.lookup.success_children;
- gf_log (this->name, GF_LOG_INFO,
- "background %s self-heal triggered. path: %s",
- sh_type_str, local->loc.path);
+ miss_count = afr_gfid_missing_count (this->name, success_children,
+ bufs, priv->child_count,
+ local->loc.path);
+ return miss_count;
+}
- afr_self_heal (frame, this);
- }
+gf_boolean_t
+afr_conflicting_iattrs (struct iatt *bufs, int32_t *success_children,
+ unsigned int child_count, const char *path,
+ const char *xlator_name)
+{
+ gf_boolean_t conflicting = _gf_false;
+ int i = 0;
+ struct iatt *child1 = NULL;
+ struct iatt *child2 = NULL;
+ uuid_t *gfid = NULL;
-unwind:
- if (unwind) {
- AFR_STACK_UNWIND (lookup, frame, local->op_ret,
- local->op_errno,
- local->cont.lookup.inode,
- &local->cont.lookup.buf,
- local->cont.lookup.xattr,
- &local->cont.lookup.postparent);
+ for (i = 0; i < child_count; i++) {
+ if (success_children[i] == -1)
+ break;
+ child1 = &bufs[success_children[i]];
+ if ((!gfid) && (!uuid_is_null (child1->ia_gfid)))
+ gfid = &child1->ia_gfid;
+
+ if (i == 0)
+ continue;
+
+ child2 = &bufs[success_children[i-1]];
+ if (FILETYPE_DIFFERS (child1, child2)) {
+ gf_log (xlator_name, GF_LOG_WARNING, "%s: filetype "
+ "differs on subvolumes (%d, %d)", path,
+ success_children[i-1], success_children[i]);
+ conflicting = _gf_true;
+ goto out;
+ }
+ if (!gfid || uuid_is_null (child1->ia_gfid))
+ continue;
+ if (uuid_compare (*gfid, child1->ia_gfid)) {
+ gf_log (xlator_name, GF_LOG_WARNING, "%s: gfid differs"
+ " on subvolume %d", path, success_children[i]);
+ conflicting = _gf_true;
+ goto out;
+ }
}
+out:
+ return conflicting;
}
-
-/*
- * During a lookup, some errors are more "important" than
- * others in that they must be given higher priority while
- * returning to the user.
- *
- * The hierarchy is ESTALE > ENOENT > others
- *
+/* afr_update_gfid_from_iatts: This function should be called only if the
+ * iatts are not conflicting.
*/
+void
+afr_update_gfid_from_iatts (uuid_t uuid, struct iatt *bufs,
+ int32_t *success_children, unsigned int child_count)
+{
+ uuid_t *gfid = NULL;
+ int i = 0;
+ int child = 0;
+
+ for (i = 0; i < child_count; i++) {
+ child = success_children[i];
+ if (child == -1)
+ break;
+ if ((!gfid) && (!uuid_is_null (bufs[child].ia_gfid))) {
+ gfid = &bufs[child].ia_gfid;
+ } else if (gfid && (!uuid_is_null (bufs[child].ia_gfid))) {
+ if (uuid_compare (*gfid, bufs[child].ia_gfid)) {
+ GF_ASSERT (0);
+ goto out;
+ }
+ }
+ }
+ if (gfid && (!uuid_is_null (*gfid)))
+ uuid_copy (uuid, *gfid);
+out:
+ return;
+}
static gf_boolean_t
-__error_more_important (int32_t old_errno, int32_t new_errno)
+afr_lookup_conflicting_entries (afr_local_t *local, xlator_t *this)
{
- gf_boolean_t ret = _gf_true;
+ afr_private_t *priv = NULL;
+ gf_boolean_t conflict = _gf_false;
- /* Nothing should ever overwrite ESTALE */
- if (old_errno == ESTALE)
- ret = _gf_false;
+ priv = this->private;
+ conflict = afr_conflicting_iattrs (local->cont.lookup.bufs,
+ local->cont.lookup.success_children,
+ priv->child_count, local->loc.path,
+ this->name);
+ return conflict;
+}
- /* Nothing should overwrite ENOENT, except ESTALE */
- else if ((old_errno == ENOENT) && (new_errno != ESTALE))
- ret = _gf_false;
+gf_boolean_t
+afr_open_only_data_self_heal (char *data_self_heal)
+{
+ return !strcmp (data_self_heal, "open");
+}
- return ret;
+gf_boolean_t
+afr_data_self_heal_enabled (char *data_self_heal)
+{
+ gf_boolean_t enabled = _gf_false;
+
+ if (gf_string2boolean (data_self_heal, &enabled) == -1) {
+ enabled = !strcmp (data_self_heal, "open");
+ GF_ASSERT (enabled);
+ }
+
+ return enabled;
}
+static void
+afr_lookup_set_self_heal_params (afr_local_t *local, xlator_t *this)
+{
+ int i = 0;
+ struct iatt *bufs = NULL;
+ dict_t **xattr = NULL;
+ afr_private_t *priv = NULL;
+ int32_t child1 = -1;
+ int32_t child2 = -1;
+ afr_self_heal_t *sh = NULL;
+ gf_boolean_t split_brain = _gf_false;
+
+ priv = this->private;
+ sh = &local->self_heal;
+
+ split_brain = afr_is_split_brain (this, local->cont.lookup.inode);
+ split_brain = split_brain || local->cont.lookup.possible_spb;
+ afr_detect_self_heal_by_lookup_status (local, this, split_brain);
+
+ if (afr_lookup_gfid_missing_count (local, this))
+ local->self_heal.do_gfid_self_heal = _gf_true;
+
+ if (_gf_true == afr_lookup_conflicting_entries (local, this))
+ local->self_heal.do_missing_entry_self_heal = _gf_true;
+ else
+ afr_update_gfid_from_iatts (local->self_heal.sh_gfid_req,
+ local->cont.lookup.bufs,
+ local->cont.lookup.success_children,
+ priv->child_count);
+
+ bufs = local->cont.lookup.bufs;
+ for (i = 1; i < local->success_count; i++) {
+ child1 = local->cont.lookup.success_children[i-1];
+ child2 = local->cont.lookup.success_children[i];
+ afr_detect_self_heal_by_iatt (local, this,
+ &bufs[child1], &bufs[child2]);
+ }
+
+ xattr = local->cont.lookup.xattrs;
+ for (i = 0; i < local->success_count; i++) {
+ child1 = local->cont.lookup.success_children[i];
+ afr_lookup_set_self_heal_params_by_xattr (local, this,
+ xattr[child1]);
+ }
+ if (afr_open_only_data_self_heal (priv->data_self_heal)
+ && !split_brain)
+ sh->do_data_self_heal = _gf_false;
+}
int
-afr_fresh_lookup_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
+afr_self_heal_lookup_unwind (call_frame_t *frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ int32_t sh_failed)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- struct iatt * lookup_buf = NULL;
- int call_count = -1;
- int child_index = -1;
- int first_up_child = -1;
+ afr_local_t *local = NULL;
+ int ret = -1;
+ dict_t *xattr = NULL;
- child_index = (long) cookie;
+ local = frame->local;
+
+ if (op_ret == -1) {
+ local->op_ret = -1;
+ if (afr_error_more_important (local->op_errno, op_errno))
+ local->op_errno = op_errno;
+
+ goto out;
+ } else {
+ local->op_ret = 0;
+ }
+
+ afr_lookup_done_success_action (frame, this, _gf_true);
+ xattr = local->cont.lookup.xattr;
+ if (xattr) {
+ ret = dict_set_int32 (xattr, "sh-failed", sh_failed);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR, "%s: Failed to set "
+ "sh-failed to %d", local->loc.path, sh_failed);
+ }
+out:
+ AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
+ local->cont.lookup.inode, &local->cont.lookup.buf,
+ local->cont.lookup.xattr,
+ &local->cont.lookup.postparent);
+
+ return 0;
+}
+
+//TODO: At the moment only lookup needs this, so not doing any checks, in the
+// future we will have to do fop specific operations
+void
+afr_post_gfid_sh_success (call_frame_t *sh_frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+ afr_local_t *sh_local = NULL;
+ afr_private_t *priv = NULL;
+ afr_self_heal_t *sh = NULL;
+ int i = 0;
+ struct iatt *lookup_bufs = NULL;
+ struct iatt *lookup_parentbufs = NULL;
+
+ sh_local = sh_frame->local;
+ sh = &sh_local->self_heal;
+ local = sh->orig_frame->local;
+ lookup_bufs = local->cont.lookup.bufs;
+ lookup_parentbufs = local->cont.lookup.postparents;
priv = this->private;
- LOCK (&frame->lock);
- {
- local = frame->local;
+ memcpy (lookup_bufs, sh->buf, priv->child_count * sizeof (*sh->buf));
+ memcpy (lookup_parentbufs, sh->parentbufs,
+ priv->child_count * sizeof (*sh->parentbufs));
- lookup_buf = &local->cont.lookup.buf;
+ afr_reset_xattr (local->cont.lookup.xattrs, priv->child_count);
+ if (local->cont.lookup.xattr) {
+ dict_unref (local->cont.lookup.xattr);
+ local->cont.lookup.xattr = NULL;
+ }
- if (op_ret == -1) {
- if (op_errno == ENOENT)
- local->enoent_count++;
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->xattr[i])
+ local->cont.lookup.xattrs[i] = dict_ref (sh->xattr[i]);
+ }
- if (__error_more_important (local->op_errno, op_errno))
- local->op_errno = op_errno;
+ afr_reset_children (local->cont.lookup.success_children,
+ priv->child_count);
+ afr_children_copy (local->cont.lookup.success_children,
+ sh->fresh_children, priv->child_count);
+}
- if (local->op_errno == ESTALE) {
- local->op_ret = -1;
- }
+static void
+afr_lookup_perform_self_heal (call_frame_t *frame, xlator_t *this,
+ gf_boolean_t *sh_launched)
+{
+ unsigned int up_count = 0;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ char *reason = NULL;
- goto unlock;
- }
+ GF_ASSERT (sh_launched);
+ *sh_launched = _gf_false;
+ priv = this->private;
+ local = frame->local;
- afr_lookup_collect_xattr (local, this, child_index, xattr);
+ up_count = afr_up_children_count (local->child_up, priv->child_count);
+ if (up_count == 1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Only 1 child up - do not attempt to detect self heal");
+ goto out;
+ }
- first_up_child = afr_first_up_child (priv);
+ afr_lookup_set_self_heal_params (local, this);
+ if (afr_can_self_heal_proceed (&local->self_heal, priv)) {
+ if (afr_is_transaction_running (local))
+ goto out;
+
+ reason = "lookup detected pending operations";
+ afr_launch_self_heal (frame, this, local->cont.lookup.inode,
+ _gf_true, local->cont.lookup.buf.ia_type,
+ reason, afr_post_gfid_sh_success,
+ afr_self_heal_lookup_unwind);
+ *sh_launched = _gf_true;
+ }
+out:
+ return;
+}
+
+void
+afr_get_fresh_children (int32_t *success_children, int32_t *sources,
+ int32_t *fresh_children, unsigned int child_count)
+{
+ unsigned int i = 0;
+ unsigned int j = 0;
- if (child_index == first_up_child) {
- local->cont.lookup.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- first_up_child);
+ GF_ASSERT (success_children);
+ GF_ASSERT (sources);
+ GF_ASSERT (fresh_children);
+
+ afr_reset_children (fresh_children, child_count);
+ for (i = 0; i < child_count; i++) {
+ if (success_children[i] == -1)
+ break;
+ if (afr_is_read_child (success_children, sources, child_count,
+ success_children[i])) {
+ fresh_children[j] = success_children[i];
+ j++;
}
+ }
+}
- if (local->success_count == 0) {
- if (local->op_errno != ESTALE)
- local->op_ret = op_ret;
+static int
+afr_lookup_set_read_ctx (afr_local_t *local, xlator_t *this, int32_t read_child)
+{
+ afr_private_t *priv = NULL;
- local->cont.lookup.inode = inode_ref (inode);
- local->cont.lookup.xattr = dict_ref (xattr);
- local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
- local->cont.lookup.postparent = *postparent;
+ GF_ASSERT (read_child >= 0);
- if (priv->first_lookup && inode->ino == 1) {
- gf_log (this->name, GF_LOG_INFO,
- "added root inode");
- priv->root_inode = inode_ref (inode);
- priv->first_lookup = 0;
- }
+ priv = this->private;
+ afr_get_fresh_children (local->cont.lookup.success_children,
+ local->cont.lookup.sources,
+ local->fresh_children, priv->child_count);
+ afr_inode_set_read_ctx (this, local->cont.lookup.inode, read_child,
+ local->fresh_children);
- *lookup_buf = *buf;
+ return 0;
+}
- lookup_buf->ia_ino = afr_itransform (buf->ia_ino,
- priv->child_count,
- child_index);
- if (priv->read_child >= 0) {
- afr_set_read_child (this,
- local->cont.lookup.inode,
- priv->read_child);
- } else {
- afr_set_read_child (this,
- local->cont.lookup.inode,
- child_index);
- }
+int
+afr_lookup_done_success_action (call_frame_t *frame, xlator_t *this,
+ gf_boolean_t fail_conflict)
+{
+ int32_t read_child = -1;
+ int32_t ret = -1;
+ afr_local_t *local = NULL;
+ gf_boolean_t fresh_lookup = _gf_false;
- } else {
- afr_lookup_self_heal_check (this, local, buf, lookup_buf);
+ local = frame->local;
+ fresh_lookup = local->cont.lookup.fresh_lookup;
- if (child_index == local->read_child_index) {
- /*
- lookup has succeeded on the read child.
- So use its inode number
- */
- if (local->cont.lookup.xattr)
- dict_unref (local->cont.lookup.xattr);
+ if (local->loc.parent == NULL)
+ fail_conflict = _gf_true;
- local->cont.lookup.xattr = dict_ref (xattr);
- local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
- local->cont.lookup.postparent = *postparent;
+ if (afr_lookup_conflicting_entries (local, this)) {
+ if (fail_conflict == _gf_false)
+ ret = 0;
+ goto out;
+ }
- *lookup_buf = *buf;
- }
+ ret = afr_lookup_select_read_child (local, this, &read_child);
+ if (!afr_is_transaction_running (local) || fresh_lookup) {
+ if (read_child < 0)
+ goto out;
- }
+ ret = afr_lookup_set_read_ctx (local, this, read_child);
+ if (ret)
+ goto out;
+ }
- local->success_count++;
+ ret = afr_lookup_build_response_params (local, this);
+ if (ret)
+ goto out;
+ afr_update_loc_gfids (&local->loc,
+ &local->cont.lookup.buf,
+ &local->cont.lookup.postparent);
+
+ ret = 0;
+out:
+ if (ret) {
+ local->op_ret = -1;
+ local->op_errno = EIO;
}
-unlock:
- UNLOCK (&frame->lock);
+ return ret;
+}
- call_count = afr_frame_return (frame);
+int
+afr_lookup_get_latest_subvol (afr_local_t *local, xlator_t *this)
+{
+ afr_private_t *priv = NULL;
+ int32_t *success_children = NULL;
+ struct iatt *bufs = NULL;
+ int i = 0;
+ int child = 0;
+ int lsubvol = -1;
- if (call_count == 0) {
- afr_lookup_done (frame, this, lookup_buf);
+ priv = this->private;
+ success_children = local->cont.lookup.success_children;
+ bufs = local->cont.lookup.bufs;
+ for (i = 0; i < priv->child_count; i++) {
+ child = success_children[i];
+ if (child == -1)
+ break;
+ if (uuid_is_null (bufs[child].ia_gfid))
+ continue;
+ if (lsubvol < 0) {
+ lsubvol = child;
+ } else if (bufs[lsubvol].ia_ctime < bufs[child].ia_ctime) {
+ lsubvol = child;
+ } else if ((bufs[lsubvol].ia_ctime == bufs[child].ia_ctime) &&
+ (bufs[lsubvol].ia_ctime_nsec < bufs[child].ia_ctime_nsec)) {
+ lsubvol = child;
+ }
}
+ return lsubvol;
+}
- return 0;
+void
+afr_lookup_mark_other_entries_stale (afr_local_t *local, xlator_t *this,
+ int subvol)
+{
+ afr_private_t *priv = NULL;
+ int32_t *success_children = NULL;
+ struct iatt *bufs = NULL;
+ int i = 0;
+ int child = 0;
+
+ priv = this->private;
+ success_children = local->cont.lookup.success_children;
+ bufs = local->cont.lookup.bufs;
+ memcpy (local->fresh_children, success_children,
+ sizeof (*success_children) * priv->child_count);
+ for (i = 0; i < priv->child_count; i++) {
+ child = local->fresh_children[i];
+ if (child == -1)
+ break;
+ if (child == subvol)
+ continue;
+ if (uuid_is_null (bufs[child].ia_gfid) &&
+ (bufs[child].ia_type == bufs[subvol].ia_type))
+ continue;
+ afr_children_rm_child (success_children, child,
+ priv->child_count);
+ local->success_count--;
+ }
+ afr_reset_children (local->fresh_children, priv->child_count);
}
+void
+afr_succeed_lookup_on_latest_iatt (afr_local_t *local, xlator_t *this)
+{
+ int lsubvol = 0;
-int
-afr_revalidate_lookup_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
+ if (!afr_lookup_conflicting_entries (local, this))
+ goto out;
+
+ lsubvol = afr_lookup_get_latest_subvol (local, this);
+ if (lsubvol < 0)
+ goto out;
+ afr_lookup_mark_other_entries_stale (local, this, lsubvol);
+out:
+ return;
+}
+
+gf_boolean_t
+afr_is_entry_possibly_under_creation (afr_local_t *local, xlator_t *this)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- struct iatt * lookup_buf = NULL;
- int call_count = -1;
- int child_index = -1;
- int first_up_child = -1;
+ /*
+ * We need to perform this test in lookup done and treat on going
+ * create/DELETE as ENOENT.
+ * Reason:
+ Multiple clients A, B and C are attempting 'mkdir -p /mnt/a/b/c'
+
+ 1 Client A is in the middle of mkdir(/a). It has acquired lock.
+ It has performed mkdir(/a) on one subvol, and second one is still
+ in progress
+ 2 Client B performs a lookup, sees directory /a on one,
+ ENOENT on the other, succeeds lookup.
+ 3 Client B performs lookup on /a/b on both subvols, both return ENOENT
+ (one subvol because /a/b does not exist, another because /a
+ itself does not exist)
+ 4 Client B proceeds to mkdir /a/b. It obtains entrylk on inode=/a with
+ basename=b on one subvol, but fails on other subvol as /a is yet to
+ be created by Client A.
+ 5 Client A finishes mkdir of /a on other subvol
+ 6 Client C also attempts to create /a/b, lookup returns ENOENT on
+ both subvols.
+ 7 Client C tries to obtain entrylk on on inode=/a with basename=b,
+ obtains on one subvol (where B had failed), and waits for B to unlock
+ on other subvol.
+ 8 Client B finishes mkdir() on one subvol with GFID-1 and completes
+ transaction and unlocks
+ 9 Client C gets the lock on the second subvol, At this stage second
+ subvol already has /a/b created from Client B, but Client C does not
+ check that in the middle of mkdir transaction
+ 10 Client C attempts mkdir /a/b on both subvols. It succeeds on
+ ONLY ONE (where Client B could not get lock because of
+ missing parent /a dir) with GFID-2, and gets EEXIST from ONE subvol.
+ This way we have /a/b in GFID mismatch. One subvol got GFID-1 because
+ Client B performed transaction on only one subvol (because entrylk()
+ could not be obtained on second subvol because of missing parent dir --
+ caused by premature/speculative succeeding of lookup() on /a when locks
+ are detected). Other subvol gets GFID-2 from Client C because while
+ it was waiting for entrylk() on both subvols, Client B was in the
+ middle of creating mkdir() on only one subvol, and Client C does not
+ "expect" this when it is between lock() and pre-op()/op() phase of the
+ transaction.
+ */
+ if (local->cont.lookup.parent_entrylk && local->enoent_count)
+ return _gf_true;
- child_index = (long) cookie;
- priv = this->private;
+ return _gf_false;
+}
- LOCK (&frame->lock);
- {
- local = frame->local;
- lookup_buf = &local->cont.lookup.buf;
+static void
+afr_lookup_done (call_frame_t *frame, xlator_t *this)
+{
+ int unwind = 1;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ int ret = -1;
+ gf_boolean_t sh_launched = _gf_false;
+ gf_boolean_t fail_conflict = _gf_false;
+ int gfid_miss_count = 0;
+ int enotconn_count = 0;
+ int up_children_count = 0;
- if (op_ret == -1) {
- if (op_errno == ENOENT)
- local->enoent_count++;
+ priv = this->private;
+ local = frame->local;
- if (__error_more_important (local->op_errno, op_errno))
- local->op_errno = op_errno;
+ if (afr_is_entry_possibly_under_creation (local, this)) {
+ local->op_ret = -1;
+ local->op_errno = ENOENT;
+ goto unwind;
+ }
- if (local->op_errno == ESTALE) {
- local->op_ret = -1;
- }
+ if (local->op_ret < 0)
+ goto unwind;
- goto unlock;
- }
+ if (local->cont.lookup.parent_entrylk && local->success_count > 1)
+ afr_succeed_lookup_on_latest_iatt (local, this);
+
+ gfid_miss_count = afr_lookup_gfid_missing_count (local, this);
+ up_children_count = afr_up_children_count (local->child_up,
+ priv->child_count);
+ enotconn_count = priv->child_count - up_children_count;
+ if ((gfid_miss_count == local->success_count) &&
+ (enotconn_count > 0)) {
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ gf_log (this->name, GF_LOG_ERROR, "Failing lookup for %s, "
+ "LOOKUP on a file without gfid is not allowed when "
+ "some of the children are down", local->loc.path);
+ goto unwind;
+ }
- afr_lookup_collect_xattr (local, this, child_index, xattr);
+ if ((gfid_miss_count == local->success_count) &&
+ uuid_is_null (local->cont.lookup.gfid_req)) {
+ local->op_ret = -1;
+ local->op_errno = ENODATA;
+ gf_log (this->name, GF_LOG_ERROR, "%s: No gfid present",
+ local->loc.path);
+ goto unwind;
+ }
- first_up_child = afr_first_up_child (priv);
+ if (gfid_miss_count && uuid_is_null (local->cont.lookup.gfid_req))
+ fail_conflict = _gf_true;
+ ret = afr_lookup_done_success_action (frame, this, fail_conflict);
+ if (ret)
+ goto unwind;
+ uuid_copy (local->self_heal.sh_gfid_req, local->cont.lookup.gfid_req);
- if (child_index == first_up_child) {
- local->cont.lookup.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- first_up_child);
- }
+ afr_lookup_perform_self_heal (frame, this, &sh_launched);
+ if (sh_launched) {
+ unwind = 0;
+ goto unwind;
+ }
- /* in case of revalidate, we need to send stat of the
- * child whose stat was sent during the first lookup.
- * (so that time stamp does not vary with revalidate.
- * in case it is down, stat of the fist success will
- * be replied */
+ unwind:
+ if (unwind) {
+ AFR_STACK_UNWIND (lookup, frame, local->op_ret,
+ local->op_errno, local->cont.lookup.inode,
+ &local->cont.lookup.buf,
+ local->cont.lookup.xattr,
+ &local->cont.lookup.postparent);
+ }
+}
- /* inode number should be preserved across revalidates */
+/*
+ * During a lookup, some errors are more "important" than
+ * others in that they must be given higher priority while
+ * returning to the user.
+ *
+ * The hierarchy is ESTALE > ENOENT > others
+ *
+ */
- if (local->success_count == 0) {
- if (local->op_errno != ESTALE)
- local->op_ret = op_ret;
+gf_boolean_t
+afr_error_more_important (int32_t old_errno, int32_t new_errno)
+{
+ gf_boolean_t ret = _gf_true;
- local->cont.lookup.inode = inode_ref (inode);
- local->cont.lookup.xattr = dict_ref (xattr);
- local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
- local->cont.lookup.postparent = *postparent;
+ /* Nothing should ever overwrite ESTALE */
+ if (old_errno == ESTALE)
+ ret = _gf_false;
- *lookup_buf = *buf;
+ /* Nothing should overwrite ENOENT, except ESTALE/EIO*/
+ else if ((old_errno == ENOENT) && (new_errno != ESTALE)
+ && (new_errno != EIO))
+ ret = _gf_false;
- lookup_buf->ia_ino = afr_itransform (buf->ia_ino,
- priv->child_count,
- child_index);
+ return ret;
+}
- if (priv->read_child >= 0) {
- afr_set_read_child (this,
- local->cont.lookup.inode,
- priv->read_child);
- } else {
- afr_set_read_child (this,
- local->cont.lookup.inode,
- child_index);
- }
+int32_t
+afr_resultant_errno_get (int32_t *children,
+ int *child_errno, unsigned int child_count)
+{
+ int i = 0;
+ int32_t op_errno = 0;
+ int child = 0;
+ for (i = 0; i < child_count; i++) {
+ if (children) {
+ child = children[i];
+ if (child == -1)
+ break;
} else {
- afr_lookup_self_heal_check (this, local, buf, lookup_buf);
+ child = i;
+ }
+ if (afr_error_more_important (op_errno, child_errno[child]))
+ op_errno = child_errno[child];
+ }
+ return op_errno;
+}
- if (child_index == local->read_child_index) {
+static void
+afr_lookup_handle_error (afr_local_t *local, int32_t op_ret, int32_t op_errno)
+{
+ GF_ASSERT (local);
+ if (op_errno == ENOENT)
+ local->enoent_count++;
- /*
- lookup has succeeded on the read child.
- So use its inode number
- */
+ if (afr_error_more_important (local->op_errno, op_errno))
+ local->op_errno = op_errno;
- if (local->cont.lookup.xattr)
- dict_unref (local->cont.lookup.xattr);
+ if (local->op_errno == ESTALE) {
+ local->op_ret = -1;
+ }
+}
- local->cont.lookup.xattr = dict_ref (xattr);
- local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
- local->cont.lookup.postparent = *postparent;
+static void
+afr_set_root_inode_on_first_lookup (afr_local_t *local, xlator_t *this,
+ inode_t *inode)
+{
+ afr_private_t *priv = NULL;
+ GF_ASSERT (inode);
- *lookup_buf = *buf;
- }
+ if (!__is_root_gfid (inode->gfid))
+ goto out;
+ if (!afr_is_fresh_lookup (&local->loc, this))
+ goto out;
+ priv = this->private;
+ if ((priv->first_lookup)) {
+ gf_log (this->name, GF_LOG_INFO, "added root inode");
+ priv->root_inode = inode_ref (inode);
+ priv->first_lookup = 0;
+ }
+out:
+ return;
+}
- }
+static void
+afr_lookup_cache_args (afr_local_t *local, int child_index, dict_t *xattr,
+ struct iatt *buf, struct iatt *postparent)
+{
+ GF_ASSERT (child_index >= 0);
+ local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
+ local->cont.lookup.postparents[child_index] = *postparent;
+ local->cont.lookup.bufs[child_index] = *buf;
+}
- local->success_count++;
+static void
+afr_lookup_handle_first_success (afr_local_t *local, xlator_t *this,
+ inode_t *inode, struct iatt *buf)
+{
+ local->cont.lookup.inode = inode_ref (inode);
+ local->cont.lookup.buf = *buf;
+ afr_set_root_inode_on_first_lookup (local, this, inode);
+}
+
+static void
+afr_lookup_handle_success (afr_local_t *local, xlator_t *this, int32_t child_index,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
+{
+ if (local->success_count == 0) {
+ if (local->op_errno != ESTALE) {
+ local->op_ret = op_ret;
+ local->op_errno = 0;
+ }
+ afr_lookup_handle_first_success (local, this, inode, buf);
}
+ afr_lookup_update_lk_counts (local, this,
+ child_index, xattr);
+
+ afr_lookup_cache_args (local, child_index, xattr,
+ buf, postparent);
+ local->cont.lookup.success_children[local->success_count] = child_index;
+ local->success_count++;
+}
+
+int
+afr_lookup_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
+{
+ afr_local_t * local = NULL;
+ int call_count = -1;
+ int child_index = -1;
+
+ child_index = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ local = frame->local;
+
+ if (op_ret == -1) {
+ afr_lookup_handle_error (local, op_ret, op_errno);
+ goto unlock;
+ }
+ afr_lookup_handle_success (local, this, child_index, op_ret,
+ op_errno, inode, buf, xattr,
+ postparent);
+
+ }
unlock:
UNLOCK (&frame->lock);
call_count = afr_frame_return (frame);
-
if (call_count == 0) {
- afr_lookup_done (frame, this, lookup_buf);
+ afr_lookup_done (frame, this);
}
- return 0;
+ return 0;
}
+int
+afr_lookup_cont_init (afr_local_t *local, unsigned int child_count)
+{
+ int ret = -ENOMEM;
+ struct iatt *iatts = NULL;
+ int32_t *success_children = NULL;
+ int32_t *sources = NULL;
+
+ GF_ASSERT (local);
+ local->cont.lookup.xattrs = GF_CALLOC (child_count,
+ sizeof (*local->cont.lookup.xattr),
+ gf_afr_mt_dict_t);
+ if (NULL == local->cont.lookup.xattrs)
+ goto out;
+
+ iatts = GF_CALLOC (child_count, sizeof (*iatts), gf_afr_mt_iatt);
+ if (NULL == iatts)
+ goto out;
+ local->cont.lookup.postparents = iatts;
+
+ iatts = GF_CALLOC (child_count, sizeof (*iatts), gf_afr_mt_iatt);
+ if (NULL == iatts)
+ goto out;
+ local->cont.lookup.bufs = iatts;
+
+ success_children = afr_children_create (child_count);
+ if (NULL == success_children)
+ goto out;
+ local->cont.lookup.success_children = success_children;
+
+ local->fresh_children = afr_children_create (child_count);
+ if (NULL == local->fresh_children)
+ goto out;
+
+ sources = GF_CALLOC (sizeof (*sources), child_count, gf_afr_mt_int32_t);
+ if (NULL == sources)
+ goto out;
+ local->cont.lookup.sources = sources;
+
+ ret = 0;
+out:
+ return ret;
+}
int
afr_lookup (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *xattr_req)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int ret = -1;
- int i = 0;
- fop_lookup_cbk_t callback = NULL;
- int call_count = 0;
- uint64_t ctx = 0;
- int32_t op_errno = 0;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ void *gfid_req = NULL;
+ int ret = -1;
+ int i = 0;
+ int call_count = 0;
+ uint64_t ctx = 0;
+ int32_t op_errno = 0;
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (local, out);
local->op_ret = -1;
frame->local = local;
+ local->fop = GF_FOP_LOOKUP;
- if (!strcmp (loc->path, "/" GF_REPLICATE_TRASH_DIR)) {
- op_errno = ENOENT;
+ loc_copy (&local->loc, loc);
+ ret = loc_path (&local->loc, NULL);
+ if (ret < 0) {
+ op_errno = EINVAL;
goto out;
}
- loc_copy (&local->loc, loc);
+ if (!strcmp (local->loc.path, "/" GF_REPLICATE_TRASH_DIR)) {
+ op_errno = ENOENT;
+ goto out;
+ }
- ret = inode_ctx_get (loc->inode, this, &ctx);
+ ret = inode_ctx_get (local->loc.inode, this, &ctx);
if (ret == 0) {
/* lookup is a revalidate */
- callback = afr_revalidate_lookup_cbk;
-
- local->cont.lookup.is_revalidate = _gf_true;
- local->read_child_index = afr_read_child (this,
- loc->inode);
+ local->read_child_index = afr_inode_get_read_ctx (this,
+ local->loc.inode,
+ NULL);
} else {
- callback = afr_fresh_lookup_cbk;
-
LOCK (&priv->read_child_lock);
{
local->read_child_index = (++priv->read_child_rr)
% (priv->child_count);
}
UNLOCK (&priv->read_child_lock);
+ local->cont.lookup.fresh_lookup = _gf_true;
}
- if (loc->parent)
- local->cont.lookup.parent_ino = loc->parent->ino;
-
- local->child_up = memdup (priv->child_up, priv->child_count);
+ local->child_up = memdup (priv->child_up,
+ sizeof (*local->child_up) * priv->child_count);
+ if (NULL == local->child_up) {
+ op_errno = ENOMEM;
+ goto out;
+ }
- local->cont.lookup.xattrs = GF_CALLOC (priv->child_count,
- sizeof (*local->cont.lookup.xattr),
- gf_afr_mt_dict_t);
+ ret = afr_lookup_cont_init (local, priv->child_count);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
+ }
- local->call_count = afr_up_children_count (priv->child_count,
- local->child_up);
+ local->call_count = afr_up_children_count (local->child_up,
+ priv->child_count);
call_count = local->call_count;
-
if (local->call_count == 0) {
ret = -1;
op_errno = ENOTCONN;
@@ -1075,41 +2224,24 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
/* By default assume ENOTCONN. On success it will be set to 0. */
local->op_errno = ENOTCONN;
- if (xattr_req == NULL)
- local->xattr_req = dict_new ();
- else
- local->xattr_req = dict_ref (xattr_req);
-
- for (i = 0; i < priv->child_count; i++) {
- ret = dict_set_uint64 (local->xattr_req, priv->pending_key[i],
- 3 * sizeof(int32_t));
- if (ret < 0)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: Unable to set dict value for %s",
- loc->path, priv->pending_key[i]);
- /* 3 = data+metadata+entry */
- }
-
- ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_INODELK_COUNT, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: Unable to set dict value for %s",
- loc->path, GLUSTERFS_INODELK_COUNT);
- }
-
- ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_ENTRYLK_COUNT, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: Unable to set dict value for %s",
- loc->path, GLUSTERFS_ENTRYLK_COUNT);
+ local->call_count = afr_up_children_count (local->child_up,
+ priv->child_count);
+ ret = afr_lookup_xattr_req_prepare (local, this, xattr_req, &local->loc,
+ &gfid_req);
+ if (ret) {
+ local->op_errno = -ret;
+ goto out;
}
-
+ afr_lookup_save_gfid (local->cont.lookup.gfid_req, gfid_req,
+ &local->loc);
+ local->fop = GF_FOP_LOOKUP;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, callback, (void *) (long) i,
+ STACK_WIND_COOKIE (frame, afr_lookup_cbk,
+ (void *) (long) i,
priv->children[i],
priv->children[i]->fops->lookup,
- loc, local->xattr_req);
+ &local->loc, local->xattr_req);
if (!--call_count)
break;
}
@@ -1117,7 +2249,7 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
ret = 0;
out:
- if (ret == -1)
+ if (ret)
AFR_STACK_UNWIND (lookup, frame, -1, op_errno,
NULL, NULL, NULL, NULL);
@@ -1128,7 +2260,7 @@ out:
/* {{{ open */
int
-afr_fd_ctx_set (xlator_t *this, fd_t *fd)
+__afr_fd_ctx_set (xlator_t *this, fd_t *fd)
{
afr_private_t * priv = NULL;
int ret = -1;
@@ -1140,68 +2272,95 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)
priv = this->private;
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_get (fd, this, &ctx);
+ ret = __fd_ctx_get (fd, this, &ctx);
- if (ret == 0)
- goto unlock;
+ if (ret == 0)
+ goto out;
- fd_ctx = GF_CALLOC (1, sizeof (afr_fd_ctx_t),
- gf_afr_mt_afr_fd_ctx_t);
- if (!fd_ctx) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx = GF_CALLOC (1, sizeof (afr_fd_ctx_t),
+ gf_afr_mt_afr_fd_ctx_t);
+ if (!fd_ctx) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->pre_op_done = GF_CALLOC (sizeof (*fd_ctx->pre_op_done),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->pre_op_done) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->pre_op_done = GF_CALLOC (sizeof (*fd_ctx->pre_op_done),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->pre_op_done) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->pre_op_piggyback = GF_CALLOC (sizeof (*fd_ctx->pre_op_piggyback),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->pre_op_piggyback) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->pre_op_piggyback = GF_CALLOC (sizeof (*fd_ctx->pre_op_piggyback),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->pre_op_piggyback) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->opened_on = GF_CALLOC (sizeof (*fd_ctx->opened_on),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->opened_on) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->opened_on = GF_CALLOC (sizeof (*fd_ctx->opened_on),
+ priv->child_count,
+ gf_afr_mt_int32_t);
+ if (!fd_ctx->opened_on) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->up_count = priv->up_count;
- fd_ctx->down_count = priv->down_count;
+ fd_ctx->lock_piggyback = GF_CALLOC (sizeof (*fd_ctx->lock_piggyback),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->lock_piggyback) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->locked_on = GF_CALLOC (sizeof (*fd_ctx->locked_on),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->locked_on) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->lock_acquired = GF_CALLOC (sizeof (*fd_ctx->lock_acquired),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->lock_acquired) {
+ ret = -ENOMEM;
+ goto out;
+ }
- ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set fd ctx (%p)", fd);
+ fd_ctx->up_count = priv->up_count;
+ fd_ctx->down_count = priv->down_count;
- INIT_LIST_HEAD (&fd_ctx->entries);
+ fd_ctx->locked_on = GF_CALLOC (sizeof (*fd_ctx->locked_on),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->locked_on) {
+ ret = -ENOMEM;
+ goto out;
}
-unlock:
- UNLOCK (&fd->lock);
+
+ INIT_LIST_HEAD (&fd_ctx->paused_calls);
+ INIT_LIST_HEAD (&fd_ctx->entries);
+
+ ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set fd ctx (%p)", fd);
out:
return ret;
}
+
+int
+afr_fd_ctx_set (xlator_t *this, fd_t *fd)
+{
+ int ret = -1;
+
+ LOCK (&fd->lock);
+ {
+ ret = __afr_fd_ctx_set (this, fd);
+ }
+ UNLOCK (&fd->lock);
+
+ return ret;
+}
+
/* {{{ flush */
int
@@ -1222,7 +2381,8 @@ afr_flush_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
AFR_STACK_UNWIND (flush, main_frame,
- local->op_ret, local->op_errno);
+ local->op_ret, local->op_errno,
+ NULL);
}
return 0;
@@ -1231,7 +2391,7 @@ afr_flush_unwind (call_frame_t *frame, xlator_t *this)
int
afr_flush_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
@@ -1286,7 +2446,7 @@ afr_flush_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_up_children_count (local->child_up, priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1301,7 +2461,7 @@ afr_flush_wind (call_frame_t *frame, xlator_t *this)
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->flush,
- local->fd);
+ local->fd, NULL);
if (!--call_count)
break;
@@ -1328,15 +2488,13 @@ afr_flush_done (call_frame_t *frame, xlator_t *this)
int
-afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
+afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- call_frame_t * transaction_frame = NULL;
- int ret = -1;
- int op_ret = -1;
- int op_errno = 0;
- int call_count = 0;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ call_frame_t *transaction_frame = NULL;
+ int ret = -1;
+ int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -1344,23 +2502,18 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
-
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
-
- call_count = afr_up_children_count (priv->child_count, local->child_up);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
op_errno = ENOMEM;
goto out;
}
- transaction_frame->local = local;
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
+
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
+ goto out;
local->op = GF_FOP_FLUSH;
@@ -1374,16 +2527,21 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
local->transaction.start = 0;
local->transaction.len = 0;
+ ret = afr_open_fd_fix (transaction_frame, this, _gf_false);
+ if (ret) {
+ op_errno = -ret;
+ goto out;
+ }
afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (flush, frame, op_ret, op_errno);
+ AFR_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
}
return 0;
@@ -1398,6 +2556,8 @@ afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd)
uint64_t ctx = 0;
afr_fd_ctx_t *fd_ctx = NULL;
int ret = 0;
+ afr_fd_paused_call_t *paused_call = NULL;
+ afr_fd_paused_call_t *tmp = NULL;
ret = fd_ctx_get (fd, this, &ctx);
if (ret < 0)
@@ -1417,6 +2577,17 @@ afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd)
if (fd_ctx->pre_op_piggyback)
GF_FREE (fd_ctx->pre_op_piggyback);
+ list_for_each_entry_safe (paused_call, tmp, &fd_ctx->paused_calls,
+ call_list) {
+ list_del_init (&paused_call->call_list);
+ GF_FREE (paused_call);
+ }
+
+ if (fd_ctx->lock_piggyback)
+ GF_FREE (fd_ctx->lock_piggyback);
+
+ if (fd_ctx->lock_acquired)
+ GF_FREE (fd_ctx->lock_acquired);
GF_FREE (fd_ctx);
}
@@ -1456,7 +2627,7 @@ afr_release (xlator_t *this, fd_t *fd)
int
afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
+ struct iatt *postbuf, dict_t *xdata)
{
afr_local_t *local = NULL;
int call_count = -1;
@@ -1465,7 +2636,7 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
- read_child = afr_read_child (this, local->fd->inode);
+ read_child = afr_inode_get_read_ctx (this, local->fd->inode, NULL);
LOCK (&frame->lock);
{
@@ -1496,12 +2667,10 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
- local->cont.fsync.prebuf.ia_ino = local->cont.fsync.ino;
- local->cont.fsync.postbuf.ia_ino = local->cont.fsync.ino;
-
AFR_STACK_UNWIND (fsync, frame, local->op_ret, local->op_errno,
&local->cont.fsync.prebuf,
- &local->cont.fsync.postbuf);
+ &local->cont.fsync.postbuf,
+ NULL);
}
return 0;
@@ -1510,14 +2679,13 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t datasync)
+ int32_t datasync, dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1526,19 +2694,16 @@ afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
call_count = local->call_count;
- frame->local = local;
local->fd = fd_ref (fd);
- local->cont.fsync.ino = fd->inode->ino;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
@@ -1546,17 +2711,16 @@ afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->fsync,
- fd, datasync);
+ fd, datasync, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (fsync, frame, op_ret, op_errno, NULL, NULL);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
return 0;
}
@@ -1566,7 +2730,8 @@ out:
int32_t
afr_fsyncdir_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno)
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
afr_local_t *local = NULL;
int call_count = -1;
@@ -1586,7 +2751,7 @@ afr_fsyncdir_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (fsyncdir, frame, local->op_ret,
- local->op_errno);
+ local->op_errno, xdata);
return 0;
}
@@ -1594,14 +2759,13 @@ afr_fsyncdir_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t datasync)
+ int32_t datasync, dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1610,33 +2774,30 @@ afr_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
call_count = local->call_count;
- frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_fsyncdir_cbk,
priv->children[i],
priv->children[i]->fops->fsyncdir,
- fd, datasync);
+ fd, datasync, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (fsyncdir, frame, op_ret, op_errno);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
return 0;
}
@@ -1647,7 +2808,7 @@ out:
int32_t
afr_xattrop_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xattr)
+ dict_t *xattr, dict_t *xdata)
{
afr_local_t *local = NULL;
int call_count = -1;
@@ -1656,8 +2817,11 @@ afr_xattrop_cbk (call_frame_t *frame, void *cookie,
LOCK (&frame->lock);
{
- if (op_ret == 0)
+ if (op_ret == 0) {
+ if (!local->cont.xattrop.xattr)
+ local->cont.xattrop.xattr = dict_ref (xattr);
local->op_ret = 0;
+ }
local->op_errno = op_errno;
}
@@ -1667,7 +2831,7 @@ afr_xattrop_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (xattrop, frame, local->op_ret, local->op_errno,
- xattr);
+ local->cont.xattrop.xattr, xdata);
return 0;
}
@@ -1675,14 +2839,13 @@ afr_xattrop_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t optype, dict_t *xattr)
+ gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1691,33 +2854,30 @@ afr_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
call_count = local->call_count;
- frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_xattrop_cbk,
priv->children[i],
priv->children[i]->fops->xattrop,
- loc, optype, xattr);
+ loc, optype, xattr, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (xattrop, frame, op_ret, op_errno, NULL);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -1728,7 +2888,7 @@ out:
int32_t
afr_fxattrop_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xattr)
+ dict_t *xattr, dict_t *xdata)
{
afr_local_t *local = NULL;
@@ -1738,8 +2898,12 @@ afr_fxattrop_cbk (call_frame_t *frame, void *cookie,
LOCK (&frame->lock);
{
- if (op_ret == 0)
+ if (op_ret == 0) {
+ if (!local->cont.fxattrop.xattr)
+ local->cont.fxattrop.xattr = dict_ref (xattr);
+
local->op_ret = 0;
+ }
local->op_errno = op_errno;
}
@@ -1749,7 +2913,7 @@ afr_fxattrop_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (fxattrop, frame, local->op_ret, local->op_errno,
- xattr);
+ local->cont.fxattrop.xattr, xdata);
return 0;
}
@@ -1757,14 +2921,13 @@ afr_fxattrop_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t optype, dict_t *xattr)
+ gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1773,33 +2936,30 @@ afr_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
call_count = local->call_count;
- frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_fxattrop_cbk,
priv->children[i],
priv->children[i]->fops->fxattrop,
- fd, optype, xattr);
+ fd, optype, xattr, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, NULL);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -1808,7 +2968,7 @@ out:
int32_t
afr_inodelk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno)
+ xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
afr_local_t *local = NULL;
@@ -1829,7 +2989,7 @@ afr_inodelk_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (inodelk, frame, local->op_ret,
- local->op_errno);
+ local->op_errno, xdata);
return 0;
}
@@ -1837,14 +2997,14 @@ afr_inodelk_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock)
+ const char *volume, loc_t *loc, int32_t cmd,
+ struct gf_flock *flock, dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1853,41 +3013,39 @@ afr_inodelk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
call_count = local->call_count;
- frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_inodelk_cbk,
priv->children[i],
priv->children[i]->fops->inodelk,
- volume, loc, cmd, flock);
+ volume, loc, cmd, flock, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (inodelk, frame, op_ret, op_errno);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (inodelk, frame, -1, op_errno, NULL);
return 0;
}
int32_t
afr_finodelk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno)
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
afr_local_t *local = NULL;
@@ -1908,7 +3066,7 @@ afr_finodelk_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (finodelk, frame, local->op_ret,
- local->op_errno);
+ local->op_errno, xdata);
return 0;
}
@@ -1916,14 +3074,14 @@ afr_finodelk_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock)
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock,
+ dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1932,42 +3090,38 @@ afr_finodelk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
call_count = local->call_count;
- frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_finodelk_cbk,
priv->children[i],
priv->children[i]->fops->finodelk,
- volume, fd, cmd, flock);
+ volume, fd, cmd, flock, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (finodelk, frame, op_ret, op_errno);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL);
return 0;
}
int32_t
-afr_entrylk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno)
-
+afr_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
afr_local_t *local = NULL;
int call_count = -1;
@@ -1987,7 +3141,7 @@ afr_entrylk_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (entrylk, frame, local->op_ret,
- local->op_errno);
+ local->op_errno, xdata);
return 0;
}
@@ -1996,14 +3150,14 @@ afr_entrylk_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc,
- const char *basename, entrylk_cmd cmd, entrylk_type type)
+ const char *basename, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -2012,34 +3166,31 @@ afr_entrylk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
call_count = local->call_count;
- frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_entrylk_cbk,
priv->children[i],
priv->children[i]->fops->entrylk,
- volume, loc, basename, cmd, type);
+ volume, loc, basename, cmd, type, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (entrylk, frame, op_ret, op_errno);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL);
return 0;
}
@@ -2047,7 +3198,7 @@ out:
int32_t
afr_fentrylk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno)
+ xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
afr_local_t *local = NULL;
@@ -2068,7 +3219,7 @@ afr_fentrylk_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (fentrylk, frame, local->op_ret,
- local->op_errno);
+ local->op_errno, xdata);
return 0;
}
@@ -2077,14 +3228,14 @@ afr_fentrylk_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_fentrylk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd,
- const char *basename, entrylk_cmd cmd, entrylk_type type)
+ const char *basename, entrylk_cmd cmd,
+ entrylk_type type, dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -2093,41 +3244,38 @@ afr_fentrylk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
call_count = local->call_count;
- frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_fentrylk_cbk,
priv->children[i],
priv->children[i]->fops->fentrylk,
- volume, fd, basename, cmd, type);
+ volume, fd, basename, cmd, type, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL);
return 0;
}
int32_t
afr_statfs_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- struct statvfs *statvfs)
+ struct statvfs *statvfs, dict_t *xdata)
{
afr_local_t *local = NULL;
int call_count = 0;
@@ -2158,7 +3306,7 @@ afr_statfs_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (statfs, frame, local->op_ret, local->op_errno,
- &local->cont.statfs.buf);
+ &local->cont.statfs.buf, xdata);
return 0;
}
@@ -2166,7 +3314,7 @@ afr_statfs_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_statfs (call_frame_t *frame, xlator_t *this,
- loc_t *loc)
+ loc_t *loc, dict_t *xdata)
{
afr_private_t * priv = NULL;
int child_count = 0;
@@ -2174,7 +3322,6 @@ afr_statfs (call_frame_t *frame, xlator_t *this,
int i = 0;
int ret = -1;
int call_count = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (this, out);
@@ -2184,15 +3331,13 @@ afr_statfs (call_frame_t *frame, xlator_t *this,
priv = this->private;
child_count = priv->child_count;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
- frame->local = local;
call_count = local->call_count;
for (i = 0; i < child_count; i++) {
@@ -2200,24 +3345,24 @@ afr_statfs (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, afr_statfs_cbk,
priv->children[i],
priv->children[i]->fops->statfs,
- loc);
+ loc, xdata);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (statfs, frame, op_ret, op_errno, NULL);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
afr_lk_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
{
afr_local_t * local = NULL;
int call_count = -1;
@@ -2227,7 +3372,7 @@ afr_lk_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (call_count == 0)
AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- lock);
+ lock, xdata);
return 0;
}
@@ -2249,7 +3394,7 @@ afr_lk_unlock (call_frame_t *frame, xlator_t *this)
if (call_count == 0) {
AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- &local->cont.lk.ret_flock);
+ &local->cont.lk.ret_flock, NULL);
return 0;
}
@@ -2263,7 +3408,7 @@ afr_lk_unlock (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->lk,
local->fd, F_SETLK,
- &local->cont.lk.user_flock);
+ &local->cont.lk.user_flock, NULL);
if (!--call_count)
break;
@@ -2276,7 +3421,7 @@ afr_lk_unlock (call_frame_t *frame, xlator_t *this)
int32_t
afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
{
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
@@ -2311,12 +3456,12 @@ afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv->children[child_index],
priv->children[child_index]->fops->lk,
local->fd, local->cont.lk.cmd,
- &local->cont.lk.user_flock);
+ &local->cont.lk.user_flock, xdata);
} else if (local->op_ret == -1) {
/* all nodes have gone down */
AFR_STACK_UNWIND (lk, frame, -1, ENOTCONN,
- &local->cont.lk.ret_flock);
+ &local->cont.lk.ret_flock, NULL);
} else {
/* locking has succeeded on all nodes that are up */
@@ -2334,7 +3479,7 @@ afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*/
AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- &local->cont.lk.ret_flock);
+ &local->cont.lk.ret_flock, NULL);
}
return 0;
@@ -2343,13 +3488,13 @@ afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
afr_lk (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t cmd, struct gf_flock *flock)
+ fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int i = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -2357,10 +3502,12 @@ afr_lk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- ALLOC_OR_GOTO (local, afr_local_t, out);
- AFR_LOCAL_INIT (local, priv);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- frame->local = local;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
+ goto out;
local->cont.lk.locked_nodes = GF_CALLOC (priv->child_count,
sizeof (*local->cont.lk.locked_nodes),
@@ -2379,13 +3526,31 @@ afr_lk (call_frame_t *frame, xlator_t *this,
STACK_WIND_COOKIE (frame, afr_lk_cbk, (void *) (long) 0,
priv->children[i],
priv->children[i]->fops->lk,
- fd, cmd, flock);
+ fd, cmd, flock, xdata);
- op_ret = 0;
+ ret = 0;
+out:
+ if (ret < 0)
+ AFR_STACK_UNWIND (lk, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+afr_forget (xlator_t *this, inode_t *inode)
+{
+ uint64_t ctx_addr = 0;
+ afr_inode_ctx_t *ctx = NULL;
+
+ inode_ctx_get (inode, this, &ctx_addr);
+
+ if (!ctx_addr)
+ goto out;
+
+ ctx = (afr_inode_ctx_t *)(long)ctx_addr;
+ if (ctx->fresh_children)
+ GF_FREE (ctx->fresh_children);
+ GF_FREE (ctx);
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (lk, frame, op_ret, op_errno, NULL);
- }
return 0;
}
@@ -2404,41 +3569,23 @@ afr_priv_dump (xlator_t *this)
GF_ASSERT (priv);
snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, this->name);
gf_proc_dump_add_section(key_prefix);
- gf_proc_dump_build_key(key, key_prefix, "child_count");
- gf_proc_dump_write(key, "%u", priv->child_count);
- gf_proc_dump_build_key(key, key_prefix, "read_child_rr");
- gf_proc_dump_write(key, "%u", priv->read_child_rr);
+ gf_proc_dump_write("child_count", "%u", priv->child_count);
+ gf_proc_dump_write("read_child_rr", "%u", priv->read_child_rr);
for (i = 0; i < priv->child_count; i++) {
- gf_proc_dump_build_key(key, key_prefix, "child_up[%d]", i);
+ sprintf (key, "child_up[%d]", i);
gf_proc_dump_write(key, "%d", priv->child_up[i]);
- gf_proc_dump_build_key(key, key_prefix,
- "pending_key[%d]", i);
+ sprintf (key, "pending_key[%d]", i);
gf_proc_dump_write(key, "%s", priv->pending_key[i]);
}
- gf_proc_dump_build_key(key, key_prefix, "data_self_heal");
- gf_proc_dump_write(key, "%d", priv->data_self_heal);
- gf_proc_dump_build_key(key, key_prefix, "metadata_self_heal");
- gf_proc_dump_write(key, "%d", priv->metadata_self_heal);
- gf_proc_dump_build_key(key, key_prefix, "entry_self_heal");
- gf_proc_dump_write(key, "%d", priv->entry_self_heal);
- gf_proc_dump_build_key(key, key_prefix, "data_change_log");
- gf_proc_dump_write(key, "%d", priv->data_change_log);
- gf_proc_dump_build_key(key, key_prefix, "metadata_change_log");
- gf_proc_dump_write(key, "%d", priv->metadata_change_log);
- gf_proc_dump_build_key(key, key_prefix, "entry_change_log");
- gf_proc_dump_write(key, "%d", priv->entry_change_log);
- gf_proc_dump_build_key(key, key_prefix, "read_child");
- gf_proc_dump_write(key, "%d", priv->read_child);
- gf_proc_dump_build_key(key, key_prefix, "favorite_child");
- gf_proc_dump_write(key, "%u", priv->favorite_child);
- gf_proc_dump_build_key(key, key_prefix, "data_lock_server_count");
- gf_proc_dump_write(key, "%u", priv->data_lock_server_count);
- gf_proc_dump_build_key(key, key_prefix, "metadata_lock_server_count");
- gf_proc_dump_write(key, "%u", priv->metadata_lock_server_count);
- gf_proc_dump_build_key(key, key_prefix, "entry_lock_server_count");
- gf_proc_dump_write(key, "%u", priv->entry_lock_server_count);
- gf_proc_dump_build_key(key, key_prefix, "wait_count");
- gf_proc_dump_write(key, "%u", priv->wait_count);
+ gf_proc_dump_write("data_self_heal", "%s", priv->data_self_heal);
+ gf_proc_dump_write("metadata_self_heal", "%d", priv->metadata_self_heal);
+ gf_proc_dump_write("entry_self_heal", "%d", priv->entry_self_heal);
+ gf_proc_dump_write("data_change_log", "%d", priv->data_change_log);
+ gf_proc_dump_write("metadata_change_log", "%d", priv->metadata_change_log);
+ gf_proc_dump_write("entry-change_log", "%d", priv->entry_change_log);
+ gf_proc_dump_write("read_child", "%d", priv->read_child);
+ gf_proc_dump_write("favorite_child", "%d", priv->favorite_child);
+ gf_proc_dump_write("wait_count", "%u", priv->wait_count);
return 0;
}
@@ -2468,18 +3615,21 @@ find_child_index (xlator_t *this, xlator_t *child)
int32_t
afr_notify (xlator_t *this, int32_t event,
- void *data, ...)
+ void *data, void *data2)
{
afr_private_t *priv = NULL;
int i = -1;
int up_children = 0;
int down_children = 0;
int propagate = 0;
-
int had_heard_from_all = 0;
int have_heard_from_all = 0;
int idx = -1;
int ret = -1;
+ int call_psh = 0;
+ int up_child = AFR_ALL_CHILDREN;
+ dict_t *input = NULL;
+ dict_t *output = NULL;
priv = this->private;
@@ -2496,7 +3646,7 @@ afr_notify (xlator_t *this, int32_t event,
/* parent xlators dont need to know about every child_up, child_down
* because of afr ha. If all subvolumes go down, child_down has
* to be triggered. In that state when 1 subvolume comes up child_up
- * needs to be triggered. dht optimises revalidate lookup by sending
+ * needs to be triggered. dht optimizes revalidate lookup by sending
* it only to one of its subvolumes. When child up/down happens
* for afr's subvolumes dht should be notified by child_modified. The
* subsequent revalidate lookup happens on all the dht's subvolumes
@@ -2513,9 +3663,19 @@ afr_notify (xlator_t *this, int32_t event,
case GF_EVENT_CHILD_UP:
LOCK (&priv->lock);
{
+ /*
+ * This only really counts if the child was never up
+ * (value = -1) or had been down (value = 0). See
+ * comment at GF_EVENT_CHILD_DOWN for a more detailed
+ * explanation.
+ */
+ if (priv->child_up[idx] != 1) {
+ priv->up_count++;
+ }
priv->child_up[idx] = 1;
- priv->up_count++;
+ call_psh = 1;
+ up_child = idx;
for (i = 0; i < priv->child_count; i++)
if (priv->child_up[i] == 1)
up_children++;
@@ -2536,8 +3696,22 @@ afr_notify (xlator_t *this, int32_t event,
case GF_EVENT_CHILD_DOWN:
LOCK (&priv->lock);
{
+ /*
+ * If a brick is down when we start, we'll get a
+ * CHILD_DOWN to indicate its initial state. There
+ * was never a CHILD_UP in this case, so if we
+ * increment "down_count" the difference between than
+ * and "up_count" will no longer be the number of
+ * children that are currently up. This has serious
+ * implications e.g. for quorum enforcement, so we
+ * don't increment these values unless the event
+ * represents an actual state transition between "up"
+ * (value = 1) and anything else.
+ */
+ if (priv->child_up[idx] == 1) {
+ priv->down_count++;
+ }
priv->child_up[idx] = 0;
- priv->down_count++;
for (i = 0; i < priv->child_count; i++)
if (priv->child_up[i] == 0)
@@ -2562,7 +3736,16 @@ afr_notify (xlator_t *this, int32_t event,
priv->last_event[idx] = event;
}
UNLOCK (&priv->lock);
+
+ break;
+
+ case GF_EVENT_TRANSLATOR_OP:
+ input = data;
+ output = data2;
+ ret = afr_xl_op (this, input, output);
+ goto out;
break;
+
default:
propagate = 1;
break;
@@ -2589,6 +3772,8 @@ afr_notify (xlator_t *this, int32_t event,
LOCK (&priv->lock);
{
+ up_children = afr_up_children_count (priv->child_up,
+ priv->child_count);
for (i = 0; i < priv->child_count; i++) {
if (priv->last_event[i] == GF_EVENT_CHILD_UP) {
event = GF_EVENT_CHILD_UP;
@@ -2608,7 +3793,415 @@ afr_notify (xlator_t *this, int32_t event,
ret = 0;
if (propagate)
ret = default_notify (this, event, data);
+ if (call_psh && priv->shd.iamshd)
+ afr_proactive_self_heal ((void*) (long) up_child);
out:
return ret;
}
+
+int
+afr_first_up_child (unsigned char *child_up, size_t child_count)
+{
+ int ret = -1;
+ int i = 0;
+
+ GF_ASSERT (child_up);
+
+ for (i = 0; i < child_count; i++) {
+ if (child_up[i]) {
+ ret = i;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int
+afr_local_init (afr_local_t *local, afr_private_t *priv, int32_t *op_errno)
+{
+ int ret = -1;
+
+ local->op_ret = -1;
+ local->op_errno = EUCLEAN;
+
+ local->child_up = GF_CALLOC (priv->child_count,
+ sizeof (*local->child_up),
+ gf_afr_mt_char);
+ if (!local->child_up) {
+ if (op_errno)
+ *op_errno = ENOMEM;
+ goto out;
+ }
+
+ memcpy (local->child_up, priv->child_up,
+ sizeof (*local->child_up) * priv->child_count);
+ local->call_count = afr_up_children_count (local->child_up,
+ priv->child_count);
+ if (local->call_count == 0) {
+ gf_log (THIS->name, GF_LOG_INFO, "no subvolumes up");
+ if (op_errno)
+ *op_errno = ENOTCONN;
+ goto out;
+ }
+
+ local->child_errno = GF_CALLOC (priv->child_count,
+ sizeof (*local->child_errno),
+ gf_afr_mt_int32_t);
+ if (!local->child_errno) {
+ if (op_errno)
+ *op_errno = ENOMEM;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+afr_internal_lock_init (afr_internal_lock_t *lk, size_t child_count,
+ transaction_lk_type_t lk_type)
+{
+ int ret = -ENOMEM;
+
+ lk->inode_locked_nodes = GF_CALLOC (sizeof (*lk->inode_locked_nodes),
+ child_count, gf_afr_mt_char);
+ if (NULL == lk->inode_locked_nodes)
+ goto out;
+
+ lk->entry_locked_nodes = GF_CALLOC (sizeof (*lk->entry_locked_nodes),
+ child_count, gf_afr_mt_char);
+ if (NULL == lk->entry_locked_nodes)
+ goto out;
+
+ lk->locked_nodes = GF_CALLOC (sizeof (*lk->locked_nodes),
+ child_count, gf_afr_mt_char);
+ if (NULL == lk->locked_nodes)
+ goto out;
+
+ lk->lower_locked_nodes = GF_CALLOC (sizeof (*lk->lower_locked_nodes),
+ child_count, gf_afr_mt_char);
+ if (NULL == lk->lower_locked_nodes)
+ goto out;
+
+ lk->lock_op_ret = -1;
+ lk->lock_op_errno = EUCLEAN;
+ lk->transaction_lk_type = lk_type;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+void
+afr_matrix_cleanup (int32_t **matrix, unsigned int m)
+{
+ int i = 0;
+
+ if (!matrix)
+ goto out;
+ for (i = 0; i < m; i++) {
+ GF_FREE (matrix[i]);
+ }
+
+ GF_FREE (matrix);
+out:
+ return;
+}
+
+int32_t**
+afr_matrix_create (unsigned int m, unsigned int n)
+{
+ int32_t **matrix = NULL;
+ int i = 0;
+
+ matrix = GF_CALLOC (sizeof (*matrix), m, gf_afr_mt_int32_t);
+ if (!matrix)
+ goto out;
+
+ for (i = 0; i < m; i++) {
+ matrix[i] = GF_CALLOC (sizeof (*matrix[i]), n,
+ gf_afr_mt_int32_t);
+ if (!matrix[i])
+ goto out;
+ }
+ return matrix;
+out:
+ afr_matrix_cleanup (matrix, m);
+ return NULL;
+}
+
+int
+afr_transaction_local_init (afr_local_t *local, xlator_t *this)
+{
+ int child_up_count = 0;
+ int ret = -ENOMEM;
+ afr_private_t *priv = NULL;
+
+ priv = this->private;
+ ret = afr_internal_lock_init (&local->internal_lock, priv->child_count,
+ AFR_TRANSACTION_LK);
+ if (ret < 0)
+ goto out;
+
+ ret = -ENOMEM;
+ child_up_count = afr_up_children_count (local->child_up,
+ priv->child_count);
+ if (priv->optimistic_change_log && child_up_count == priv->child_count)
+ local->optimistic_change_log = 1;
+
+ local->first_up_child = afr_first_up_child (local->child_up,
+ priv->child_count);
+
+ local->transaction.eager_lock =
+ GF_CALLOC (sizeof (*local->transaction.eager_lock),
+ priv->child_count,
+ gf_afr_mt_int32_t);
+
+ if (!local->transaction.eager_lock)
+ goto out;
+
+ local->fresh_children = afr_children_create (priv->child_count);
+ if (!local->fresh_children)
+ goto out;
+
+ if (local->fd) {
+ local->fd_open_on = GF_CALLOC (sizeof (*local->fd_open_on),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!local->fd_open_on)
+ goto out;
+ }
+
+ local->transaction.pre_op = GF_CALLOC (sizeof (*local->transaction.pre_op),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!local->transaction.pre_op)
+ goto out;
+
+ local->pending = afr_matrix_create (priv->child_count,
+ AFR_NUM_CHANGE_LOGS);
+ if (!local->pending)
+ goto out;
+
+ local->transaction.child_errno =
+ GF_CALLOC (sizeof (*local->transaction.child_errno),
+ priv->child_count,
+ gf_afr_mt_int32_t);
+ local->transaction.erase_pending = 1;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+void
+afr_reset_children (int32_t *fresh_children, int32_t child_count)
+{
+ unsigned int i = 0;
+ for (i = 0; i < child_count; i++)
+ fresh_children[i] = -1;
+}
+
+int32_t*
+afr_children_create (int32_t child_count)
+{
+ int32_t *children = NULL;
+ int i = 0;
+
+ GF_ASSERT (child_count > 0);
+
+ children = GF_CALLOC (child_count, sizeof (*children),
+ gf_afr_mt_int32_t);
+ if (NULL == children)
+ goto out;
+ for (i = 0; i < child_count; i++)
+ children[i] = -1;
+out:
+ return children;
+}
+
+void
+afr_children_add_child (int32_t *children, int32_t child,
+ int32_t child_count)
+{
+ gf_boolean_t child_found = _gf_false;
+ int i = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (children[i] == -1)
+ break;
+ if (children[i] == child) {
+ child_found = _gf_true;
+ break;
+ }
+ }
+
+ if (!child_found) {
+ GF_ASSERT (i < child_count);
+ children[i] = child;
+ }
+}
+
+void
+afr_children_rm_child (int32_t *children, int32_t child, int32_t child_count)
+{
+ int i = 0;
+
+ GF_ASSERT ((child >= 0) && (child < child_count));
+ for (i = 0; i < child_count; i++) {
+ if (children[i] == -1)
+ break;
+ if (children[i] == child) {
+ if (i != (child_count - 1))
+ memmove (children + i, children + i + 1,
+ sizeof (*children)*(child_count - i - 1));
+ children[child_count - 1] = -1;
+ break;
+ }
+ }
+}
+
+int
+afr_get_children_count (int32_t *children, unsigned int child_count)
+{
+ int count = 0;
+ int i = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (children[i] == -1)
+ break;
+ count++;
+ }
+ return count;
+}
+
+void
+afr_set_low_priority (call_frame_t *frame)
+{
+ frame->root->pid = LOW_PRIO_PROC_PID;
+}
+
+int
+afr_child_fd_ctx_set (xlator_t *this, fd_t *fd, int32_t child,
+ int flags)
+{
+ int ret = 0;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+
+ GF_ASSERT (fd && fd->inode);
+ ret = afr_fd_ctx_set (this, fd);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not set fd ctx for fd=%p", fd);
+ goto out;
+ }
+
+ ret = fd_ctx_get (fd, this, &ctx);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not get fd ctx for fd=%p", fd);
+ goto out;
+ }
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+ fd_ctx->opened_on[child] = AFR_FD_OPENED;
+ if (!IA_ISDIR (fd->inode->ia_type)) {
+ fd_ctx->flags = flags;
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+gf_boolean_t
+afr_have_quorum (char *logname, afr_private_t *priv)
+{
+ unsigned int quorum = 0;
+
+ GF_VALIDATE_OR_GOTO(logname,priv,out);
+
+ quorum = priv->quorum_count;
+ if (quorum != AFR_QUORUM_AUTO) {
+ return (priv->up_count >= (priv->down_count + quorum));
+ }
+
+ quorum = priv->child_count / 2 + 1;
+ if (priv->up_count >= (priv->down_count + quorum)) {
+ return _gf_true;
+ }
+
+ /*
+ * Special case for even numbers of nodes: if we have exactly half
+ * and that includes the first ("senior-most") node, then that counts
+ * as quorum even if it wouldn't otherwise. This supports e.g. N=2
+ * while preserving the critical property that there can only be one
+ * such group.
+ */
+ if ((priv->child_count % 2) == 0) {
+ quorum = priv->child_count / 2;
+ if (priv->up_count >= (priv->down_count + quorum)) {
+ if (priv->child_up[0]) {
+ return _gf_true;
+ }
+ }
+ }
+
+out:
+ return _gf_false;
+}
+
+void
+afr_priv_destroy (afr_private_t *priv)
+{
+ int i = 0;
+
+ if (!priv)
+ goto out;
+ inode_unref (priv->root_inode);
+ GF_FREE (priv->shd.pos);
+ GF_FREE (priv->shd.pending);
+ GF_FREE (priv->shd.inprogress);
+// for (i = 0; i < priv->child_count; i++)
+// if (priv->shd.timer && priv->shd.timer[i])
+// gf_timer_call_cancel (this->ctx, priv->shd.timer[i]);
+ GF_FREE (priv->shd.timer);
+
+ if (priv->shd.healed)
+ eh_destroy (priv->shd.healed);
+
+ if (priv->shd.heal_failed)
+ eh_destroy (priv->shd.heal_failed);
+
+ if (priv->shd.split_brain)
+ eh_destroy (priv->shd.split_brain);
+
+ GF_FREE (priv->last_event);
+ if (priv->pending_key) {
+ for (i = 0; i < priv->child_count; i++)
+ GF_FREE (priv->pending_key[i]);
+ }
+ GF_FREE (priv->pending_key);
+ GF_FREE (priv->children);
+ GF_FREE (priv->child_up);
+ LOCK_DESTROY (&priv->lock);
+ LOCK_DESTROY (&priv->read_child_lock);
+ pthread_mutex_destroy (&priv->mutex);
+ GF_FREE (priv);
+out:
+ return;
+}
+
+int
+xlator_subvolume_count (xlator_t *this)
+{
+ int i = 0;
+ xlator_list_t *list = NULL;
+
+ for (list = this->children; list; list = list->next)
+ i++;
+ return i;
+}
diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c
index b2a001a19..b661cfa9c 100644
--- a/xlators/cluster/afr/src/afr-dir-read.c
+++ b/xlators/cluster/afr/src/afr-dir-read.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -49,9 +40,9 @@
#include "afr-self-heal.h"
#include "afr-self-heal-common.h"
-
int
-afr_examine_dir_sh_unwind (call_frame_t *frame, xlator_t *this)
+afr_examine_dir_sh_unwind (call_frame_t *frame, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, int32_t sh_failed)
{
afr_local_t *local = NULL;
@@ -60,7 +51,7 @@ afr_examine_dir_sh_unwind (call_frame_t *frame, xlator_t *this)
afr_set_opendir_done (this, local->fd->inode);
AFR_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd);
+ local->op_errno, local->fd, NULL);
return 0;
}
@@ -70,15 +61,19 @@ gf_boolean_t
__checksums_differ (uint32_t *checksum, int child_count,
unsigned char *child_up)
{
- int ret = _gf_false;
- int i = 0;
- uint32_t cksum = 0;
-
- cksum = checksum[0];
+ int ret = _gf_false;
+ int i = 0;
+ uint32_t cksum = 0;
+ gf_boolean_t activate_check = _gf_false;
for (i = 0; i < child_count; i++) {
if (!child_up[i])
continue;
+ if (_gf_false == activate_check) {
+ cksum = checksum[i];
+ activate_check = _gf_true;
+ continue;
+ }
if (cksum != checksum[i]) {
ret = _gf_true;
@@ -95,22 +90,24 @@ __checksums_differ (uint32_t *checksum, int child_count,
int32_t
afr_examine_dir_readdir_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries)
+ gf_dirent_t *entries, dict_t *xdata)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
afr_self_heal_t * sh = NULL;
gf_dirent_t * entry = NULL;
gf_dirent_t * tmp = NULL;
+ char *reason = NULL;
int child_index = 0;
uint32_t entry_cksum = 0;
int call_count = 0;
off_t last_offset = 0;
- char sh_type_str[256] = {0,};
+ inode_t *inode = NULL;
priv = this->private;
local = frame->local;
sh = &local->self_heal;
+ inode = local->fd->inode;
child_index = (long) cookie;
@@ -131,7 +128,7 @@ afr_examine_dir_readdir_cbk (call_frame_t *frame, void *cookie,
}
list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- entry_cksum = gf_rsync_weak_checksum (entry->d_name,
+ entry_cksum = gf_rsync_weak_checksum ((unsigned char *)entry->d_name,
strlen (entry->d_name));
local->cont.opendir.checksum[child_index] ^= entry_cksum;
}
@@ -146,7 +143,7 @@ afr_examine_dir_readdir_cbk (call_frame_t *frame, void *cookie,
(void *) (long) child_index,
priv->children[child_index],
priv->children[child_index]->fops->readdir,
- local->fd, 131072, last_offset);
+ local->fd, 131072, last_offset, NULL);
return 0;
@@ -158,27 +155,18 @@ out:
priv->child_count,
local->child_up)) {
- sh->need_entry_self_heal = _gf_true;
+ sh->do_entry_self_heal = _gf_true;
sh->forced_merge = _gf_true;
- sh->type = local->fd->inode->ia_type;
- sh->background = _gf_false;
- sh->unwind = afr_examine_dir_sh_unwind;
- afr_self_heal_type_str_get(&local->self_heal,
- sh_type_str,
- sizeof(sh_type_str));
- gf_log (this->name, GF_LOG_INFO,
- "%s self-heal triggered. path: %s, "
- "reason: checksums of directory differ,"
- " forced merge option set",
- sh_type_str, local->loc.path);
-
- afr_self_heal (frame, this);
+ reason = "checksums of directory differ";
+ afr_launch_self_heal (frame, this, inode, _gf_false,
+ inode->ia_type, reason, NULL,
+ afr_examine_dir_sh_unwind);
} else {
- afr_set_opendir_done (this, local->fd->inode);
+ afr_set_opendir_done (this, inode);
AFR_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd);
+ local->op_errno, local->fd, NULL);
}
}
@@ -201,7 +189,7 @@ afr_examine_dir (call_frame_t *frame, xlator_t *this)
sizeof (*local->cont.opendir.checksum),
gf_afr_mt_int32_t);
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_up_children_count (local->child_up, priv->child_count);
local->call_count = call_count;
@@ -211,7 +199,7 @@ afr_examine_dir (call_frame_t *frame, xlator_t *this)
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->readdir,
- local->fd, 131072, 0);
+ local->fd, 131072, 0, NULL);
if (!--call_count)
break;
@@ -225,27 +213,37 @@ afr_examine_dir (call_frame_t *frame, xlator_t *this)
int32_t
afr_opendir_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int32_t up_children_count = 0;
int ret = -1;
int call_count = -1;
+ int32_t child_index = 0;
priv = this->private;
local = frame->local;
+ child_index = (long) cookie;
- up_children_count = afr_up_children_count (priv->child_count,
- local->child_up);
+ up_children_count = afr_up_children_count (local->child_up,
+ priv->child_count);
LOCK (&frame->lock);
{
- if (op_ret >= 0)
+ if (op_ret >= 0) {
local->op_ret = op_ret;
+ ret = afr_child_fd_ctx_set (this, fd, child_index, 0);
+ if (ret) {
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ goto unlock;
+ }
+ }
local->op_errno = op_errno;
}
+unlock:
UNLOCK (&frame->lock);
call_count = afr_frame_return (frame);
@@ -254,15 +252,6 @@ afr_opendir_cbk (call_frame_t *frame, void *cookie,
if (local->op_ret != 0)
goto out;
- ret = afr_fd_ctx_set (this, local->fd);
- if (ret) {
- local->op_ret = -1;
- local->op_errno = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set fd ctx for fd %p",
- local->fd);
- goto out;
- }
if (!afr_is_opendir_done (this, local->fd->inode) &&
up_children_count > 1) {
@@ -273,7 +262,7 @@ afr_opendir_cbk (call_frame_t *frame, void *cookie,
* to regular entry self-heal because the readdir
* call is sent only to the first subvolume, and
* thus files that exist only there will never be healed
- * otherwise (assuming changelog shows no anamolies).
+ * otherwise (assuming changelog shows no anomalies).
*/
gf_log (this->name, GF_LOG_TRACE,
@@ -292,7 +281,7 @@ afr_opendir_cbk (call_frame_t *frame, void *cookie,
out:
AFR_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd);
+ local->op_errno, local->fd, NULL);
return 0;
}
@@ -308,7 +297,6 @@ afr_opendir (call_frame_t *frame, xlator_t *this,
int i = 0;
int ret = -1;
int call_count = -1;
- int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -319,37 +307,36 @@ afr_opendir (call_frame_t *frame, xlator_t *this,
child_count = priv->child_count;
- ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
+
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
loc_copy (&local->loc, loc);
- frame->local = local;
local->fd = fd_ref (fd);
call_count = local->call_count;
for (i = 0; i < child_count; i++) {
if (local->child_up[i]) {
- STACK_WIND (frame, afr_opendir_cbk,
- priv->children[i],
- priv->children[i]->fops->opendir,
- loc, fd);
+ STACK_WIND_COOKIE (frame, afr_opendir_cbk,
+ (void*) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->opendir,
+ loc, fd, NULL);
if (!--call_count)
break;
}
}
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (opendir, frame, op_ret, op_errno, fd);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (opendir, frame, -1, op_errno, fd, NULL);
return 0;
}
@@ -479,26 +466,18 @@ afr_forget_entries (fd_t *fd)
int32_t
afr_readdir_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries)
+ gf_dirent_t *entries, dict_t *xdata)
{
- afr_private_t * priv = NULL;
afr_local_t * local = NULL;
gf_dirent_t * entry = NULL;
gf_dirent_t * tmp = NULL;
- int child_index = -1;
- priv = this->private;
local = frame->local;
- child_index = (long) cookie;
if (op_ret == -1)
goto out;
list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- entry->d_ino = afr_itransform (entry->d_ino,
- priv->child_count,
- child_index);
-
if ((local->fd->inode == local->fd->inode->table->root)
&& !strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR)) {
list_del_init (&entry->list);
@@ -507,7 +486,7 @@ afr_readdir_cbk (call_frame_t *frame, void *cookie,
}
out:
- AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, entries);
+ AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, entries, NULL);
return 0;
}
@@ -515,27 +494,41 @@ out:
int32_t
afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- ino_t inum = 0;
- int call_child = 0;
- int ret = 0;
- gf_dirent_t * entry = NULL;
- gf_dirent_t * tmp = NULL;
- int child_index = -1;
- uint64_t ctx = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
- off_t offset = 0;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int32_t next_call_child = -1;
+ int ret = 0;
+ gf_dirent_t * entry = NULL;
+ gf_dirent_t * tmp = NULL;
+ int32_t *last_index = NULL;
+ int32_t read_child = -1;
+ int32_t *fresh_children = NULL;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ off_t offset = 0;
+ int32_t call_child = -1;
priv = this->private;
children = priv->children;
local = frame->local;
- child_index = (long) cookie;
+ read_child = (long) cookie;
+ last_index = &local->cont.readdir.last_index;
+ fresh_children = local->fresh_children;
+
+ /* the value of the last_index changes if afr_next_call_child is
+ * called. So to find the call_child of this callback use last_index
+ * before the next_call_child call.
+ */
+ if (*last_index == -1)
+ call_child = read_child;
+ else
+ call_child = fresh_children[*last_index];
if (priv->strict_readdir) {
ret = fd_ctx_get (local->fd, this, &ctx);
@@ -549,39 +542,33 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- if (child_went_down (op_ret, op_errno)) {
- if (all_tried (child_index, priv->child_count)) {
- gf_log (this->name, GF_LOG_INFO,
- "all options tried going out");
+ if (op_ret == -1) {
+ next_call_child = afr_next_call_child (fresh_children,
+ local->child_up,
+ priv->child_count,
+ last_index,
+ read_child);
+ if (next_call_child < 0)
goto out;
- }
-
- call_child = ++child_index;
-
gf_log (this->name, GF_LOG_TRACE,
"starting readdir afresh on child %d, offset %"PRId64,
- call_child, (uint64_t) 0);
+ next_call_child, (uint64_t) 0);
fd_ctx->failed_over = _gf_true;
STACK_WIND_COOKIE (frame, afr_readdirp_cbk,
- (void *) (long) call_child,
- children[call_child],
- children[call_child]->fops->readdirp, local->fd,
- local->cont.readdir.size, 0);
+ (void *) (long) read_child,
+ children[next_call_child],
+ children[next_call_child]->fops->readdirp,
+ local->fd,
+ local->cont.readdir.size, 0,
+ local->cont.readdir.dict);
return 0;
}
}
if (op_ret != -1) {
list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- inum = afr_itransform (entry->d_ino, priv->child_count,
- child_index);
- entry->d_ino = inum;
- inum = afr_itransform (entry->d_stat.ia_ino,
- priv->child_count, child_index);
- entry->d_stat.ia_ino = inum;
-
if ((local->fd->inode == local->fd->inode->table->root)
&& !strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR)) {
list_del_init (&entry->list);
@@ -605,19 +592,20 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (list_empty (&entries->list)) {
/* All the entries we got were duplicate. We
shouldn't send an empty list now, because
- that'll make the application stop reading. So
+ that will make the application stop reading. So
try to get more entries */
gf_log (this->name, GF_LOG_TRACE,
"trying to fetch non-duplicate entries "
"from offset %"PRId64", child %s",
- offset, children[child_index]->name);
+ offset, children[call_child]->name);
STACK_WIND_COOKIE (frame, afr_readdirp_cbk,
- (void *) (long) child_index,
- children[child_index],
- children[child_index]->fops->readdirp,
- local->fd, local->cont.readdir.size, offset);
+ (void *) (long) read_child,
+ children[call_child],
+ children[call_child]->fops->readdirp,
+ local->fd, local->cont.readdir.size, offset,
+ local->cont.readdir.dict);
return 0;
}
} else {
@@ -626,15 +614,14 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
out:
- AFR_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries);
+ AFR_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries, NULL);
return 0;
}
-
int32_t
afr_do_readdir (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, int whichop)
+ fd_t *fd, size_t size, off_t offset, int whichop, dict_t *dict)
{
afr_private_t * priv = NULL;
xlator_t ** children = NULL;
@@ -643,8 +630,8 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this,
uint64_t ctx = 0;
afr_fd_ctx_t *fd_ctx = NULL;
int ret = -1;
- int32_t op_ret = -1;
int32_t op_errno = 0;
+ uint64_t read_child = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -653,25 +640,33 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this,
priv = this->private;
children = priv->children;
- ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
+
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
- frame->local = local;
+ local->fresh_children = afr_children_create (priv->child_count);
+ if (!local->fresh_children) {
+ op_errno = ENOMEM;
+ goto out;
+ }
- call_child = afr_first_up_child (priv);
- if (call_child == -1) {
- op_errno = ENOTCONN;
- gf_log (this->name, GF_LOG_INFO,
- "no child is up");
+ read_child = afr_inode_get_read_ctx (this, fd->inode,
+ local->fresh_children);
+ ret = afr_get_call_child (this, local->child_up, read_child,
+ local->fresh_children,
+ &call_child,
+ &local->cont.readdir.last_index);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
}
local->fd = fd_ref (fd);
local->cont.readdir.size = size;
+ local->cont.readdir.dict = (dict)? dict_ref (dict) : NULL;
if (priv->strict_readdir) {
ret = fd_ctx_get (fd, this, &ctx);
@@ -702,37 +697,36 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this,
(void *) (long) call_child,
children[call_child],
children[call_child]->fops->readdir, fd,
- size, offset);
+ size, offset, dict);
else
STACK_WIND_COOKIE (frame, afr_readdirp_cbk,
(void *) (long) call_child,
children[call_child],
children[call_child]->fops->readdirp, fd,
- size, offset);
+ size, offset, dict);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, NULL);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
afr_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset)
+ off_t offset, dict_t *xdata)
{
- afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIR);
+ afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIR, xdata);
return 0;
}
int32_t
afr_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset)
+ off_t offset, dict_t *dict)
{
- afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIRP);
+ afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIRP, dict);
return 0;
}
diff --git a/xlators/cluster/afr/src/afr-dir-read.h b/xlators/cluster/afr/src/afr-dir-read.h
index 40c7b6aef..09456d159 100644
--- a/xlators/cluster/afr/src/afr-dir-read.h
+++ b/xlators/cluster/afr/src/afr-dir-read.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 __DIR_READ_H__
@@ -23,28 +14,23 @@
int32_t
afr_opendir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, fd_t *fd);
+ loc_t *loc, fd_t *fd, dict_t *xdata);
int32_t
afr_releasedir (xlator_t *this, fd_t *fd);
int32_t
afr_readdir (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset);
+ fd_t *fd, size_t size, off_t offset, dict_t *xdata);
int32_t
afr_readdirp (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset);
-
-int32_t
-afr_getdents (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, int32_t flag);
-
+ fd_t *fd, size_t size, off_t offset, dict_t *dict);
int32_t
afr_checksum (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags);
+ loc_t *loc, int32_t flags, dict_t *xdata);
#endif /* __DIR_READ_H__ */
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
index 06559ede0..46f5dceeb 100644
--- a/xlators/cluster/afr/src/afr-dir-write.c
+++ b/xlators/cluster/afr/src/afr-dir-write.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -47,28 +38,31 @@
#include "afr.h"
#include "afr-transaction.h"
-
-void
-afr_build_parent_loc (loc_t *parent, loc_t *child)
+int
+afr_build_parent_loc (loc_t *parent, loc_t *child, int32_t *op_errno)
{
- char *tmp = NULL;
+ int ret = -1;
+ char *child_path = NULL;
if (!child->parent) {
- loc_copy (parent, child);
- return;
+ if (op_errno)
+ *op_errno = EINVAL;
+ goto out;
}
- tmp = gf_strdup (child->path);
- parent->path = gf_strdup (dirname (tmp));
- GF_FREE (tmp);
-
- parent->name = strrchr (parent->path, '/');
- if (parent->name)
- parent->name++;
-
+ child_path = gf_strdup (child->path);
+ if (!child_path) {
+ if (op_errno)
+ *op_errno = ENOMEM;
+ goto out;
+ }
+ parent->path = dirname (child_path);
parent->inode = inode_ref (child->parent);
- parent->parent = inode_parent (parent->inode, 0, NULL);
- parent->ino = parent->inode->ino;
+ uuid_copy (parent->gfid, child->pargfid);
+
+ ret = 0;
+out:
+ return ret;
}
/* {{{ create */
@@ -98,17 +92,13 @@ afr_create_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.create.buf;
}
- unwind_buf->ia_ino = local->cont.create.ino;
-
- local->cont.create.preparent.ia_ino = local->cont.create.parent_ino;
- local->cont.create.postparent.ia_ino = local->cont.create.parent_ino;
-
AFR_STACK_UNWIND (create, main_frame,
local->op_ret, local->op_errno,
local->cont.create.fd,
local->cont.create.inode,
unwind_buf, &local->cont.create.preparent,
- &local->cont.create.postparent);
+ &local->cont.create.postparent,
+ NULL);
}
return 0;
@@ -119,15 +109,17 @@ int
afr_create_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
fd_t *fd, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent)
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- uint64_t ctx = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
- int ret = 0;
- int call_count = -1;
- int child_index = -1;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ int ret = 0;
+ int call_count = -1;
+ int child_index = -1;
+ int32_t *fresh_children = NULL;
local = frame->local;
priv = this->private;
@@ -165,33 +157,12 @@ afr_create_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- fd_ctx->opened_on[child_index] = 1;
+ fd_ctx->opened_on[child_index] = AFR_FD_OPENED;
fd_ctx->flags = local->cont.create.flags;
- if (local->success_count == 0) {
+ if (local->success_count == 0)
local->cont.create.buf = *buf;
- local->cont.create.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- child_index);
-
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
- }
-
- if (child_index == local->first_up_child) {
- local->cont.create.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- local->first_up_child);
- }
-
if (child_index == local->read_child_index) {
local->cont.create.read_child_buf = *buf;
local->cont.create.preparent = *preparent;
@@ -200,6 +171,8 @@ afr_create_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.create.inode = inode;
+ fresh_children = local->fresh_children;
+ fresh_children[local->success_count] = child_index;
local->success_count++;
}
@@ -212,6 +185,10 @@ unlock:
call_count = afr_frame_return (frame);
if (call_count == 0) {
+ afr_set_read_ctx_from_policy (this, inode,
+ local->fresh_children,
+ local->read_child_index,
+ priv->read_child);
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -232,7 +209,8 @@ afr_create_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
+ priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -242,7 +220,7 @@ afr_create_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
+ if (local->transaction.pre_op[i]) {
STACK_WIND_COOKIE (frame, afr_create_wind_cbk,
(void *) (long) i,
priv->children[i],
@@ -250,8 +228,9 @@ afr_create_wind (call_frame_t *frame, xlator_t *this)
&local->loc,
local->cont.create.flags,
local->cont.create.mode,
+ local->umask,
local->cont.create.fd,
- local->cont.create.params);
+ local->xdata_req);
if (!--call_count)
break;
}
@@ -279,14 +258,13 @@ afr_create_done (call_frame_t *frame, xlator_t *this)
int
afr_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params)
+ mode_t umask, fd_t *fd, dict_t *params)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- call_frame_t * transaction_frame = NULL;
- int ret = -1;
- int op_ret = -1;
- int op_errno = 0;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ call_frame_t *transaction_frame = NULL;
+ int ret = -1;
+ int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -294,20 +272,20 @@ afr_create (call_frame_t *frame, xlator_t *this,
priv = this->private;
+ QUORUM_CHECK(create,out);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
+ op_errno = ENOMEM;
goto out;
}
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
-
- transaction_frame->local = local;
loc_copy (&local->loc, loc);
@@ -321,30 +299,31 @@ afr_create (call_frame_t *frame, xlator_t *this,
local->cont.create.flags = flags;
local->cont.create.mode = mode;
local->cont.create.fd = fd_ref (fd);
+ local->umask = umask;
if (params)
- local->cont.create.params = dict_ref (params);
-
- if (loc->parent)
- local->cont.create.parent_ino = loc->parent->ino;
+ local->xdata_req = dict_ref (params);
local->transaction.fop = afr_create_wind;
local->transaction.done = afr_create_done;
local->transaction.unwind = afr_create_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, loc);
+ ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
+ &op_errno);
+ if (ret)
+ goto out;
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (create, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (create, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL, NULL, NULL);
}
return 0;
@@ -379,16 +358,12 @@ afr_mknod_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.mknod.buf;
}
- unwind_buf->ia_ino = local->cont.mknod.ino;
-
- local->cont.mknod.preparent.ia_ino = local->cont.mknod.parent_ino;
- local->cont.mknod.postparent.ia_ino = local->cont.mknod.parent_ino;
-
AFR_STACK_UNWIND (mknod, main_frame,
local->op_ret, local->op_errno,
local->cont.mknod.inode,
unwind_buf, &local->cont.mknod.preparent,
- &local->cont.mknod.postparent);
+ &local->cont.mknod.postparent,
+ NULL);
}
return 0;
@@ -399,12 +374,13 @@ int
afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- int call_count = -1;
- int child_index = -1;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = -1;
+ int child_index = -1;
+ int32_t *fresh_children = NULL;
local = frame->local;
priv = this->private;
@@ -419,28 +395,8 @@ afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret != -1) {
local->op_ret = op_ret;
- if (local->success_count == 0){
+ if (local->success_count == 0)
local->cont.mknod.buf = *buf;
- local->cont.mknod.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- child_index);
-
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
- }
-
- if (child_index == local->first_up_child) {
- local->cont.mknod.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- local->first_up_child);
- }
if (child_index == local->read_child_index) {
local->cont.mknod.read_child_buf = *buf;
@@ -450,6 +406,8 @@ afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.mknod.inode = inode;
+ fresh_children = local->fresh_children;
+ fresh_children[local->success_count] = child_index;
local->success_count++;
}
@@ -460,6 +418,10 @@ afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
+ afr_set_read_ctx_from_policy (this, inode,
+ local->fresh_children,
+ local->read_child_index,
+ priv->read_child);
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -480,7 +442,8 @@ afr_mknod_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
+ priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -490,13 +453,14 @@ afr_mknod_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
+ if (local->transaction.pre_op[i]) {
STACK_WIND_COOKIE (frame, afr_mknod_wind_cbk, (void *) (long) i,
priv->children[i],
priv->children[i]->fops->mknod,
&local->loc, local->cont.mknod.mode,
local->cont.mknod.dev,
- local->cont.mknod.params);
+ local->umask,
+ local->xdata_req);
if (!--call_count)
break;
}
@@ -521,14 +485,13 @@ afr_mknod_done (call_frame_t *frame, xlator_t *this)
int
-afr_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t dev, dict_t *params)
+afr_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t dev, mode_t umask, dict_t *params)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
- int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -537,20 +500,20 @@ afr_mknod (call_frame_t *frame, xlator_t *this,
priv = this->private;
+ QUORUM_CHECK(mknod,out);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
+ op_errno = ENOMEM;
goto out;
}
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
-
- transaction_frame->local = local;
loc_copy (&local->loc, loc);
@@ -563,30 +526,31 @@ afr_mknod (call_frame_t *frame, xlator_t *this,
local->cont.mknod.mode = mode;
local->cont.mknod.dev = dev;
+ local->umask = umask;
if (params)
- local->cont.mknod.params = dict_ref (params);
-
- if (loc->parent)
- local->cont.mknod.parent_ino = loc->parent->ino;
+ local->xdata_req = dict_ref (params);
local->transaction.fop = afr_mknod_wind;
local->transaction.done = afr_mknod_done;
local->transaction.unwind = afr_mknod_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, loc);
+ ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
+ &op_errno);
+ if (ret)
+ goto out;
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (mknod, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (mknod, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
}
return 0;
@@ -622,16 +586,12 @@ afr_mkdir_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.mkdir.buf;
}
- unwind_buf->ia_ino = local->cont.mkdir.ino;
-
- local->cont.mkdir.preparent.ia_ino = local->cont.mkdir.parent_ino;
- local->cont.mkdir.postparent.ia_ino = local->cont.mkdir.parent_ino;
-
AFR_STACK_UNWIND (mkdir, main_frame,
local->op_ret, local->op_errno,
local->cont.mkdir.inode,
unwind_buf, &local->cont.mkdir.preparent,
- &local->cont.mkdir.postparent);
+ &local->cont.mkdir.postparent,
+ NULL);
}
return 0;
@@ -642,12 +602,13 @@ int
afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- int call_count = -1;
- int child_index = -1;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = -1;
+ int child_index = -1;
+ int32_t *fresh_children = NULL;
local = frame->local;
priv = this->private;
@@ -662,30 +623,9 @@ afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret != -1) {
local->op_ret = op_ret;
- if (local->success_count == 0) {
+ if (local->success_count == 0)
local->cont.mkdir.buf = *buf;
- local->cont.mkdir.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- child_index);
-
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
- }
-
- if (child_index == local->first_up_child) {
- local->cont.mkdir.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- local->first_up_child);
- }
-
if (child_index == local->read_child_index) {
local->cont.mkdir.read_child_buf = *buf;
local->cont.mkdir.preparent = *preparent;
@@ -694,6 +634,8 @@ afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.mkdir.inode = inode;
+ fresh_children = local->fresh_children;
+ fresh_children[local->success_count] = child_index;
local->success_count++;
}
@@ -704,6 +646,10 @@ afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
+ afr_set_read_ctx_from_policy (this, inode,
+ local->fresh_children,
+ local->read_child_index,
+ priv->read_child);
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -724,7 +670,8 @@ afr_mkdir_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
+ priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -734,13 +681,14 @@ afr_mkdir_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
+ if (local->transaction.pre_op[i]) {
STACK_WIND_COOKIE (frame, afr_mkdir_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->mkdir,
&local->loc, local->cont.mkdir.mode,
- local->cont.mkdir.params);
+ local->umask,
+ local->xdata_req);
if (!--call_count)
break;
}
@@ -767,13 +715,12 @@ afr_mkdir_done (call_frame_t *frame, xlator_t *this)
int
afr_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params)
+ loc_t *loc, mode_t mode, mode_t umask, dict_t *params)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
- int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -782,20 +729,20 @@ afr_mkdir (call_frame_t *frame, xlator_t *this,
priv = this->private;
+ QUORUM_CHECK(mkdir,out);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
+ op_errno = ENOMEM;
goto out;
}
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
-
- transaction_frame->local = local;
loc_copy (&local->loc, loc);
@@ -807,31 +754,32 @@ afr_mkdir (call_frame_t *frame, xlator_t *this,
UNLOCK (&priv->read_child_lock);
local->cont.mkdir.mode = mode;
+ local->umask = umask;
if (params)
- local->cont.mkdir.params = dict_ref (params);
-
- if (loc->parent)
- local->cont.mkdir.parent_ino = loc->parent->ino;
+ local->xdata_req = dict_ref (params);
local->transaction.fop = afr_mkdir_wind;
local->transaction.done = afr_mkdir_done;
local->transaction.unwind = afr_mkdir_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, loc);
+ ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
+ &op_errno);
+ if (ret)
+ goto out;
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (mkdir, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (mkdir, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
}
return 0;
@@ -867,16 +815,12 @@ afr_link_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.link.buf;
}
- unwind_buf->ia_ino = local->cont.link.ino;
-
- local->cont.link.preparent.ia_ino = local->cont.link.parent_ino;
- local->cont.link.postparent.ia_ino = local->cont.link.parent_ino;
-
AFR_STACK_UNWIND (link, main_frame,
local->op_ret, local->op_errno,
local->cont.link.inode,
unwind_buf, &local->cont.link.preparent,
- &local->cont.link.postparent);
+ &local->cont.link.postparent,
+ NULL);
}
return 0;
@@ -887,12 +831,13 @@ int
afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- int call_count = -1;
- int child_index = -1;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = -1;
+ int child_index = -1;
+ int32_t *fresh_children = NULL;
local = frame->local;
priv = this->private;
@@ -909,14 +854,6 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->success_count == 0) {
local->cont.link.buf = *buf;
-
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
}
if (child_index == local->read_child_index) {
@@ -925,11 +862,12 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.link.postparent = *postparent;
}
- local->cont.link.inode = inode;
-
+ fresh_children = local->fresh_children;
+ fresh_children[local->success_count] = child_index;
local->success_count++;
}
+ local->cont.link.inode = inode;
local->op_errno = op_errno;
}
UNLOCK (&frame->lock);
@@ -937,6 +875,10 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
+ afr_set_read_ctx_from_policy (this, inode,
+ local->fresh_children,
+ local->read_child_index,
+ priv->read_child);
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -957,7 +899,8 @@ afr_link_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
+ priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -967,12 +910,12 @@ afr_link_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
+ if (local->transaction.pre_op[i]) {
STACK_WIND_COOKIE (frame, afr_link_wind_cbk, (void *) (long) i,
priv->children[i],
priv->children[i]->fops->link,
&local->loc,
- &local->newloc);
+ &local->newloc, local->xdata_req);
if (!--call_count)
break;
@@ -998,13 +941,12 @@ afr_link_done (call_frame_t *frame, xlator_t *this)
int
afr_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc)
+ loc_t *oldloc, loc_t *newloc, dict_t *xdata)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
- int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1013,23 +955,25 @@ afr_link (call_frame_t *frame, xlator_t *this,
priv = this->private;
+ QUORUM_CHECK(link,out);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
+ op_errno = ENOMEM;
goto out;
}
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
-
- transaction_frame->local = local;
loc_copy (&local->loc, oldloc);
loc_copy (&local->newloc, newloc);
+ if (xdata)
+ local->xdata_req = dict_ref (xdata);
LOCK (&priv->read_child_lock);
{
@@ -1038,30 +982,27 @@ afr_link (call_frame_t *frame, xlator_t *this,
}
UNLOCK (&priv->read_child_lock);
- local->cont.link.ino = oldloc->inode->ino;
-
- if (oldloc->parent)
- local->cont.link.parent_ino = newloc->parent->ino;
-
local->transaction.fop = afr_link_wind;
local->transaction.done = afr_link_done;
local->transaction.unwind = afr_link_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, oldloc);
+ ret = afr_build_parent_loc (&local->transaction.parent_loc, newloc,
+ &op_errno);
+ if (ret)
+ goto out;
local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (oldloc->path);
- local->transaction.new_basename = AFR_BASENAME (newloc->path);
+ local->transaction.basename = AFR_BASENAME (newloc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (link, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (link, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
}
return 0;
@@ -1097,16 +1038,12 @@ afr_symlink_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.symlink.buf;
}
- unwind_buf->ia_ino = local->cont.symlink.ino;
-
- local->cont.symlink.preparent.ia_ino = local->cont.symlink.parent_ino;
- local->cont.symlink.postparent.ia_ino = local->cont.symlink.parent_ino;
-
AFR_STACK_UNWIND (symlink, main_frame,
local->op_ret, local->op_errno,
local->cont.symlink.inode,
unwind_buf, &local->cont.symlink.preparent,
- &local->cont.symlink.postparent);
+ &local->cont.symlink.postparent,
+ NULL);
}
return 0;
@@ -1117,12 +1054,13 @@ int
afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- int call_count = -1;
- int child_index = -1;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = -1;
+ int child_index = -1;
+ int32_t *fresh_children = NULL;
local = frame->local;
priv = this->private;
@@ -1137,27 +1075,8 @@ afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret != -1) {
local->op_ret = op_ret;
- if (local->success_count == 0) {
+ if (local->success_count == 0)
local->cont.symlink.buf = *buf;
- local->cont.symlink.ino =
- afr_itransform (buf->ia_ino, priv->child_count,
- child_index);
-
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
- }
-
- if (child_index == local->first_up_child) {
- local->cont.symlink.ino =
- afr_itransform (buf->ia_ino,
- priv->child_count,
- local->first_up_child);
- }
if (child_index == local->read_child_index) {
local->cont.symlink.read_child_buf = *buf;
@@ -1167,6 +1086,8 @@ afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.symlink.inode = inode;
+ fresh_children = local->fresh_children;
+ fresh_children[local->success_count] = child_index;
local->success_count++;
}
@@ -1177,6 +1098,10 @@ afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
+ afr_set_read_ctx_from_policy (this, inode,
+ local->fresh_children,
+ local->read_child_index,
+ priv->read_child);
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -1197,7 +1122,8 @@ afr_symlink_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
+ priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1207,14 +1133,15 @@ afr_symlink_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
+ if (local->transaction.pre_op[i]) {
STACK_WIND_COOKIE (frame, afr_symlink_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->symlink,
local->cont.symlink.linkpath,
&local->loc,
- local->cont.symlink.params);
+ local->umask,
+ local->xdata_req);
if (!--call_count)
break;
@@ -1241,13 +1168,12 @@ afr_symlink_done (call_frame_t *frame, xlator_t *this)
int
afr_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params)
+ const char *linkpath, loc_t *loc, mode_t umask, dict_t *params)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
- int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1256,20 +1182,20 @@ afr_symlink (call_frame_t *frame, xlator_t *this,
priv = this->private;
+ QUORUM_CHECK(symlink,out);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
+ op_errno = ENOMEM;
goto out;
}
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
-
- transaction_frame->local = local;
loc_copy (&local->loc, loc);
@@ -1281,30 +1207,31 @@ afr_symlink (call_frame_t *frame, xlator_t *this,
UNLOCK (&priv->read_child_lock);
local->cont.symlink.linkpath = gf_strdup (linkpath);
+ local->umask = umask;
if (params)
- local->cont.symlink.params = dict_ref (params);
-
- if (loc->parent)
- local->cont.symlink.parent_ino = loc->parent->ino;
+ local->xdata_req = dict_ref (params);
local->transaction.fop = afr_symlink_wind;
local->transaction.done = afr_symlink_done;
local->transaction.unwind = afr_symlink_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, loc);
+ ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
+ &op_errno);
+ if (ret)
+ goto out;
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (symlink, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (symlink, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
}
return 0;
@@ -1339,20 +1266,14 @@ afr_rename_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.rename.buf;
}
- unwind_buf->ia_ino = local->cont.rename.ino;
-
- local->cont.rename.preoldparent.ia_ino = local->cont.rename.oldparent_ino;
- local->cont.rename.postoldparent.ia_ino = local->cont.rename.oldparent_ino;
- local->cont.rename.prenewparent.ia_ino = local->cont.rename.newparent_ino;
- local->cont.rename.postnewparent.ia_ino = local->cont.rename.newparent_ino;
-
AFR_STACK_UNWIND (rename, main_frame,
local->op_ret, local->op_errno,
unwind_buf,
&local->cont.rename.preoldparent,
&local->cont.rename.postoldparent,
&local->cont.rename.prenewparent,
- &local->cont.rename.postnewparent);
+ &local->cont.rename.postnewparent,
+ NULL);
}
return 0;
@@ -1363,7 +1284,8 @@ int
afr_rename_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent)
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
{
afr_local_t * local = NULL;
int call_count = -1;
@@ -1425,7 +1347,8 @@ afr_rename_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
+ priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1435,13 +1358,13 @@ afr_rename_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
+ if (local->transaction.pre_op[i]) {
STACK_WIND_COOKIE (frame, afr_rename_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->rename,
&local->loc,
- &local->newloc);
+ &local->newloc, NULL);
if (!--call_count)
break;
}
@@ -1466,13 +1389,12 @@ afr_rename_done (call_frame_t *frame, xlator_t *this)
int
afr_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc)
+ loc_t *oldloc, loc_t *newloc, dict_t *xdata)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
- int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1481,39 +1403,38 @@ afr_rename (call_frame_t *frame, xlator_t *this,
priv = this->private;
+ QUORUM_CHECK(rename,out);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
+ op_errno = ENOMEM;
goto out;
}
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
-
- transaction_frame->local = local;
loc_copy (&local->loc, oldloc);
loc_copy (&local->newloc, newloc);
- local->read_child_index = afr_read_child (this, oldloc->inode);
-
- local->cont.rename.ino = oldloc->inode->ino;
-
- if (oldloc->parent)
- local->cont.rename.oldparent_ino = oldloc->parent->ino;
- if (newloc->parent)
- local->cont.rename.newparent_ino = newloc->parent->ino;
+ local->read_child_index = afr_inode_get_read_ctx (this, oldloc->inode, NULL);
local->transaction.fop = afr_rename_wind;
local->transaction.done = afr_rename_done;
local->transaction.unwind = afr_rename_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, oldloc);
- afr_build_parent_loc (&local->transaction.new_parent_loc, newloc);
+ ret = afr_build_parent_loc (&local->transaction.parent_loc, oldloc,
+ &op_errno);
+ if (ret)
+ goto out;
+ ret = afr_build_parent_loc (&local->transaction.new_parent_loc, newloc,
+ &op_errno);
+ if (ret)
+ goto out;
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (oldloc->path);
@@ -1521,14 +1442,14 @@ afr_rename (call_frame_t *frame, xlator_t *this,
afr_transaction (transaction_frame, this, AFR_ENTRY_RENAME_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (rename, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (rename, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL, NULL, NULL);
}
return 0;
@@ -1556,13 +1477,11 @@ afr_unlink_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
- local->cont.unlink.preparent.ia_ino = local->cont.unlink.parent_ino;
- local->cont.unlink.postparent.ia_ino = local->cont.unlink.parent_ino;
-
AFR_STACK_UNWIND (unlink, main_frame,
local->op_ret, local->op_errno,
&local->cont.unlink.preparent,
- &local->cont.unlink.postparent);
+ &local->cont.unlink.postparent,
+ NULL);
}
return 0;
@@ -1572,15 +1491,13 @@ afr_unlink_unwind (call_frame_t *frame, xlator_t *this)
int
afr_unlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
int call_count = -1;
int child_index = (long) cookie;
local = frame->local;
- priv = this->private;
LOCK (&frame->lock);
{
@@ -1633,7 +1550,8 @@ afr_unlink_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
+ priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1643,12 +1561,13 @@ afr_unlink_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
+ if (local->transaction.pre_op[i]) {
STACK_WIND_COOKIE (frame, afr_unlink_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->unlink,
- &local->loc);
+ &local->loc, local->xflag,
+ local->xdata_req);
if (!--call_count)
break;
@@ -1674,13 +1593,12 @@ afr_unlink_done (call_frame_t *frame, xlator_t *this)
int32_t
afr_unlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc)
+ loc_t *loc, int xflag, dict_t *xdata)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
- int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1689,44 +1607,47 @@ afr_unlink (call_frame_t *frame, xlator_t *this,
priv = this->private;
+ QUORUM_CHECK(unlink,out);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
+ op_errno = ENOMEM;
goto out;
}
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
-
- transaction_frame->local = local;
loc_copy (&local->loc, loc);
-
- if (loc->parent)
- local->cont.unlink.parent_ino = loc->parent->ino;
+ local->xflag = xflag;
+ if (xdata)
+ local->xdata_req = dict_ref (xdata);
local->transaction.fop = afr_unlink_wind;
local->transaction.done = afr_unlink_done;
local->transaction.unwind = afr_unlink_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, loc);
+ ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
+ &op_errno);
+ if (ret)
+ goto out;
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (unlink, frame, op_ret, op_errno,
- NULL, NULL);
+ AFR_STACK_UNWIND (unlink, frame, -1, op_errno,
+ NULL, NULL, NULL);
}
return 0;
@@ -1756,13 +1677,11 @@ afr_rmdir_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
- local->cont.rmdir.preparent.ia_ino = local->cont.rmdir.parent_ino;
- local->cont.rmdir.postparent.ia_ino = local->cont.rmdir.parent_ino;
-
AFR_STACK_UNWIND (rmdir, main_frame,
local->op_ret, local->op_errno,
&local->cont.rmdir.preparent,
- &local->cont.rmdir.postparent);
+ &local->cont.rmdir.postparent,
+ NULL);
}
return 0;
@@ -1772,16 +1691,14 @@ afr_rmdir_unwind (call_frame_t *frame, xlator_t *this)
int
afr_rmdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent)
+ struct iatt *postparent, dict_t *xdata)
{
afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
int call_count = -1;
int child_index = (long) cookie;
int read_child = 0;
local = frame->local;
- priv = this->private;
LOCK (&frame->lock);
{
@@ -1834,7 +1751,8 @@ afr_rmdir_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (priv->child_count, local->child_up);
+ call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
+ priv->child_count);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1844,12 +1762,13 @@ afr_rmdir_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
+ if (local->transaction.pre_op[i]) {
STACK_WIND_COOKIE (frame, afr_rmdir_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->rmdir,
- &local->loc, local->cont.rmdir.flags);
+ &local->loc, local->cont.rmdir.flags,
+ NULL);
if (!--call_count)
break;
@@ -1875,13 +1794,12 @@ afr_rmdir_done (call_frame_t *frame, xlator_t *this)
int
afr_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags)
+ loc_t *loc, int flags, dict_t *xdata)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
- int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1890,45 +1808,44 @@ afr_rmdir (call_frame_t *frame, xlator_t *this,
priv = this->private;
+ QUORUM_CHECK(rmdir,out);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
+ op_errno = ENOMEM;
goto out;
}
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
+ local = transaction_frame->local;
- ret = AFR_LOCAL_INIT (local, priv);
- if (ret < 0) {
- op_errno = -ret;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
goto out;
- }
-
- transaction_frame->local = local;
local->cont.rmdir.flags = flags;
loc_copy (&local->loc, loc);
- if (loc->parent)
- local->cont.rmdir.parent_ino = loc->parent->ino;
-
local->transaction.fop = afr_rmdir_wind;
local->transaction.done = afr_rmdir_done;
local->transaction.unwind = afr_rmdir_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, loc);
+ ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
+ &op_errno);
+ if (ret)
+ goto out;
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
+ if (ret < 0) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (rmdir, frame, op_ret, op_errno,
- NULL, NULL);
+ AFR_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
}
return 0;
diff --git a/xlators/cluster/afr/src/afr-dir-write.h b/xlators/cluster/afr/src/afr-dir-write.h
index e589efa37..02f0a3682 100644
--- a/xlators/cluster/afr/src/afr-dir-write.h
+++ b/xlators/cluster/afr/src/afr-dir-write.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-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 __DIR_WRITE_H__
@@ -23,38 +14,34 @@
int32_t
afr_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
+ mode_t umask, fd_t *fd, dict_t *xdata);
int32_t
afr_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t dev, dict_t *params);
+ loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata);
int32_t
afr_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
+ loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata);
int32_t
afr_unlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc);
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t
afr_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
+ loc_t *loc, int flags, dict_t *xdata);
int32_t
afr_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc);
+ loc_t *oldloc, loc_t *newloc, dict_t *xdata);
int32_t
afr_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc);
+ loc_t *oldloc, loc_t *newloc, dict_t *xdata);
int
afr_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *oldloc, dict_t *params);
-
-int32_t
-afr_setdents (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t flags, dir_entry_t *entries, int32_t count);
+ const char *linkpath, loc_t *oldloc, mode_t umask, dict_t *params);
#endif /* __DIR_WRITE_H__ */
diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c
index dd832ffe7..40e5abd3a 100644
--- a/xlators/cluster/afr/src/afr-inode-read.c
+++ b/xlators/cluster/afr/src/afr-inode-read.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -44,9 +35,6 @@
#include "compat-errno.h"
#include "compat.h"
-#include "afr.h"
-
-
/**
* Common algorithm for inode read calls:
*
@@ -61,15 +49,16 @@
int32_t
afr_access_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno)
+ xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int last_tried = -1;
- int this_try = -1;
- int read_child = -1;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int32_t *last_index = NULL;
+ int32_t next_call_child = -1;
+ int32_t read_child = -1;
+ int32_t *fresh_children = NULL;
priv = this->private;
children = priv->children;
@@ -79,33 +68,28 @@ afr_access_cbk (call_frame_t *frame, void *cookie,
read_child = (long) cookie;
if (op_ret == -1) {
- retry:
- last_tried = local->cont.access.last_tried;
-
- if (all_tried (last_tried, priv->child_count)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s: all subvolumes tried, going out",
- local->loc.path);
+ last_index = &local->cont.access.last_index;
+ fresh_children = local->fresh_children;
+ next_call_child = afr_next_call_child (fresh_children,
+ local->child_up,
+ priv->child_count,
+ last_index, read_child);
+ if (next_call_child < 0)
goto out;
- }
- this_try = ++local->cont.access.last_tried;
-
- if (this_try == read_child) {
- goto retry;
- }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_access_cbk,
(void *) (long) read_child,
- children[this_try],
- children[this_try]->fops->access,
- &local->loc, local->cont.access.mask);
+ children[next_call_child],
+ children[next_call_child]->fops->access,
+ &local->loc, local->cont.access.mask,
+ NULL);
}
out:
if (unwind) {
- AFR_STACK_UNWIND (access, frame, op_ret, op_errno);
+ AFR_STACK_UNWIND (access, frame, op_ret, op_errno, xdata);
}
return 0;
@@ -113,15 +97,16 @@ out:
int32_t
-afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
+ dict_t *xdata)
{
- afr_private_t * priv = NULL;
- xlator_t ** children = NULL;
- int call_child = 0;
- afr_local_t *local = NULL;
- int32_t read_child = -1;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
+ afr_private_t *priv = NULL;
+ xlator_t **children = NULL;
+ int call_child = 0;
+ afr_local_t *local = NULL;
+ int32_t op_errno = 0;
+ int32_t read_child = -1;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -132,25 +117,29 @@ afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
children = priv->children;
- ALLOC_OR_GOTO (local, afr_local_t, out);
-
- read_child = afr_read_child (this, loc->inode);
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- if ((read_child >= 0) && (priv->child_up[read_child])) {
- call_child = read_child;
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
+ goto out;
- local->cont.access.last_tried = -1;
+ local->fresh_children = afr_children_create (priv->child_count);
+ if (!local->fresh_children) {
+ op_errno = ENOMEM;
+ goto out;
+ }
- } else {
- call_child = afr_first_up_child (priv);
- if (call_child == -1) {
- op_errno = ENOTCONN;
- gf_log (this->name, GF_LOG_INFO,
- "%s: no child is up", loc->path);
- goto out;
- }
- local->cont.access.last_tried = call_child;
+ read_child = afr_inode_get_read_ctx (this, loc->inode,
+ local->fresh_children);
+ ret = afr_get_call_child (this, local->child_up, read_child,
+ local->fresh_children,
+ &call_child,
+ &local->cont.access.last_index);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
}
loc_copy (&local->loc, loc);
@@ -158,14 +147,14 @@ afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
STACK_WIND_COOKIE (frame, afr_access_cbk,
(void *) (long) call_child,
- children[call_child], children[call_child]->fops->access,
- loc, mask);
+ children[call_child],
+ children[call_child]->fops->access,
+ loc, mask, xdata);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (access, frame, op_ret, op_errno);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (access, frame, -1, op_errno, NULL);
return 0;
}
@@ -177,15 +166,16 @@ out:
int32_t
afr_stat_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- struct iatt *buf)
+ struct iatt *buf, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int last_tried = -1;
- int this_try = -1;
- int read_child = -1;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int32_t *last_index = NULL;
+ int32_t next_call_child = -1;
+ int32_t read_child = -1;
+ int32_t *fresh_children = NULL;
priv = this->private;
children = priv->children;
@@ -195,36 +185,27 @@ afr_stat_cbk (call_frame_t *frame, void *cookie,
local = frame->local;
if (op_ret == -1) {
- retry:
- last_tried = local->cont.stat.last_tried;
-
- if (all_tried (last_tried, priv->child_count)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s: all subvolumes tried, going out",
- local->loc.path);
+ last_index = &local->cont.stat.last_index;
+ fresh_children = local->fresh_children;
+ next_call_child = afr_next_call_child (fresh_children,
+ local->child_up,
+ priv->child_count,
+ last_index, read_child);
+ if (next_call_child < 0)
goto out;
- }
- this_try = ++local->cont.stat.last_tried;
-
- if (this_try == read_child) {
- goto retry;
- }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_stat_cbk,
(void *) (long) read_child,
- children[this_try],
- children[this_try]->fops->stat,
- &local->loc);
+ children[next_call_child],
+ children[next_call_child]->fops->stat,
+ &local->loc, NULL);
}
out:
if (unwind) {
- if (buf)
- buf->ia_ino = local->cont.stat.ino;
-
- AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, buf);
+ AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata);
}
return 0;
@@ -232,15 +213,15 @@ out:
int32_t
-afr_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
+afr_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int32_t read_child = -1;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ xlator_t **children = NULL;
int call_child = 0;
- int32_t op_ret = -1;
int32_t op_errno = 0;
+ int32_t read_child = -1;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -251,43 +232,40 @@ afr_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
children = priv->children;
- ALLOC_OR_GOTO (local, afr_local_t, out);
-
- frame->local = local;
-
- read_child = afr_read_child (this, loc->inode);
-
- if ((read_child >= 0) && (priv->child_up[read_child])) {
- call_child = read_child;
-
- local->cont.stat.last_tried = -1;
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- } else {
- call_child = afr_first_up_child (priv);
- if (call_child == -1) {
- op_errno = ENOTCONN;
- gf_log (this->name, GF_LOG_INFO,
- "%s: no child is up", loc->path);
- goto out;
- }
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
+ goto out;
- local->cont.stat.last_tried = call_child;
+ local->fresh_children = afr_children_create (priv->child_count);
+ if (!local->fresh_children) {
+ op_errno = ENOMEM;
+ goto out;
}
+ read_child = afr_inode_get_read_ctx (this, loc->inode,
+ local->fresh_children);
+ ret = afr_get_call_child (this, local->child_up, read_child,
+ local->fresh_children,
+ &call_child,
+ &local->cont.stat.last_index);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
+ }
loc_copy (&local->loc, loc);
- local->cont.stat.ino = loc->inode->ino;
-
STACK_WIND_COOKIE (frame, afr_stat_cbk, (void *) (long) call_child,
children[call_child],
children[call_child]->fops->stat,
- loc);
+ loc, xdata);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, NULL);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -299,15 +277,17 @@ out:
int32_t
afr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int last_tried = -1;
- int this_try = -1;
- int read_child = -1;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ xlator_t **children = NULL;
+ int unwind = 1;
+ int32_t *last_index = NULL;
+ int32_t next_call_child = -1;
+ int32_t read_child = -1;
+ int32_t *fresh_children = NULL;
priv = this->private;
children = priv->children;
@@ -317,36 +297,27 @@ afr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
read_child = (long) cookie;
if (op_ret == -1) {
- retry:
- last_tried = local->cont.fstat.last_tried;
-
- if (all_tried (last_tried, priv->child_count)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%p: all subvolumes tried, going out",
- local->fd);
+ last_index = &local->cont.fstat.last_index;
+ fresh_children = local->fresh_children;
+ next_call_child = afr_next_call_child (fresh_children,
+ local->child_up,
+ priv->child_count,
+ last_index, read_child);
+ if (next_call_child < 0)
goto out;
- }
- this_try = ++local->cont.fstat.last_tried;
-
- if (this_try == read_child) {
- goto retry;
- }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_fstat_cbk,
(void *) (long) read_child,
- children[this_try],
- children[this_try]->fops->fstat,
- local->fd);
+ children[next_call_child],
+ children[next_call_child]->fops->fstat,
+ local->fd, NULL);
}
out:
if (unwind) {
- if (buf)
- buf->ia_ino = local->cont.fstat.ino;
-
- AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf);
+ AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata);
}
return 0;
@@ -355,15 +326,15 @@ out:
int32_t
afr_fstat (call_frame_t *frame, xlator_t *this,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ xlator_t **children = NULL;
int call_child = 0;
- int32_t read_child = -1;
- int32_t op_ret = -1;
int32_t op_errno = 0;
+ int32_t read_child = 0;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -375,44 +346,51 @@ afr_fstat (call_frame_t *frame, xlator_t *this,
children = priv->children;
- ALLOC_OR_GOTO (local, afr_local_t, out);
+ VALIDATE_OR_GOTO (fd->inode, out);
- frame->local = local;
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- VALIDATE_OR_GOTO (fd->inode, out);
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
+ goto out;
- read_child = afr_read_child (this, fd->inode);
+ local->fresh_children = afr_children_create (priv->child_count);
+ if (!local->fresh_children) {
+ op_errno = ENOMEM;
+ goto out;
+ }
- if ((read_child >= 0) && (priv->child_up[read_child])) {
- call_child = read_child;
+ read_child = afr_inode_get_read_ctx (this, fd->inode,
+ local->fresh_children);
- local->cont.fstat.last_tried = -1;
- } else {
- call_child = afr_first_up_child (priv);
- if (call_child == -1) {
- op_errno = ENOTCONN;
- gf_log (this->name, GF_LOG_INFO,
- "%p: no child is up", fd);
- goto out;
- }
- local->cont.fstat.last_tried = call_child;
+ ret = afr_get_call_child (this, local->child_up, read_child,
+ local->fresh_children,
+ &call_child,
+ &local->cont.fstat.last_index);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
}
- local->cont.fstat.ino = fd->inode->ino;
local->fd = fd_ref (fd);
+ ret = afr_open_fd_fix (frame, this, _gf_false);
+ if (ret) {
+ op_errno = -ret;
+ goto out;
+ }
STACK_WIND_COOKIE (frame, afr_fstat_cbk, (void *) (long) call_child,
children[call_child],
children[call_child]->fops->fstat,
- fd);
+ fd, xdata);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, NULL);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -424,15 +402,16 @@ out:
int32_t
afr_readlink_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- const char *buf, struct iatt *sbuf)
+ const char *buf, struct iatt *sbuf, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int last_tried = -1;
- int this_try = -1;
- int read_child = -1;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int32_t *last_index = NULL;
+ int32_t next_call_child = -1;
+ int32_t read_child = -1;
+ int32_t *fresh_children = NULL;
priv = this->private;
children = priv->children;
@@ -442,36 +421,28 @@ afr_readlink_cbk (call_frame_t *frame, void *cookie,
read_child = (long) cookie;
if (op_ret == -1) {
- retry:
- last_tried = local->cont.readlink.last_tried;
-
- if (all_tried (last_tried, priv->child_count)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s: all subvolumes tried, going out",
- local->loc.path);
+ last_index = &local->cont.readlink.last_index;
+ fresh_children = local->fresh_children;
+ next_call_child = afr_next_call_child (fresh_children,
+ local->child_up,
+ priv->child_count,
+ last_index, read_child);
+ if (next_call_child < 0)
goto out;
- }
- this_try = ++local->cont.readlink.last_tried;
-
- if (this_try == read_child) {
- goto retry;
- }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_readlink_cbk,
(void *) (long) read_child,
- children[this_try],
- children[this_try]->fops->readlink,
+ children[next_call_child],
+ children[next_call_child]->fops->readlink,
&local->loc,
- local->cont.readlink.size);
+ local->cont.readlink.size, NULL);
}
out:
if (unwind) {
- if (sbuf)
- sbuf->ia_ino = local->cont.readlink.ino;
-
- AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno, buf, sbuf);
+ AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno, buf, sbuf,
+ xdata);
}
return 0;
@@ -480,15 +451,15 @@ out:
int32_t
afr_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size)
+ loc_t *loc, size_t size, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- xlator_t ** children = NULL;
- int call_child = 0;
- afr_local_t *local = NULL;
- int32_t read_child = -1;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
+ afr_private_t *priv = NULL;
+ xlator_t **children = NULL;
+ int call_child = 0;
+ afr_local_t *local = NULL;
+ int32_t op_errno = 0;
+ int32_t read_child = -1;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -499,45 +470,43 @@ afr_readlink (call_frame_t *frame, xlator_t *this,
children = priv->children;
- ALLOC_OR_GOTO (local, afr_local_t, out);
-
- frame->local = local;
-
- read_child = afr_read_child (this, loc->inode);
-
- if ((read_child >= 0) && (priv->child_up[read_child])) {
- call_child = read_child;
-
- local->cont.readlink.last_tried = -1;
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
- } else {
- call_child = afr_first_up_child (priv);
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
+ goto out;
- if (call_child == -1) {
- op_errno = ENOTCONN;
- gf_log (this->name, GF_LOG_INFO,
- "%s: no child is up", loc->path);
- goto out;
- }
-
- local->cont.readlink.last_tried = call_child;
+ local->fresh_children = afr_children_create (priv->child_count);
+ if (!local->fresh_children) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+ read_child = afr_inode_get_read_ctx (this, loc->inode,
+ local->fresh_children);
+ ret = afr_get_call_child (this, local->child_up, read_child,
+ local->fresh_children,
+ &call_child,
+ &local->cont.readlink.last_index);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
}
loc_copy (&local->loc, loc);
local->cont.readlink.size = size;
- local->cont.readlink.ino = loc->inode->ino;
STACK_WIND_COOKIE (frame, afr_readlink_cbk,
(void *) (long) call_child,
- children[call_child], children[call_child]->fops->readlink,
- loc, size);
+ children[call_child],
+ children[call_child]->fops->readlink,
+ loc, size, xdata);
- op_ret = 0;
+ ret = 0;
out:
- if (op_ret == -1) {
- AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno, NULL, NULL);
- }
+ if (ret < 0)
+ AFR_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL, NULL);
return 0;
}
@@ -600,15 +569,16 @@ __filter_xattrs (dict_t *dict)
int32_t
afr_getxattr_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict)
+ dict_t *dict, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int last_tried = -1;
- int this_try = -1;
- int read_child = -1;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int32_t *last_index = NULL;
+ int32_t next_call_child = -1;
+ int32_t read_child = -1;
+ int32_t *fresh_children = NULL;
priv = this->private;
children = priv->children;
@@ -618,28 +588,23 @@ afr_getxattr_cbk (call_frame_t *frame, void *cookie,
read_child = (long) cookie;
if (op_ret == -1) {
- retry:
- last_tried = local->cont.getxattr.last_tried;
-
- if (all_tried (last_tried, priv->child_count)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s: all subvolumes tried, going out",
- local->loc.path);
+ last_index = &local->cont.getxattr.last_index;
+ fresh_children = local->fresh_children;
+ next_call_child = afr_next_call_child (fresh_children,
+ local->child_up,
+ priv->child_count,
+ last_index, read_child);
+ if (next_call_child < 0)
goto out;
- }
- this_try = ++local->cont.getxattr.last_tried;
-
- if (this_try == read_child) {
- goto retry;
- }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_getxattr_cbk,
(void *) (long) read_child,
- children[this_try],
- children[this_try]->fops->getxattr,
+ children[next_call_child],
+ children[next_call_child]->fops->getxattr,
&local->loc,
- local->cont.getxattr.name);
+ local->cont.getxattr.name,
+ NULL);
}
out:
@@ -647,35 +612,336 @@ out:
if (op_ret >= 0 && dict)
__filter_xattrs (dict);
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
}
return 0;
}
int32_t
-afr_getxattr_unwind (call_frame_t *frame,
- int op_ret, int op_errno, dict_t *dict)
+afr_getxattr_unwind (call_frame_t *frame, int op_ret, int op_errno,
+ dict_t *dict, dict_t *xdata)
+
+{
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+int32_t
+afr_getxattr_clrlk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *dict, dict_t *xdata)
+{
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ xlator_t **children = NULL;
+ dict_t *xattr = NULL;
+ char *tmp_report = NULL;
+ char lk_summary[1024] = {0,};
+ int serz_len = 0;
+ int32_t callcnt = 0;
+ long int cky = 0;
+ int ret = 0;
+
+ priv = this->private;
+ children = priv->children;
+
+ local = frame->local;
+ cky = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (op_ret == -1)
+ local->child_errno[cky] = op_errno;
+
+ if (!local->dict)
+ local->dict = dict_new ();
+ if (local->dict) {
+ ret = dict_get_str (dict, local->cont.getxattr.name,
+ &tmp_report);
+ if (ret)
+ goto unlock;
+ ret = dict_set_dynstr (local->dict,
+ children[cky]->name,
+ gf_strdup (tmp_report));
+ if (ret)
+ goto unlock;
+ }
+ }
+unlock:
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ xattr = dict_new ();
+ if (!xattr) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ ret = dict_serialize_value_with_delim (local->dict,
+ lk_summary,
+ &serz_len, '\n');
+ if (ret) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Error serializing dictionary");
+ goto unwind;
+ }
+ if (serz_len == -1)
+ snprintf (lk_summary, sizeof (lk_summary),
+ "No locks cleared.");
+ ret = dict_set_dynstr (xattr, local->cont.getxattr.name,
+ gf_strdup (lk_summary));
+ if (ret) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Error setting dictionary");
+ goto unwind;
+ }
+
+ unwind:
+ // Updating child_errno with more recent 'events'
+ local->child_errno[cky] = op_errno;
+ op_errno = afr_resultant_errno_get (NULL, local->child_errno,
+ priv->child_count);
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata);
+ if (xattr)
+ dict_unref (xattr);
+ }
+
+ return ret;
+}
+
+/**
+ * node-uuid cbk uses next child querying mechanism
+ */
+int32_t
+afr_getxattr_node_uuid_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *dict, dict_t *xdata)
{
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ xlator_t **children = NULL;
+ int unwind = 1;
+ int curr_call_child = 0;
+
+ priv = this->private;
+ children = priv->children;
+
+ local = frame->local;
+
+ if (op_ret == -1) { /** query the _next_ child */
+
+ /**
+ * _current_ becomes _next_
+ * If done with all childs and yet no success; give up !
+ */
+ curr_call_child = (int) ((long)cookie);
+ if (++curr_call_child == priv->child_count)
+ goto unwind;
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "op_ret (-1): Re-querying afr-child (%d/%d)",
+ curr_call_child, priv->child_count);
+
+ unwind = 0;
+ STACK_WIND_COOKIE (frame, afr_getxattr_node_uuid_cbk,
+ (void *) (long) curr_call_child,
+ children[curr_call_child],
+ children[curr_call_child]->fops->getxattr,
+ &local->loc,
+ local->cont.getxattr.name,
+ NULL);
+ }
+
+ unwind:
+ if (unwind)
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, NULL);
+
return 0;
}
int32_t
+afr_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *dict, dict_t *xdata)
+{
+ afr_local_t *local = NULL;
+ int32_t callcnt = 0;
+ int ret = 0;
+ char *xattr = NULL;
+ char *xattr_serz = NULL;
+ char xattr_cky[1024] = {0,};
+ dict_t *nxattr = NULL;
+ long cky = 0;
+ int32_t padding = 0;
+ int32_t tlen = 0;
+
+ if (!frame || !frame->local || !this) {
+ gf_log ("", GF_LOG_ERROR, "possible NULL deref");
+ goto out;
+ }
+
+ local = frame->local;
+ cky = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (!dict || (op_ret < 0))
+ goto out;
+
+ if (!local->dict)
+ local->dict = dict_new ();
+
+ if (local->dict) {
+ ret = dict_get_str (dict,
+ local->cont.getxattr.name,
+ &xattr);
+ if (ret)
+ goto out;
+
+ xattr = gf_strdup (xattr);
+
+ (void)snprintf (xattr_cky, 1024, "%s-%ld",
+ local->cont.getxattr.name, cky);
+ ret = dict_set_dynstr (local->dict,
+ xattr_cky, xattr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Cannot set xattr cookie key");
+ goto out;
+ }
+
+ local->cont.getxattr.xattr_len += strlen (xattr) + 1;
+ }
+ }
+ out:
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (!local->cont.getxattr.xattr_len)
+ goto unwind;
+
+ nxattr = dict_new ();
+ if (!nxattr)
+ goto unwind;
+
+ /* extra bytes for decorations (brackets and <>'s) */
+ padding += strlen (this->name) + strlen (AFR_PATHINFO_HEADER) + 4;
+ local->cont.getxattr.xattr_len += (padding + 2);
+
+ xattr_serz = GF_CALLOC (local->cont.getxattr.xattr_len,
+ sizeof (char), gf_common_mt_char);
+
+ if (!xattr_serz)
+ goto unwind;
+
+ /* the xlator info */
+ (void) sprintf (xattr_serz, "(<"AFR_PATHINFO_HEADER"%s> ",
+ this->name);
+
+ /* actual series of pathinfo */
+ ret = dict_serialize_value_with_delim (local->dict,
+ xattr_serz + strlen (xattr_serz),
+ &tlen, ' ');
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Error serializing"
+ " dictionary");
+ goto unwind;
+ }
+
+ /* closing part */
+ *(xattr_serz + padding + tlen) = ')';
+ *(xattr_serz + padding + tlen + 1) = '\0';
+
+ ret = dict_set_dynstr (nxattr, local->cont.getxattr.name,
+ xattr_serz);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo"
+ " key in dict");
+
+ unwind:
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, nxattr,
+ xdata);
+
+ if (nxattr)
+ dict_unref (nxattr);
+ }
+
+ return ret;
+}
+
+static gf_boolean_t
+afr_is_special_xattr (const char *name, fop_getxattr_cbk_t *cbk)
+{
+ gf_boolean_t is_spl = _gf_true;
+
+ GF_ASSERT (cbk);
+ if (!cbk) {
+ is_spl = _gf_false;
+ goto out;
+ }
+
+ if (!strcmp (name, GF_XATTR_PATHINFO_KEY))
+ *cbk = afr_getxattr_pathinfo_cbk;
+
+ else if (!strncmp (name, GF_XATTR_CLRLK_CMD,
+ strlen (GF_XATTR_CLRLK_CMD)))
+ *cbk = afr_getxattr_clrlk_cbk;
+ else
+ is_spl = _gf_false;
+
+out:
+ return is_spl;
+}
+
+static void
+afr_getxattr_frm_all_children (xlator_t *this, call_frame_t *frame,
+ const char *name, loc_t *loc,
+ fop_getxattr_cbk_t cbk)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ xlator_t **children = NULL;
+ int i = 0;
+
+ priv = this->private;
+ children = priv->children;
+
+ local = frame->local;
+ local->call_count = priv->child_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ STACK_WIND_COOKIE (frame, cbk,
+ (void *) (long) i,
+ children[i], children[i]->fops->getxattr,
+ loc, name, NULL);
+ }
+ return;
+}
+
+int32_t
afr_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name)
+ loc_t *loc, const char *name, dict_t *xdata)
{
- afr_private_t * priv = NULL;
- xlator_t ** children = NULL;
- int call_child = 0;
- afr_local_t * local = NULL;
- xlator_list_t * trav = NULL;
- xlator_t ** sub_volumes = NULL;
- int read_child = -1;
- int i = 0;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
+ afr_private_t *priv = NULL;
+ xlator_t **children = NULL;
+ int call_child = 0;
+ afr_local_t *local = NULL;
+ xlator_list_t *trav = NULL;
+ xlator_t **sub_volumes = NULL;
+ int i = 0;
+ int32_t op_errno = 0;
+ int32_t read_child = -1;
+ int ret = -1;
+ fop_getxattr_cbk_t cbk = NULL;
VALIDATE_OR_GOTO (frame, out);
@@ -687,26 +953,79 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
children = priv->children;
- ALLOC_OR_GOTO (local, afr_local_t, out);
- frame->local = local;
+ AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
+ local = frame->local;
+
+ ret = afr_local_init (local, priv, &op_errno);
+ if (ret < 0)
+ goto out;
loc_copy (&l